Class: Fontisan::Svg::ViewBoxCalculator
- Inherits:
-
Object
- Object
- Fontisan::Svg::ViewBoxCalculator
- Defined in:
- lib/fontisan/svg/view_box_calculator.rb
Overview
Calculates SVG viewBox and handles coordinate transformations
ViewBoxCalculator manages
the coordinate system transformation between font space and SVG space.
Font coordinates use a Y-up system (ascender is positive), while SVG
uses Y-down (origin at top-left).
Responsibilities:
- Calculate appropriate viewBox for glyphs
- Transform Y-coordinates (flip Y-axis)
- Scale coordinates based on units-per-em
- Provide consistent coordinate mapping
This is a pure utility class with no state or side effects.
Instance Attribute Summary collapse
-
#ascent ⇒ Integer
readonly
Font ascent.
-
#descent ⇒ Integer
readonly
Font descent (typically negative).
-
#units_per_em ⇒ Integer
readonly
Units per em from font.
Instance Method Summary collapse
-
#calculate_viewbox(x_min:, y_min:, x_max:, y_max:) ⇒ String
Calculate viewBox string for SVG.
-
#font_viewbox ⇒ String
Calculate font-level viewBox.
-
#initialize(units_per_em:, ascent:, descent:) ⇒ ViewBoxCalculator
constructor
Initialize calculator with font metrics.
-
#scale_factor(target_units: 1000) ⇒ Float
Get scale factor for coordinate precision.
-
#transform_point(font_x, font_y) ⇒ Array<Numeric>
Transform point from font space to SVG space.
-
#transform_y(font_y) ⇒ Numeric
Transform Y coordinate from font space to SVG space.
Constructor Details
#initialize(units_per_em:, ascent:, descent:) ⇒ ViewBoxCalculator
Initialize calculator with font metrics
43 44 45 46 47 48 49 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 43 def initialize(units_per_em:, ascent:, descent:) validate_parameters!(units_per_em, ascent, descent) @units_per_em = units_per_em @ascent = ascent @descent = descent end |
Instance Attribute Details
#ascent ⇒ Integer (readonly)
Returns Font ascent.
32 33 34 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 32 def ascent @ascent end |
#descent ⇒ Integer (readonly)
Returns Font descent (typically negative).
35 36 37 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 35 def descent @descent end |
#units_per_em ⇒ Integer (readonly)
Returns Units per em from font.
29 30 31 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 29 def units_per_em @units_per_em end |
Instance Method Details
#calculate_viewbox(x_min:, y_min:, x_max:, y_max:) ⇒ String
Calculate viewBox string for SVG
80 81 82 83 84 85 86 87 88 89 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 80 def calculate_viewbox(x_min:, y_min:, x_max:, y_max:) # Transform bounding box to SVG space svg_y_min = transform_y(y_max) # Y is flipped svg_y_max = transform_y(y_min) width = x_max - x_min height = svg_y_max - svg_y_min "#{x_min} #{svg_y_min} #{width} #{height}" end |
#font_viewbox ⇒ String
Calculate font-level viewBox
Uses font metrics to create a viewBox covering the entire font space
96 97 98 99 100 101 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 96 def font_viewbox # Typical font viewBox covers descent to ascent # Width is units_per_em height = ascent - descent "0 0 #{units_per_em} #{height}" end |
#scale_factor(target_units: 1000) ⇒ Float
Get scale factor for coordinate precision
107 108 109 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 107 def scale_factor(target_units: 1000) target_units.to_f / units_per_em end |
#transform_point(font_x, font_y) ⇒ Array<Numeric>
Transform point from font space to SVG space
69 70 71 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 69 def transform_point(font_x, font_y) [font_x, transform_y(font_y)] end |
#transform_y(font_y) ⇒ Numeric
Transform Y coordinate from font space to SVG space
Font space: Y-up (ascender positive, descender negative) SVG space: Y-down (origin at top)
Transformation: svg_y = ascent - font_y
60 61 62 |
# File 'lib/fontisan/svg/view_box_calculator.rb', line 60 def transform_y(font_y) ascent - font_y end |