dNyaanopaasak
dNyaanopaasak

Reputation: 49

MigraDoc/PDFsharp throwing Exceptions with Chinese YaHei font

Recently after moving our Website from Windows Server 2008 to Server 2016, we started facing problems exporting PDF documents from our C# code that uses MigraDoc/PDFsharp library.
Problem can also be reproduced on windows 10. Exactly same code works just fine on Windows 7 or, as mentioned earlier, any server OS prior to Server 2016.
Previously we were getting this exception:

Error while parsing an OpenType font. InnerException: InvalidOperationException: Font has no usable platform or encoding ID. It cannot be used with PDFsharp.

So we tried to upgrade the references to the latest assembly version and now we are getting a different error:

TrueType collection fonts are not yet supported by PDFsharp.

Please do not jump the gun and mark this as duplicate of some other issues where Chinese characters are being displayed as squares or ??? in the exported PDF. This is not an font embedding issue. It is different than that. Somehow on Windows 10 and Server 2016, if you try to use the Microsoft Ya Hei (微软雅黑) font then it just does not work. Strangely enough everything was working fine with the same code same version assembly before migrating to Server 2016. Here is a relevant code without the paraphernalia

.
.
.
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");

Can someone help me understand the bigger picture: What has changed with respect to Chinese fonts and what exactly is going on here?

Upvotes: 1

Views: 2418

Answers (2)

guanjun
guanjun

Reputation: 26

The root cause is the font changed to ttcf format. In windows, there is 2 type font: TrueType, the extension is .ttf. and TrueType Collection, the extension is ttc. you can go to \Windows\Fonts folder, and list font file to valid it. the font file should be msyh.ttc.

PdfSharp use GetFontData Windows API to get font data.

// 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);

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

But, the Windows API does not work as expected. if the font is ttcf, Windows API does not return GDI_ERROR, it will return a invalid truetype data with wrong offset.

GetFontData Windows API not sure whether the data returned is completed data for TrueType file, or a part of TrueType font collection. What's worse. See: 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

That is the root cause.

Upvotes: 0

The error message tells it: Font collections (extension .ttc) are not yet supported, TrueType fonts (extension .ttf) are supported.

So a workaround could be using the font files from an older Windows version as they appear to be compatible with the current version of PDFsharp.
There could be problems installing fonts from older Windows versions on the Fonts folder of Windows.
The IFontResolver interface of the WPF build of PDFsharp/MigraDoc allows using fonts that are not installed on the computer. Maybe try EZFontResolver to keep it simple: forum.pdfsharp.net/viewtopic.php?f=8&t=3244

Adding support for font collections seems to be not very complicated, but somebody must implement it. The current version of today, 1.50.4845-RC2a, does not yet support them.

Upvotes: 1

Related Questions