【问题标题】:How can I use a bold version of Arial Unicode in iText?如何在 iText 中使用粗体版的 Arial Unicode?
【发布时间】:2011-03-29 20:47:19
【问题描述】:

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

【问题讨论】:

    标签: fonts itext


    【解决方案1】:

    字体通常被绘制为“填充形状”。您可以通过更改文本渲染模式来添加一定宽度的笔划来做“穷人的粗体”。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-05
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多