Adobe Font Development Kit for OpenType

repository·develop·Indexed 22 days ago

https://github.com/adobe-type-tools/afdko

A toolkit for building OpenType font files from PostScript and TrueType data. AFDKO provides a suite of command-line tools for font development, including 'addfeatures' for processing OpenType fonts and applying feature files, 'spot' for dumping SFNT data and proofing glyphs, and various utilities for variable font support, validation, and proofing.

Tokens
32.9K
Snippets
92
Records
126
Agent score
76%

What's inside AFDKO

  1. Overview of AFDKO Programs

    develop

    The Adobe Font Development Kit for OpenType (AFDKO) provides a suite of command-line tools for font development, categorized into three main functional groups:

    1. Making/editing fonts: Tools for building OpenType fonts from UFO, PFA, TTF, or TXT files, merging glyphs, converting formats (e.g., otf2ttf, otc2otf), and handling variable fonts (buildmasterotfs, buildcff2vf).
    2. Proofing: Tools to visualize font data, such as spot for table reports, tx -pdf for glyph overviews, and various *plot tools (charplot, fontplot, hintplot, etc.) for generating PDF proofs of outlines, hints, and metrics.
    3. Validation: Tools for quality control, including comparefamily for checking consistency across a font family, sfntdiff for low-level binary comparisons, and ttxn for normalized functional comparisons between fonts.
  2. Overview of MakeOTF OpenType/CFF compiler

    develop

    MakeOTF is a command-line tool used to compile OpenType® fonts from source files and high-level OpenType layout feature descriptions. It is a compiler for font data, not a font editor.

    Required Source Files

    To build a font, MakeOTF typically requires the following files:

    • font: A source font file (e.g., font.pfa or cidfont.ps). It can be Type 1, CID, TrueType, or OpenType/CFF. Only glyph outlines are extracted from this file.
    • features: A text file containing OpenType layout feature rule definitions and overrides for OpenType table fields.
    • FontMenuNameDB: A text file providing Windows and Mac menu names for the font.
    • GlyphOrderAndAliasDB: A text file that establishes glyph ID order, allows for glyph name aliasing (mapping development names to final OpenType names), and provides Unicode® values.

    Optional Files

    • fontinfo: An optional file containing keywords that trigger specific MakeOTF options.
  3. Overview of Adobe Font Development Kit for OpenType (AFDKO)

    develop

    AFDKO is a set of tools designed for building OpenType font files from PostScript and TrueType font data. It includes data files, Python scripts, and command-line programs.

    As of version 5.0.0, the toolkit features a unified command interface using the afdko <command> syntax and provides variable font support in addfeatures (which replaces the older makeotfexe).

  4. Understanding the `otfautohint` tool

    develop

    otfautohint is a Python-based port of the original C-based "Automatic Coloring" code (formerly known as psautohint). It is used for automatic hinting of OpenType fonts.

    Key Characteristics

    • Performance: Because it is written in Python, it is significantly slower than the original C version when hinting a single glyph. However, it uses the multiprocessing module to hint different glyphs in parallel across multiple CPU cores by default. On an 8-core machine, it is typically slightly faster than the C version.
    • Compatibility: It supports hinting variable CFF-based fonts and directly hinting built CFF2 fonts.
    • Behavioral Changes: Users migrating from psautohint should expect differences in results due to improved algorithms and a different encoding in UFO glif files. This is intended to be a one-time change.
    • Memory Usage: It uses more memory than the C version, but it manages this by unpacking glyphs just before hinting and updating them immediately after to lower the peak memory footprint.
  5. How `otfautohint` handles variable font stems

    develop

    When hinting variable fonts, otfautohint must manage stem ordering and overlaps across the design space.

    Stem Ordering

    CFF2 specifications require stems to be defined in increasing order by their starting locations (and then ending locations). To maintain this in variable fonts, otfautohint supports two modes:

    1. Default Mode: Stems are removed until they are in the correct order across all masters.
    2. Experimental Mode: Stems that change order are retained but treated as conflicting with any stems they "cross" anywhere in the design space.

    Stem Overlap

    Two stems are considered to overlap in the design space if:

    1. They change order in any master relative to the default master.
    2. They maintain the same order across all masters, but overlap (within the overlap margin $O_m$) in at least one master.

    If either condition is met, the stems are treated as overlapping.

  6. Specify variable font locations

    develop

    In OpenType feature files, a <location> represents a position in a variable design space. It is a comma-separated list of axis location specifiers (one per axis). Each specifier consists of an axis tag, an equals sign, a value, and an optional unit letter.

    Unit Letters:

    • u: User units (input values in the designspace axis map).
    • d: Design units (output values in the designspace axis map).
    • n: Normalized units (values between -1 and 1, where 0 is default).

    Incremental adjustments:

    • A trailing + adds the minimum F2Dot14 increment to the calculated normalized value.
    • A trailing - subtracts the minimum F2Dot14 increment.
    wght=800
    wght=1000d, opsz=0n
    wght=1000d, opsz=20u+
    wght=1000d-, opsz=20u
  7. OpenType Feature File Overview

    develop

    An OpenType feature file is a text-based specification used to define typographic layout features (such as ligatures and kerning) for an OpenType font. It can also be used to override specific values in font tables during the font creation or editing process. The file is processed by layout engines to apply typographic rules based on the script and language context.

    # Script and language coverage
    languagesystem DFLT dflt;
    languagesystem latn dflt;
    
    # Ligature formation
    feature liga {
        substitute f i by f_i;
        substitute f l by f_l;
    } liga;
    
    # Kerning
    feature kern {
        position A Y -100;
        position a y -80;
        position s f' <0 0 10 0> t;
    } kern;
  8. Understanding Subroutinization in MakeOTF

    develop

    Subroutinization is the process of decomposing common elements in a set of glyphs into separate subroutines.

    Benefits:

    • Reduces the final font file size.
    • Highly useful for Roman fonts and Korean CID fonts.

    Trade-offs:

    • Memory/Time: Can require significant resources. A 5MB CID font might require up to 768MB of memory to subroutinize.
    • Performance: Subroutinizing in memory is fast (minutes for Roman, ~30-180 mins for CID). If the system relies on virtual memory, processing time can increase by 20x or more.
    • Diminishing Returns: Japanese and Chinese CID fonts typically see only a few percent size reduction due to fewer repeating path elements.

    Control Flags:

    • --S: Turn on subroutinization.
    • -nS: Turn off subroutinization.
    • --r: Enables subroutinization as part of 'release mode'.
  9. Specifying anonymous data blocks in OpenType feature files

    develop

    OpenType feature files can include anonymous (or abbreviated anon) tagged blocks of data. These blocks are used to pass custom or unsupported table information back to the implementation software. The parser does not attempt to parse the content inside these blocks; it simply extracts the data and the associated tag for the client.

    Syntax Requirements:

    • Use the keyword anonymous or anon followed by a <tag>.
    • The block starts with an opening brace {.
    • Crucial: The closing brace, the tag, and the semicolon must all reside on the same line (e.g., } <tag>;) to signal the end of the block to the parser.
    • The include directive is not recognized inside an anonymous block; therefore, the entire block must be contained within a single file.

    Data Extraction: The client receives the data starting from the first line after the opening brace up to (and including) the newline character immediately preceding the closing line.

    # Using the 'anonymous' keyword
    anon sbit {
        /* sbit table specifications */
        72  % dpi
        sizes {
            10, 12, 14 source {
                oall "Generic/JGeneric"
            }
        }
    } sbit;
  10. Use value records for positioning

    develop

    A <valuerecord> is used in positioning rules to adjust metrics (x/y placement and x/y advance). There are several formats:

    • Format A (Simple): A single <metric>. Represents an x advance adjustment (or y advance in vkrn, vpal, vhal, or valt features). Example: -3.
    • Format B (Variable): (<metric> <location>:<metric> <location>:<metric> ...). A bare metric is for the default instance. Example: (-3 wght=200u:-5 wght=900u:-2).
    • Format C (Four-part): <<(v)metric> <(v)metric> <(v)metric> <(v)metric>>. Order is: x placement, y placement, x advance, y advance. Example: <-80 0 -160 0>.
    • Format D (Combined): (<<metric> <metric> <metric> <metric>> <location>:<<metric> <metric> <metric> <metric>> ...). Combines B and C for multiple locations.
    • Format G (Named): <name>. Uses a name defined via valueRecordDef and must be enclosed in angle brackets.
    # Format A
    -3
    
    # Format B
    (-3 wght=200u:-5 wght=900u:-2)
    
    # Format C
    <-80 0 -160 0>
    
    # Format D
    (<-80 0 -160 0> wght=200u:<-80 0 -140 0> @ExtraBlack:<-80 0 -180 0>)
    
    # Format G
    <KERN_POS_1>
  11. How the OpenType Layout (OTL) engine processes lookups and rules

    develop

    The OpenType Layout engine performs substitutions (GSUB) and positionings (GPOS) using a specific algorithm. A critical concept for feature file authors is that each lookup corresponds to one "pass" over the glyph run.

    Each lookup takes the accumulated result of all previous lookups in the LookupList as its input. This means the order in which lookups appear in your feature file directly affects the state of the glyph run for subsequent lookups.

    The Layout Algorithm Summary

    1. Language System Check: All glyphs in the run must belong to the same language system.
    2. Feature Assembly: All features (including required features) for the language system are assembled.
    3. Lookup Assembly: All lookups in those features are assembled in LookupList order, removing duplicates.
    4. Lookup Execution: For each lookup, the engine iterates through the glyph run. If a lookup is applied and the lookupflag does not indicate the glyph should be ignored, the engine checks the lookup's subtables.
    5. Subtable Matching: If a subtable's target context (input sequence, backtrack, and lookahead) is matched, the substitution or positioning is performed.
    6. Contextual Lookups: For (chain) contextual lookups, the engine follows the Subst/PosLookupRecord order defined in the subtable.
    7. Sequence Advancement: After a match, the engine moves to the glyph following the matched input sequence.
  12. Specify designspace locations and unit suffixes

    develop

    A designspace location is a set of axis-value pairs (e.g., tag=value). When specifying axis values, you must use one of three unit suffixes:

    • d (Design units): Units chosen by the designer, typically specified in a designspace file. This is generally the most intuitive and stable scale.
    • u (User units): Units presented to a user. A designspace file maps design units to user units.
    • n (Normalized units): A range from -1n (minimum) to 1n (maximum), with 0n representing the default location. Precision is F2dot14.

    Incremental positioning:

    • Use + (e.g., wght=600d+) to specify the minimum F2dot14 increment above the value.
    • Use - (e.g., wght=600d-) to specify the minimum F2dot14 decrement below the value.
    // Example of a full location specification
    wght=1000d, opsz=0n
    
    // Example using incremental positioning
    wght=600d+, opsz=0n+