Class: Prawn::Text::Formatted::Box

Inherits:
Object
  • Object
show all
Includes:
Wrap
Defined in:
lib/prawn/text/formatted/box.rb

Overview

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

Direct Known Subclasses

Box

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Wrap

#wrap

Constructor Details

#initialize(formatted_text, options = {}) ⇒ Box

See Prawn::Text#text_box for valid options



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/prawn/text/formatted/box.rb', line 186

def initialize(formatted_text, options={})
  @inked             = false
  Prawn.verify_options(valid_options, options)
  options            = options.dup

  self.class.extensions.reverse_each { |e| extend e }

  @overflow          = options[:overflow] || :truncate

  self.original_text = formatted_text
  @text              = nil

  @document          = options[:document]
  @direction         = options[:direction] || @document.text_direction
  @fallback_fonts    = options[:fallback_fonts] ||
                       @document.fallback_fonts
  @at                = (options[:at] ||
                       [@document.bounds.left, @document.bounds.top]).dup
  @width             = options[:width] ||
                       @document.bounds.right - @at[0]
  @height            = options[:height] || default_height
  @align             = options[:align] ||
                       (@direction == :rtl ? :right : :left)
  @vertical_align    = options[:valign] || :top
  @leading           = options[:leading] || @document.default_leading
  @character_spacing = options[:character_spacing] ||
                       @document.character_spacing
  @mode              = options[:mode] || @document.text_rendering_mode
  @rotate            = options[:rotate] || 0
  @rotate_around     = options[:rotate_around] || :upper_left
  @single_line       = options[:single_line]
  @skip_encoding     = options[:skip_encoding] || @document.skip_encoding
  @draw_text_callback = options[:draw_text_callback]

  # if the text rendering mode is :unknown, force it back to :fill
  if @mode == :unknown
    @mode = :fill
  end

  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 = default_height
    @overflow = :truncate
  end
  @min_font_size = options[:min_font_size] || 5
  if options[:kerning].nil? then
    options[:kerning] = @document.default_kerning?
  end
  @options = { :kerning => options[:kerning],
    :size    => options[:size],
    :style   => options[:style] }

  super(formatted_text, options)
end

Instance Attribute Details

#ascenderObject (readonly)

The height of the ascender of the last line printed



138
139
140
# File 'lib/prawn/text/formatted/box.rb', line 138

def ascender
  @ascender
end

#atObject (readonly)

The upper left corner of the text box



134
135
136
# File 'lib/prawn/text/formatted/box.rb', line 134

def at
  @at
end

#descenderObject (readonly)

The height of the descender of the last line printed



140
141
142
# File 'lib/prawn/text/formatted/box.rb', line 140

def descender
  @descender
end

#leadingObject (readonly)

The leading used during printing



142
143
144
# File 'lib/prawn/text/formatted/box.rb', line 142

def leading
  @leading
end

#line_heightObject (readonly)

The line height of the last line printed



136
137
138
# File 'lib/prawn/text/formatted/box.rb', line 136

def line_height
  @line_height
end

#textObject (readonly)

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



119
120
121
# File 'lib/prawn/text/formatted/box.rb', line 119

def text
  @text
end

Class Method Details

.extensionsObject

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"?')


176
177
178
# File 'lib/prawn/text/formatted/box.rb', line 176

def self.extensions
  @extensions ||= []
end

.inherited(base) ⇒ Object

:nodoc:



180
181
182
# File 'lib/prawn/text/formatted/box.rb', line 180

def self.inherited(base) #:nodoc:
  extensions.each { |e| base.extensions << e }
end

Instance Method Details

#available_widthObject

The width available at this point in the box



287
288
289
# File 'lib/prawn/text/formatted/box.rb', line 287

def available_width
  @width
end

#draw_fragment(fragment, accumulated_width = 0, line_width = 0, word_spacing = 0) ⇒ Object

fragment is a Prawn::Text::Formatted::Fragment object



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# File 'lib/prawn/text/formatted/box.rb', line 300

def draw_fragment(fragment, accumulated_width=0, line_width=0, word_spacing=0) #:nodoc:
  case(@align)
  when :left
    x = @at[0]
  when :center
    x = @at[0] + @width * 0.5 - line_width * 0.5
  when :right
    x = @at[0] + @width - line_width
  when :justify
    if @direction == :ltr
      x = @at[0]
    else
      x = @at[0] + @width - line_width
    end
  end

  x += accumulated_width

  y = @at[1] + @baseline_y

  y += fragment.y_offset

  fragment.left = x
  fragment.baseline = y

  if @inked
    draw_fragment_underlays(fragment)

    @document.word_spacing(word_spacing) {
      if @draw_text_callback
        @draw_text_callback.call(fragment.text, :at => [x, y],
                                 :kerning => @kerning)
      else
        @document.draw_text!(fragment.text, :at => [x, y],
                             :kerning => @kerning)
      end
    }

    draw_fragment_overlays(fragment)
  end
end

#everything_printed?Boolean

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

Returns:

  • (Boolean)


129
130
131
# File 'lib/prawn/text/formatted/box.rb', line 129

def everything_printed?
  @everything_printed
end

#heightObject

The height actually used during the previous render



293
294
295
296
# File 'lib/prawn/text/formatted/box.rb', line 293

def height
  return 0 if @baseline_y.nil? || @descender.nil?
  (@baseline_y - @descender).abs
end

#line_gapObject



144
145
146
# File 'lib/prawn/text/formatted/box.rb', line 144

def line_gap
  line_height - (ascender + descender)
end

#nothing_printed?Boolean

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

Returns:

  • (Boolean)


123
124
125
# File 'lib/prawn/text/formatted/box.rb', line 123

def nothing_printed?
  @nothing_printed
end

#render(flags = {}) ⇒ Object

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



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/prawn/text/formatted/box.rb', line 253

def render(flags={})
  unprinted_text = []

  @document.save_font do
    @document.character_spacing(@character_spacing) do
      @document.text_rendering_mode(@mode) do
        process_options

        if @skip_encoding
          text = original_text
        else
          text = normalize_encoding
        end

        @document.font_size(@font_size) do
          shrink_to_fit(text) if @overflow == :shrink_to_fit
          process_vertical_alignment(text)
          @inked = true unless flags[:dry_run]
          if @rotate != 0 && @inked
            unprinted_text = render_rotated(text)
          else
            unprinted_text = wrap(text)
          end
          @inked = false
        end
      end
    end
  end

  unprinted_text
end

#valid_optionsObject



103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/prawn/text/formatted/box.rb', line 103

def valid_options
  PDF::Core::Text::VALID_OPTIONS + [:at, :height, :width,
                                      :align, :valign,
                                      :rotate, :rotate_around,
                                      :overflow, :min_font_size,
                                      :leading, :character_spacing,
                                      :mode, :single_line,
                                      :skip_encoding,
                                      :document,
                                      :direction,
                                      :fallback_fonts,
                                      :draw_text_callback]
end