How to use private fonts in PDFSharp

Jon P Smith picture Jon P Smith · Mar 11, 2015 · Viewed 10.9k times · Source

I am trying to add text to a PDF document using private, i.e. not installed on the system, TrueType fonts and having trouble. I am using PDFSharp + MigraDoc WPF version 1.32.2608.0 from NuGet.

I have found numerous items on the forum and on StackOverFlow. The latest is this stackoverflow article which refers to this example on the PdfSharp site. However this example contains the code:

this.fontFamilies.Add(key, fontFamily);

on line 22, but I cannot find any reference to fontFamilies in assembly.

I therefore have followed what looked like an excellent example, but it does not work for me. When I use this approach I can successfully add the font but when I come to use the command:

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

Where fontStyle.Name is the name of the font without the # on the front. At this point PdfSharp breaks inside the private void Initialise() method inside the PdfSharp.Drawing namespace.

Inspecting the variables inside the Initialise method at this point it has:

  1. Found the font family, i.e. this.family != null
  2. Found the typeface, i.e. this.typeface != null

I am assuming it break on the line if (!typeface2.TryGetGlyphTypeface(out typeface)) but I can't be sure.

Note: I have tried both a .ttf and a .otf font to no avail.

Could someone point me in the right direction please?

Update

In the end I swapped to PDFSharp WPF 1.50 beta as its font handling is MUCH better. See this SO post on my second issues and information on the new font resolver which solved my problem. Everything is working well now.

Answer

Jon P Smith picture Jon P Smith · Mar 12, 2015

Ok, the answer to this is fairly complex, but in case it helps someone else then here is the answer.

If you want to use private fonts, i.e. fonts not already installed on you system, with PDFSharp then you need to do the following.

At this point in time, March 2015, the only released NuGet library that works with private fonts is the PDFsharp + MigraDoc (WPF) 1.32.2608 release. There are plenty of beta releases for 1.50 but this answer is about 1.32 version.

  1. You MUST use the WPF version of 1.32, not the GDI+ version.
  2. I found the code in the PDFSharp page called 'Private Fonts' misleading. According to ThomasH the PDFSharp team expected people to download the sample, which has a very different piece of code in its sample.
  3. The best example of how to write the code can be found at http://forum.pdfsharp.net/viewtopic.php?f=2&t=1880#p5395 .
    Note: the author's note about loading a font twice causes an exception is correct. His method of handling this works, but it is slow. I pre-scan all my fonts and group them by name so that only add them once.
  4. Be VERY careful about the name of the font (see note at end). It is very easy to get the name wrong and if you do you get into all sorts of trouble. The released NuGet version has a nasty Debugger.Break instead of an exception and in released code it just stalls - In my Unit Tests I have to close Visual Studio to get out of it!
  5. Be aware that TrueType (.ttf) fonts can come in MAC or Windows format - that threw me. OpenType (.otf) fonts are fine.

NOTE: On the name of the font the best way to find it in Windows is to double click the font file. Windows then shows you the font with the name on the first line. As I say, get that wrong and you can get a stalled system.

Finally I should say thank you to @ThomasH who directed me to the PDFSharp 1.32 source code. This has the 'proper' example for private fonts and also doesn't have that nasty Debugger.Break but the proper exception when the name of the font you asked for isn't present.

Update

In the end I swapped to PDFSharp WPF 1.50 beta as its font handling is MUCH better. See this SO post on my problem and information on the new font resolver which helped.