IText7 如何获取文言文档格式的文本位置?

问题描述 投票:0回答:1

我的意思是文言文档格式

段落由行组成,第一行在最右边,第二行在第一行的左边,依此类推。 该行由字符组成,第一个字符在最上面,第二个字符在第一个字符的下面,依此类推。

我有文言文档格式的文件LR-10709-24-25.pdf,出于某种原因我需要文本的位置进行分析。

  1. 将程序(见下文)应用于普通英语格式的history-2-3.pdf,得到正确的结果:

enter image description here

  1. 将相同的程序应用于LR-10709-24-25.pdf,得到了非常错误的结果:

enter image description here

  1. 我猜这是关于坐标,当前变换矩阵,textMatrix,TextRenderInfo,但我需要帮助来通过这个问题来理解这些东西。

这是我的程序

using iText.Kernel.Colors;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Canvas;
using iText.Kernel.Pdf.Canvas.Parser;
using iText.Kernel.Pdf.Canvas.Parser.Data;
using iText.Kernel.Pdf.Canvas.Parser.Listener;
using System.Text;

string srcFileName = "LR-10709-24-25.pdf";
string destFileName = "LR-10709-24-25-enclose.pdf";
//string srcFileName = "history-2-3.pdf";
//string destFileName = "history-2-3-enclose.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfReader(srcFileName), new PdfWriter(destFileName));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pdfDoc.GetNumberOfPages(); i++)
{
    SimplePositionalTextEventListener listener = new SimplePositionalTextEventListener();
    new PdfCanvasProcessor(listener).ProcessPageContent(pdfDoc.GetPage(i + 1));
    List<SimpleTextWithRectangle> result = listener.GetResultantTextWithPosition();
    int R = 0, G = 0, B = 0;
    foreach (SimpleTextWithRectangle textWithRectangle in result)
    {
        R += 40; R = R % 256;
        G += 20; G = G % 256;
        B += 80; B = B % 256;
        PdfCanvas canvas = new PdfCanvas(pdfDoc.GetPage(i + 1));
        canvas.SetStrokeColor(new DeviceRgb(R, G, B));
        var rect = textWithRectangle.GetRectangle();
        canvas.Rectangle(rect);
        canvas.Stroke();
    }
}
pdfDoc.Close();

Console.WriteLine("Press any key to continue!");
Console.ReadKey();

class SimpleTextWithRectangle
{
    private Rectangle rectangle;
    private string text;

    public SimpleTextWithRectangle(Rectangle rectangle, String text)
    {
        this.rectangle = rectangle;
        this.text = text;
    }

    public Rectangle GetRectangle()
    {
        return rectangle;
    }
    public string GetText()
    {
        return text;
    }
}

class SimplePositionalTextEventListener : IEventListener
{
    private List<SimpleTextWithRectangle> textWithRectangleList = new List<SimpleTextWithRectangle>();
    private void renderText(TextRenderInfo renderInfo)
    {
        if (renderInfo.GetText().Trim().Length == 0)
            return;
        LineSegment ascent = renderInfo.GetAscentLine();
        LineSegment descent = renderInfo.GetDescentLine();
        float initX = descent.GetStartPoint().Get(0);
        float initY = descent.GetStartPoint().Get(1);
        float endX = ascent.GetEndPoint().Get(0);
        float endY = ascent.GetEndPoint().Get(1);

        Rectangle rectangle = new Rectangle(initX, initY, endX - initX, endY - initY);

        SimpleTextWithRectangle textWithRectangle = new SimpleTextWithRectangle(rectangle, renderInfo.GetText());
        textWithRectangleList.Add(textWithRectangle);
    }

    public List<SimpleTextWithRectangle> GetResultantTextWithPosition()
    {
        return textWithRectangleList;
    }
    public void EventOccurred(IEventData data, EventType type)
    {
        renderText((TextRenderInfo)data);
    }

    public ICollection<EventType> GetSupportedEvents()
    {
        return new List<EventType> { EventType.RENDER_TEXT };
    }
}

和两个pdf文件 历史-2-3.pdf LR-10709-24-25.pdf

itext7
1个回答
0
投票

iText文本解析目前仅正确支持水平书写模式,不支持垂直书写模式。它处理所有文本就像以水平模式编写一样。

在您的第二个 PDF 中,大多数字体都配置为使用垂直书写模式,只有一些字体用于水平书写模式。

您可以轻松识别以水平模式书写的字符,它们正确地包含在各自的边界框中。

另一方面,以垂直模式绘制的文本块的(不正确的)边界框从其宽度中间的第一个字符顶部开始,并向右延伸与该块向下包含的字符一样多的字符宽度。

要扩展 iText 以也支持垂直书写模式,您必须修复

PdfCanvasProcessor
(特别是它的
displayPdfString
方法,该方法始终水平推进
textMatrix
)和
TextRenderInfo
(始终像文本一样计算尺寸)是横写的)。

© www.soinside.com 2019 - 2024. All rights reserved.