Class: Prawn::Text::Box

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

Overview

Generally, one would use the Prawn::Text#text_box convenience method. However, using Text::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

Formatted::Box

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Core::Text::Wrap

#wrap

Constructor Details

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

See Prawn::Text#text_box for valid options



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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
# File 'lib/prawn/text/box.rb', line 169

def initialize(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 = text
  @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] || @document.default_leading?
  @character_spacing = options[:character_spacing] ||
                       @document.character_spacing
  @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
  if options[:kerning].nil? then
    options[:kerning] = @document.default_kerning?
  end
  @options = { :kerning => options[:kerning],
               :size    => options[:size],
               :style   => options[:style] }

  super(text, options)
end

Instance Attribute Details

#ascenderObject (readonly)

The height of the ascender of the last line printed



125
126
127
# File 'lib/prawn/text/box.rb', line 125

def ascender
  @ascender
end

#atObject (readonly)

The upper left corner of the text box



121
122
123
# File 'lib/prawn/text/box.rb', line 121

def at
  @at
end

#descenderObject (readonly)

The height of the descender of the last line printed



127
128
129
# File 'lib/prawn/text/box.rb', line 127

def descender
  @descender
end

#leadingObject (readonly)

The leading used during printing



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

def leading
  @leading
end

#line_heightObject (readonly)

The line height of the last line printed



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

def line_height
  @line_height
end

#textObject (readonly)

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



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

def text
  @text
end

Class Method Details

.extensionsObject

Extend Prawn::Text::Box

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

module MyWrap

  def wrap
    @text = nil
    @line_height = @document.font.height
    @descender   = @document.font.descender
    @ascender    = @document.font.ascender
    @baseline_y  = -@ascender
    draw_line("all your base are belong to us")
    ""
  end

end

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

box = Prawn::Text::Box.new('hello world')
box.render('why can't I print anything other than' +
           '"all your base are belong to us"?')


159
160
161
# File 'lib/prawn/text/box.rb', line 159

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

.inherited(base) ⇒ Object

:nodoc:



163
164
165
# File 'lib/prawn/text/box.rb', line 163

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



268
269
270
# File 'lib/prawn/text/box.rb', line 268

def available_width
  @width
end

#draw_line(line_to_print, line_width = 0, word_spacing = 0, include_ellipses = false) ⇒ Object

:nodoc:



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
# File 'lib/prawn/text/box.rb', line 272

def draw_line(line_to_print, line_width=0, word_spacing=0, include_ellipses=false) #:nodoc:
  insert_ellipses(line_to_print) if include_ellipses

  case(@align)
  when :left, :justify
    x = @at[0]
  when :center
    x = @at[0] + @width * 0.5 - line_width * 0.5
  when :right
    x = @at[0] + @width - line_width
  end

  y = @at[1] + @baseline_y

  if @inked
    @document.word_spacing(word_spacing) {
      @document.character_spacing(@character_spacing) {
        @document.draw_text!(line_to_print, :at => [x, y],
                             :kerning => @kerning)
      }
    }
  end

  line_to_print
end

#heightObject

The height actually used during the previous render



257
258
259
260
261
262
263
264
# File 'lib/prawn/text/box.rb', line 257

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 - @ascender - @leading
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



226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
# File 'lib/prawn/text/box.rb', line 226

def render(flags={})
  unprinted_text = ''
  @document.save_font do
    @document.character_spacing(@character_spacing) 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

  unprinted_text
end

#valid_optionsObject



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

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