Class: Idml::TextEngine::VerticalLayout

Inherits:
Object
  • Object
show all
Defined in:
lib/idml/text_engine/vertical_layout.rb

Overview

Positions lines vertically within a text frame. The layout is block-oriented: each call to layout_block returns the positioned lines for one block (paragraph, run, etc.) and the y cursor for the next block, so callers can stack paragraphs without re-deriving cursor math.

Constant Summary collapse

DEFAULT_LEADING_FACTOR =
1.2

Class Method Summary collapse

Class Method Details

.bottom_limit(frame) ⇒ Object

Bottom y of the frame's text area (frame bottom edge + bottom inset). Lines whose y falls below this are clipped.



53
54
55
# File 'lib/idml/text_engine/vertical_layout.rb', line 53

def self.bottom_limit(frame)
  frame.y + (frame.inset_bottom || 0)
end

.layout_block(lines:, frame:, font_size:, cursor_y:, leading: nil, space_before: 0, space_after: 0, first_line_indent: 0, left_indent: 0) ⇒ Object

Position lines starting at cursor_y and walking downward. cursor_y is the top of the available space; the first line sits one leading below it. Returns [positioned_lines, next_y] where next_y is where the next block should start (i.e. below this block's last line plus space_after).



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/idml/text_engine/vertical_layout.rb', line 33

def self.layout_block(lines:, frame:, font_size:, cursor_y:, leading: nil, space_before: 0, space_after: 0,
                      first_line_indent: 0, left_indent: 0)
  effective_leading = leading || (font_size * DEFAULT_LEADING_FACTOR)
  y = cursor_y - space_before
  positioned = []

  lines.each_with_index do |line, idx|
    y -= effective_leading
    x = frame_left(frame) + left_indent +
      (idx.zero? ? first_line_indent : 0) + line.x_offset.to_f
    positioned << PositionedLine.new(
      glyphs: line.glyphs, x: x, y: y, width: line.width,
    )
  end

  [positioned, y - space_after]
end

.wrap_width(frame, right_indent = 0) ⇒ Object

Effective wrap width after subtracting insets and indents.



58
59
60
61
# File 'lib/idml/text_engine/vertical_layout.rb', line 58

def self.wrap_width(frame, right_indent = 0)
  width = frame.width - (frame.inset_left || 0) - (frame.inset_right || 0)
  width - right_indent
end