Class: Arrolio::Flowables::TextFlowable
- Inherits:
-
Arrolio::Flowable
- Object
- Arrolio::Flowable
- Arrolio::Flowables::TextFlowable
- Defined in:
- lib/arrolio/flowables/text_flowable.rb
Overview
A paragraph of flowing text. Selects a line-breaking strategy
based on the style's line_break attribute (:greedy or
:knuth_plass). Both strategies produce TextLayout::Line
with the same shape, so the rest of the pipeline is agnostic.
Direct Known Subclasses
Constant Summary collapse
- MATH_OPERATOR =
Inline math with relational operators lays out stacked in the reference (JEuclid gives the formula box roughly two text lines of vertical extent); simple sub/superscripts stay compact. The operators only ever come from math content.
/[\u2264\u2265\u00d7\u00f7\u00b1\u2212\u2260]|\+\d/- MATH_LINE_FACTOR =
1.9
Instance Attribute Summary collapse
-
#hanging_indent ⇒ Object
readonly
Returns the value of attribute hanging_indent.
-
#measurer ⇒ Object
readonly
Returns the value of attribute measurer.
-
#runs ⇒ Object
readonly
Returns the value of attribute runs.
Attributes inherited from Arrolio::Flowable
Instance Method Summary collapse
- #do_split(width, remaining_height, _context = nil) ⇒ Object
- #emit(x, y, width, _context = nil) ⇒ Object
- #height(width, _context = nil) ⇒ Object
-
#initialize(runs, style: Style::Definition.new, measurer: nil, hanging_indent: 0.0) ⇒ TextFlowable
constructor
A new instance of TextFlowable.
-
#min_keep_height(_width, _context = nil) ⇒ Object
Widows for keep-with-next predecessors: how many lines must follow when the paragraph starts after a kept block.
- #splittable? ⇒ Boolean
- #widows_count ⇒ Object
Methods inherited from Arrolio::Flowable
#keep_together?, #keep_with_next?, #page_break_after?, #page_break_before?, #space_after, #space_before, #split
Constructor Details
#initialize(runs, style: Style::Definition.new, measurer: nil, hanging_indent: 0.0) ⇒ TextFlowable
Returns a new instance of TextFlowable.
12 13 14 15 16 17 18 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 12 def initialize(runs, style: Style::Definition.new, measurer: nil, hanging_indent: 0.0) super(style: style) @runs = Array(runs) @measurer = measurer || GlyphMeasurer.new(font_name: style.font_name) @hanging_indent = hanging_indent.to_f end |
Instance Attribute Details
#hanging_indent ⇒ Object (readonly)
Returns the value of attribute hanging_indent.
10 11 12 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 10 def hanging_indent @hanging_indent end |
#measurer ⇒ Object (readonly)
Returns the value of attribute measurer.
10 11 12 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 10 def measurer @measurer end |
#runs ⇒ Object (readonly)
Returns the value of attribute runs.
10 11 12 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 10 def runs @runs end |
Instance Method Details
#do_split(width, remaining_height, _context = nil) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 71 def do_split(width, remaining_height, _context = nil) lines = laid_out(width) line_h = line_height available = remaining_height - space_before head_count = (available.to_f / line_h).floor head_count = [head_count, lines.length].min head_count = 1 if head_count < 1 && lines.any? head_lines = lines[0...head_count] tail_lines = lines[head_count..] || [] head_runs = collect_runs(head_lines) tail_runs = collect_runs(tail_lines) head = head_runs.empty? ? nil : self.class.new(head_runs, style: @style, measurer: @measurer) tail = tail_runs.empty? ? nil : self.class.new(tail_runs, style: @style, measurer: @measurer) [head, tail] end |
#emit(x, y, width, _context = nil) ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 35 def emit(x, y, width, _context = nil) effective_width = width - @hanging_indent lines = laid_out(effective_width) text_height = (lines.length * line_height) + (math_line_count(lines) * line_height * (MATH_LINE_FACTOR - 1.0)) total = text_height + space_before + space_after return [[], total] if lines.empty? text_y = y - space_before heights = lines.map do |line| math = line.placed_runs.any? { |pr| pr.run.text.match?(MATH_OPERATOR) } line_height * (math ? MATH_LINE_FACTOR : 1.0) end box = Output::PlacedBox.text( x: x, y: text_y - text_height, width: width, height: text_height, lines: lines, line_height: line_height, style: @style, hanging_indent: @hanging_indent, line_heights: heights ) [[box], total] end |
#height(width, _context = nil) ⇒ Object
27 28 29 30 31 32 33 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 27 def height(width, _context = nil) effective_width = width - @hanging_indent laid = laid_out(effective_width) text_height = (laid.length * line_height) + (math_line_count(laid) * line_height * (MATH_LINE_FACTOR - 1.0)) text_height + space_before + space_after end |
#min_keep_height(_width, _context = nil) ⇒ Object
Widows for keep-with-next predecessors: how many lines must follow when the paragraph starts after a kept block.
63 64 65 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 63 def min_keep_height(_width, _context = nil) space_before + ([widows_count, 1].max * line_height) end |
#splittable? ⇒ Boolean
57 58 59 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 57 def splittable? true end |
#widows_count ⇒ Object
67 68 69 |
# File 'lib/arrolio/flowables/text_flowable.rb', line 67 def widows_count @style.widows ? @style.widows.to_i : 1 end |