【问题标题】:How to use private fonts in PDFSharp如何在 PDFSharp 中使用私有字体
【发布时间】:2015-05-13 19:48:37
【问题描述】:

我正在尝试使用私有(即系统上未安装)TrueType 字体将文本添加到 PDF 文档中并且遇到问题。我正在使用来自 NuGet 的 PDFSharp + MigraDoc WPF 版本 1.32.2608.0。

我在论坛和 StackOverFlow 上找到了许多项目。最新的是 this stackoverflow 文章,它指的是 PdfSharp 网站上的 this example。但是,此示例包含代码:

this.fontFamilies.Add(key, fontFamily);

在第 22 行,但我在程序集中找不到对 fontFamilies 的任何引用。

因此,我遵循了看起来像 excellent example 的方法,但它对我不起作用。当我使用这种方法时,我可以成功添加字体,但是当我开始使用命令时:

var font = new XFont(fontStyle.Name, new XUnit(fontStyle.SizePt, XGraphicsUnit.Point), XFontStyle.Regular, _fontOptions);

其中fontStyle.Name 是前面没有# 的字体名称。此时 PdfSharp 在 PdfSharp.Drawing 命名空间内的 private void Initialise() 方法内部中断。

此时检查 Initialise 方法中的变量:

  1. 找到字体家族,即this.family != null
  2. 找到字体,即this.typeface != null

我假设它在if (!typeface2.TryGetGlyphTypeface(out typeface)) 线上中断,但我不能确定。

注意:我尝试了 .ttf 和 .otf 字体都无济于事。

有人能指点我正确的方向吗?

更新

最后我换成了PDFSharp WPF 1.50 beta,因为它的字体处理要好得多。请参阅此SO post 关于我的第二个问题以及解决我的问题的new font resolver 的信息。现在一切正常。

【问题讨论】:

    标签: c# wpf fonts pdfsharp


    【解决方案1】:

    好的,这个问题的答案相当复杂,但如果它对其他人有帮助,那么这里就是答案。

    如果您想通过 PDFSharp 使用私有字体,即系统上尚未安装的字体,那么您需要执行以下操作。

    在 2015 年 3 月的这个时间点,唯一发布的适用于私有字体的 NuGet 库是 PDFsharp + MigraDoc (WPF) 1.32.2608 版本。 1.50 有很多 beta 版本,但这个答案大约是 1.32 版本。

    1. 您必须使用 1.32 的 WPF 版本,而不是 GDI+ 版本。
    2. 我发现 PDFSharp 页面中名为“Private Fonts”的代码具有误导性。根据 ThomasH 的说法,PDFSharp 团队希望人们下载该示例,该示例中有一段非常不同的代码。
    3. 如何编写代码的最佳示例可以在http://forum.pdfsharp.net/viewtopic.php?f=2&t=1880#p5395 找到。
      注意:作者关于加载字体两次导致异常的说明是正确的。他的处理方法很有效,但速度很慢。我预先扫描了所有字体并按名称对它们进行分组,以便只添加一次。
    4. 非常小心字体的名称(请参阅末尾的注释)。名字很容易弄错,如果你弄错了,你会遇到各种各样的麻烦。发布的 NuGet 版本有一个讨厌的 Debugger.Break 而不是异常,在发布的代码中它只是停滞不前 - 在我的单元测试中,我必须关闭 Visual Studio 才能摆脱它!
    5. 请注意,TrueType (.ttf) 字体可以采用 MAC 或 Windows 格式 - 这让我大吃一惊。 OpenType (.otf) 字体很好。

    注意:在字体名称上,在 Windows 中找到它的最佳方法是双击字体文件。然后,Windows 会在第一行显示带有名称的字体。就像我说的那样,弄错了,你就会得到一个停滞不前的系统。

    最后,我要感谢@ThomasH,他将我引导到 PDFSharp 1.32 源代码。这有私有字体的“正确”示例,也没有那个讨厌的Debugger.Break,但是当您要求的字体名称不存在时,这是正确的例外。

    更新

    最后我换成了PDFSharp WPF 1.50 beta,因为它的字体处理要好得多。请参阅此SO post 了解我的问题以及有关new font resolver 的信息,这对我有帮助。

    【讨论】:

    • Re 1:截至目前,Wiki 中的私有字体示例尚未针对 PDFsharp 1.50 进行更新,并展示了如何使用 PDFsharp 1.3x 进行更新。
    • 嗨,ThomasH,这很奇怪。您指向的 1.32 代码中的代码与 PDFSharp private fonts link 上的代码完全不同。你能解释一下,然后我会更新我的答案。
    • Wiki 包含一个 sn-p 并解释了不明显的内容。它是很久以前编写的,当时 PDFsharp 团队建议下载源代码包并从源代码引用项目(在 NuGet 之前的 VS 2005/2008 时代)。对于那些获得 NuGet 包并查看 sn-p 的人来说,这是令人困惑的。该示例最终将针对 PDFsharp 1.50 进行更新,然后将针对 NuGet 生成进行编写。
    • 嗨,ThomasH。好的,我已经更新了我的答案。让我知道这是否更有意义。我不得不说私有字体示例与实际代码中的示例代码没有任何相似之处。它让我到处追逐。
    【解决方案2】:

    关于“第 22 行”:PDFsharp 论坛只显示了示例中的一个 sn-p。

    对于 PDFsharp 1.3x:您可以从 CodePlex 或 SourceForge 下载完整的示例代码以及完整的工作示例(包括项目、解决方案、示例 TTF 文件)。

    另请参阅:
    https://stackoverflow.com/a/21545488/1015447

    1.32版的完整源代码:
    http://pdfsharp.codeplex.com/releases

    【讨论】:

    • 谢谢 ThomasH。您的提示让我查看了源代码,并找到了我正在寻找的答案 - 见下文。
    【解决方案3】:

    对于 PDFsharp 1.50,您必须实现 IFontResolver 接口并将您的实现分配给全局 PDFsharp 属性。

    GlobalFontSettings.FontResolver = new DemoFontResolver();
    

    PDFsharp 提供了一个类 FontResolverBase,您可以使用它来派生您自己的类。只需为您的私有字体添加代码并将调用传递给其他字体的基类。

    IFontResolver 接口需要两个方法:ResolveTypefaceGetFont

    更多信息可以在我的博文中找到:
    http://developer.th-soft.com/developer/?p=11

    此处以 ZIP 文件的形式提供了完整的解决方案。

    【讨论】:

    • 嗨@ThomasH。感谢您提供非常有用的博客文章。我正在考虑切换到 1.50 Beta WPF 版本,它工作正常。一个问题:是否可以在任何地方检查源代码或任何发行说明?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多