Link

PDF Fonts how they work and how they can be displayed in

This article explains how PDF fonts work and how they can be displayed in JPedal.

What is font embedding?

PDF files can contain 2 types of font. Embedded PDF fonts include all the actual details for drawing all the font characters while non-embedded fonts just include the name of the font and expect the system to find the font details. Font embedding results in larger PDF files. The original PDF specification allowed for 14 fonts, but the later revisions of the PDF specification (version 1.7 onwards) reduce this to only 5 fonts. These are:

  • Courier
  • Courier-Bold
  • Courier-BoldOblique
  • Courier-Oblique
  • Symbol

You can tell if a PDF file contains embedded fonts by opening it in the JPedal Viewer or Acrobat and looking at the list of fonts. Open a PDF file in the JPedal Java Viewer and choose File - Document Properties - Font tab

How does JPedal handle PDF fonts?

If a font is embedded in a PDF file, JPedal will use the font information inside the PDF file to display it. This cannot be over-ridden. For non-embedded PDF fonts, JPedal will try and find a font with a matching PDF font name available to Java or replace it with a standard font, so the PDF can be viewed. These fonts are not always a good match so we recommend font substitution for best results. If the font is subsetted, it may not be possible to replace the font.

CID fonts

Some PDF files may contain non-embedded CID font files (with the assumption that the PDF is being viewed in Adobe Acrobat which will then download the required language pack). In this case, a message similar to this will appear. You may need to open the file in Adobe Acrobat to install the fonts. JPedal will then be able to find them. In this case, you will need to locate the fonts (which will be downloaded by Adobe) and attempt to map them using the techniques described below.

PDF Font substitution in JPedal

There is an additional operation in JPedal called font substitution which allows JPedal to replace missing fonts (which should be embedded) with local fonts. This only works with non-CID fonts. Most computers have far more fonts installed on them than are available to Java. So JPedal also the option to use these fonts for display - it treats them as if they were embedded inside the PDF. This is already setup for some common examples inside the Java PDF viewer example. The class FontMappings sets up all the common font substitutions for non-embedded fonts on Windows and Mac. All the code examples include the Java line below to switch it on.

//mappings for non-embedded fonts to use
FontMappings.setFontReplacements();

To manually remap a single font (if not embedded)

//replace Century and CenturyGothic with any installed Arial if not embedded
String[] aliases={"Century","CenturyGothic"}; //(all names are case-insensitive)
FontMappings.setSubstitutedFontAliases("arial",aliases);

Linux does not have a well-defined font location with fonts JPedal can use. See item at the bottom of this page for advice on how to resolve this.

How are fonts mapped

Font mapping is case-insensitive so Arial and arial are the same fonts. The option must be set first, using the FontMappings class method public static void setFontSubstitutionMode(int mode) where mode is a SUBSTITUTE_* value from PdfDecoder.

Filename (default option)

This maps the font using the name for the font file without its suffix. So the font file arial.ttf would be used to display non-embedded text in Arial in the PDF.

Postscript name

Using the Postscript name found inside the PDF file. So the font file myFile.ttf might actually have the Postscript name ComicSans and any non-embedded text in ComicSans would use this.

Full family name

Using the full family name found inside the file. So the font file myFile.ttf might actually have the family name ComicSans and any non-embedded text in ComicSans would use this.

Postscript name (family name if duplicate)

Using the Postscript name found inside the file so long as it is unique. So the font file myFile.ttf might actually have the Postscript name “arial” and family name “arialsup”. As “arial” is not unique, “arialsup” would be used but needs the font to be correctly named in the PDF. Important Note TrueType font collections can contain several TrueType fonts so mapping needs to use Postscript names if you are using these. To make it easier to find all these options, the available tab on the Info box displays all this information. View some sample code of list properties.

Which fonts can be used?

JPedal can use the following font files for font substitution.

  • TrueType fonts which have the file ending .ttf (ie arial.ttf)
  • OpenType fonts which have the file ending .otf (ie arial.otf)
  • TrueType font collections which have the file ending .ttc (ie arial.ttc)
  • Type1 font files ending . pfb or .pfa (from version 3.76)

How are the fonts added.

Our PDF viewer, PDF printing and PDF to image conversion examples already call this code to set up common defaults for non-embedded fonts. So if you are writing your own code, you may just need to add this call to your code after creating an instance of PdfDecoder. //mappings for non-embedded fonts to use FontMappings.setFontReplacements();

Manually adding Fonts

You can add new directories containing fonts for JPedal to use. The methods can be called repeatedly to add additional fonts. The font name is used as a key so any duplicate font names will override previous settings.

To add a new directory of fonts via JVM flag set the JVM flag -Dorg.jpedal.fontdirs=dirList where dirList is a comma-separated list of possible directories. See JVM options for more details.

To add a whole directory of fonts with a method call, use the FontMappings method setFontDirs(String[] paths) where paths is an array of possible locations. The locations do all need to exist on the local filesystem (jar: or http: protocols not supported) and provide a way to offer cross-platform settings.

Important note for Linux/Unix users

Both Windows and MacOS have clearly defined locations for fonts. Linux does not have a well-defined font location with fonts which JPedal can use for substitution. The best solution on a Linux box is install ttf-mscorefonts-installer package (sudo apt-get install ttf-mscorefonts-installer on our systems) which adds some fonts. JPedal will automatically use these fonts if present.

Otherwise, copy the Windows font directory across from a Windows machine and point JPedal to it with the command:

 FontMappings.setFontDirs(new String[] { "/home/yourDir/fonts/" });