Class: Fontisan::Tables::VariationCommon::ItemVariationData

Inherits:
Binary::BaseRecord
  • Object
show all
Defined in:
lib/fontisan/tables/variation_common.rb

Overview

Item variation data

Contains delta values for a set of items. Each item can have deltas for multiple regions.

Instance Method Summary collapse

Methods inherited from Binary::BaseRecord

#raw_data, read, #valid?

Instance Method Details

#delta_setsArray<Array<Integer>>

Parse delta sets for all items

Returns:

  • (Array<Array<Integer>>)

    Delta sets for each item



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/fontisan/tables/variation_common.rb', line 145

def delta_sets
  return @delta_sets if @delta_sets
  return @delta_sets = [] if item_count.zero?

  data = raw_data
  # Delta data starts after header and region indices
  offset = 6 + (region_index_count * 2)

  # Each item has region_index_count deltas
  # short_delta_count are int16, rest are int8
  long_count = region_index_count - short_delta_count

  # Safety check: long_count should not be negative
  if long_count.negative?
    warn "ItemVariationData parsing error: short_delta_count (#{short_delta_count}) > region_index_count (#{region_index_count})"
    return @delta_sets = []
  end

  @delta_sets = Array.new(item_count) do |i|
    item_offset = offset + (i * (short_delta_count * 2 + long_count))

    # Read short deltas (int16)
    shorts = Array.new(short_delta_count) do |j|
      delta_offset = item_offset + (j * 2)
      next nil if delta_offset + 2 > data.bytesize

      # Signed 16-bit
      value = data.byteslice(delta_offset, 2).unpack1("n")
      value > 0x7FFF ? value - 0x10000 : value
    end.compact

    # Read long deltas (int8)
    longs = Array.new(long_count) do |j|
      delta_offset = item_offset + (short_delta_count * 2) + j
      next nil if delta_offset + 1 > data.bytesize

      # Signed 8-bit
      value = data.byteslice(delta_offset, 1).unpack1("C")
      value > 0x7F ? value - 0x100 : value
    end.compact

    shorts + longs
  end
end

#region_indicesArray<Integer>

Parse region indices

Returns:

  • (Array<Integer>)

    Region indices



127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/fontisan/tables/variation_common.rb', line 127

def region_indices
  return @region_indices if @region_indices
  return @region_indices = [] if region_index_count.zero?

  data = raw_data
  offset = 6 # After header fields

  @region_indices = Array.new(region_index_count) do |i|
    idx_offset = offset + (i * 2)
    next nil if idx_offset + 2 > data.bytesize

    data.byteslice(idx_offset, 2).unpack1("n")
  end.compact
end