Class: Fontisan::Type1::SeacExpander

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/type1/seac_expander.rb

Overview

Expands Type 1 seac composite glyphs into base + accent outlines

SeacExpander handles the decomposition of Type 1 composite glyphs that use the seac operator. The seac operator combines two glyphs (a base character and an accent) with a positioning offset, which must be decomposed for CFF conversion.

Supports nested seac: if a base or accent glyph is itself a seac composite, it is recursively expanded. Cycles are detected and raise SeacReferenceError.

The seac operator format is:

seac asb adx ady bchar achar

Where:

  • asb: Accent side bearing (not used in decomposition)
  • adx: X offset for accent placement
  • ady: Y offset for accent placement
  • bchar: Character code of base glyph
  • achar: Character code of accent glyph

Examples:

Decompose a seac composite

expander = Fontisan::Type1::SeacExpander.new(charstrings, private_dict)
decomposed = expander.decompose("Agrave")
# => Returns merged outline of base 'A' + accent 'grave'

See Also:

Constant Summary collapse

MAX_DEPTH =
16

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(charstrings, private_dict) ⇒ SeacExpander

Initialize a new SeacExpander

Parameters:

  • charstrings (CharStrings)

    Type 1 CharStrings dictionary

  • private_dict (PrivateDict)

    Private dictionary for context



51
52
53
54
# File 'lib/fontisan/type1/seac_expander.rb', line 51

def initialize(charstrings, private_dict)
  @charstrings = charstrings
  @private_dict = private_dict
end

Instance Attribute Details

#charstringsCharStrings (readonly)

Returns Type 1 CharStrings dictionary.

Returns:



42
43
44
# File 'lib/fontisan/type1/seac_expander.rb', line 42

def charstrings
  @charstrings
end

#private_dictPrivateDict (readonly)

Returns Private dictionary for hinting.

Returns:



45
46
47
# File 'lib/fontisan/type1/seac_expander.rb', line 45

def private_dict
  @private_dict
end

Instance Method Details

#composite?(glyph_name) ⇒ Boolean

Check if a glyph is a seac composite

Parameters:

  • glyph_name (String)

    Glyph name to check

Returns:

  • (Boolean)

    True if the glyph uses seac operator



71
72
73
# File 'lib/fontisan/type1/seac_expander.rb', line 71

def composite?(glyph_name)
  @charstrings.composite?(glyph_name)
end

#composite_glyphsArray<String>

Get all seac composite glyphs in the font

Returns:

  • (Array<String>)

    List of composite glyph names



78
79
80
# File 'lib/fontisan/type1/seac_expander.rb', line 78

def composite_glyphs
  @charstrings.glyph_names.select { |name| composite?(name) }
end

#decompose(glyph_name) ⇒ String?

Decompose a seac composite glyph into base + accent outlines. Handles nested seac recursively.

Parameters:

  • glyph_name (String)

    Name of the composite glyph to decompose

Returns:

  • (String, nil)

    Decomposed CharString bytecode, or nil if not a seac composite

Raises:

  • (SeacReferenceError)

    If base or accent glyphs are not found, or if a cycle is detected



63
64
65
# File 'lib/fontisan/type1/seac_expander.rb', line 63

def decompose(glyph_name)
  decompose_with_visited(glyph_name, Set.new)
end