1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
# encoding: utf-8
# text.rb: Text table cells.
#
# Copyright December 2009, Gregory Brown and Brad Ediger. All Rights Reserved.
#
# This is free software. Please see the LICENSE and COPYING files for details.
module Prawn
class Table
class Cell
# A Cell that contains text. Has some limited options to set font family,
# size, and style.
#
class Text < Cell
TextOptions = [:inline_format, :kerning, :size, :align, :valign,
:rotate, :rotate_around, :leading, :single_line, :skip_encoding,
:overflow, :min_font_size]
TextOptions.each do |option|
define_method("#{option}=") { |v| @text_options[option] = v }
define_method(option) { @text_options[option] }
end
attr_writer :font, :text_color
def initialize(pdf, point, options={})
@text_options = {}
super
end
# Returns the font that will be used to draw this cell.
#
def font
with_font { @pdf.font }
end
# Sets the style of the font in use. Equivalent to the Text::Box
# +style+ option, but we already have a style method.
#
def font_style=(style)
@text_options[:style] = style
end
# Returns the width of this text with no wrapping. This will be far off
# from the final width if the text is long.
#
def natural_content_width
[styled_width_of(@content), @pdf.bounds.width].min
end
# Returns the natural height of this block of text, wrapped to the
# preset width.
#
def natural_content_height
with_font do
b = text_box(:width => content_width + FPTolerance)
b.render(:dry_run => true)
b.height + b.line_gap
end
end
# Draws the text content into its bounding box.
#
def draw_content
with_font do
@pdf.move_down((@pdf.font.line_gap + @pdf.font.descender)/2)
with_text_color do
text_box(:width => content_width + FPTolerance,
:height => content_height + FPTolerance,
:at => [0, @pdf.cursor]).render
end
end
end
def set_width_constraints
# Sets a reasonable minimum width. If the cell has any content, make
# sure we have enough width to be at least one character wide. This is
# a bit of a hack, but it should work well enough.
min_content_width = [natural_content_width, styled_width_of("M")].min
@min_width ||= padding_left + padding_right + min_content_width
super
end
protected
def with_font
@pdf.save_font do
options = {}
options[:style] = @text_options[:style] if @text_options[:style]
@pdf.font(@font || @pdf.font.name, options)
yield
end
end
def with_text_color
old_color = @pdf.fill_color || '000000'
@pdf.fill_color(@text_color) if @text_color
yield
ensure
@pdf.fill_color(old_color)
end
def text_box(extra_options={})
if @text_options[:inline_format]
options = @text_options.dup
options.delete(:inline_format)
array = ::Prawn::Text::Formatted::Parser.to_array(@content)
::Prawn::Text::Formatted::Box.new(array,
options.merge(extra_options).merge(:document => @pdf))
else
::Prawn::Text::Box.new(@content, @text_options.merge(extra_options).
merge(:document => @pdf))
end
end
# Returns the width of +text+ under the given text options.
#
def styled_width_of(text)
@pdf.width_of(text, @text_options)
end
end
end
end
end
|