Class: Fontisan::Subset::TableStrategy::Cff

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/subset/table_strategy/cff.rb

Overview

CFF (Compact Font Format) subsetter strategy.

Subsets CFF tables by routing through the UFO model:

source font  Ufo::Convert::FromBinData  UFO (with contours)
            filter glyphs to mapping 
            Ufo::Compile::Cff.build  new CFF bytes

This is the architecturally preferred path: the UFO model is the canonical representation, CFF is a serialization. The strategy reuses the existing compile pipeline rather than reimplementing CFF INDEX arithmetic.

Glyphs not in the mapping are dropped from the UFO before compilation. The Cff.build pipeline generates the correct charset (GID → SID mapping) from the retained glyph names.

See TODO #15 for the full design rationale and the CFF2 extension path.

Class Method Summary collapse

Class Method Details

.call(context:, tag:, table:) ⇒ String

Returns subset CFF table bytes.

Parameters:

  • context (SubsetContext)
  • tag (String)

    "CFF "

  • table (Object)

    parsed CFF table (unused — we work from the source font directly)

Returns:

  • (String)

    subset CFF table bytes



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/fontisan/subset/table_strategy/cff.rb', line 31

def self.call(context:, tag:, table:)
  source_font = context.font
  mapping = context.mapping

  ufo = Ufo::Convert::FromBinData.convert(source_font)
  filter_ufo_glyphs!(ufo, mapping)

  # Rename the first glyph (source GID 0) to .notdef so the
  # CFF compiler's charset generation produces a valid .notdef
  # entry at GID 0.
  first_name = ufo.glyphs.keys.first
  if first_name && first_name != ".notdef"
    notdef = ufo.glyphs.delete(first_name)
    notdef = Ufo::Glyph.new(name: ".notdef") if notdef.nil?
    ufo.glyphs[".notdef"] = notdef
  end

  glyphs = ufo.layers.default_layer.each.to_a
  Fontisan::Ufo::Compile::Cff.build(ufo, glyphs: glyphs)
end