Class: Fontisan::Variable::AxisNormalizer

Inherits:
Object
  • Object
show all
Defined in:
lib/fontisan/variable/axis_normalizer.rb

Overview

Normalizes user coordinates to design space

Converts user-provided axis coordinates (e.g., wght=700) to normalized values in the range -1.0 to 1.0 based on axis definitions from the fvar table.

The normalization algorithm follows the OpenType specification:

  • For values below default: normalized = (value - default) / (default - min)
  • For values above default: normalized = (value - default) / (max - default)
  • Values are clamped to the -1.0 to 1.0 range

Examples:

Normalize coordinates

normalizer = AxisNormalizer.new(fvar_table)
normalized = normalizer.normalize({ "wght" => 700, "wdth" => 100 })
# => { "wght" => 0.5, "wdth" => 0.0 }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fvar, config = {}) ⇒ AxisNormalizer

Initialize the normalizer

Parameters:

  • fvar (Fontisan::Tables::Fvar)

    Font variations table

  • config (Hash) (defaults to: {})

    Optional configuration overrides



32
33
34
35
36
# File 'lib/fontisan/variable/axis_normalizer.rb', line 32

def initialize(fvar, config = {})
  @fvar = fvar
  @config = load_config.merge(config)
  @axes = build_axis_map
end

Instance Attribute Details

#axesHash (readonly)

Returns Axis definitions from fvar table.

Returns:

  • (Hash)

    Axis definitions from fvar table



26
27
28
# File 'lib/fontisan/variable/axis_normalizer.rb', line 26

def axes
  @axes
end

#configHash (readonly)

Returns Configuration settings.

Returns:

  • (Hash)

    Configuration settings



23
24
25
# File 'lib/fontisan/variable/axis_normalizer.rb', line 23

def config
  @config
end

Instance Method Details

#axis_info(axis_tag) ⇒ Hash?

Get axis information

Parameters:

  • axis_tag (String)

    Axis tag

Returns:

  • (Hash, nil)

    Axis information or nil



87
88
89
# File 'lib/fontisan/variable/axis_normalizer.rb', line 87

def axis_info(axis_tag)
  @axes[axis_tag]
end

#axis_tagsArray<String>

Get all axis tags

Returns:

  • (Array<String>)

    Array of axis tags



94
95
96
# File 'lib/fontisan/variable/axis_normalizer.rb', line 94

def axis_tags
  @axes.keys
end

#normalize(user_coords) ⇒ Hash<String, Float>

Normalize user coordinates to design space

Parameters:

  • user_coords (Hash<String, Numeric>)

    User coordinates by axis tag

Returns:

  • (Hash<String, Float>)

    Normalized coordinates (-1.0 to 1.0)



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/fontisan/variable/axis_normalizer.rb', line 42

def normalize(user_coords)
  result = {}

  @axes.each do |tag, axis_info|
    user_value = user_coords[tag] || user_coords[tag.to_sym]

    # Use default if not provided and config allows
    if user_value.nil?
      user_value = if @config.dig(:coordinate_normalization,
                                  :use_axis_defaults)
                     axis_info[:default]
                   else
                     next
                   end
    end

    # Validate and clamp if configured
    validated_value = validate_coordinate(user_value, axis_info)

    # Normalize the value
    normalized = normalize_value(validated_value, axis_info)

    result[tag] = normalized
  end

  result
end

#normalize_axis(value, axis_tag) ⇒ Float

Normalize a single axis value

Parameters:

  • value (Numeric)

    User coordinate value

  • axis_tag (String)

    Axis tag

Returns:

  • (Float)

    Normalized value (-1.0 to 1.0)

Raises:

  • (ArgumentError)


75
76
77
78
79
80
81
# File 'lib/fontisan/variable/axis_normalizer.rb', line 75

def normalize_axis(value, axis_tag)
  axis_info = @axes[axis_tag]
  raise ArgumentError, "Unknown axis: #{axis_tag}" unless axis_info

  validated_value = validate_coordinate(value, axis_info)
  normalize_value(validated_value, axis_info)
end