我正在尝试使用 itextpdf 在 pdf 中强调合理的测试,我认为我发现了一个错误,并且我真的很想解决这个问题。
当我按照 mailing lists 中的描述调用 getBaseline() 时下划线远远超出文本末尾,进入下一列。
float lx = renderInfos.get(i).getBaseline().getStartPoint().get(0);
float rx = renderInfos.get(i).getBaseline().getEndPoint().get(0);
可以下载原版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
调用期间计算的,因此是正确的:
PS:@Bruno 也许 JavaDoc 警告应该附加到 renderText
方法和 TextRenderInfo
类。
关于java - 使用itextpdf为对齐的pdf文本添加下划线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22312964/