Class: Fontisan::Tables::Fvar

Inherits:
Binary::BaseRecord show all
Defined in:
lib/fontisan/tables/fvar.rb

Overview

Parser for the ‘fvar’ (Font Variations) table

The fvar table contains information about variation axes and named instances for variable fonts. This table is present only in variable fonts (OpenType Font Variations).

Reference: OpenType specification, fvar table

Examples:

Reading an fvar table

data = font.table_data("fvar")
fvar = Fontisan::Tables::Fvar.read(data)
fvar.axes.each do |axis|
  puts "#{axis.axis_tag}: #{axis.min_value} - #{axis.max_value}"
end

Instance Method Summary collapse

Methods inherited from Binary::BaseRecord

#raw_data, read, #valid?

Instance Method Details

#axesArray<VariationAxisRecord>

Parse variation axes from the table data

Returns:



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/fontisan/tables/fvar.rb', line 87

def axes
  return @axes if @axes
  return @axes = [] if axis_count.zero?

  # Get the full data buffer as binary string
  data = raw_data

  @axes = Array.new(axis_count) do |i|
    offset = axes_array_offset + (i * axis_size)
    axis_data = data.byteslice(offset, axis_size)
    VariationAxisRecord.read(axis_data)
  end
end

#instancesArray<Hash>

Parse instance records from the table data

Returns:

  • (Array<Hash>)

    Array of instance information hashes



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'lib/fontisan/tables/fvar.rb', line 104

def instances
  return @instances if @instances
  return @instances = [] if instance_count.zero?

  # Get the full data buffer as binary string
  data = raw_data

  # Calculate instance data offset (after all axes)
  instance_offset = axes_array_offset + (axis_count * axis_size)

  @instances = Array.new(instance_count) do |i|
    offset = instance_offset + (i * instance_size)

    # Check bounds
    next nil if offset + instance_size > data.bytesize

    instance_data = data.byteslice(offset, instance_size)
    next nil if instance_data.nil? || instance_data.empty?

    # Parse instance data manually
    io = StringIO.new(instance_data)
    io.set_encoding(Encoding::BINARY)

    # Read subfamily name ID and flags
    subfamily_name_id = io.read(2).unpack1("n")
    flags = io.read(2).unpack1("n")

    # Read coordinates for each axis (as int32 fixed-point values)
    coordinates = Array.new(axis_count) do
      fixed_to_float(io.read(4).unpack1("N"))
    end

    # Read optional postScriptNameID if present
    postscript_name_id = nil
    postscript_name_id = io.read(2).unpack1("n") if instance_size >= (4 + (axis_count * 4) + 2)

    {
      name_id: subfamily_name_id,
      flags: flags,
      coordinates: coordinates,
      postscript_name_id: postscript_name_id,
    }
  end.compact
end

#versionFloat

Get version as a float

Returns:

  • (Float)

    Version number (e.g., 1.0)



152
153
154
# File 'lib/fontisan/tables/fvar.rb', line 152

def version
  major_version + (minor_version / 10.0)
end