我需要将一些动态文本放到pdf上。我需要验证文本没有溢出我允许用来放置文本的边界框。
由于
答案 0 :(得分:3)
iText5
处于维护模式,我建议您使用iText7
启动项目。 iText7
目前不提供用于复制的开箱即用机制,但它可以轻松地手动完成,因为布局引擎在iText7
中非常灵活。从技术上讲,它也可以在iText5
中完成,但我会为iText7
提供Java的答案,转换为C#对你来说应该不是问题。
基本思想是利用渲染器概念,尝试在给定区域中使用不同的字体大小布置段落,直到找到适合您的大小。二元搜索方法非常适合这里。
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
Document doc = new Document(pdfDoc);
String text = "...";
Rectangle area = new Rectangle(100, 100, 200, 200);
// Just draw a black box around to verify the result visually
new PdfCanvas(pdfDoc.addNewPage()).rectangle(area).setStrokeColor(Color.BLACK).stroke();
Paragraph p = new Paragraph(text);
IRenderer renderer = p.createRendererSubTree().setParent(doc.getRenderer());
LayoutArea layoutArea = new LayoutArea(1, area);
// lFontSize means the font size which will be definitely small enough to fit all the text into the box.
// rFontSize is the maximum bound for the font size you want to use. The only constraint is that it should be greater than lFontSize
// Set rFontSize to smaller value if you don't want the font size to scale upwards
float lFontSize = 0.0001f, rFontSize = 10000;
// Binary search. Can be replaced with while (Math.abs(lFontSize - rFontSize) < eps). It is a matter of implementation/taste
for (int i = 0; i < 100; i++) {
float mFontSize = (lFontSize + rFontSize) / 2;
p.setFontSize(mFontSize);
LayoutResult result = renderer.layout(new LayoutContext(layoutArea));
if (result.getStatus() == LayoutResult.FULL) {
lFontSize = mFontSize;
} else {
rFontSize = mFontSize;
}
}
// lFontSize is guaranteed to be small enough to fit all the text. Using it.
float finalFontSize = lFontSize;
System.out.println("Final font size: " + finalFontSize);
p.setFontSize(finalFontSize);
// We need to layout the final time with the final font size set.
renderer.layout(new LayoutContext(layoutArea));
renderer.draw(new DrawContext(pdfDoc, new PdfCanvas(pdfDoc.getPage(1))));
doc.close();
输出:
Final font size: 5.7393746
视觉结果: