MigraDoc / PDFsharp中文YaHei字体引发异常

时间:2018-10-13 08:31:28

标签: c# pdf pdfsharp migradoc

最近,我们将网站从Windows Server 2008迁移到Server 2016之后,我们开始遇到从使用MigraDoc / PDFsharp库的C#代码导出PDF文档的问题。
问题也可以在Windows 10上重现。完全相同的代码在Windows 7或Server 2016之前的任何服务器OS上都可以正常工作。 以前,我们遇到此异常:

  

解析OpenType字体时出错。   InnerException:InvalidOperationException:字体没有可用   平台或编码ID。不能与PDFsharp一起使用。

因此,我们尝试将引用升级到最新的程序集版本,现在又遇到了另一个错误:

  

PDFsharp尚不支持TrueType集合字体。

请不要跳开枪,并将其标记为与其他一些将汉字显示为正方形或???的其他问题的重复项?在导出的PDF中。这不是字体嵌入问题。与此不同。在Windows 10和Server 2016上以某种方式,如果您尝试使用Microsoft Ya Hei(微软雅黑)字体,则它将无法正常工作。奇怪的是,在迁移到Server 2016之前,使用相同代码和相同版本的程序集,一切都可以正常工作。这是不带相关工具的相关代码

.
.
.
using MigraDoc.DocumentObjectModel;
using MigraDoc.Rendering;
.
.

Document document = new Document();
document.Info.Title = "Report";
document.Styles["Normal"].Font.Name = "微软雅黑";   // Microsoft YaHei Chinese Font

Section section = document.AddSection();
document.LastSection.AddParagraph("### This font is: 微软雅黑");

PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = document;

renderer.RenderDocument();
renderer.PdfDocument.Save(@"Test.pdf");

有人可以帮我理解大局吗:中文字体发生了什么变化,这到底是怎么回事?

2 个答案:

答案 0 :(得分:0)

错误消息说明:尚不支持字体集合(扩展名.ttc),支持TrueType字体(扩展名.ttf)。

因此,一种变通办法是使用Windows早期版本的字体文件,因为它们似乎与当前版本的PDFsharp兼容。
在Windows的“字体”文件夹中安装较旧Windows版本的字体可能会出现问题。
PDFsharp / MigraDoc的WPF构建的IFontResolver界面允许使用计算机上未安装的字体。也许尝试使用EZFontResolver使其保持简单:forum.pdfsharp.net/viewtopic.php?f=8&t=3244

添加对字体集合的支持似乎不是很复杂,但是必须有人实现它。今天的当前版本1.50.4845-RC2a尚不支持它们。

答案 1 :(得分:0)

根本原因是字体变成了ttcf格式。 在 Windows 中,有 2 种字体:TrueType,扩展名为 .ttf。和TrueType Collection,扩展名是ttc。您可以转到 \Windows\Fonts 文件夹,并列出字体文件以使其有效。字体文件应该是 msyh.ttc。

PdfSharp 使用 GetFontData Windows API 来获取字体数据。

// Get size of the font file.
bool isTtcf = false;
int size = NativeMethods.GetFontData(hdc, 0, 0, null, 0);
if (size == NativeMethods.GDI_ERROR)
{
     // Assume that the font file is a true type collection.
     size = NativeMethods.GetFontData(hdc, ttcf, 0, null, 0);
     isTtcf = true;
}

byte[] bytes = new byte[size];
int effectiveSize = NativeMethods.GetFontData(hdc, isTtcf ? ttcf : 0, 0, bytes, size);

见:https://github.com/empira/PDFsharp/blob/master/src/PdfSharp/Drawing/XFontSource.cs#L147

但是,Windows API 没有按预期工作。如果字体是 ttcf,Windows API 不返回 GDI_ERROR,它将返回一个偏移量错误的无效 truetype 数据。

GetFontData Windows API 不确定返回的数据是 TrueType 文件的完整数据,还是 TrueType 字体集合的一部分。更糟糕的是。 请参阅:https://www.google.com/books/edition/Windows_Graphics_Programming/-O92IIF1Bj4C?hl=en&gbpv=1&dq=how+to+identify+windows+font+is+ttcf&pg=PA883&printsec=frontcover

这是根本原因。