iTextSharp - 并非所有字符都以 Helvetica 字体显示

iTextSharp - not all characters present in Helvetica font

我有一些包含 Omega 字符 (0x3A9) 的文本,当我以默认的 Helvetica 字体显示此字符时,PDF 中没有显示任何内容。

我正在使用

创建我的字体
BaseFont Helvetica = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);

并且,正如预期的那样,Helvetica.CharExists(0x3A9) returns false。

我还为 TIMES_ROMAN、SYMBOL 和 ZAPF_DINGBATS 字体调用了 CharExists(0x3A9)。全部 return 错误。

  1. 我创建的字体不正确吗?有没有更好的方法来创建包含 omega 字符的字体?
  2. 有没有通用的方法来处理像这样丢失的字符?我是否应该枚举所有可用字体,直到找到 CharExists(0x3A9) returns true 的字体?

我的文档是英文的,但有一些特殊字符 - plus/minus、左右双引号、微米等

p.s。我看到我可以创建 Arial 字体:

BaseFont arial = BaseFont.CreateFont("c:\windows\fonts\arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);

并且确实包含字符 0x3A9 的字形。但显然我无法使用 IDENTITY_H 编码创建 HELVETICA 字体。

我最终得到的东西有点复杂,但看起来很可靠。每次我将文本添加到我的文档时(到目前为止我只是通过简单地创建一个新短语来完成),我首先枚举字符串中的每个字符并调用 BaseFont.CharExists()。如果任何字符的答案都是假的,我会根据 CharExists() 的连续序列是真还是假将文本分成块。然后,对于存在于 Helvetica 中的块,我在 Helvetica 中创建了一个块,而其他的我在 Arial 中创建了一个块,然后 assemble 将这些块放入我的短语中。

我这样做的原因(这对大多数读者来说可能是显而易见的,但以防万一)是我不想总是将 Arial 字体添加到我的 PDF 文件中(以减小大小),并且我 95% 的文档不包含像 Omega 这样需要 Arial 的字符。这样,我只将 Arial 字体添加到真正需要它的那几个文档中。

Phrase phrase = null;
string s = "";
for (int i = 0 ; i < text.Length ; i++)
{
   char c = text[i];
   if (fonts.Regular.BaseFont.CharExists(c))
      s += c;   // Accumulate Helvetica characters in 's'
   else
   {
      // Try adding the Arial font
      iTextSharp.text.Font arial = fonts.Arial;       // Creates the Arial font and adds it to the document if not already there
      if (arial == null)
      {
         Debug.WriteLine("   Arial font not found");
         s += c;
      }
      else if (!arial.BaseFont.CharExists(c))
      {
         Debug.WriteLine("   Arial does not contain the required glyph");
         s += c;
      }
      else
      {
         // We have a character that Helvetica doesn't have, that Arial does
         if (phrase == null)
         {
            // This is the first time we've realize that we need a split phrase
            if (s.Length > 0)
            {
               // There was Helvetica text before the Arial character.
               phrase = new Phrase(s, fonts.Regular);
               // This code assumes that non-Helvetica characters generally come singly
               phrase.Add(new Chunk(c, arial));
               s = "";
            }
            else
            {
               // The Arial character is the first one in the string
               phrase = new Phrase(new Chunk(c, arial));
            }
         }
         else
         {
            // This is not the first Arial character in the string
            if (s != "")
            {
               // There were Helvetica characters before this Arial character
               phrase.Add(new Chunk(s, fonts.Regular);
               s = "";
            }
            phrase.Add(new Chunk(c, arial));
         }
      }
   }
}

if (phrase == null)
{
   // We did not encounter any Arial characters, create a simple Phrase
   phrase = new Phrase(text, fonts.Regular);
}
else if (s.Length > 0)
{
   // There were Helvetica characters at the end of the string, add them now
   phrase.Add(new Chunk(s, fonts.Regular));
}