FontForge SFNT Structure Format Specifications

FontForge enforces strict structural rules when generating and parsing Spline Font Numeric Table (SFNT) containers, which serve as the foundation for modern TrueType and OpenType fonts. This article details the core format specifications FontForge mandates for SFNT architectures, covering table directory formatting, memory alignment rules, binary checksum integrity, and essential table dependencies.

SFNT Offset Table and Directory Rules

FontForge requires all SFNT-based fonts to start with a standard Offset Table followed immediately by the Table Directory.

  • Scaler Type (Version Tag): FontForge validates the 4-byte identifier at byte offset 0. For TrueType outlines, it enforces 0x00010000 or true. For OpenType fonts containing PostScript/CFF outlines, it enforces the 4-byte tag OTTO.
  • Search Fields: When writing fonts, FontForge strictly calculates the binary search optimization fields based on the total number of tables (numTables):
    • searchRange: Maximum power of 2 less than or equal to numTables, multiplied by 16.
    • entrySelector: Log2 of the maximum power of 2 less than or equal to numTables.
    • rangeShift: Calculated precisely as (numTables * 16) - searchRange.
  • Tag Sorting: FontForge requires entries in the Table Directory to be ordered alphabetically by their 4-byte ASCII tags (e.g., CFF, OS/2, cmap, head, hmtx).

4-Byte Alignment and Padding

The SFNT specification requires every table to begin on a 4-byte boundary. FontForge strictly enforces this by calculating offsets as multiples of four. If a table's actual data length is not an exact multiple of 4 bytes, FontForge pads the end of the table with null bytes (0x00) to reach the next 32-bit boundary. The table directory entry records the actual unpadded size in the length field, while the offset field points to the aligned starting position.

Checksum Calculations

FontForge enforces SFNT data integrity using 32-bit unsigned checksums:

  • Table Checksums: Each directory entry contains a checkSum value. FontForge computes this by treating table data as an array of unsigned 32-bit integers and summing them with logical wrapping on overflow.
  • The head Table Exception: FontForge treats the head table differently during checksum validation. It sets the checkSumAdjustment field to 0x00000000, calculates the font-wide checksum across all tables, and then writes the result of 0xB1B0AFBA - totalChecksum into checkSumAdjustment.

Mandatory Table Requirements

To generate a valid SFNT container, FontForge mandates the presence and proper structure of core metadata and metric tables:

  • head (Font Header): Requires the fixed magicNumber (0x5F0F3CF5), valid timestamp formats, bounding box limits, and the indexToLocFormat flag (defining 16-bit short vs. 32-bit long offsets for TrueType glyphs).
  • maxp (Maximum Profile): Enforces a version 0.5 format for CFF/OpenType fonts (storing only glyph counts) or version 1.0 for TrueType fonts (which explicitly defines nesting depth, contour limits, points, and twilight zones).
  • hhea & hmtx (Horizontal Metrics): Enforces baseline, advance, and side-bearing consistency corresponding directly to the glyph count declared in maxp.
  • cmap (Character to Glyph Index Mapping): Mandates standard Unicode subtable mappings (typically Format 4 for BMP characters and Format 12 for full Unicode coverage).
  • name (Naming Table): Enforces standard platform IDs (Unicode, Windows, and legacy Macintosh) and required name records, such as font family, subfamily, and PostScript name.

Outline-Specific Structure Enforcement

FontForge strictly separates outline data formats based on the SFNT wrapper's scaler type:

  • TrueType Collections: When generating 0x00010000 SFNT containers, FontForge enforces the paired presence of the glyf (glyph geometry) and loca (glyph locations) tables.
  • PostScript/CFF: When generating OTTO containers, FontForge disallows glyf and loca, enforcing a single compact CFF or CFF2 table containing the dictionary keys, charstrings, and Subrs global/local subroutines.