Skip to content

Xojo’s PDFDocument Class, Beyond the Standard 14 and More

One of the trickier things when dealing with PDF document creation is typography. By default, the PDF typography handling in Xojo’s PDFDocument class includes the “standard 14“, 14 typefaces you can use freely without requiring them to be included as part of the document itself. This guarantees a very important thing: any user can open and view that PDF document as it was created, without the text suffering from typography substitution, style lost, variations in kerning and tracking, etc. The standard 14 include Times, Courier, Helvetica, Symbol and Zapf Dingbats.

In order to simplify their use, we included an Enumeration as part of the PDFDocument Class. So, if for example you want to use the Times-Bold variant, then you only need to use these two lines of code:

g.FontName = PDFDocument.StandardFontNames.Times
g.Bold = True

This also speeds up the creation of your PDFs – Bonus!

Beyond the Standard 14

But you may need something beyond the standard 14 and that is where things can start to get more complicated. In order to be able to “draw” these other fonts in vectorial representation as part of your document, the PDF standard needs to know in advance lots of details of the typography itself: glyphs width, maximum and minimum kerning values, if they include Italic or Bold variations, etc. And it can get even more complicated when you need to support several fonts. That means that the PDFDocument class needs to go inside and explore every one of the fonts you may use in your document so they are properly rendered, and that means inspecting a LOT of data!

In oder to alleviate this very consuming process, the PDFDocument class uses several techniques to speed things up when it comes to the many fonts you have installed. For example, one of the more obvious of these is using a delayed font exploration … so it only takes place when you are going to use a specific font the first time, caching all the required information for later accesses. In addition, it pre-caches the name of all the fonts you have installed in your OS Fonts folder so it can “find” those fonts faster once you’re ready to use one of them.

These two techniques, in addition to others, ensure that the initial PDFDocument creation and text drawing is as fast as possible for the “reasonable” (or even for the not so “reasonable”) amount of fonts you may have installed in your computer.

An important difference when using fonts other than the standard 14, is that nobody ensures that the user viewing your PDF document will have that same fonts installed on their computer too (including even variants of the same font) and that can lead to a rendering text “disaster”!

In order to guarantee that your PDF texts will render correctly, no matter how many fonts you are using, all the required font data is included as part of the PDF document itself (it has embedded the font data). For the small price of including the font data as part of the document, regardless of if the user has any of the fonts installed on their computer, the text of the PDF document will be rendered however you set it during its creation.

No matter how many times you are going to use the same font in your document, the reference (and, thus, the font data) will be included only once.

Speeding Things Up

In addition, it may be the case that you are interested in working only with a subset of the fonts you have installed on your drive (or apart from these, for example, only the ones included as part of your own app or solution). If that is the case, then you can use the PDFDocument.AddFonts method passing along a FolderItem parameter pointing to the folder containing the font files. Just make sure to use this method before using any of the fonts! Also, this will speed up the font inspection process even more because the PDF will look for the required data only among the files added by the AddFonts method. You may use the PDFDocument.AddFonts pointing to different font sets as many times as you may need.

For example, let’s say we have a folder on the desktop with a total of 20 font files inside; so the following snippet of code will create a “Font catalog” PDF document whose contents are a total of 20 lines composed with a fixed sample text followed by the font name:

Var f As FolderItem = SpecialFolder.Desktop.Child("Fonts Catalog")

PDFDocument.AddFonts(f)

Var fName As String
Var pdfDoc As New PDFDocument
Var g As Graphics = pdfDoc.Graphics
Var offset As Integer = 20

Var textSample As String = "Text Sample with Font: "

For n As Integer = 0 To 20
  
  fName = f.ChildAt(n).Name.NthField(".", 1)
  
  g.FontName = fName
  g.FontSize = 10
  g.DrawText(textSample + fName, 20, offset)
  
  offset = offset + 10 + g.FontAscent
  
Next

Var target As FolderItem = SpecialFolder.Desktop.Child("FontSample.pdf")

pdfDoc.Save(target)

target.Open

In this case, the following screenshot shows the resulting PDF document:

The total size of the PDF document is a mere 700 KB on disk, with the guarantee that it will be correctly displayed by anyone you send it because the font data is embedded in the document itself! If you are curious, you can download the PDF document itself from this link.