File: text.rb

package info (click to toggle)
ruby-prawn 1.0.0~rc1%2Bdfsg1-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 4,248 kB
  • sloc: ruby: 17,499; sh: 44; makefile: 17
file content (130 lines) | stat: -rw-r--r-- 3,952 bytes parent folder | download
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