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
46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 46 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.
31 32 33 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 31 def axis_normalizer @axis_normalizer end |
#config ⇒ Hash (readonly)
Returns Configuration settings.
28 29 30 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 28 def config @config end |
#glyph_delta_processor ⇒ GlyphDeltaProcessor (readonly)
Returns Glyph delta processor.
37 38 39 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 37 def glyph_delta_processor @glyph_delta_processor end |
#metric_delta_processor ⇒ MetricDeltaProcessor (readonly)
Returns Metric delta processor.
40 41 42 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 40 def metric_delta_processor @metric_delta_processor end |
#region_matcher ⇒ RegionMatcher (readonly)
Returns Region matcher.
34 35 36 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 34 def region_matcher @region_matcher end |
Instance Method Details
#advance_width_delta(glyph_id, user_coords) ⇒ Integer
Get advance width delta for a glyph
154 155 156 157 158 159 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 154 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
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 92 93 94 95 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 65 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
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 102 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
134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 134 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.each_with_object({}) do |glyph_id, results| results[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
171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 171 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
189 190 191 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 189 def @axis_normalizer. end |
#region_count ⇒ Integer
Get number of variation regions
196 197 198 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 196 def region_count @region_matcher.region_count end |
#variable_font? ⇒ Boolean
Check if font is a variable font
164 165 166 |
# File 'lib/fontisan/variable/delta_applicator.rb', line 164 def variable_font? !@fvar.nil? end |