Class: Fontisan::Tables::Cff::CFFGlyph

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/tables/cff/cff_glyph.rb

Overview

Wrapper class for CFF glyph data

[‘CFFGlyph`](lib/fontisan/tables/cff/cff_glyph.rb) provides a unified interface for CFF glyphs that matches the API of TrueType glyphs ([`SimpleGlyph`](lib/fontisan/tables/glyf/simple_glyph.rb) and [`CompoundGlyph`](lib/fontisan/tables/glyf/compound_glyph.rb)).

This allows [‘GlyphAccessor`](lib/fontisan/glyph_accessor.rb) to work transparently with both TrueType (glyf) and OpenType/CFF fonts.

CFF Glyph Characteristics:

  • Always “simple” (no composite structure like TrueType compound glyphs)

  • Outline data stored as Type 2 CharString programs

  • Width information embedded in CharString

  • Glyph names from Charset

Reference: [‘docs/ttfunk-feature-analysis.md:541-575`](docs/ttfunk-feature-analysis.md:541)

Examples:

Accessing a CFF glyph

cff = font.table("CFF ")
charstring = cff.charstring_for_glyph(42)
glyph = CFFGlyph.new(42, charstring, cff.charset, cff.encoding)

puts glyph.name           # => "A"
puts glyph.width          # => 500
puts glyph.bounding_box   # => [10, 0, 490, 700]
puts glyph.simple?        # => true
puts glyph.compound?      # => false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(glyph_id, charstring, charset, encoding = nil) ⇒ CFFGlyph

Initialize a CFF glyph wrapper

Parameters:

  • glyph_id (Integer)

    Glyph ID (0-based, 0 is .notdef)

  • charstring (CharString)

    Interpreted CharString object

  • charset (Charset)

    Charset for name lookup

  • encoding (Encoding, nil) (defaults to: nil)

    Encoding (optional, for character code mapping)



48
49
50
51
52
53
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 48

def initialize(glyph_id, charstring, charset, encoding = nil)
  @glyph_id = glyph_id
  @charstring = charstring
  @charset = charset
  @encoding = encoding
end

Instance Attribute Details

#charstringCharString (readonly)

Returns Interpreted CharString with path data.

Returns:

  • (CharString)

    Interpreted CharString with path data



39
40
41
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 39

def charstring
  @charstring
end

#glyph_idInteger (readonly)

Returns Glyph ID (GID).

Returns:

  • (Integer)

    Glyph ID (GID)



36
37
38
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 36

def glyph_id
  @glyph_id
end

Instance Method Details

#bounding_boxArray<Float>?

Get the bounding box for this glyph

Returns the glyph’s bounding box in font units as calculated from the CharString path.

Returns:

  • (Array<Float>, nil)
    xMin, yMin, xMax, yMax

    or nil if empty



94
95
96
97
98
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 94

def bounding_box
  return nil unless @charstring

  @charstring.bounding_box
end

#compound?Boolean

Check if this is a compound glyph

CFF glyphs don’t have components like TrueType compound glyphs.

Returns:

  • (Boolean)

    Always false for CFF glyphs



72
73
74
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 72

def compound?
  false
end

#empty?Boolean

Check if this glyph has no outline data

A glyph is empty if its CharString path is empty (e.g., space character)

Returns:

  • (Boolean)

    True if glyph has no path data



82
83
84
85
86
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 82

def empty?
  return true unless @charstring

  @charstring.path.empty?
end

#nameString

Get the PostScript glyph name

Looks up the glyph name from the Charset using the glyph ID.

Returns:

  • (String)

    Glyph name (e.g., “A”, “Aacute”, “.notdef”)



117
118
119
120
121
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 117

def name
  return ".notdef" unless @charset

  @charset.glyph_name(@glyph_id) || ".notdef"
end

#pathArray<Hash>

Get the raw path data

Returns the raw path array from the CharString for advanced use cases.

Returns:

  • (Array<Hash>)

    Array of path command hashes with keys:

    • :type (:move_to, :line_to, :curve_to)

    • :x, :y (coordinates)

    • :x1, :y1, :x2, :y2 (control points for curves)



158
159
160
161
162
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 158

def path
  return [] unless @charstring

  @charstring.path
end

#simple?Boolean

Check if this is a simple glyph

CFF glyphs are conceptually “simple” - they don’t have the composite structure that TrueType compound glyphs have. While CFF CharStrings can call subroutines, these are code reuse mechanisms, not glyph composition.

Returns:

  • (Boolean)

    Always true for CFF glyphs



63
64
65
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 63

def simple?
  true
end

#to_commandsArray<Array>

Convert the glyph outline to drawing commands

Returns an array of drawing commands that can be used to render the glyph outline.

Examples:

Rendering a glyph

glyph.to_commands.each do |cmd|
  case cmd[0]
  when :move_to
    canvas.move_to(cmd[1], cmd[2])
  when :line_to
    canvas.line_to(cmd[1], cmd[2])
  when :curve_to
    canvas.curve_to(cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6])
  end
end

Returns:

  • (Array<Array>)

    Array of command arrays:

    • :move_to, x, y
    • :line_to, x, y
    • :curve_to, x1, y1, x2, y2, x, y


144
145
146
147
148
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 144

def to_commands
  return [] unless @charstring

  @charstring.to_commands
end

#to_sString Also known as: inspect

String representation for debugging

Returns:

  • (String)

    Human-readable representation



167
168
169
170
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 167

def to_s
  "#<#{self.class.name} gid=#{@glyph_id} name=#{name.inspect} " \
    "width=#{width} bbox=#{bounding_box.inspect}>"
end

#widthInteger?

Get the advance width for this glyph

Returns the glyph’s advance width from the CharString.

Returns:

  • (Integer, nil)

    Advance width in font units, or nil if not available



106
107
108
109
110
# File 'lib/fontisan/tables/cff/cff_glyph.rb', line 106

def width
  return nil unless @charstring

  @charstring.width
end