Class: Fontisan::Tables::Cff::CharstringsIndex

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

Overview

CharStrings INDEX wrapper

This class wraps the CharStrings INDEX to provide convenient access to individual CharString objects. The CharStrings INDEX contains the glyph outline programs (Type 2 CharStrings) for each glyph in the font.

CharStrings Format:

  • INDEX structure containing binary CharString data

  • Each entry is a Type 2 CharString program

  • Number of entries typically matches the number of glyphs

  • Index 0 is typically .notdef glyph

Usage:

  1. Create from raw CharStrings INDEX data

  2. Provide Private DICT and subroutine INDEXes for interpretation

  3. Access individual CharStrings by glyph index

Reference: CFF specification section 16 “Local/Global Subrs INDEXes” adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf

Examples:

Using CharStringsIndex

# Get CharStrings INDEX from CFF table
charstrings_offset = top_dict.charstrings
io = StringIO.new(cff.raw_data)
io.seek(charstrings_offset)
charstrings_index = CharstringsIndex.new(io, start_offset:
                                          charstrings_offset)

# Get a specific CharString
charstring = charstrings_index.charstring_at(
  glyph_index,
  private_dict,
  global_subrs,
  local_subrs
)

# Access CharString properties
puts charstring.width
puts charstring.bounding_box
charstring.to_commands.each { |cmd| puts cmd.inspect }

Instance Attribute Summary

Attributes inherited from Index

#count, #data, #off_size, #offsets

Instance Method Summary collapse

Methods inherited from Index

#[], #each, #empty?, #initialize, #item_size, #to_a, #total_size

Constructor Details

This class inherits a constructor from Fontisan::Tables::Cff::Index

Instance Method Details

#all_charstrings(private_dict, global_subrs, local_subrs = nil) ⇒ Array<CharString>

Get all CharStrings as an array of CharString objects

This method interprets all CharStrings in the INDEX. Use with caution for fonts with many glyphs as this can be memory-intensive.

Examples:

Getting all CharStrings

charstrings = charstrings_index.all_charstrings(
  private_dict,
  global_subrs,
  local_subrs
)
charstrings.each_with_index do |cs, i|
  puts "Glyph #{i}: width=#{cs.width}, bbox=#{cs.bounding_box}"
end

Parameters:

  • private_dict (PrivateDict)

    Private DICT for width defaults

  • global_subrs (Index)

    Global subroutines INDEX

  • local_subrs (Index, nil) (defaults to: nil)

    Local subroutines INDEX (optional)

Returns:

  • (Array<CharString>)

    Array of interpreted CharString objects



97
98
99
100
101
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 97

def all_charstrings(private_dict, global_subrs, local_subrs = nil)
  Array.new(count) do |i|
    charstring_at(i, private_dict, global_subrs, local_subrs)
  end
end

#charstring_at(index, private_dict, global_subrs, local_subrs = nil) ⇒ CharString?

Get a CharString object at the specified glyph index

This method retrieves the binary CharString data at the given index and interprets it as a Type 2 CharString program.

Examples:

Getting a CharString

charstring = charstrings_index.charstring_at(
  42,
  private_dict,
  global_subrs,
  local_subrs
)
puts "Width: #{charstring.width}"
puts "Bounding box: #{charstring.bounding_box.inspect}"

Parameters:

  • index (Integer)

    Glyph index (0-based, 0 is typically .notdef)

  • private_dict (PrivateDict)

    Private DICT for width defaults

  • global_subrs (Index)

    Global subroutines INDEX

  • local_subrs (Index, nil) (defaults to: nil)

    Local subroutines INDEX (optional)

Returns:

  • (CharString, nil)

    Interpreted CharString object, or nil if index is out of bounds



71
72
73
74
75
76
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 71

def charstring_at(index, private_dict, global_subrs, local_subrs = nil)
  data = self[index]
  return nil unless data

  CharString.new(data, private_dict, global_subrs, local_subrs)
end

#charstring_size(index) ⇒ Integer?

Get the size of a CharString in bytes

This returns the size of the binary CharString data without interpreting it.

Parameters:

  • index (Integer)

    Glyph index

Returns:

  • (Integer, nil)

    Size in bytes, or nil if index is invalid



156
157
158
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 156

def charstring_size(index)
  item_size(index)
end

#each_charstring(private_dict, global_subrs, local_subrs = nil) {|CharString, Integer| ... } ⇒ Enumerator

Iterate over each CharString in the INDEX

This method yields each CharString as it is interpreted, which is more memory-efficient than loading all at once.

Examples:

Iterating over CharStrings

charstrings_index.each_charstring(private_dict, global_subrs,
                                  local_subrs) do |cs, index|
  puts "Glyph #{index}: #{cs.bounding_box}"
end

Parameters:

  • private_dict (PrivateDict)

    Private DICT for width defaults

  • global_subrs (Index)

    Global subroutines INDEX

  • local_subrs (Index, nil) (defaults to: nil)

    Local subroutines INDEX (optional)

Yields:

  • (CharString, Integer)

    Interpreted CharString and its index

Returns:

  • (Enumerator)

    If no block given



119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 119

def each_charstring(private_dict, global_subrs, local_subrs = nil)
  unless block_given?
    return enum_for(:each_charstring, private_dict, global_subrs,
                    local_subrs)
  end

  count.times do |i|
    charstring = charstring_at(i, private_dict, global_subrs,
                               local_subrs)
    yield charstring, i if charstring
  end
end

#glyph_countInteger

Get the number of glyphs (CharStrings) in this INDEX

This is typically the same as the number of glyphs in the font.

Returns:

  • (Integer)

    Number of glyphs



137
138
139
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 137

def glyph_count
  count
end

#valid_glyph_index?(index) ⇒ Boolean

Check if a glyph index is valid

Parameters:

  • index (Integer)

    Glyph index to check

Returns:

  • (Boolean)

    True if index is valid



145
146
147
# File 'lib/fontisan/tables/cff/charstrings_index.rb', line 145

def valid_glyph_index?(index)
  index >= 0 && index < count
end