Module: Idml::Render::CharacterStyle
- Defined in:
- lib/idml/render/character_style.rb
Overview
Applies character-level styling from a StyleResolver::StyledRun
around a text-emitting block. Centralizes the IDML → PDF mapping
for run-level visual properties (text color, underline rule,
strike-through rule, capitalization, super/subscript position).
Used by TextFrameRenderer so character-level effects live in
one place (DRY). The block typically calls canvas.text (or
canvas.text_rich); this helper sets the surrounding graphics
state and emits the rule lines after the block returns.
Constant Summary collapse
- UNDERLINE_THICKNESS_FACTOR =
0.05
- UNDERLINE_DROP_FACTOR =
0.10
- STRIKE_THICKNESS_FACTOR =
0.05
- STRIKE_RISE_FACTOR =
0.25
Class Method Summary collapse
-
.apply(canvas, run, context, x:, y:, width:, size:) ⇒ Object
Yields with the run's fill color applied, then draws underline and/or strike-through rules above/below the text baseline.
-
.baseline_offset(run) ⇒ Object
Returns the run's baseline shift (in PDF units).
-
.position_scale(position, font_size) ⇒ Object
Returns
[font_size, baseline_offset]for the CSR's Position attribute. - .scaling_identity?(sx, sy) ⇒ Boolean
-
.text_kwargs(run, base_kwargs) ⇒ Object
Returns the canvas.text kwargs augmented with the run's Tracking (PDF char_spacing).
-
.transform_text(text, capitalization) ⇒ Object
Transforms the text per the CSR's Capitalization attribute.
-
.with_glyph_scaling(canvas, run) ⇒ Object
Yields within a transformed coordinate space when the run declares glyph scaling.
Class Method Details
.apply(canvas, run, context, x:, y:, width:, size:) ⇒ Object
Yields with the run's fill color applied, then draws underline
and/or strike-through rules above/below the text baseline.
x, y, width, size describe the line's geometry so the
rules can be positioned correctly. The block's emitted text
gets the run's character-level adjustments baked in via
text_kwargs (caller passes the canvas.text kwargs in, and
CharacterStyle adds tracking/scale on top).
27 28 29 30 31 32 |
# File 'lib/idml/render/character_style.rb', line 27 def self.apply(canvas, run, context, x:, y:, width:, size:) apply_fill_color(canvas, run, context) yield draw_underline(canvas, run, x, y, width, size) draw_strike_through(canvas, run, x, y, width, size) end |
.baseline_offset(run) ⇒ Object
Returns the run's baseline shift (in PDF units). Positive
values shift up; negative shift down. Used to offset the
text's at: y for CSR's BaselineShift.
66 67 68 |
# File 'lib/idml/render/character_style.rb', line 66 def self.baseline_offset(run) run.baseline_shift&.nonzero? ? run.baseline_shift.to_f : 0.0 end |
.position_scale(position, font_size) ⇒ Object
Returns [font_size, baseline_offset] for the CSR's Position
attribute. Superscript/subscript shrink the font and shift
the baseline. Normal / nil returns the size unchanged.
82 83 84 85 86 87 88 |
# File 'lib/idml/render/character_style.rb', line 82 def self.position_scale(position, font_size) case position when "Superscript" then [font_size * 0.583, font_size * 0.333] when "Subscript" then [font_size * 0.583, -font_size * 0.0833] else [font_size, 0.0] end end |
.scaling_identity?(sx, sy) ⇒ Boolean
56 57 58 |
# File 'lib/idml/render/character_style.rb', line 56 def self.scaling_identity?(sx, sy) (sx - 1.0).abs < FLOAT_EPSILON && (sy - 1.0).abs < FLOAT_EPSILON end |
.text_kwargs(run, base_kwargs) ⇒ Object
Returns the canvas.text kwargs augmented with the run's Tracking (PDF char_spacing). IDML Tracking is in points; pdfrb's char_spacing is also in text-space units, so the mapping is 1:1.
38 39 40 41 42 |
# File 'lib/idml/render/character_style.rb', line 38 def self.text_kwargs(run, base_kwargs) return base_kwargs unless run.tracking base_kwargs.merge(char_spacing: run.tracking.to_f) end |
.transform_text(text, capitalization) ⇒ Object
Transforms the text per the CSR's Capitalization attribute. AllCaps/SmallCaps → uppercase (true small-caps would require an OpenType feature; deferred). Other values pass through.
73 74 75 76 77 |
# File 'lib/idml/render/character_style.rb', line 73 def self.transform_text(text, capitalization) return text unless %w[AllCaps SmallCaps].include?(capitalization) text.upcase end |
.with_glyph_scaling(canvas, run) ⇒ Object
Yields within a transformed coordinate space when the run declares glyph scaling. IDML HorizontalScale/VerticalScale are percentages (100 = no scaling). When both are 100 / nil, yields without transformation (no graphics-state push).
48 49 50 51 52 53 54 |
# File 'lib/idml/render/character_style.rb', line 48 def self.with_glyph_scaling(canvas, run, &) sx = scale_factor(run.horizontal_scale) sy = scale_factor(run.vertical_scale) return yield if scaling_identity?(sx, sy) canvas.scale(sx, sy, &) end |