class Prawn::Text::Box
Generally, one would use the text_box convenience method. However, using Text::Box.new
in conjunction with render() enables one to do look-ahead calculations prior to placing text on the page, or to determine how much vertical space was consumed by the printed text
Constants
- VALID_OPTIONS
Attributes
The height of the ascender of the last line printed
The upper left corner of the text box
The height of the descender of the last line printed
The leading used during printing
The line height of the last line printed
The text that was successfully printed (or, if dry_run
was used, the test that would have been successfully printed)
Public Class Methods
Source
# File lib/prawn/text/box.rb, line 128 def initialize(string, options={}) @inked = false Prawn.verify_options(VALID_OPTIONS, options) options = options.dup @overflow = options[:overflow] || :truncate @original_string = string @text = nil @document = options[:document] @at = options[:at] || [@document.bounds.left, @document.bounds.top] @width = options[:width] || @document.bounds.right - @at[0] @height = options[:height] || @at[1] - @document.bounds.bottom @align = options[:align] || :left @vertical_align = options[:valign] || :top @leading = options[:leading] || 0 @rotate = options[:rotate] || 0 @rotate_around = options[:rotate_around] || :upper_left @single_line = options[:single_line] @skip_encoding = options[:skip_encoding] || @document.skip_encoding if @overflow == :expand # if set to expand, then we simply set the bottom # as the bottom of the document bounds, since that # is the maximum we should expand to @height = @at[1] - @document.bounds.bottom @overflow = :truncate end @min_font_size = options[:min_font_size] || 5 @line_wrap = options [:line_wrap] || @document.default_line_wrap @options = @document.text_options.merge(:kerning => options[:kerning], :size => options[:size], :style => options[:style]) end
See Prawn::Text#text_box
for valid options
Public Instance Methods
Source
# File lib/prawn/text/box.rb, line 203 def height return 0 if @baseline_y.nil? || @descender.nil? # baseline is already pushed down one line below the current # line, so we need to subtract line line_height and leading, # but we need to add in the descender since baseline is # above the descender @baseline_y.abs + @descender - @line_height - @leading end
The height actually used during the previous render
Source
# File lib/prawn/text/box.rb, line 175 def render(flags={}) # dup because normalize_encoding changes the string string = @original_string.dup unprinted_text = '' @document.save_font do process_options unless @skip_encoding @document.font.normalize_encoding!(string) end @document.font_size(@font_size) do shrink_to_fit(string) if @overflow == :shrink_to_fit process_vertical_alignment(string) @inked = true unless flags[:dry_run] if @rotate != 0 && @inked unprinted_text = render_rotated(string) else unprinted_text = _render(string) end @inked = false end end unprinted_text end
Render text to the document based on the settings defined in initialize.
In order to facilitate look-ahead calculations, render
accepts a :dry_run => true
option. If provided then everything is executed as if rendering, with the exception that nothing is drawn on the page. Useful for look-ahead computations of height, unprinted text, etc.
Returns any text that did not print under the current settings
Private Instance Methods
Source
# File lib/prawn/text/box.rb, line 271 def _render(remaining_text) @line_height = @document.font.height @descender = @document.font.descender @ascender = @document.font.ascender @baseline_y = -@ascender printed_text = [] while remaining_text && remaining_text.length > 0 && @baseline_y.abs + @descender <= @height line_to_print = @line_wrap.wrap_line(remaining_text.first_line, :document => @document, :kerning => @kerning, :size => @font_size, :width => @width) if line_to_print.empty? && remaining_text.length > 0 raise Errors::CannotFit end remaining_text = remaining_text.slice(line_to_print.length.. remaining_text.length) print_ellipses = (@overflow == :ellipses && last_line? && remaining_text.length > 0) printed_text << print_line(line_to_print, print_ellipses) @baseline_y -= (@line_height + @leading) break if @single_line end @text = printed_text.join("\n") if @inked remaining_text end
Source
# File lib/prawn/text/box.rb, line 338 def insert_ellipses(line_to_print) if @document.width_of(line_to_print + "...", :kerning => @kerning) < @width line_to_print.insert(-1, "...") else line_to_print[-3..-1] = "..." if line_to_print.length > 3 end end
Source
# File lib/prawn/text/box.rb, line 334 def last_line? @baseline_y.abs + @descender > @height - @line_height end
Source
# File lib/prawn/text/box.rb, line 306 def print_line(line_to_print, print_ellipses) # strip so that trailing and preceding white space don't # interfere with alignment line_to_print.strip! insert_ellipses(line_to_print) if print_ellipses case(@align) when :left x = @at[0] when :center line_width = @document.width_of(line_to_print, :kerning => @kerning) x = @at[0] + @width * 0.5 - line_width * 0.5 when :right line_width = @document.width_of(line_to_print, :kerning => @kerning) x = @at[0] + @width - line_width end y = @at[1] + @baseline_y if @inked @document.draw_text!(line_to_print, :at => [x, y], :size => @font_size, :kerning => @kerning) end line_to_print end
Source
# File lib/prawn/text/box.rb, line 236 def process_options # must be performed within a save_font bock because # document.process_text_options sets the font @document.process_text_options(@options) @font_size = @options[:size] @kerning = @options[:kerning] end
Source
# File lib/prawn/text/box.rb, line 214 def process_vertical_alignment(string) return if @vertical_align == :top _render(string) case @vertical_align when :center @at[1] = @at[1] - (@height - height) * 0.5 when :bottom @at[1] = @at[1] - (@height - height) end @height = height end
Source
# File lib/prawn/text/box.rb, line 244 def render_rotated(string) unprinted_text = '' case @rotate_around when :center x = @at[0] + @width * 0.5 y = @at[1] - @height * 0.5 when :upper_right x = @at[0] + @width y = @at[1] when :lower_right x = @at[0] + @width y = @at[1] - @height when :lower_left x = @at[0] y = @at[1] - @height else x = @at[0] y = @at[1] end @document.rotate(@rotate, :origin => [x, y]) do unprinted_text = _render(string) end unprinted_text end
Source
# File lib/prawn/text/box.rb, line 228 def shrink_to_fit(string) while (unprinted_text = _render(string)).length > 0 && @font_size > @min_font_size @font_size -= 0.5 @document.font_size = @font_size end end
Decrease the font size until the text fits or the min font size is reached