Class: Fontisan::Tables::Cff::Index
- Inherits:
-
Object
- Object
- Fontisan::Tables::Cff::Index
- Includes:
- Enumerable
- Defined in:
- lib/fontisan/tables/cff/index.rb
Overview
CFF INDEX structure
INDEX is a fundamental data structure used throughout CFF for storing arrays of variable-length data items. It's used for:
- Name INDEX (font names)
- String INDEX (string data)
- Global Subr INDEX (global subroutines)
- Local Subr INDEX (local subroutines)
- CharStrings INDEX (glyph programs)
Structure:
- count (Card16): Number of objects stored in INDEX
- offSize (OffSize): Size of offset values (1-4 bytes)
- offset (Offset): Array of offsets to data
- data: The actual data bytes
Offsets are relative to the byte before the data array. The first offset is always 1, not 0. The last offset points one byte past the end of the data.
Reference: CFF specification section 5 "INDEX Data" https://adobe-type-tools.github.io/font-tech-notes/pdfs/5176.CFF.pdf
Direct Known Subclasses
Instance Attribute Summary collapse
-
#count ⇒ Integer
readonly
Number of items in the INDEX.
-
#data ⇒ String
readonly
Binary string containing all data.
-
#off_size ⇒ Integer
readonly
Size of offset values (1-4 bytes).
-
#offsets ⇒ Array<Integer>
readonly
Array of offsets (count + 1 elements).
-
#start_offset ⇒ Integer
readonly
Byte offset where this INDEX starts in the source data.
Instance Method Summary collapse
-
#[](index) ⇒ String?
Get the item at the specified index.
-
#each {|String| ... } ⇒ Enumerator
Iterate over each item in the INDEX.
-
#empty? ⇒ Boolean
Check if the INDEX is empty.
-
#initialize(io, start_offset: 0) ⇒ Index
constructor
Initialize an INDEX from binary data.
-
#item_size(index) ⇒ Integer?
Get the size of a specific item.
-
#to_a ⇒ Array<String>
Get all items as an array.
-
#total_size ⇒ Integer
Calculate total size of the INDEX in bytes.
Constructor Details
#initialize(io, start_offset: 0) ⇒ Index
Initialize an INDEX from binary data
58 59 60 61 62 63 64 |
# File 'lib/fontisan/tables/cff/index.rb', line 58 def initialize(io, start_offset: 0) @io = io.is_a?(String) ? StringIO.new(io) : io @start_offset = start_offset @io.seek(start_offset) parse! end |
Instance Attribute Details
#count ⇒ Integer (readonly)
Returns Number of items in the INDEX.
40 41 42 |
# File 'lib/fontisan/tables/cff/index.rb', line 40 def count @count end |
#data ⇒ String (readonly)
Returns Binary string containing all data.
49 50 51 |
# File 'lib/fontisan/tables/cff/index.rb', line 49 def data @data end |
#off_size ⇒ Integer (readonly)
Returns Size of offset values (1-4 bytes).
43 44 45 |
# File 'lib/fontisan/tables/cff/index.rb', line 43 def off_size @off_size end |
#offsets ⇒ Array<Integer> (readonly)
Returns Array of offsets (count + 1 elements).
46 47 48 |
# File 'lib/fontisan/tables/cff/index.rb', line 46 def offsets @offsets end |
#start_offset ⇒ Integer (readonly)
Returns Byte offset where this INDEX starts in the source data.
52 53 54 |
# File 'lib/fontisan/tables/cff/index.rb', line 52 def start_offset @start_offset end |
Instance Method Details
#[](index) ⇒ String?
Get the item at the specified index
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/fontisan/tables/cff/index.rb', line 70 def [](index) return nil if index.negative? || index >= count return "" if count.zero? # Offsets are 1-based in the data array start_pos = offsets[index] - 1 end_pos = offsets[index + 1] - 1 length = end_pos - start_pos data[start_pos, length] end |
#each {|String| ... } ⇒ Enumerator
Iterate over each item in the INDEX
86 87 88 89 90 91 92 |
# File 'lib/fontisan/tables/cff/index.rb', line 86 def each return enum_for(:each) unless block_given? count.times do |i| yield self[i] end end |
#empty? ⇒ Boolean
Check if the INDEX is empty
104 105 106 |
# File 'lib/fontisan/tables/cff/index.rb', line 104 def empty? count.zero? end |
#item_size(index) ⇒ Integer?
Get the size of a specific item
112 113 114 115 116 117 |
# File 'lib/fontisan/tables/cff/index.rb', line 112 def item_size(index) return nil if index.negative? || index >= count return 0 if count.zero? offsets[index + 1] - offsets[index] end |
#to_a ⇒ Array<String>
Get all items as an array
97 98 99 |
# File 'lib/fontisan/tables/cff/index.rb', line 97 def to_a Array.new(count) { |i| self[i] } end |
#total_size ⇒ Integer
Calculate total size of the INDEX in bytes
This includes the count, offSize, offset array, and data.
124 125 126 127 128 129 |
# File 'lib/fontisan/tables/cff/index.rb', line 124 def total_size return 2 if count.zero? # Just the count field # count (2) + offSize (1) + offset array + data 2 + 1 + ((count + 1) * off_size) + data.bytesize end |