Class: Fontisan::Tables::Hvar

Inherits:
Binary::BaseRecord show all
Extended by:
Registered
Defined in:
lib/fontisan/tables/hvar.rb

Overview

Parser for the 'HVAR' (Horizontal Metrics Variations) table

The HVAR table provides variation data for horizontal metrics including:

  • Advance width variations
  • Left side bearing (LSB) variations

This table uses the ItemVariationStore structure to efficiently store delta values for different regions in the design space.

Reference: OpenType specification, HVAR table

Examples:

Reading an HVAR table

data = font.table_data("HVAR")
hvar = Fontisan::Tables::Hvar.read(data)
advance_deltas = hvar.advance_width_deltas(glyph_id, coordinates)

Instance Attribute Summary

Attributes inherited from Binary::BaseRecord

#raw_data

Instance Method Summary collapse

Methods included from Registered

register_tag

Methods inherited from Binary::BaseRecord

read

Instance Method Details

#advance_width_delta_set(glyph_id) ⇒ Array<Integer>?

Get advance width delta set for a glyph

Parameters:

  • glyph_id (Integer)

    Glyph ID

Returns:

  • (Array<Integer>, nil)

    Delta values or nil



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/fontisan/tables/hvar.rb', line 119

def advance_width_delta_set(glyph_id)
  return nil unless item_variation_store

  # If no mapping, use glyph_id directly
  if advance_width_mapping.nil?
    return item_variation_store.delta_set(0, glyph_id)
  end

  # Use mapping to get delta set indices
  map_data = advance_width_mapping.map_data
  return nil if glyph_id >= map_data.length

  delta_index = map_data[glyph_id]
  outer_index = (delta_index >> 16) & 0xFFFF
  inner_index = delta_index & 0xFFFF

  item_variation_store.delta_set(outer_index, inner_index)
end

#advance_width_mappingVariationCommon::DeltaSetIndexMap?

Parse advance width mapping

Returns:



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/fontisan/tables/hvar.rb', line 61

def advance_width_mapping
  return @advance_width_mapping if defined?(@advance_width_mapping)
  return @advance_width_mapping = nil if advance_width_mapping_offset.zero?

  data = raw_data
  offset = advance_width_mapping_offset

  return @advance_width_mapping = nil if offset >= data.bytesize

  map_data = data.byteslice(offset..-1)
  @advance_width_mapping = VariationCommon::DeltaSetIndexMap.read(map_data)
rescue StandardError => e
  warn "Failed to parse HVAR advance width mapping: #{e.message}"
  @advance_width_mapping = nil
end

#item_variation_storeVariationCommon::ItemVariationStore?

Parse the item variation store

Returns:



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/fontisan/tables/hvar.rb', line 42

def item_variation_store
  return @item_variation_store if defined?(@item_variation_store)
  return @item_variation_store = nil if item_variation_store_offset.zero?

  data = raw_data
  offset = item_variation_store_offset

  return @item_variation_store = nil if offset >= data.bytesize

  store_data = data.byteslice(offset..-1)
  @item_variation_store = VariationCommon::ItemVariationStore.read(store_data)
rescue StandardError => e
  warn "Failed to parse HVAR item variation store: #{e.message}"
  @item_variation_store = nil
end

#lsb_delta_set(glyph_id) ⇒ Array<Integer>?

Get LSB delta set for a glyph

Parameters:

  • glyph_id (Integer)

    Glyph ID

Returns:

  • (Array<Integer>, nil)

    Delta values or nil



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/fontisan/tables/hvar.rb', line 142

def lsb_delta_set(glyph_id)
  return nil unless item_variation_store

  # If no mapping, use glyph_id directly
  if lsb_mapping.nil?
    return item_variation_store.delta_set(0, glyph_id)
  end

  # Use mapping to get delta set indices
  map_data = lsb_mapping.map_data
  return nil if glyph_id >= map_data.length

  delta_index = map_data[glyph_id]
  outer_index = (delta_index >> 16) & 0xFFFF
  inner_index = delta_index & 0xFFFF

  item_variation_store.delta_set(outer_index, inner_index)
end

#lsb_mappingVariationCommon::DeltaSetIndexMap?

Parse LSB (left side bearing) mapping

Returns:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/fontisan/tables/hvar.rb', line 80

def lsb_mapping
  return @lsb_mapping if defined?(@lsb_mapping)
  return @lsb_mapping = nil if lsb_mapping_offset.zero?

  data = raw_data
  offset = lsb_mapping_offset

  return @lsb_mapping = nil if offset >= data.bytesize

  map_data = data.byteslice(offset..-1)
  @lsb_mapping = VariationCommon::DeltaSetIndexMap.read(map_data)
rescue StandardError => e
  warn "Failed to parse HVAR LSB mapping: #{e.message}"
  @lsb_mapping = nil
end

#rsb_delta_set(glyph_id) ⇒ Array<Integer>?

Get RSB delta set for a glyph

Parameters:

  • glyph_id (Integer)

    Glyph ID

Returns:

  • (Array<Integer>, nil)

    Delta values or nil



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/fontisan/tables/hvar.rb', line 165

def rsb_delta_set(glyph_id)
  return nil unless item_variation_store

  # If no mapping, use glyph_id directly
  if rsb_mapping.nil?
    return item_variation_store.delta_set(0, glyph_id)
  end

  # Use mapping to get delta set indices
  map_data = rsb_mapping.map_data
  return nil if glyph_id >= map_data.length

  delta_index = map_data[glyph_id]
  outer_index = (delta_index >> 16) & 0xFFFF
  inner_index = delta_index & 0xFFFF

  item_variation_store.delta_set(outer_index, inner_index)
end

#rsb_mappingVariationCommon::DeltaSetIndexMap?

Parse RSB (right side bearing) mapping

Returns:



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/fontisan/tables/hvar.rb', line 99

def rsb_mapping
  return @rsb_mapping if defined?(@rsb_mapping)
  return @rsb_mapping = nil if rsb_mapping_offset.zero?

  data = raw_data
  offset = rsb_mapping_offset

  return @rsb_mapping = nil if offset >= data.bytesize

  map_data = data.byteslice(offset..-1)
  @rsb_mapping = VariationCommon::DeltaSetIndexMap.read(map_data)
rescue StandardError => e
  warn "Failed to parse HVAR RSB mapping: #{e.message}"
  @rsb_mapping = nil
end

#valid?Boolean

Check if table is valid

Returns:

  • (Boolean)

    True if valid



187
188
189
# File 'lib/fontisan/tables/hvar.rb', line 187

def valid?
  major_version == 1 && minor_version.zero?
end

#versionFloat

Get version as a float

Returns:

  • (Float)

    Version number (e.g., 1.0)



35
36
37
# File 'lib/fontisan/tables/hvar.rb', line 35

def version
  major_version + (minor_version / 10.0)
end