Class: Fontisan::Variable::DeltaApplicator
- Inherits:
-
Object
- Object
- Fontisan::Variable::DeltaApplicator
- Defined in:
- lib/fontisan/variable/delta_applicator.rb
Overview
Main orchestrator for delta application in variable fonts
Coordinates the entire delta application pipeline:
- Normalizes user coordinates to design space
- Calculates region scalars based on normalized coordinates
- Applies glyph outline deltas via GlyphDeltaProcessor
- Applies metric deltas via MetricDeltaProcessor
This is the primary interface for applying variation deltas to fonts.
Instance Attribute Summary collapse
-
#axis_normalizer ⇒ AxisNormalizer
readonly
Axis normalizer.
-
#config ⇒ Hash
readonly
Configuration settings.
-
#glyph_delta_processor ⇒ GlyphDeltaProcessor
readonly
Glyph delta processor.
-
#metric_delta_processor ⇒ MetricDeltaProcessor
readonly
Metric delta processor.
-
#region_matcher ⇒ RegionMatcher
readonly
Region matcher.
Instance Method Summary collapse
-
#advance_width_delta(glyph_id, user_coords) ⇒ Integer
Get advance width delta for a glyph.
-
#apply(user_coords) ⇒ Hash
Apply deltas at specified user coordinates.
-
#apply_glyph(glyph_id, user_coords) ⇒ Hash
Apply deltas to a specific glyph.
-
#apply_glyphs(glyph_ids, user_coords) ⇒ Hash<Integer, Hash>
Apply deltas to multiple glyphs.
-
#axes ⇒ Hash
Get axis information.
-
#axis_tags ⇒ Array<String>
Get available axis tags.
-
#initialize(font, config = {}) ⇒ DeltaApplicator
constructor
Initialize the delta applicator.
-
#region_count ⇒ Integer
Get number of variation regions.
-
#variable_font? ⇒ Boolean
Check if font is a variable font.
Constructor Details
#initialize(font, config = {}) ⇒ DeltaApplicator
Initialize the delta applicator
42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 42 def initialize(font, config = {}) @font = font @config = load_config.merge(config) # Load variation tables @fvar = load_table("fvar") @gvar = load_table("gvar") @hvar = load_table("HVAR") @vvar = load_table("VVAR") @mvar = load_table("MVAR") # Initialize components initialize_components end |
Instance Attribute Details
#axis_normalizer ⇒ AxisNormalizer (readonly)
Returns Axis normalizer.
27 28 29 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 27 def axis_normalizer @axis_normalizer end |
#config ⇒ Hash (readonly)
Returns Configuration settings.
24 25 26 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 24 def config @config end |
#glyph_delta_processor ⇒ GlyphDeltaProcessor (readonly)
Returns Glyph delta processor.
33 34 35 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 33 def glyph_delta_processor @glyph_delta_processor end |
#metric_delta_processor ⇒ MetricDeltaProcessor (readonly)
Returns Metric delta processor.
36 37 38 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 36 def metric_delta_processor @metric_delta_processor end |
#region_matcher ⇒ RegionMatcher (readonly)
Returns Region matcher.
30 31 32 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 30 def region_matcher @region_matcher end |
Instance Method Details
#advance_width_delta(glyph_id, user_coords) ⇒ Integer
Get advance width delta for a glyph
150 151 152 153 154 155 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 150 def advance_width_delta(glyph_id, user_coords) normalized_coords = @axis_normalizer.normalize(user_coords) region_scalars = @region_matcher.match(normalized_coords) @metric_delta_processor.advance_width_delta(glyph_id, region_scalars) end |
#apply(user_coords) ⇒ Hash
Apply deltas at specified user coordinates
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 61 def apply(user_coords) # Validate we have required tables unless @fvar raise ArgumentError, "Font does not have fvar table (not a variable font)" end # Step 1: Normalize coordinates normalized_coords = @axis_normalizer.normalize(user_coords) # Step 2: Calculate region scalars region_scalars = @region_matcher.match(normalized_coords) # Step 3: Prepare result structure result = { user_coords: user_coords, normalized_coords: normalized_coords, region_scalars: region_scalars, glyph_deltas: {}, metric_deltas: {}, font_metrics: {}, } # Step 4: Apply font-level metrics if MVAR present if @metric_delta_processor.has_mvar? result[:font_metrics] = @metric_delta_processor.apply_font_metrics(region_scalars) end result end |
#apply_glyph(glyph_id, user_coords) ⇒ Hash
Apply deltas to a specific glyph
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 98 def apply_glyph(glyph_id, user_coords) # Normalize and get region scalars normalized_coords = @axis_normalizer.normalize(user_coords) region_scalars = @region_matcher.match(normalized_coords) result = { glyph_id: glyph_id, normalized_coords: normalized_coords, } # Apply glyph outline deltas if gvar present if @glyph_delta_processor result[:outline_deltas] = @glyph_delta_processor.apply_deltas( glyph_id, region_scalars, ) end # Apply metric deltas result[:metric_deltas] = @metric_delta_processor.apply_deltas( glyph_id, region_scalars, ) result end |
#apply_glyphs(glyph_ids, user_coords) ⇒ Hash<Integer, Hash>
Apply deltas to multiple glyphs
130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 130 def apply_glyphs(glyph_ids, user_coords) # Normalize once for all glyphs normalized_coords = @axis_normalizer.normalize(user_coords) region_scalars = @region_matcher.match(normalized_coords) glyph_ids.to_h do |glyph_id| [glyph_id, { outline_deltas: @glyph_delta_processor&.apply_deltas(glyph_id, region_scalars), metric_deltas: @metric_delta_processor.apply_deltas(glyph_id, region_scalars), }] end end |
#axes ⇒ Hash
Get axis information
167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 167 def axes return {} unless @fvar @fvar.axes.each_with_object({}) do |axis, hash| # Convert BinData::String to regular Ruby String tag = axis.axis_tag.to_s hash[tag] = { min: axis.min_value, default: axis.default_value, max: axis.max_value, name_id: axis.axis_name_id, } end end |
#axis_tags ⇒ Array<String>
Get available axis tags
185 186 187 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 185 def @axis_normalizer. end |
#region_count ⇒ Integer
Get number of variation regions
192 193 194 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 192 def region_count @region_matcher.region_count end |
#variable_font? ⇒ Boolean
Check if font is a variable font
160 161 162 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 160 def variable_font? !@fvar.nil? end |