Chapter 10. Fonts

Table of Contents

1. Font setup
2. Classes and interfaces used in the font package

1. Font setup

Terminology:

  • Index, font index: The index of a character in a font, i.e. the place of the glyph for a character in a font.
  • Code point: The same as font index.
  • Character value: The two-byte (char) value by which a character is represented in memory and in Unicode. Note that this only works straightforwardly for the basal plane (BMP) of Unicode, i.e. for characters <= 0xFFFF.
  • Unicode code point: The same as the character value.

During compilation for each of the 14 base fonts a class is generated from the XML font metric files. Each font class contains the metric information and an encoding table (a CodePointMapping object). The metric information is static, the encoding table is an object member.

During compilation also a class CodePointMapping is generated, which contains the known encodings as static values. For each known encoding it contains a table as a static final array of int. The array holds an alternation of font index and character value; in fact it is a mapping from table[2i] to table[2i+1], where table[2i] is the font index and table[2i+1] is the character.

When an encoding is needed in the process, a CodePointMapping object is created from the encoding table. It contains a table (char array) called latin1Map of the font indices for the characters of the Latin1 range (0-0xFF) in character value order. It also contains two tables (char arrays), called characters and codepoints, for the higher character values. The table characters contains the character values in order, and the table codepoints contains the corresponding font indexes for this encoding in the same order. The characters can be retrieved from these tables as follows:

char <= 0xFF: index = latin1Map[character]
char > 0xFF:
	 find i such that characters[i] == char;
	 then index = codepoints[i]

In the code the characters are retrieved from the CodePointMapping object with its method mapChar(char c).

In FOP's preparation stage the fonts are set up in the method Driver.getContentHandler. It calls the renderer's method setupFontInfo(currentDocument). The Document object currentDocument (which is the foTreeControl object) is able to store the font setup info and has methods to access the fonts registered with it.

The PrintRenderer (PostScript and PDF) then calls FontSetup.setup(fontInfo, fontList), where fontInfo is the Document object and fontList is the list of user configured fonts registered with the renderer in its member fontList.

  [1] org.apache.fop.fonts.FontSetup.setup (FontSetup.java:98)
  [2] org.apache.fop.render.PrintRenderer.setupFontInfo (PrintRenderer.java:77)
  [3] org.apache.fop.apps.Driver.getContentHandler (Driver.java:551)
  [4] org.apache.fop.apps.Driver.render (Driver.java:602)
  [5] org.apache.fop.apps.Driver.render (Driver.java:589)
  [6] org.apache.fop.apps.Fop.main (Fop.java:102)

FontSetup.setup takes three actions:

  1. An object is created for each of the base 14 fonts and registered with the fontInfo object in its member fonts.
  2. A series of triplets (family, style, weight) is set up. To each triplet a font is assigned; this font will be used when a font with the characteristics of that triplet is requested. The triplets registered with fontInfo in its member triplets. The member triplets is a map which uses a string of the form family,style,weight as a key. There is also a class FontTriplet, which is not used.
  3. The user configured fonts are added.

In the following listing treeBuilder is the tree builder object set up in the preparation stage, and foTreeControl is the document object. The list of user configured fonts of the renderer is empty, and the list of used fonts is still empty.

 treeBuilder.foTreeControl.fonts = "{
  F1=org.apache.fop.fonts.base14.Helvetica@e3c624,
  F2=org.apache.fop.fonts.base14.HelveticaOblique@e020c9,
  F3=org.apache.fop.fonts.base14.HelveticaBold@13e58d4,
  F4=org.apache.fop.fonts.base14.HelveticaBoldOblique@15a6029,
  F5=org.apache.fop.fonts.base14.TimesRoman@17494c8,
  F6=org.apache.fop.fonts.base14.TimesItalic@1e57e8f,
  F7=org.apache.fop.fonts.base14.TimesBold@888e6c,
  F8=org.apache.fop.fonts.base14.TimesBoldItalic@d3db51,
  F9=org.apache.fop.fonts.base14.Courier@5f6303,
  F10=org.apache.fop.fonts.base14.CourierOblique@117f31e,
  F11=org.apache.fop.fonts.base14.CourierBold@1d7fbfb,
  F12=org.apache.fop.fonts.base14.CourierBoldOblique@5d9084
  F13=org.apache.fop.fonts.base14.Symbol@39e5b5,
  F14=org.apache.fop.fonts.base14.ZapfDingbats@1b5998f,
}"

 treeBuilder.foTreeControl.triplets = "{
  Computer-Modern-Typewriter,normal,400=F9,
  Courier,italic,400=F10,
  Courier,italic,700=F12,
  Courier,normal,400=F9,
  Courier,normal,700=F11,
  Courier,oblique,400=F10,
  Courier,oblique,700=F12,
  Helvetica,italic,400=F2,
  Helvetica,italic,700=F4,
  Helvetica,normal,400=F1,
  Helvetica,normal,700=F3,
  Helvetica,oblique,400=F2,
  Helvetica,oblique,700=F4,
  Symbol,normal,400=F13,
  Times Roman,italic,400=F6,
  Times Roman,italic,700=F8,
  Times Roman,normal,400=F5,
  Times Roman,normal,700=F7,
  Times Roman,oblique,400=F6,
  Times Roman,oblique,700=F8,
  Times,italic,400=F6,
  Times,italic,700=F8,
  Times,normal,400=F5,
  Times,normal,700=F7,
  Times,oblique,400=F6,
  Times,oblique,700=F8,
  Times-Roman,italic,400=F6,
  Times-Roman,italic,700=F8,
  Times-Roman,normal,400=F5,
  Times-Roman,normal,700=F7,
  Times-Roman,oblique,400=F6,
  Times-Roman,oblique,700=F8,
  ZapfDingbats,normal,400=F14,
  any,italic,400=F6,
  any,italic,700=F8,
  any,normal,400=F5,
  any,normal,700=F7,
  any,oblique,400=F6,
  any,oblique,700=F8,
  monospace,italic,400=F10,
  monospace,italic,700=F12,
  monospace,normal,400=F9,
  monospace,normal,700=F11,
  monospace,oblique,400=F10,
  monospace,oblique,700=F12,
  sans-serif,italic,400=F2,
  sans-serif,italic,700=F4,
  sans-serif,normal,400=F1,
  sans-serif,normal,700=F3,
  sans-serif,oblique,400=F2,
  sans-serif,oblique,700=F4,
  serif,italic,400=F6,
  serif,italic,700=F8,
  serif,normal,400=F5,
  serif,normal,700=F7,
  serif,oblique,400=F6
  serif,oblique,700=F8,
}"

 treeBuilder.foTreeControl.atModel.renderer.fontList = null
 treeBuilder.foTreeControl.usedFonts = "{}"

User configured fonts should be listed in the member fontList of the renderer. The objects in the list are EmbedFontInfo objects. They are created from the path to the metrics file, boolean kerning, the list of triplets for which this font may be used, the path to the font file. The triplets are FontTriplet objects. The list may be created from an Avalon configuration object with FontSetup.buildFontListFromConfiguration(Configuration cfg).

>FontSetup.addConfiguredFonts creates a LazyFont font object from each EmbedFontInfo object. LazyFont fonts are not loaded until they are actually used. This makes it possible to register a large number of fonts at low cost.

Font weights are integers between 100 and 900. Font.NORMAL and Font.BOLD are set to 400 and 700, respectively. See FontUtil.parseCSS2FontWeight.