Skip to main content Skip to footer

How to Manage PDF Document Fonts Using .NET C#

Let's be honest; talking about fonts, using fonts, font size, decorations, and other properties, is not really what we all got into programming to do, nor is it the most exciting topic of conversation.   It's highly unlikely this would be a great date-opening conversation or even a good dinner conversation for your spouse and children.

But ultimately, it is necessary to discuss as professional programmers creating online applications that use, create, convert, and otherwise store or modify PDF documents. 

More importantly, it's essential that programmers know the ins and outs of the APIs that do a lot of the heavy lifting in making this easier, especially when creating files programmatically using C# .NET and the GcPdf API Library to manage .NET PDF Fonts within files.

Ready to Test it Out? Download GrapeCity Documents Today!

So, let's dive in!  Here's what you can expect from this blog content:

  • An understanding of how to set up and use the GcPdf API library in a Visual Studio Environment
  • Working examples of loading fonts from files
  • Managing fonts within a PDF document
  • Saving documents with multiple font types, sizes, and decorations.

Set up Visual Studio to Work with GcPdf API Library and Prepare to Incorporate C# .NET PDF Fonts

The easiest and most efficient way to test our products is to download examples from our website.  In this instance, the best place to check in for fonts is here, where you can find over ten different examples of working with fonts. 

This article will cover a couple of those in detail.  Starting with working with fonts from a file (get this specific example from the website).

  1. Open Program.CS and review the code, paying close attention to line 80, where it calls "CreatePDF"
  2. Open FontFromFile.cs - this is where we will get into details of managing fonts and do a code review:

 

FontFromFile.cs

// Copyright (c) GrapeCity, Inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using GrapeCity.Documents.Pdf;
using GrapeCity.Documents.Text;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
 
namespace GcPdfWeb.Samples.Basics
{
    // This short sample demonstrates how a Font can be loaded from a file
    // and used in your code to render text.
    // The sample relies on font files Gabriola.ttf and timesbi.ttf to exist in the
    // Resources/Fonts folder.
    //
    // NOTE 1: When Font.FromFile() is used, the actual data is loaded on demand,
    // so that usually a Font instance will not take too much space.
    // The situation is different for fonts created using Font.FromArray()
    // and Font.FromStream() methods - in those cases the whole font is
    // immediately loaded into memory. The font will still be parsed
    // only on demand, but memory consumption is slightly higher,
    // so using Font.FromFile() should generally be preferred.
    //
    // NOTE 2: When different Font instances (created using any of the static ctors
    // mentioned above) are used to render text in a PDF, each instance will result
    // in embedding a separate subset of glyphs even if the glyphs are the same,
    // because GcPdf has no way of knowing that two different Font instances
    // represent the same physical font. So either make sure that only one Font instance
    // is created for each physical font, or better yet use the FontCollection class
    // to add the fonts you need, and specify them via TextFormat.FontName.
    public class FontFromFile
    {
        public void CreatePDF(Stream stream)
        {
            var gabriola = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "Gabriola.ttf"));
            if (gabriola == null)
                throw new Exception("Could not load font Gabriola");
 
            // Now that we have our font, use it to render some text:
            TextFormat tf = new TextFormat() { Font = gabriola, FontSize = 16 };
            GcPdfDocument doc = new GcPdfDocument();
            GcPdfGraphics g = doc.NewPage().Graphics;
            g.DrawString($"Sample text drawn with font {gabriola.FontFamilyName}.", tf, new PointF(72, 72));
            // We can change the font size:
            tf.FontSize += 4;
            g.DrawString("The quick brown fox jumps over the lazy dog.", tf, new PointF(72, 72 * 2));
            // We can force GcPdf to emulate bold or italic style with a non-bold (non-italic) font, e.g.:
            tf.FontStyle = GCTEXT.FontStyle.Bold;
            g.DrawString("This line prints with the same font, using emulated bold style.", tf, new PointF(72, 72 * 3));
            // But of course rather than emulated, it is much better to use real bold/italic fonts.
            // So finally, get a real bold italic font and print a line with it:
            var timesbi = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "timesbi.ttf"));
            tf.Font = timesbi ?? throw new Exception("Could not load font timesbi");
            tf.FontStyle = GCTEXT.FontStyle.Regular;
            g.DrawString($"This line prints with {timesbi.FullFontName}.", tf, new PointF(72, 72 * 4));
            // Done:
            doc.Save(stream);
        }
    }
}

C# .NET PDF Code Review for Managing Fonts From Files

The first thing to note is to be sure the font file is available to the application and located where it should be.  In this case, a directory called "Resources" is where the font files are located.  After ensuring the proper location of the resources, the code creates a variable "gabriola" from the font file.  Once completed, the text format is set to instantiate a new instance of TextFormat() and set the font appropriately.

Next, the page must be created and made available to the application by instantiating a new instance of GcPdfDocument into an object called "doc".  Then the graphics need to be added to the page by creating a graphics variable that is assigned to the Graphics property of the doc.NewPage() object.

After this setup, it's as easy as using the graphics variable/object to draw text and manipulate the font, as is seen in the following line of code:

g.DrawString($"Sample text drawn with font {gabriola.FontFamilyName}.", tf, new PointF(72, 72));
// We can change the font size:
tf.FontSize += 4;

Continue to read through the block of code above and notice several other properties can be set on the fonts. Even bold and italics can be emulated on fonts that do not support the bold or italic fonts.

Lastly, save the document to the stream (returning control to the Program.cs file), and the file is saved to the disk as either a PDF or a TIFF depending on which selection was chosen in the console.

Did I Just Get Ghosted by my Font?  How to Handle Missing Fonts with GcPdf API Fallback Fonts using C# .NET

Sometimes, no matter how many fonts you have or load, there are just characters that don't behave appropriately or are so specific that only a few font families can manage larger font images.  When this occurs, GcPdf provides a great tool by allowing for a list of "fallback" fonts to be available. 

Utilizing these fallback fonts is easy because it's just part of the API, but the real power comes in the ability to add new fonts to this fallback list.  Download the following example, and let's get started!

After opening the example in Visual Studio, let's get right to the file of importance (we know the Program.cs file will manage the calls appropriately, so there is no need to rehash that.  However, we do suggest reviewing the file, so you understand what calls are being made and when). Open up the FontFallbacks.cs file, and let's get right into the code review!

First, what are fallback fonts, and why do we need them?  Let’s use a musical reference as an analogy:  We’re on stage with our electric guitar, playing away, having a great time, when suddenly one of the strings breaks.  Now we no longer can play certain notes, which can be problematic.  Lucky for us, we have a second guitar on stage (a fallback guitar, if you will), which allows us, with a small amount of effort, to continue playing the song with limited interruption. 

Fallback fonts are similar only because we're talking about computers; there are no interruptions at all. The system recognizes the missing font and substitutes one that will allow for the rendering of the character without delay.  In the GcPdf API, these fallback fonts are automatically set up and suitable for use with many languages. 

The other powerful piece of this is being able to add to the list of fallback fonts from a file.  The example goes into great detail about the fallback fonts, prints, various examples, etc.  However, we will focus on using C# .NET PDF Fonts to bolster the fallback capabilities of the API.  Let's review this part of the code:

// Get the list of fallback font families:
          string[] fallbacks = FontCollection.SystemFonts.GetFallbackFontFamilies();
 
          // Clear global fallbacks list:
          FontCollection.SystemFonts.ClearFallbackFontFamilies();
          FontCollection.SystemFonts.ClearFallbackFonts();
 
          // Now there are no global fallback fonts, so Japanese text rendered using
          // a standard font will produce 'blank boxes' instead of real Japanese characters:
          g.DrawString("A Japanese text that won't render: あなたは日本語を話せますか?", tf, ip);
          ip.Y += 36;
 
          // Re-add the original list of fallback font families to global SystemFonts:
          FontCollection.SystemFonts.AppendFallbackFontFamilies(fallbacks);
          // On some systems, default system fallbacks might not provide Japanese glyphs,
          // so we add our own fallback just in case:
          var arialuni = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "arialuni.ttf"));
          FontCollection.SystemFonts.AppendFallbackFonts(arialuni);
 
          // Now that fallback fonts are available again, the same Japanese text will render
          // correctly as an appropriate fallback will have been found:
          g.DrawString("Same text with fallbacks available: あなたは日本語を話せますか?", tf, ip);
          ip.Y += 36;

Because the example clears the default list of fallbacks, the first thing to do is save that list to an array.  We do that in the first line here, then clear out all the default fallbacks afterward.  Once those have been cleared, we try to print out a set of Japanese characters to the file, but they won't render at this point.  Instead, they will be blanks, so it will look like no text is being printed.

This is an excellent test to show how you need fallbacks to avoid ending up with unexpected blank spaces depending on what type of text is trying to be rendered.  

Next, we add back all the default font families, then (and this is the super cool and powerful part), we add our fallback font to the list.  In this case, Arial Unicode (but it could be anything).  Once we add all those back to the text, we try to write the same string of characters, and low and behold; they are now present!

example of C# .NET PDF Font using fallback fonts in the GcPdf API Library

Summary of C# .NET PDF Fonts and GcPdf

It's really easy to use the GcPdf API to manipulate text in a PDF document.  Also, we should all have some great stories to tell at our next meeting at the local pub! 

Now that we are all on the same page, we’re certain we can have some exhilarating conversations related to fonts, font families, which font families are the most dysfunctional, which keep it real, and which families should be used as the best possible fallback fonts. 

Although we can hear the barkeep snoring from here, these are important conversational topics for professionals like us!

Keep on coding, and don't hesitate to reach out with any questions!

Ready to Test it Out? Download GrapeCity Documents Today!

comments powered by Disqus