如何在iText中使用粗体版Arial Unicode?

时间:2011-03-29 20:47:19

标签: fonts itext

我想在iText中使用标准的粗体Arial字体,但如果字符不存在为粗体,我想默认为Arial Unicode。有没有办法在iText中组合字体?我搜索了Arial Unicode的粗体ttf文件,但我找不到。

1 个答案:

答案 0 :(得分:0)

字体通常绘制为“填充形状”。你可以通过改变文字渲染模式来增加一些宽度的笔划来做一个“穷人的大胆”。

看起来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中绘制给定的char。可以重写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中产生两个单独的字体资源,但是一个没有嵌入(并且大部分时间都在使用),另一个是希望稀有字符的嵌入子集。