java - 使用itextpdf为对齐的pdf文本添加下划线

标签 java pdf itextpdf

我正在尝试使用 itextpdf 在 pdf 中强调合理的测试,我认为我发现了一个错误,并且我真的很想解决这个问题。

当我按照 mailing lists 中的描述调用 getBaseline() 时下划线远远超出文本末尾,进入下一列。

        float lx = renderInfos.get(i).getBaseline().getStartPoint().get(0);
        float rx = renderInfos.get(i).getBaseline().getEndPoint().get(0);

enter image description here

可以下载原版pdf来自publisher's website

谢谢!

我在我尝试过的所有 itextpdf 版本上都看到了这一点,从 4.1.0 到最新的 5.5.0

将下划线代码与我无法共享的其他专有代码分开需要一些努力。如果您认为有帮助,我可以这样做。

如果这是一个错误,是否有一个问题跟踪器可以用来记录它?

PS (mkl):这里有一个简短的代码片段来重现该问题:

PdfReader reader = new PdfReader(...);

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(...));

for (int page = 1; page <= reader.getNumberOfPages(); page++)
{
    final List<TextRenderInfo> infos = new ArrayList<TextRenderInfo>();
    PdfTextExtractor.getTextFromPage(reader, page, new TextExtractionStrategy()
    {
        public void renderText(TextRenderInfo renderInfo)
        {
            infos.add(renderInfo);
        }

        public void renderImage(ImageRenderInfo renderInfo) { }
        public void endTextBlock() { }
        public void beginTextBlock() { }
        public String getResultantText() { return "";}
    });

    PdfContentByte content = stamper.getOverContent(page);
    for (TextRenderInfo info : infos)
    {
        float lx = info.getBaseline().getStartPoint().get(0);
        float rx = info.getBaseline().getEndPoint().get(0);
        float y = info.getBaseline().getEndPoint().get(1);
        content.moveTo(lx, y);
        content.lineTo(rx, y);
        content.stroke();
    }
}

stamper.close();

最佳答案

此问题背后的错误是 OP 收集他在某个列表 renderInfos 中的 renderText 中检索的 TextRenderInfo 对象,然后使用它们。 (在我添加到问题中以重现问题的示例代码中,我同样使用了列表 infos。)

TextRenderInfo 对象不会存储其出现时的整个图形状态,也不会计算稍后可以查询的所有属性。相反,当请求其属性时,它们是使用属性请求时的当前信息来计算的。

打电话时,例如TextRenderInfo 实例的 getBaseline() 方法,使用 getBaseline() 调用时解析器的图形状态计算基线。如果代码重现问题,这意味着基线是使用页面末尾内容流的图形状态设置来计算的。这尤其包括图形状态属性,例如字符和单词间距,它们对基线长度有影响。

因此,为了修复 OP 的代码,必须在 renderText 调用期间计算 TextRenderInfo 实例所需的所有信息。

例如要修复我添加到问题中以重现问题的代码,可以这样更改:

PdfReader reader = new PdfReader(...);

PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(...));

for (int page = 1; page <= reader.getNumberOfPages(); page++)
{
    final List<LineSegment> lines = new ArrayList<LineSegment>();
    PdfTextExtractor.getTextFromPage(reader, page, new TextExtractionStrategy()
    {
        public void renderText(TextRenderInfo renderInfo)
        {
            lines.add(renderInfo.getBaseline());
        }

        public void renderImage(ImageRenderInfo renderInfo) { }
        public void endTextBlock() { }
        public void beginTextBlock() { }
        public String getResultantText() { return "";}
    });

    PdfContentByte content = stamper.getOverContent(page);
    for (LineSegment line : lines)
    {
        float lx = line.getStartPoint().get(0);
        float rx = line.getEndPoint().get(0);
        float y = line.getEndPoint().get(1);
        content.moveTo(lx, y);
        content.lineTo(rx, y);
        content.stroke();
    }
}

stamper.close();

现在基线是在 renderText 调用期间计算的,因此是正确的:

enter image description here

PS:@Bruno 也许 JavaDoc 警告应该附加到 renderText 方法和 TextRenderInfo 类。

关于java - 使用itextpdf为对齐的pdf文本添加下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22312964/

相关文章:

java - 如何在 "X"no 之后显示插页式广告应用程序中的点击次数?

java - 如何忽略逗号

java - 3 个数字按升序排列,在 Java 中不使用条件语句。正如我根本无法使用 if 语句

生成雷达图的PHP方案

php - Apple Mail 不显示使用 Zend_Mail 发送的 PDF

java - 使用 itextpdf,PDF 的页面大小在横向和纵向之间始终相同

java - 文本pdf : set image in middle of text

java - lib 升级后 iText pdf 功能损坏 - 无法合并表格

Java toString 方法 - 打印不正确

Linux替代pdftk填写表格