Class: Fontisan::Tables::Mvar
- Inherits:
-
Binary::BaseRecord
- Object
- BinData::Record
- Binary::BaseRecord
- Fontisan::Tables::Mvar
- Defined in:
- lib/fontisan/tables/mvar.rb
Overview
Parser for the ‘MVAR’ (Metrics Variations) table
The MVAR table provides variation data for global font metrics such as:
-
Ascender and descender
-
Line gap
-
Caret offsets
-
Strikeout and underline positions/sizes
-
Subscript and superscript sizes
Each metric is identified by a tag and references delta sets in the ItemVariationStore.
Reference: OpenType specification, MVAR table
Defined Under Namespace
Classes: ValueRecord
Constant Summary collapse
- METRIC_TAGS =
Value tags for standard metrics
{ "hasc" => :horizontal_ascender, "hdsc" => :horizontal_descender, "hlgp" => :horizontal_line_gap, "hcla" => :horizontal_caret_ascender, "hcld" => :horizontal_caret_descender, "hcof" => :horizontal_caret_offset, "vasc" => :vertical_ascender, "vdsc" => :vertical_descender, "vlgp" => :vertical_line_gap, "vcof" => :vertical_caret_offset, "xhgt" => :x_height, "cpht" => :cap_height, "sbxs" => :subscript_em_x_size, "sbys" => :subscript_em_y_size, "sbxo" => :subscript_em_x_offset, "sbyo" => :subscript_em_y_offset, "spxs" => :superscript_em_x_size, "spys" => :superscript_em_y_size, "spxo" => :superscript_em_x_offset, "spyo" => :superscript_em_y_offset, "strs" => :strikeout_size, "stro" => :strikeout_offset, "unds" => :underline_size, "undo" => :underline_offset, }.freeze
Instance Method Summary collapse
-
#has_metric?(tag) ⇒ Boolean
Check if a specific metric is present.
-
#item_variation_store ⇒ VariationCommon::ItemVariationStore?
Parse the item variation store.
-
#metric_delta_set(tag) ⇒ Array<Integer>?
Get delta set for a specific metric tag.
-
#metric_tags ⇒ Array<String>
Get all metric tags present in this table.
-
#metrics ⇒ Hash<String, Hash>
Get all metrics as a hash.
-
#valid? ⇒ Boolean
Check if table is valid.
-
#value_record(tag) ⇒ ValueRecord?
Get value record by tag.
-
#value_records ⇒ Array<ValueRecord>
Parse value records.
-
#version ⇒ Float
Get version as a float.
Methods inherited from Binary::BaseRecord
Instance Method Details
#has_metric?(tag) ⇒ Boolean
Check if a specific metric is present
173 174 175 |
# File 'lib/fontisan/tables/mvar.rb', line 173 def has_metric?(tag) !value_record(tag).nil? end |
#item_variation_store ⇒ VariationCommon::ItemVariationStore?
Parse the item variation store
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/fontisan/tables/mvar.rb', line 86 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 MVAR item variation store: #{e.}" @item_variation_store = nil end |
#metric_delta_set(tag) ⇒ Array<Integer>?
Get delta set for a specific metric tag
135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/fontisan/tables/mvar.rb', line 135 def metric_delta_set(tag) return nil unless item_variation_store record = value_record(tag) return nil if record.nil? item_variation_store.delta_set( record.delta_set_outer_index, record.delta_set_inner_index, ) end |
#metric_tags ⇒ Array<String>
Get all metric tags present in this table
150 151 152 |
# File 'lib/fontisan/tables/mvar.rb', line 150 def value_records.map { |record| record.value_tag.to_s } end |
#metrics ⇒ Hash<String, Hash>
Get all metrics as a hash
157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/fontisan/tables/mvar.rb', line 157 def metrics value_records.each_with_object({}) do |record, hash| # Strip trailing nulls from value_tag tag = record.value_tag.delete("\x00") hash[tag] = { name: record.metric_name, outer_index: record.delta_set_outer_index, inner_index: record.delta_set_inner_index, } end end |
#valid? ⇒ Boolean
Check if table is valid
180 181 182 |
# File 'lib/fontisan/tables/mvar.rb', line 180 def valid? major_version == 1 && minor_version.zero? end |
#value_record(tag) ⇒ ValueRecord?
Get value record by tag
127 128 129 |
# File 'lib/fontisan/tables/mvar.rb', line 127 def value_record(tag) value_records.find { |record| record.value_tag.to_s == tag } end |
#value_records ⇒ Array<ValueRecord>
Parse value records
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/fontisan/tables/mvar.rb', line 105 def value_records return @value_records if @value_records return @value_records = [] if value_record_count.zero? data = raw_data # Value records start after the header (14 bytes: 2+2+2+2+2+4) offset = 14 @value_records = Array.new(value_record_count) do |i| record_offset = offset + (i * value_record_size) next nil if record_offset + value_record_size > data.bytesize record_data = data.byteslice(record_offset, value_record_size) ValueRecord.read(record_data) end.compact end |
#version ⇒ Float
Get version as a float
79 80 81 |
# File 'lib/fontisan/tables/mvar.rb', line 79 def version major_version + (minor_version / 10.0) end |