我正在开发一个程序,它可以创建几个pdf文档,并将不同的文本放在同一个位置。文本应该放在一个特定的区域,如果它的宽度不适合它应该包装。它还有一个自定义字体,在该区域可能会有不同的对齐方式。它应该与顶部垂直对齐,因为当该区域布置为三条线,而我只有一条线时,它应该出现在顶部。最后,我需要在字体大小方面保持领先地位。
精确的文本定位很重要(例如,我需要“Hello world”中“H”的左上角明确显示为0,100)。
现在,我正在使用
canvas.showTextAligned(paragraph, 0, 300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
然而,当我尝试用不同的字体实现它时,它与期望的y=300有不同的偏移量。此外,偏移量因字体而异。对于Helvetica(使用50 fontSize的所有地方),偏移量约为13像素,对于Oswald,偏移量约为17像素,对于SedgwickAveDisplay,偏移量为90像素。为了调试,我在段落中添加了边框,事情变得更加奇怪。
我的代码创建pdf的完整片段如下:
public byte[] createBadgeInMemory(int i) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
PdfDocument newPdf = new PdfDocument(new PdfWriter(out));
srcPdf.copyPagesTo(1,1,newPdf);
PdfPage page = newPdf.getFirstPage();
PdfCanvas pdfCanvas = new PdfCanvas(page);
Canvas canvas = new Canvas(pdfCanvas, newPdf, pageSize);
File defaultFont = new File("src/main/resources/fonts/Helvetica.otf");
PdfFont font = PdfFontFactory
.createFont(fontPath == null ? defaultFont.getAbsolutePath() : fontPath,
PdfEncodings.IDENTITY_H, true);
String value = "Example word";
Paragraph paragraph = new Paragraph(value);
float textWidth = font.getWidth("Example", 50);
paragraph.setWidth(textWidth);
switch (alignment) {
case("CENTER"):
textWidth /= 2;
break;
case("RIGHT"):
break;
default:
textWidth = 0;
break;
}
paragraph.setFont(font)
.setFontSize(fontSize)
.setFixedLeading(fontSize)
.setFontColor(new DeviceRgb(red, green, blue))
.setMargin(0)
.setPadding(0);
paragraph.setBorderTop(new DashedBorder(Color.BLACK, 0.5f))
.setBorderBottom(new DashedBorder(Color.BLACK, 0.5f))
.setBorderRight(new DashedBorder(Color.BLACK, 0.5f));
paragraph.setHyphenation(new HyphenationConfig(0,
"Example".length()));
canvas.showTextAligned(paragraph,
0 + textWidth,
300,
TextAlignment.valueOf(alignment),
VerticalAlignment.TOP);
newPdf.close();
return out.toByteArray();
}
我需要你的帮助。我做错了什么,或者是否有其他方法在特定区域使用对齐和字体布局文本?提前谢谢你。
更新21.09.17也尝试变体从这个问题与SedgwickAveDisplay:
paragraph.setHorizontalAlignment(HorizontalAlignment.LEFT);
paragraph.setVerticalAlignment(VerticalAlignment.TOP);
paragraph.setFixedPosition( 0, 300 - textHeight, "Example".length());
doc.add(paragraph);
结果与第二张截图上的结果相同。
最后,我创造了一个适合我的变体。
pdfCanvas.beginText()
.setFontAndSize(font, fontSize)
.setLeading(fontSize)
.moveText(0, 300);
numberOfLines = 0;
sumOfShifts = 0;
float maxWidth = computeStringWidth("Exaxple");
String[] words = value.split("\\s");
StringBuilder line = new StringBuilder();
line.append(words[0]);
float spaceWidth = computeStringWidth(" ") ;
float lineWidth;
for (int index = 1; index < words.length; index++) {
String word = words[index];
float wordWidth = computeStringWidth(word) ;
lineWidth = computeStringWidth(line.toString()) ;
if (lineWidth + spaceWidth + wordWidth <= maxWidth) {
line.append(" ").append(word);
} else {
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
line.delete(0, line.length());
line.append(word);
}
}
if(line.length() != 0) {
lineWidth = computeStringWidth(line.toString()) ;
showTextAligned(alignment, pdfCanvas, line.toString(), lineWidth, maxWidth);
}
pdfCanvas.endText();
作为我使用的computeStringWidth(String str)
Toolkit.getToolkit().getFontLoader().computeStringWidth(String str, Font font);
从导入com.sun.javafx.tk.工具包
,字体来自javafx.scene.text.Font
。我选择它是因为我在应用程序的其他部分使用它。
showTextAligned(…)下面是我自己的方法:
private void showTextAligned(String alignment,
PdfCanvas pdfCanvas,
String line,
float lineWidth,
float maxWidth) {
switch (alignment) {
case "CENTER": {
float shift = (maxWidth - lineWidth) / 2 - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
case "RIGHT": {
float shift = maxWidth - lineWidth - sumOfShifts;
pdfCanvas.moveText(shift, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
sumOfShifts += shift;
break;
}
default:
pdfCanvas.moveText(0, 0);
if(numberOfLines == 0) pdfCanvas.showText(line);
else pdfCanvas.newlineShowText(line);
numberOfLines++;
break;
}
}
在我的项目中,我使用了我的变体,因为它给了我一个更深入地使用断字的机会(例如,我可以在未来添加功能,以避免将介词作为行中的最后一个单词)。
这是一个特定于字体的问题。iText猜测关于字体字形的信息,即错误的bbox。
有一种快速而肮脏的方法来调整这种行为。可以为文本创建自定义渲染器,并调整其中的计算位置。此类课程的一个例子如下:
class CustomTextRenderer extends TextRenderer {
private CustomTextRenderer(Text text) {
super(text);
}
@Override
public LayoutResult layout(LayoutContext layoutContext) {
LayoutResult result = super.layout(layoutContext);
Rectangle oldBbox = this.occupiedArea.getBBox().clone();
// you can also make the height more than font size or less if needed
this.occupiedArea.setBBox(oldBbox.moveUp(oldBbox.getHeight() - fontSize).setHeight(fontSize));
yLineOffset = fontSize * 0.8f; // here you config the proportion of the ascender
return result;
}
@Override
public IRenderer getNextRenderer() {
return new CustomTextRenderer((Text) modelElement);
}
}
为了应用新的渲染逻辑,必须以以下方式使用它:
Text text = new Text(value);
text.setNextRenderer(new CustomTextRenderer(text));
Paragraph paragraph = new Paragraph(text);
请注意,你必须非常小心这种低层次的布局,注意你正在做的事情,并尽可能少地使用它。
我正在使用IText7从html字符串生成pdf。现在,我需要对段落应用自定义颜色和自定义字体或字体系列。 如何使用Itext7实现这一点? 谢谢
问题内容: 我正在尝试在使用wkhtmltopdf生成的PDF中使用自定义字体。我读到您不能使用google webfonts,而wkhtmltopdf使用truetype .ttf文件。谁能确认?因此,我从Google webfont下载了一个.ttf文件,并将其放入服务器中,然后使用了字体: 和字体系列: 现在应该以Jolly Lodger字体呈现的文本根本没有出现,页面为空白。 我究竟做错了
问题内容: 我有一台Mac,并且安装了一种名为“ 7 Segment”的字体(它显示在Font Book中)。当我使用Helvetica(或类似字体)而不是浏览器的默认字体时,它仍然没有显示正确的字体。该页面仅需要在此计算机上显示。我将如何使用此页面上的字体?谢谢。 问题答案: 您需要使用css-property font-face来声明您的字体。 例:
有人知道记事本++中使用的字体吗?它们是它自己的字体还是系统的字体,是否可以在记事本++(设置->样式配置器->字体样式)中使用不同的(非系统的,用户创建的)字体,或者只是编辑现有的字体?
问题内容: 我看到一些新网站在其网站上使用自定义字体(常规Arial,Tahoma等除外)。 并且它们支持大量的浏览器。 怎么做到的?同时,如果可能的话,还会阻止人们自由下载字体。 问题答案: 通常,您可以在CSS中使用自定义字体。这是一个非常基本的示例: 然后,简单地在特定元素上使用字体: (是您的选择器)。 请注意,某些字体格式并非在所有浏览器上都有效;您可以使用fontsquirrel.co
问题内容: 我正在尝试在JFrame中使用特殊字体,但遇到了问题。我有一个这样定义的JLabel: 并且我有一个名为CUSTOMFONT-MEDIUM.TTF(TrueType字体)的文件,但是编写了以下内容: 代码会编译,并且一切正常,除了不会显示“ lab”,因此没有文本。我想这是因为我从未指定字体大小,但是我所做的任何尝试都失败了。有人可以帮我吗? 问题答案: 您创建的字体必须先在中注册,以