Parent

Prawn::Text::Formatted::Box

Generally, one would use the Prawn::Text::Formatted#formatted_text_box convenience method. However, using Text::Formatted::Box.new in conjunction with #(:dry_run => true) 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

Attributes

text[R]

The text that was successfully printed (or, if dry_run was used, the text that would have been successfully printed)

at[R]

The upper left corner of the text box

line_height[R]

The line height of the last line printed

ascender[R]

The height of the ascender of the last line printed

descender[R]

The height of the descender of the last line printed

leading[R]

The leading used during printing

Public Class Methods

extensions() click to toggle source

Example (see Prawn::Text::Core::Formatted::Wrap for what is required of the wrap method if you want to override the default wrapping algorithm):

  module MyWrap

    def wrap(array)
      initialize_wrap([{ :text => 'all your base are belong to us' }])
      @line_wrap.wrap_line(:document => @document,
                           :kerning => @kerning,
                           :width => 10000,
                           :arranger => @arranger)
      fragment = @arranger.retrieve_fragment
      format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
      []
    end

  end

  Prawn::Text::Formatted::Box.extensions << MyWrap

  box = Prawn::Text::Formatted::Box.new('hello world')
  box.render('why can't I print anything other than' +
             '"all your base are belong to us"?')
     # File lib/prawn/text/formatted/box.rb, line 166
166:         def self.extensions
167:           @extensions ||= []
168:         end
new(formatted_text, options={}) click to toggle source

See Prawn::Text#text_box for valid options

     # File lib/prawn/text/formatted/box.rb, line 176
176:         def initialize(formatted_text, options={})
177:           @inked             = false
178:           Prawn.verify_options(valid_options, options)
179:           options            = options.dup
180: 
181:           self.class.extensions.reverse_each { |e| extend e }
182: 
183:           @overflow          = options[:overflow] || :truncate
184: 
185:           self.original_text = formatted_text
186:           @text              = nil
187: 
188:           @document          = options[:document]
189:           @direction         = options[:direction] || @document.text_direction
190:           @fallback_fonts    = options[:fallback_fonts] ||
191:                                @document.fallback_fonts
192:           @at                = (options[:at] ||
193:                                [@document.bounds.left, @document.bounds.top]).dup
194:           @width             = options[:width] ||
195:                                @document.bounds.right - @at[0]
196:           @height            = options[:height] || default_height
197:           @align             = options[:align] ||
198:                                (@direction == :rtl ? :right : :left)
199:           @vertical_align    = options[:valign] || :top
200:           @leading           = options[:leading] || @document.default_leading
201:           @character_spacing = options[:character_spacing] ||
202:                                @document.character_spacing
203:           @mode              = options[:mode] || @document.text_rendering_mode
204:           @rotate            = options[:rotate] || 0
205:           @rotate_around     = options[:rotate_around] || :upper_left
206:           @single_line       = options[:single_line]
207:           @skip_encoding     = options[:skip_encoding] || @document.skip_encoding
208: 
209:           if @overflow == :expand
210:             # if set to expand, then we simply set the bottom
211:             # as the bottom of the document bounds, since that
212:             # is the maximum we should expand to
213:             @height = default_height
214:             @overflow = :truncate
215:           end
216:           @min_font_size = options[:min_font_size] || 5
217:           if options[:kerning].nil? then
218:             options[:kerning] = @document.default_kerning?
219:           end
220:           @options = { :kerning => options[:kerning],
221:             :size    => options[:size],
222:             :style   => options[:style] }
223: 
224:           super(formatted_text, options)
225:         end

Public Instance Methods

available_width() click to toggle source

The width available at this point in the box

     # File lib/prawn/text/formatted/box.rb, line 271
271:         def available_width
272:           @width
273:         end
everything_printed?() click to toggle source

True iff everything printed (or, if dry_run was used, everything would have been successfully printed)

     # File lib/prawn/text/formatted/box.rb, line 119
119:         def everything_printed?
120:           @everything_printed
121:         end
height() click to toggle source

The height actually used during the previous render

     # File lib/prawn/text/formatted/box.rb, line 277
277:         def height
278:           return 0 if @baseline_y.nil? || @descender.nil?
279:           (@baseline_y - @descender).abs
280:         end
line_gap() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 134
134:         def line_gap
135:           line_height - (ascender + descender)
136:         end
nothing_printed?() click to toggle source

True iff nothing printed (or, if dry_run was used, nothing would have been successfully printed)

     # File lib/prawn/text/formatted/box.rb, line 113
113:         def nothing_printed?
114:           @nothing_printed
115:         end
render(flags={}) click to toggle source

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/formatted/box.rb, line 237
237:         def render(flags={})
238:           unprinted_text = []
239: 
240:           @document.save_font do
241:             @document.character_spacing(@character_spacing) do
242:               @document.text_rendering_mode(@mode) do
243:                 process_options
244: 
245:                 if @skip_encoding
246:                   text = original_text
247:                 else
248:                   text = normalize_encoding
249:                 end
250: 
251:                 @document.font_size(@font_size) do
252:                   shrink_to_fit(text) if @overflow == :shrink_to_fit
253:                   process_vertical_alignment(text)
254:                   @inked = true unless flags[:dry_run]
255:                   if @rotate != 0 && @inked
256:                     unprinted_text = render_rotated(text)
257:                   else
258:                     unprinted_text = wrap(text)
259:                   end
260:                   @inked = false
261:                 end
262:               end
263:             end
264:           end
265: 
266:           unprinted_text
267:         end
valid_options() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 94
 94:         def valid_options
 95:           Prawn::Core::Text::VALID_OPTIONS + [:at, :height, :width,
 96:                                               :align, :valign,
 97:                                               :rotate, :rotate_around,
 98:                                               :overflow, :min_font_size,
 99:                                               :leading, :character_spacing,
100:                                               :mode, :single_line,
101:                                               :skip_encoding,
102:                                               :document,
103:                                               :direction,
104:                                               :fallback_fonts]
105:         end

Private Instance Methods

analyze_glyphs_for_fallback_font_support(hash) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 362
362:         def analyze_glyphs_for_fallback_font_support(hash)
363:           font_glyph_pairs = []
364: 
365:           original_font = @document.font.family
366:           fragment_font = hash[:font] || original_font
367:           @document.font(fragment_font)
368: 
369:           fallback_fonts = @fallback_fonts.dup
370:           # always default back to the current font if the glyph is missing from
371:           # all fonts
372:           fallback_fonts << fragment_font
373: 
374:           hash[:text].unpack("U*").each do |char_int|
375:             char = [char_int].pack("U")
376:             @document.font(fragment_font)
377:             font_glyph_pairs << [find_font_for_this_glyph(char,
378:                                                           @document.font.family,
379:                                                           fallback_fonts.dup),
380:                                  char]
381:           end
382: 
383:           @document.font(original_font)
384: 
385:           form_fragments_from_like_font_glyph_pairs(font_glyph_pairs, hash)
386:         end
default_height() click to toggle source

Returns the default height to be used if none is provided or if the overflow option is set to :expand. If we are in a stretchy bounding box, assume we can stretch to the bottom of the innermost non-stretchy box.

     # File lib/prawn/text/formatted/box.rb, line 431
431:         def default_height
432:           # Find the "frame", the innermost non-stretchy bbox.
433:           frame = @document.bounds
434:           frame = frame.parent while frame.stretchy? && frame.parent
435: 
436:           @at[1] + @document.bounds.absolute_bottom - frame.absolute_bottom
437:         end
draw_fragment_overlay_anchor(fragment) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 523
523:         def draw_fragment_overlay_anchor(fragment)
524:           return unless fragment.anchor
525:           box = fragment.absolute_bounding_box
526:           @document.link_annotation(box,
527:                                     :Border => [0, 0, 0],
528:                                     :Dest => fragment.anchor)
529:         end
draw_fragment_overlay_styles(fragment) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 531
531:         def draw_fragment_overlay_styles(fragment)
532:           underline = fragment.styles.include?(:underline)
533:           if underline
534:             @document.stroke_line(fragment.underline_points)
535:           end
536:           
537:           strikethrough = fragment.styles.include?(:strikethrough)
538:           if strikethrough
539:             @document.stroke_line(fragment.strikethrough_points)
540:           end
541:         end
draw_fragment_overlays(fragment) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 504
504:         def draw_fragment_overlays(fragment)
505:           draw_fragment_overlay_styles(fragment)
506:           draw_fragment_overlay_link(fragment)
507:           draw_fragment_overlay_anchor(fragment)
508:           fragment.callback_objects.each do |obj|
509:             obj.render_in_front(fragment) if obj.respond_to?(:render_in_front)
510:           end
511:         end
draw_fragment_underlays(fragment) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 498
498:         def draw_fragment_underlays(fragment)
499:           fragment.callback_objects.each do |obj|
500:             obj.render_behind(fragment) if obj.respond_to?(:render_behind)
501:           end
502:         end
find_font_for_this_glyph(char, current_font, fallback_fonts) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 388
388:         def find_font_for_this_glyph(char, current_font, fallback_fonts)
389:           if fallback_fonts.length == 0 || @document.font.glyph_present?(char)
390:             current_font
391:           else
392:             current_font = fallback_fonts.shift
393:             @document.font(current_font)
394:             find_font_for_this_glyph(char, @document.font.family, fallback_fonts)
395:           end
396:         end
form_fragments_from_like_font_glyph_pairs(font_glyph_pairs, hash) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 398
398:         def form_fragments_from_like_font_glyph_pairs(font_glyph_pairs, hash)
399:           fragments = []
400:           fragment = nil
401:           current_font = nil
402: 
403:           font_glyph_pairs.each do |font, char|
404:             if font != current_font
405:               current_font = font
406:               fragment = hash.dup
407:               fragment[:text] = char
408:               fragment[:font] = font
409:               fragments << fragment
410:             else
411:               fragment[:text] += char
412:             end
413:           end
414: 
415:           fragments
416:         end
move_baseline_down() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 418
418:         def move_baseline_down
419:           if @baseline_y == 0
420:             @baseline_y  = -@ascender
421:           else
422:             @baseline_y -= (@line_height + @leading)
423:           end
424:         end
normalize_encoding() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 331
331:         def normalize_encoding
332:           formatted_text = original_text
333: 
334:           unless @fallback_fonts.empty?
335:             formatted_text = process_fallback_fonts(formatted_text)
336:           end
337: 
338:           formatted_text.each do |hash|
339:             if hash[:font]
340:               @document.font(hash[:font]) do
341:                 hash[:text] = @document.font.normalize_encoding(hash[:text])
342:               end
343:             else
344:               hash[:text] = @document.font.normalize_encoding(hash[:text])
345:             end
346:           end
347: 
348:           formatted_text
349:         end
original_text() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 323
323:         def original_text
324:           @original_array.collect { |hash| hash.dup }
325:         end
original_text=(formatted_text) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 327
327:         def original_text=(formatted_text)
328:           @original_array = formatted_text
329:         end
process_fallback_fonts(formatted_text) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 351
351:         def process_fallback_fonts(formatted_text)
352:           modified_formatted_text = []
353: 
354:           formatted_text.each do |hash|
355:             fragments = analyze_glyphs_for_fallback_font_support(hash)
356:             modified_formatted_text.concat(fragments)
357:           end
358: 
359:           modified_formatted_text
360:         end
process_options() click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 463
463:         def process_options
464:           # must be performed within a save_font bock because
465:           # document.process_text_options sets the font
466:           @document.process_text_options(@options)
467:           @font_size = @options[:size]
468:           @kerning   = @options[:kerning]
469:         end
process_vertical_alignment(text) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 439
439:         def process_vertical_alignment(text)
440:           return if @vertical_align == :top
441:           wrap(text)
442: 
443:           case @vertical_align
444:           when :center
445:             @at[1] = @at[1] - (@height - height) * 0.5
446:           when :bottom
447:             @at[1] = @at[1] - (@height - height)
448:           end
449:           @height = height
450:         end
render_rotated(text) click to toggle source
     # File lib/prawn/text/formatted/box.rb, line 471
471:         def render_rotated(text)
472:           unprinted_text = ''
473: 
474:           case @rotate_around
475:           when :center
476:             x = @at[0] + @width * 0.5
477:             y = @at[1] - @height * 0.5
478:           when :upper_right
479:             x = @at[0] + @width
480:             y = @at[1]
481:           when :lower_right
482:             x = @at[0] + @width
483:             y = @at[1] - @height
484:           when :lower_left
485:             x = @at[0]
486:             y = @at[1] - @height
487:           else
488:             x = @at[0]
489:             y = @at[1]
490:           end
491: 
492:           @document.rotate(@rotate, :origin => [x, y]) do
493:             unprinted_text = wrap(text)
494:           end
495:           unprinted_text
496:         end
shrink_to_fit(text) click to toggle source

Decrease the font size until the text fits or the min font size is reached

     # File lib/prawn/text/formatted/box.rb, line 454
454:         def shrink_to_fit(text)
455:           wrap(text)
456:           until @everything_printed || @font_size <= @min_font_size
457:             @font_size = [@font_size - 0.5, @min_font_size].max
458:             @document.font_size = @font_size
459:             wrap(text)
460:           end
461:         end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.