glyphsLib

repository·main·Indexed 41 days ago

https://github.com/googlefonts/glyphslib

A Python library that acts as a bridge between Glyphs source files (.glyphs) and UFO/Designspace formats. It provides tools for converting font data, managing axis locations via AxisDefinition, handling kerning conversion between Glyphs and UFO, and decomposing smart components. Key functions include build_masters for exporting complete font family structures and load_to_ufos for loading .glyphs objects into memory.

Tokens
10.5K
Snippets
37
Records
59
Agent score
52%

What's inside glyphsLib

  1. Overview of glyphsLib.builder conversion process

    main
    glyphsLib.builder is a component designed to convert a Glyphs GSFont object into a structured set of UFO (Unified Font Object) and Designspace files. The conversion process follows a hierarchical workflow: converting masters, layers, and individual glyphs, and finally generating a Designspace file to represent the font's variations and instances.
  2. How glyphsLib.builder converts masters

    main

    When converting a Glyphs GSFont to masters, the builder performs the following steps:

    1. Base UFO Creation: Creates base UFOs using GSFont metadata and per-master metadata, including names, user data, custom parameters, and custom filters.
    2. Layer Conversion: Converts the main layer of each master, including bracket/brace layers.
    3. Anchor Propagation: Propagates anchors to the UFO layers.
    4. Feature Conversion: Converts Glyphs features into a dedicated feature file.
    5. Parameter Application: Applies custom parameters such as codePageRanges, GASP table, Color Palettes (stored in a ufo2ft key), Name records, glyphOrder, and Filters.
    6. Color Layer Handling: Fixes up color layers by creating color palette layers (e.g., {glyphname}.color{i}) and COLRv1 layers with appropriate paint/stroke applications.
    7. Group and Kerning Conversion: Converts feature groups, kerning groups, and kerning data.
  3. How glyphsLib.builder creates the Designspace file

    main

    To generate the Designspace file, the builder performs these mappings:

    • Axes: Converts Glyphs axes to Designspace axes by inspecting custom parameters like Axis Mappings, Axes, Axis Location, and Variable Font Origin / Variation Font Origin.
    • Sources & Instances: Converts Glyphs masters into Designspace sources and Glyphs instances into Designspace instances.
    • Metadata: Copies user data into the Designspace lib and adds feature writers (unless a manual kern feature exists).
    • Bracket Layers: Extracts bracket layers into free-standing UFO glyphs using Designspace substitution rules. The Feature for Feature Variations custom parameter is used to set the OT feature for these rules.
  4. How glyphsLib.builder converts glyphs

    main

    The glyph conversion process involves several specialized steps for each glyph:

    • Color Glyphs: Creates a mapping between layers and palette IDs and clones layers with shared components.
    • Metadata & Attributes: Sets unicodes, determines production name/category/subcategory, and handles width determination (checking parameters like Link Metrics With Master or Link Metrics With First Master).
    • Components & Anchors: Resolves/decomposes smart components, converts components to UFO format, and converts anchors to UFO.
    • Drawing: Uses a pen to draw paths onto the UFO glyph.
    • Hints & Vertical Fonts: Converts hints and, if the font is vertical, sets the height and vertical origin in the UFO.
  5. Minimize git diffs when round-tripping between Glyphs and UFOs

    main

    When converting between formats, glyphsLib can add bookkeeping metadata to minimize the number of changes (diffs) that appear in version control (git) when converting back and forth.

    • Glyphs $\rightarrow$ UFO: Use minimize_ufo_diffs=True in to_glyphs(). This adds bookkeeping to userData fields (e.g., remembering which GSClass came from groups.plist).
    • UFO $\rightarrow$ Glyphs: Use minimize_glyphs_diffs=True in to_designspace(). This adds bookkeeping to the UFO lib (e.g., keeping the same UUIDs for Glyphs layers).
    import os
    from fontTools.designspaceLib import DesignSpaceDocument
    from glyphsLib import to_glyphs, to_designspace, GSFont
    
    # 1. Glyphs -> UFOs (with minimized diffs)
    doc = DesignSpaceDocument()
    doc.read("spectral-build-roman.designspace")
    font = to_glyphs(doc, minimize_ufo_diffs=True)
    
    doc2 = to_designspace(font, propagate_anchors=False)
    doc2.write(doc.path)
    for source in doc2.sources:
        path = os.path.join(os.path.dirname(doc.path), source.filename)
        source.font.save(path)
    
    # 2. UFOs -> Glyphs (with minimized diffs)
    font = GSFont("SpectralRoman.glyphs")
    doc = to_designspace(font, minimize_glyphs_diffs=True, propagate_anchors=False)
    font2 = to_glyphs(doc)
    font2.save(font.filepath)
  6. How glyphsLib.builder converts layers

    main

    The layer conversion logic distinguishes between master layers and non-master layers:

    • Master Layers: For each glyph, the builder looks at all Glyphs layers and selects/creates the appropriate UFO layers corresponding to the masters.
    • Non-Master Layers: The builder collects Glyphs layers and associated glyphs. It discards layers that have no associated master and no name, or other irrelevant layers. Bracket layers are gathered to be processed during Designspace generation.
  7. How load_glyphspackage processes .glyphspackages

    main

    When load_glyphspackage is called on a directory, it performs the following steps to reconstruct a font:

    1. Reads Metadata: It loads fontinfo.plist for core font data.
    2. Handles UI State: If UIState.plist exists, it updates the font data. It specifically handles a key migration where displayStrings is normalized to DisplayStrings.
    3. Collects Glyphs: It iterates through all *.glyph files in the glyphs/ subdirectory of the package.
    4. Sorts Glyphs: It uses order.plist to determine the glyph order. Glyphs listed in the order file are placed first (maintaining their relative order), followed by any remaining glyphs sorted alphabetically by name.
  8. Convert Glyphs user data to UFO and Designspace formats

    main

    The user_data.py module provides methods to translate metadata (user data) between Glyphs-style font representations and UFO (Unified Font Object) or Designspace formats. This is primarily used when building master UFOs or Designspace files from a Glyphs source.

    Key conversion directions include:

    • To Designspace: Moves family-wide user data into the Designspace lib.
    • To UFO (Family): Sets family-wide data in the UFO lib under FONT_USER_DATA_KEY.
    • To UFO (Master): Sets master-specific data in the UFO lib.
    • To UFO (Glyph/Layer/Node): Maps specific metadata to glyph-level, layer-level, or individual node-level keys in the UFO lib.
  9. Propagate anchors when converting to UFO

    main

    This module is DEPRECATED and will be removed in a future release. It provides functionality to copy anchors from parent glyphs' components to the parent glyph during UFO conversion.

    Depending on your object type, use one of the following alternatives:

    1. For GSFont objects: Use the glyphsLib.builder.transformations.propagate_anchors module.
    2. For UFO font objects: Use the ufo2ft.filters.propagateAnchors filter.

    If you must use this deprecated logic for a UFO object, the method to_ufo_propagate_font_anchors(self, ufo) is available on the relevant object to propagate anchors from components to the parent.

  10. Convert UFOs to Glyphs using a Designspace file

    main

    To convert a collection of UFOs into a single .glyphs file using a .designspace document, use glyphsLib.to_glyphs() passing in a DesignSpaceDocument.

    import glob
    from fontTools.designspaceLib import DesignSpaceDocument
    from glyphsLib import to_glyphs
    
    doc = DesignSpaceDocument()
    doc.read("spectral-build-roman.designspace")
    font = to_glyphs(doc)
    font.save("SpectralRoman.glyphs")
  11. Read and write Glyphs data using GSFont

    main

    The GSFont class provides an interface for reading and saving Glyphs files as Python objects. The glyphsLib.classes module aims to provide an interface similar to the Glyphs.app Python Scripting API.

    from glyphsLib import GSFont
    
    font = GSFont("path/to/font.glyphs")
    # ... manipulate font ...
    font.save("path/to/font.glyphs")
  12. Convert Glyphs files to UFOs and Designspace

    main

    Use glyphsLib.build_masters() to convert a .glyphs source file into a directory of master UFOs and a .designspace file.

    Note: If you need to interpolate instances, use fontmake instead; fontmake uses glyphsLib internally for Glyphs file handling.

    import glyphsLib
    
    master_dir = "master_ufos"
    ufo_list, designspace_path = glyphsLib.build_masters("MyFont.glyphs", master_dir)