Class: Idml::Render::PositionTracker
- Inherits:
-
Object
- Object
- Idml::Render::PositionTracker
- Defined in:
- lib/idml/render/position_tracker.rb
Overview
Accumulates positioned text ranges during TextFrame rendering.
Used by HyperlinkEmitter to compute precise per-source link
rects when text contains IDML hyperlinks.
Lifecycle:
1. Pipeline constructs one tracker per render.
2. RenderContext carries it to renderers.
3. TextFrameRenderer records each line's range after layout.
4. HyperlinkEmitter queries for ranges overlapping each
hyperlink source's character range.
PositionedRange is a plain Struct so the data is trivially
shareable without coupling to any renderer implementation.
Defined Under Namespace
Classes: PositionedRange
Instance Method Summary collapse
-
#add(frame_self, start_char:, end_char:, x:, y:, width:, height:) ⇒ Object
Records a positioned range for a frame.
-
#clear ⇒ Object
Test helper: clears all recorded ranges.
-
#initialize ⇒ PositionTracker
constructor
A new instance of PositionTracker.
-
#ranges_for(frame_self) ⇒ Object
Returns the list of positioned ranges for a frame, or [].
-
#rect_for_range(frame_self, from:, to:) ⇒ Object
Returns the bounding rect
[x1, y1, x2, y2]covering all ranges whose[start_char, end_char]intersects[from, to].
Constructor Details
#initialize ⇒ PositionTracker
Returns a new instance of PositionTracker.
24 25 26 |
# File 'lib/idml/render/position_tracker.rb', line 24 def initialize @ranges_by_frame = {} end |
Instance Method Details
#add(frame_self, start_char:, end_char:, x:, y:, width:, height:) ⇒ Object
Records a positioned range for a frame. frame_self is the
Self attribute of the TextFrame so multiple frames on the
same spread don't collide.
31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/idml/render/position_tracker.rb', line 31 def add(frame_self, start_char:, end_char:, x:, y:, width:, height:) bucket = @ranges_by_frame[frame_self] ||= [] bucket << PositionedRange.new( start_char: start_char, end_char: end_char, x: x, y: y, width: width, height: height, ) end |
#clear ⇒ Object
Test helper: clears all recorded ranges.
63 64 65 |
# File 'lib/idml/render/position_tracker.rb', line 63 def clear @ranges_by_frame.clear end |
#ranges_for(frame_self) ⇒ Object
Returns the list of positioned ranges for a frame, or [].
44 45 46 |
# File 'lib/idml/render/position_tracker.rb', line 44 def ranges_for(frame_self) @ranges_by_frame[frame_self] || [] end |
#rect_for_range(frame_self, from:, to:) ⇒ Object
Returns the bounding rect [x1, y1, x2, y2] covering all
ranges whose [start_char, end_char] intersects
[from, to]. Returns nil when no range overlaps.
51 52 53 54 55 56 57 58 59 60 |
# File 'lib/idml/render/position_tracker.rb', line 51 def rect_for_range(frame_self, from:, to:) matching = ranges_for(frame_self).select do |range| range.start_char < to && range.end_char > from end return nil if matching.empty? xs = matching.flat_map { |r| [r.x, r.x + r.width] } ys = matching.flat_map { |r| [r.y, r.y + r.height] } [xs.min, ys.min, xs.max, ys.max] end |