3.12.  Fonts

Overview

Fonts are a difficult topic in PDF documents. The PDF standard defines 14 fonts, but does your document use any others? Fonts are also important for archiving. PDFUnit provides several test methods for different requirements.

// Simple tests:
.hasFont()
.hasFonts()           // identical with hasFont()
.hasNumberOfFonts(..) 

// Tests for one font:
.hasFont().withNameContaining(..) 
.hasFont().withNameNotContaining(..) 

// Tests for many fonts:
.hasFonts().ofThisTypeOnly(..)

Number of Fonts

What is a font? Should a subset of a font count as a separate font? In most situations this question is irrelevant for developers, but for a testing tool the question has to be answered.

Fonts have different aspects (name, type, size). So, it's difficult to say when two fonts are equal. In PDFUnit, two fonts are 'equal' if the selected comparison criteria have the same values. The criteria are defined by the following constants:

// Constants to identify fonts:

com.pdfunit.Constants.IDENTIFIEDBY_ALLPROPERTIES                          
com.pdfunit.Constants.IDENTIFIEDBY_BASENAME                       
com.pdfunit.Constants.IDENTIFIEDBY_EMBEDDED                       
com.pdfunit.Constants.IDENTIFIEDBY_NAME
com.pdfunit.Constants.IDENTIFIEDBY_NAME_TYPE                      
com.pdfunit.Constants.IDENTIFIEDBY_TYPE

The following list explains the available criteria to compare fonts.

Constant Description
ALLPROPERTIES All properties of a font are used to identify a font. Two fonts having the same values for all properties considered equal.
BASENAME Fonts are different when they have different base fonts.
EMBEDDED This filter counts only fonts that are embedded.
NAME Only the fonts' names are relevant to the test.
NAME_TYPE Only the font name and font type are used to compare fonts.
TYPE Only the types of the fonts are considered in the comparison.

The following example shows all possible filters:

@Test
public void hasNumberOfFonts_Japanese() throws Exception {
  String filename = "documentUnderTest.pdf";
  
  AssertThat.document(filename)
            .hasNumberOfFonts(11, IDENTIFIEDBY_ALLPROPERTIES)
            .hasNumberOfFonts( 9, IDENTIFIEDBY_BASENAME)
            .hasNumberOfFonts( 8, IDENTIFIEDBY_EMBEDDED)
            .hasNumberOfFonts( 9, IDENTIFIEDBY_NAME)
            .hasNumberOfFonts( 9, IDENTIFIEDBY_NAME_TYPE)
            .hasNumberOfFonts( 2, IDENTIFIEDBY_TYPE)
  ;
}

Font Names

Testing the names of fonts is easy:

@Test
public void hasFont_WithNameContaining() throws Exception {
  String filename = "documentUnderTest.pdf";
  
  AssertThat.document(filename)
            .hasFont().withNameContaining("Arial")
  ;
}

Sometimes, font names in a PDF document have a prefix, e.g. FGNNPL+ArialMT. Because this prefix is worthless for tests, PDFUnit only checks whether the desired font name is a substring of the existing font names.

Of course, you can chain multiple methods:

@Test
public void hasFont_WithNameContaining_MultipleInvocation() throws Exception {
  String filename = "documentUnderTest.pdf";
  
  AssertThat.document(filename)
            .hasFont().withNameContaining("Arial")
            .hasFont().withNameContaining("Georgia")
            .hasFont().withNameContaining("Tahoma")
            .hasFont().withNameContaining("TimesNewRoman")
            .hasFont().withNameContaining("Verdana")
            .hasFont().withNameContaining("Verdana-BoldItalic")
  ;
}

Because it is sometimes interesting to know that a particular font is not included in a document, PDFUnit provides a suitable test method for it:

@Test
public void hasFont_WithNameNotContaining() throws Exception {
  String filename = "documentUnderTest.pdf";
  String wrongFontnameIntended = "ComicSansMS";
  
  AssertThat.document(filename)
            .hasFont().withNameNotContaining(wrongFontnameIntended)
  ;
}

Font Types

You can check that all fonts used in a PDF document are of a certain type:

@Test
public void hasFonts_OfThisTypeOnly_TrueType() throws Exception {
  String filename = "documentUnderTest.pdf";
  
  AssertThat.document(filename)
            .hasFonts()
            .ofThisTypeOnly(FONTTYPE_TRUETYPE)
  ;
}

Predefined font types are:

// Constants for font types:
com.pdfunit.Constants.FONTTYPE_CID
com.pdfunit.Constants.FONTTYPE_CID_TYPE0
com.pdfunit.Constants.FONTTYPE_CID_TYPE2
com.pdfunit.Constants.FONTTYPE_MMTYPE1
com.pdfunit.Constants.FONTTYPE_OPENTYPE
com.pdfunit.Constants.FONTTYPE_TRUETYPE
com.pdfunit.Constants.FONTTYPE_TYPE0
com.pdfunit.Constants.FONTTYPE_TYPE1
com.pdfunit.Constants.FONTTYPE_TYPE3