Class: HexaPDF::Layout::TextBox
- Defined in:
- lib/hexapdf/layout/text_box.rb
Overview
A TextBox is used for drawing text, either inside a rectangular box or by flowing it around objects of a Frame.
This class uses TextLayouter behind the scenes to do the hard work.
Instance Attribute Summary
Attributes inherited from Box
#height, #properties, #style, #width
Instance Method Summary collapse
-
#empty? ⇒ Boolean
:nodoc:.
-
#fit(available_width, available_height, frame) ⇒ Object
Fits the text box into the Frame.
-
#initialize(items:, **kwargs) ⇒ TextBox
constructor
Creates a new TextBox object with the given inline items (e.g. TextFragment and InlineBox objects).
-
#split(available_width, available_height, frame) ⇒ Object
Splits the text box into two boxes if necessary and possible.
-
#supports_position_flow? ⇒ Boolean
Returns
true
as the ‘position’ style property value :flow is supported. -
#text ⇒ Object
Returns the text that will be drawn.
Methods inherited from Box
#content_height, #content_width, create, #draw, #split_box?
Constructor Details
#initialize(items:, **kwargs) ⇒ TextBox
Creates a new TextBox object with the given inline items (e.g. TextFragment and InlineBox objects).
50 51 52 53 54 55 |
# File 'lib/hexapdf/layout/text_box.rb', line 50 def initialize(items:, **kwargs) super(**kwargs) @tl = TextLayouter.new(style) @items = items @result = nil end |
Instance Method Details
#empty? ⇒ Boolean
:nodoc:
127 128 129 |
# File 'lib/hexapdf/layout/text_box.rb', line 127 def empty? super && (!@result || @result.lines.empty?) end |
#fit(available_width, available_height, frame) ⇒ Object
Fits the text box into the Frame.
Depending on the ‘position’ style property, the text is either fit into the current region of the frame using available_width
and available_height
, or fit to the shape of the frame starting from the top (when ‘position’ is set to :flow).
The spacing after the last line can be controlled via the style property last_line_gap
.
Also see TextLayouter#style for other style properties taken into account.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/hexapdf/layout/text_box.rb', line 78 def fit(available_width, available_height, frame) return false if (@initial_width > 0 && @initial_width > available_width) || (@initial_height > 0 && @initial_height > available_height) @width = @height = 0 @result = if style.position == :flow @tl.fit(@items, frame.width_specification, frame.shape.bbox.height, apply_first_text_indent: !split_box?, frame: frame) else @width = reserved_width @height = reserved_height width = (@initial_width > 0 ? @initial_width : available_width) - @width height = (@initial_height > 0 ? @initial_height : available_height) - @height @tl.fit(@items, width, height, apply_first_text_indent: !split_box?, frame: frame) end @width += if @initial_width > 0 || style.text_align == :center || style.text_align == :right width else @result.lines.max_by(&:width)&.width || 0 end @height += if @initial_height > 0 || style.text_valign == :center || style.text_valign == :bottom height else @result.height end if style.last_line_gap && @result.lines.last @height += style.line_spacing.gap(@result.lines.last, @result.lines.last) end @result.status == :success end |
#split(available_width, available_height, frame) ⇒ Object
Splits the text box into two boxes if necessary and possible.
111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/hexapdf/layout/text_box.rb', line 111 def split(available_width, available_height, frame) fit(available_width, available_height, frame) unless @result if style.position != :flow && (float_compare(@width, available_width) > 0 || float_compare(@height, available_height) > 0) [nil, self] elsif @result.remaining_items.empty? [self] elsif @result.lines.empty? [nil, self] else [self, create_box_for_remaining_items] end end |
#supports_position_flow? ⇒ Boolean
Returns true
as the ‘position’ style property value :flow is supported.
65 66 67 |
# File 'lib/hexapdf/layout/text_box.rb', line 65 def supports_position_flow? true end |
#text ⇒ Object
Returns the text that will be drawn.
This will ignore any inline boxes or kerning values.
60 61 62 |
# File 'lib/hexapdf/layout/text_box.rb', line 60 def text @items.map {|item| item.kind_of?(TextFragment) ? item.text : '' }.join end |