【发布时间】:2011-03-29 20:47:19
【问题描述】:
我想在 iText 中使用标准的粗体 Arial 字体,但如果字符不存在为粗体,我想默认为 Arial Unicode。有没有办法在 iText 中组合字体?我搜索了一个 Arial Unicode 的粗体 ttf 文件,但我没有找到。
【问题讨论】:
我想在 iText 中使用标准的粗体 Arial 字体,但如果字符不存在为粗体,我想默认为 Arial Unicode。有没有办法在 iText 中组合字体?我搜索了一个 Arial Unicode 的粗体 ttf 文件,但我没有找到。
【问题讨论】:
字体通常被绘制为“填充形状”。您可以通过更改文本渲染模式来添加一定宽度的笔划来做“穷人的粗体”。
看起来 iText 已经实现了这个功能(以及 PdfChunk.java 中的“穷人的斜体”。它使用的笔画宽度为字体大小的 1/30。
因此,如果您只要求 Arial Unicode 的粗体版本,您应该已经得到“穷人的粗体”。
至于组合字体,我不知道有一个系统可以这样做,不。您可以通过分解块在更高级别上执行类似的操作。比如:
void addTextToPara(Paragraph paragraph, String string, Font font, Font otherFont) {
BaseFont mainfont = font.getBaseFont();
StringBuffer curChunk = new StringBuffer();
StringBuffer otherChunk = new StringBuffer();
for (int curCharIdx = 0; curCharIdx< string.length(); ++curCharIdx) {
char curChar = string.charAt(curCharIdx);
byte charBytes[] = mainFont.convertToBytes(curChar);
if (charBytes == null || charBytes.length == 0) {
// can't represent that character in the main font
if (curChunk.length() > 0) {
paragraph.add(new Chunk(curChunk.toString(), font);
curChunk.setLength(0);
}
otherChunk.append(curChar);
} else {
if (otherChunk.length() > 0) {
paragraph.add(new Chunk(otherChunk.toString(), otherFont);
otherChunk.setLength(0);
}
curChunk.append(curChar);
// can represent the character with the main font
}
}
if (curChunk.length() > 0) {
paragraph.add(new Chunk(curChunk.toString(), font);
} else if (otherChunk.length() > 0) {
paragraph.add(new Chunk(otherChunk.toString(), otherFont);
}
}
BaseFont arialBoldBaseFont = BaseFont.createFont(arialBoldPath, BaseFont.WINANSI, false); // not embedded
BaseFont arialUnicodeBaseFont = BaseFont.createFont(arialUniPath, BaseFont.IDENTITY_H, true); // IDENITY_H forces an embedded subset, ignores "embedded" param.
Font mainFont = new Font(arialBoldBaseFont, size);
Font backupFont = new Font(arialUnicodeBaseFont, size, Font.BOLD);
...
addTextToPara(paragraph, string, mainFont, backupFont);
请注意,上面的代码不会尝试查看是否可以在otherFont 中绘制给定的字符。可以重写addTextToPara() 来获取一系列字体,但我并没有那么无聊。 ;)
使用上面的代码,您可以使用您喜欢的任何编码创建 BaseFonts,对于 98% 的情况,我只是更喜欢“Identity H”。 mainFont 可以从 WinAnsiEncoding 字体构建,backupFont 可以是其他东西。哎呀,您甚至可以执行以下操作:
BaseFont mainFont = BaseFont.createFont(arialBoldPath, BaseFont.WINANSI, false);
BaseFont backupFont = BaseFont.createFont(arialBoldPath, BaseFont.IDENTITY_H, true);
对两者使用相同的系统级字体,并且只嵌入不属于“规范”的字符。这仍然会在 PDF 中生成两个单独的字体资源,但一个没有嵌入(并且大部分时间都在使用),另一个是希望稀有字符的嵌入子集。
【讨论】: