Object
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
See Prawn::Text#text_box for valid options
# File lib/prawn/text/box.rb, line 128 128: def initialize(string, options={}) 129: @inked = false 130: Prawn.verify_options(VALID_OPTIONS, options) 131: options = options.dup 132: @overflow = options[:overflow] || :truncate 133: @original_string = string 134: @text = nil 135: 136: @document = options[:document] 137: @at = options[:at] || 138: [@document.bounds.left, @document.bounds.top] 139: @width = options[:width] || 140: @document.bounds.right - @at[0] 141: @height = options[:height] || 142: @at[1] - @document.bounds.bottom 143: @align = options[:align] || :left 144: @vertical_align = options[:valign] || :top 145: @leading = options[:leading] || 0 146: @rotate = options[:rotate] || 0 147: @rotate_around = options[:rotate_around] || :upper_left 148: @single_line = options[:single_line] 149: @skip_encoding = options[:skip_encoding] || @document.skip_encoding 150: 151: if @overflow == :expand 152: # if set to expand, then we simply set the bottom 153: # as the bottom of the document bounds, since that 154: # is the maximum we should expand to 155: @height = @at[1] - @document.bounds.bottom 156: @overflow = :truncate 157: end 158: @min_font_size = options[:min_font_size] || 5 159: @line_wrap = options [:line_wrap] || @document.default_line_wrap 160: @options = @document.text_options.merge(:kerning => options[:kerning], 161: :size => options[:size], 162: :style => options[:style]) 163: end
The height actually used during the previous render
# File lib/prawn/text/box.rb, line 203 203: def height 204: return 0 if @baseline_y.nil? || @descender.nil? 205: # baseline is already pushed down one line below the current 206: # line, so we need to subtract line line_height and leading, 207: # but we need to add in the descender since baseline is 208: # above the descender 209: @baseline_y.abs + @descender - @line_height - @leading 210: 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
# File lib/prawn/text/box.rb, line 175 175: def render(flags={}) 176: # dup because normalize_encoding changes the string 177: string = @original_string.dup 178: unprinted_text = '' 179: @document.save_font do 180: process_options 181: 182: unless @skip_encoding 183: @document.font.normalize_encoding!(string) 184: end 185: 186: @document.font_size(@font_size) do 187: shrink_to_fit(string) if @overflow == :shrink_to_fit 188: process_vertical_alignment(string) 189: @inked = true unless flags[:dry_run] 190: if @rotate != 0 && @inked 191: unprinted_text = render_rotated(string) 192: else 193: unprinted_text = _render(string) 194: end 195: @inked = false 196: end 197: end 198: unprinted_text 199: end
# File lib/prawn/text/box.rb, line 271 271: def _render(remaining_text) 272: @line_height = @document.font.height 273: @descender = @document.font.descender 274: @ascender = @document.font.ascender 275: @baseline_y = -@ascender 276: 277: printed_text = [] 278: 279: while remaining_text && 280: remaining_text.length > 0 && 281: @baseline_y.abs + @descender <= @height 282: line_to_print = @line_wrap.wrap_line(remaining_text.first_line, 283: :document => @document, 284: :kerning => @kerning, 285: :size => @font_size, 286: :width => @width) 287: 288: if line_to_print.empty? && remaining_text.length > 0 289: raise Errors::CannotFit 290: end 291: 292: remaining_text = remaining_text.slice(line_to_print.length.. 293: remaining_text.length) 294: print_ellipses = (@overflow == :ellipses && last_line? && 295: remaining_text.length > 0) 296: printed_text << print_line(line_to_print, print_ellipses) 297: @baseline_y -= (@line_height + @leading) 298: break if @single_line 299: end 300: 301: @text = printed_text.join("\n") if @inked 302: 303: remaining_text 304: end
# File lib/prawn/text/box.rb, line 338 338: def insert_ellipses(line_to_print) 339: if @document.width_of(line_to_print + "...", 340: :kerning => @kerning) < @width 341: line_to_print.insert(1, "...") 342: else 343: line_to_print[3..1] = "..." if line_to_print.length > 3 344: end 345: end
# File lib/prawn/text/box.rb, line 334 334: def last_line? 335: @baseline_y.abs + @descender > @height - @line_height 336: end
# File lib/prawn/text/box.rb, line 306 306: def print_line(line_to_print, print_ellipses) 307: # strip so that trailing and preceding white space don't 308: # interfere with alignment 309: line_to_print.strip! 310: 311: insert_ellipses(line_to_print) if print_ellipses 312: 313: case(@align) 314: when :left 315: x = @at[0] 316: when :center 317: line_width = @document.width_of(line_to_print, :kerning => @kerning) 318: x = @at[0] + @width * 0.5 - line_width * 0.5 319: when :right 320: line_width = @document.width_of(line_to_print, :kerning => @kerning) 321: x = @at[0] + @width - line_width 322: end 323: 324: y = @at[1] + @baseline_y 325: 326: if @inked 327: @document.draw_text!(line_to_print, :at => [x, y], 328: :size => @font_size, :kerning => @kerning) 329: end 330: 331: line_to_print 332: end
# File lib/prawn/text/box.rb, line 236 236: def process_options 237: # must be performed within a save_font bock because 238: # document.process_text_options sets the font 239: @document.process_text_options(@options) 240: @font_size = @options[:size] 241: @kerning = @options[:kerning] 242: end
# File lib/prawn/text/box.rb, line 214 214: def process_vertical_alignment(string) 215: return if @vertical_align == :top 216: _render(string) 217: case @vertical_align 218: when :center 219: @at[1] = @at[1] - (@height - height) * 0.5 220: when :bottom 221: @at[1] = @at[1] - (@height - height) 222: end 223: @height = height 224: end
# File lib/prawn/text/box.rb, line 244 244: def render_rotated(string) 245: unprinted_text = '' 246: 247: case @rotate_around 248: when :center 249: x = @at[0] + @width * 0.5 250: y = @at[1] - @height * 0.5 251: when :upper_right 252: x = @at[0] + @width 253: y = @at[1] 254: when :lower_right 255: x = @at[0] + @width 256: y = @at[1] - @height 257: when :lower_left 258: x = @at[0] 259: y = @at[1] - @height 260: else 261: x = @at[0] 262: y = @at[1] 263: end 264: 265: @document.rotate(@rotate, :origin => [x, y]) do 266: unprinted_text = _render(string) 267: end 268: unprinted_text 269: end
Decrease the font size until the text fits or the min font size is reached
# File lib/prawn/text/box.rb, line 228 228: def shrink_to_fit(string) 229: while (unprinted_text = _render(string)).length > 0 && 230: @font_size > @min_font_size 231: @font_size -= 0.5 232: @document.font_size = @font_size 233: end 234: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.