Class: Fontisan::Stitcher

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/stitcher.rb,
lib/fontisan/stitcher/source.rb,
lib/fontisan/stitcher/selector.rb,
lib/fontisan/stitcher/selector/gid.rb,
lib/fontisan/stitcher/selector/range.rb,
lib/fontisan/stitcher/selector/codepoints.rb

Overview

Multi-source font stitcher. Combines glyphs from one or more source fonts (UFO or loaded TTF/OTF) into a single new font.

The Stitcher builds a Fontisan::Ufo::Font from selected glyphs, then delegates compilation to the existing TtfCompiler or OtfCompiler. Single source of truth: one compiler pipeline, whether the input is one UFO or many sources.

Examples:

Stitch ASCII from one UFO, Hiragana from another

stitcher = Fontisan::Stitcher.new
stitcher.add_source(:latin, Fontisan::Ufo::Font.open("latin.ufo"))
stitcher.add_source(:jp, Fontisan::Ufo::Font.open("jp.ufo"))
stitcher.include_range(0x41..0x5A, from: :latin)
stitcher.include_range(0x3040..0x309F, from: :jp)
stitcher.write_to("stitched.ttf", format: :ttf)

Defined Under Namespace

Modules: Selector Classes: Source

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeStitcher

Returns a new instance of Stitcher.



25
26
27
28
29
# File 'lib/fontisan/stitcher.rb', line 25

def initialize
  @sources = {}
  @bindings = []
  @target = Ufo::Font.new
end

Instance Attribute Details

#bindingsObject (readonly)

Returns the value of attribute bindings.



23
24
25
# File 'lib/fontisan/stitcher.rb', line 23

def bindings
  @bindings
end

#sourcesObject (readonly)

Returns the value of attribute sources.



23
24
25
# File 'lib/fontisan/stitcher.rb', line 23

def sources
  @sources
end

Instance Method Details

#add_source(label, font) ⇒ Object

Register a named source font.

Parameters:



34
35
36
# File 'lib/fontisan/stitcher.rb', line 34

def add_source(label, font)
  @sources[label.to_sym] = Source.new(font)
end

#build_target_fontFontisan::Ufo::Font

Build the internal UFO::Font from the current bindings. Useful for testing or for further manipulation before writing.

Returns:



96
97
98
99
100
# File 'lib/fontisan/stitcher.rb', line 96

def build_target_font
  @target = Ufo::Font.new
  assign_gids_and_copy_glyphs
  @target
end

#include_codepoints(codepoints, from:) ⇒ Object

Include an explicit list of codepoints.

Parameters:

  • codepoints (Array<Integer>)
  • from (Symbol, String)

    source label



48
49
50
# File 'lib/fontisan/stitcher.rb', line 48

def include_codepoints(codepoints, from:)
  Selector::Codepoints.new(codepoints).apply(source(from), @bindings)
end

#include_gid(donor_gid, from:) ⇒ Object

Include a single glyph by donor gid (rare; for unencoded glyphs like .notdef).

Parameters:

  • donor_gid (Integer)
  • from (Symbol, String)

    source label



56
57
58
# File 'lib/fontisan/stitcher.rb', line 56

def include_gid(donor_gid, from:)
  Selector::Gid.new(donor_gid).apply(source(from), @bindings)
end

#include_notdef(from:) ⇒ Object

Always include .notdef from a named source.

Parameters:

  • from (Symbol, String)

    source label



62
63
64
# File 'lib/fontisan/stitcher.rb', line 62

def include_notdef(from:)
  include_gid(0, from: from)
end

#include_range(range, from:) ⇒ Object

Include all codepoints in a range from a named source.

Parameters:

  • range (Range<Integer>)

    codepoint range

  • from (Symbol, String)

    source label



41
42
43
# File 'lib/fontisan/stitcher.rb', line 41

def include_range(range, from:)
  Selector::Range.new(range).apply(source(from), @bindings)
end

#set_info(info_hash) ⇒ Object

Set font-wide metadata on the stitched font.

Parameters:

  • info_hash (Hash)

    any subset of Fontisan::Ufo::Info fields



68
69
70
# File 'lib/fontisan/stitcher.rb', line 68

def set_info(info_hash)
  @target.info = Ufo::Info.new(info_hash)
end

#write_to(path, format: :ttf) ⇒ Object

Write the stitched font to disk.

For CBDT/CBLC sources (e.g. NotoColorEmoji), the raw CBDT and CBLC tables are copied byte-for-byte into the output. This works because CBDT-mode glyphs are processed first (GIDs 0..N-1), matching the source's GID layout. Only one CBDT source is supported; multiple CBDT sources raise MultipleCbdtSourcesError.

Parameters:

  • path (String)

    output file path

  • format (Symbol) (defaults to: :ttf)

    :ttf or :otf



82
83
84
85
86
87
88
89
90
91
# File 'lib/fontisan/stitcher.rb', line 82

def write_to(path, format: :ttf)
  build_target_font
  compiler = compiler_for(format)
  compiler_instance = compiler.new(@target)
  compiler_instance.compile(output_path: path)

  propagate_cbdt_tables(path) if cbdt_source

  path
end