Module: Fontisan::Converters::OutlineExtraction

Included in:
OutlineConverter
Defined in:
lib/fontisan/converters/outline_extraction.rb

Overview

Extracts all glyph outlines from a font for conversion purposes

Unlike OutlineExtractor which extracts single glyphs, this module extracts ALL glyphs from a font for bulk conversion operations.

Instance Method Summary collapse

Instance Method Details

#extract_cff_outlines(font) ⇒ Array<Outline>

Extract all outlines from CFF font

Parameters:

Returns:

  • (Array<Outline>)

    Array of outline objects

Raises:



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/fontisan/converters/outline_extraction.rb', line 58

def extract_cff_outlines(font)
  # Get CFF table
  cff = font.table("CFF ")
  raise Fontisan::Error, "CFF table not found" unless cff

  # Get number of glyphs
  num_glyphs = cff.glyph_count

  # Extract all glyphs
  outlines = []
  num_glyphs.times do |glyph_id|
    charstring = cff.charstring_for_glyph(glyph_id)

    outlines << if charstring.nil? || charstring.path.empty?
                  # Empty glyph
                  Models::Outline.new(
                    glyph_id: glyph_id,
                    commands: [],
                    bbox: { x_min: 0, y_min: 0, x_max: 0, y_max: 0 },
                  )
                else
                  # Convert CharString to outline
                  Models::Outline.from_cff(charstring, glyph_id)
                end
  end

  outlines
end

#extract_ttf_outlines(font) ⇒ Array<Outline>

Extract all outlines from TrueType font

Parameters:

Returns:

  • (Array<Outline>)

    Array of outline objects



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/fontisan/converters/outline_extraction.rb', line 17

def extract_ttf_outlines(font)
  # Get required tables
  head = font.table("head")
  maxp = font.table("maxp")
  loca = font.table("loca")
  glyf = font.table("glyf")

  # Parse loca with context
  loca.parse_with_context(head.index_to_loc_format, maxp.num_glyphs)

  # Create resolver for compound glyphs
  resolver = Tables::CompoundGlyphResolver.new(glyf, loca, head)

  # Extract all glyphs
  outlines = []
  maxp.num_glyphs.times do |glyph_id|
    glyph = glyf.glyph_for(glyph_id, loca, head)

    outlines << if glyph.nil? || glyph.empty?
                  # Empty glyph - create empty outline
                  Models::Outline.new(
                    glyph_id: glyph_id,
                    commands: [],
                    bbox: { x_min: 0, y_min: 0, x_max: 0, y_max: 0 },
                  )
                elsif glyph.simple?
                  # Convert simple glyph to outline
                  Models::Outline.from_truetype(glyph, glyph_id)
                else
                  # Compound glyph - resolve to simple outline
                  resolver.resolve(glyph)
                end
  end

  outlines
end