Module: Fontisan::Ufo::Compile::Filters::PropagateAnchors

Defined in:
lib/fontisan/ufo/compile/filters/propagate_anchors.rb

Overview

Propagates anchors from base glyphs to composite glyphs.

In UFO sources, a composite glyph references base glyphs via Component entries. Anchors (mark-attachment points used by GPOS mark feature writers) typically live on the base glyphs only — the composite inherits them by applying each component's transformation matrix to the base's anchors.

This filter does that propagation in place. After it runs, every composite glyph carries its component-derived anchors, ready for the mark feature writer to read.

Single-pass (no recursive propagation through multi-level component chains). Multi-level propagation would require topological sort; if you need it, run the filter repeatedly until no anchors change.

Class Method Summary collapse

Class Method Details

.run(glyphs, font: nil, **_opts) ⇒ Array<Fontisan::Ufo::Glyph>

Returns the same array, mutated in place.

Parameters:

  • glyphs (Array<Fontisan::Ufo::Glyph>)

    the glyphs to mutate. Must include any base glyphs referenced by components, or those references will be silently skipped.

  • font (Fontisan::Ufo::Font, nil) (defaults to: nil)

    optional explicit font lookup. When provided, base glyphs are resolved via font.glyph(name) instead of the glyphs array, so composites can reference base glyphs that aren't in the glyphs list.

Returns:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/fontisan/ufo/compile/filters/propagate_anchors.rb', line 35

def self.run(glyphs, font: nil, **_opts)
  lookup = build_lookup(font, glyphs)

  glyphs.each do |glyph|
    next if glyph.components.empty?

    glyph.components.each do |component|
      base = lookup[component.base_glyph]
      next unless base

      transform = coerce_transformation(component.transformation)
      propagate_anchors(glyph, base, transform)
    end
  end

  glyphs
end