File: box.rb

package info (click to toggle)
ruby-prawn 2.5.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,528 kB
  • sloc: ruby: 17,688; sh: 43; makefile: 20
file content (192 lines) | stat: -rw-r--r-- 9,236 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# frozen_string_literal: true

require_relative 'formatted/box'

module Prawn
  module Text # rubocop: disable Style/Documentation
    # @group Stable API

    # Draws the requested text into a box.
    #
    # When the text overflows the rectangle, you shrink to fit, or truncate the
    # text. Text boxes are independent of the document y position.
    #
    # #### Encoding
    #
    # Note that strings passed to this function should be encoded as UTF-8. If
    # you get unexpected characters appearing in your rendered document, check
    # this.
    #
    # If the current font is a built-in one, although the string must be encoded
    # as UTF-8, only characters that are available in WinAnsi are allowed.
    #
    # If an empty box is rendered to your PDF instead of the character you
    # wanted it usually means the current font doesn't include that character.
    #
    # @param string [String]
    # @param options [Hash{Symbol => any}]
    # @option options :kerning [Boolean] (value of document.default_kerning?)
    #   Whether or not to use kerning (if it is available with the current
    #   font).
    # @option options :size [Number] (current font size)
    #   The font size to use.
    # @option options :character_spacing [Number] (0)
    #   The amount of space to add to or remove from the default character
    #   spacing.
    # @option options :disable_wrap_by_char [Boolean] (false)
    #   Whether or not to prevent mid-word breaks when text does not fit in box.
    # @option options :mode [Symbol] (:fill)
    #   The text rendering mode. See documentation for
    #   {Prawn::Document#text_rendering_mode} for a list of valid options.
    # @option option :style [Symbol] (current style)
    #   The style to use. The requested style must be part of the current font
    #   family.
    # @option option :at [Array(Number, Number)] (bounds top left corner)
    #   The upper left corner of the box.
    # @option options :width [Number] (bounds.right - at[0])
    #   The width of the box.
    # @option options :height [Number] (default_height())
    #   The height of the box.
    # @option options :direction [:ltr, :rtl] (value of document.text_direction)
    #   Direction of the text (left-to-right or right-to-left).
    # @option options :fallback_fonts [Array<String>]
    #   An array of font names. Each name must be the name of an AFM font or the
    #   name that was used to register a family of external fonts (see
    #   {Prawn::Document#font_families}). If present, then each glyph will be
    #   rendered using the first font that includes the glyph, starting with the
    #   current font and then moving through `:fallback_fonts`.
    # @option options :align [:left, :center, :right, :justify]
    #   (:left if direction is :ltr, :right if direction is :rtl)
    #   Alignment within the bounding box.
    # @option options :valign [:top, :center, :bottom] (:top)
    #   Vertical alignment within the bounding box.
    # @option options :rotate [Number]
    #   The angle to rotate the text.
    # @option options :rotate_around
    #   [:center, :upper_left, :upper_right, :lower_right, :lower_left]
    #   (:upper_left)
    #   The point around which to rotate the text.
    # @option options :leading [Number] (value of document.default_leading)
    #   Additional space between lines.
    # @option options :single_line [Boolean] (false)
    #   If true, then only the first line will be drawn.
    # @option options :overflow [:truncate, :shrink_to_fit, :expand] (:truncate)
    #   This controls the behavior when the amount of text exceeds the available
    #   space.
    # @option options :min_font_size [Number] (5)
    #   The minimum font size to use when `:overflow` is set to `:shrink_to_fit`
    #   (that is the font size will not be reduced to less than this value, even
    #   if it means that some text will be cut off).
    # @return [String] Any text that did not print under the current settings.
    # @raise [Prawn::Errors::CannotFit]
    #   If not wide enough to print any text.
    def text_box(string, options = {})
      options = options.dup
      options[:document] = self

      box =
        if options[:inline_format]
          p = options.delete(:inline_format)
          p = [] unless p.is_a?(Array)
          array = text_formatter.format(string, *p)
          Text::Formatted::Box.new(array, options)
        else
          Text::Box.new(string, options)
        end

      box.render
    end

    # @group Experimental API

    # Text box.
    #
    # Generally, one would use the {Prawn::Text#text_box} convenience method.
    # However, using {Prawn::Text::Box#initialize Box.new} in conjunction with
    # `render(dry_run: true)` enables one to do calculations prior to placing
    # text on the page, or to determine how much vertical space was consumed by
    # the printed text.
    class Box < Prawn::Text::Formatted::Box
      # @param string [String]
      # @param options [Hash{Symbol => any}]
      # @option options :document [Prawn::Document] Owning document.
      # @option options :kerning [Boolean] (value of document.default_kerning?)
      #   Whether or not to use kerning (if it is available with the current
      #   font).
      # @option options :size [Number] (current font size)
      #   The font size to use.
      # @option options :character_spacing [Number] (0)
      #   The amount of space to add to or remove from the default character
      #   spacing.
      # @option options :disable_wrap_by_char [Boolean] (false)
      #   Whether or not to prevent mid-word breaks when text does not fit in box.
      # @option options :mode [Symbol] (:fill)
      #   The text rendering mode. See documentation for
      #   {Prawn::Document#text_rendering_mode} for a list of valid options.
      # @option option :style [Symbol] (current style)
      #   The style to use. The requested style must be part of the current font
      #   family.
      # @option option :at [Array(Number, Number)] (bounds top left corner)
      #   The upper left corner of the box.
      # @option options :width [Number] (bounds.right - at[0])
      #   The width of the box.
      # @option options :height [Number] (default_height())
      #   The height of the box.
      # @option options :direction [:ltr, :rtl] (value of document.text_direction)
      #   Direction of the text (left-to-right or right-to-left).
      # @option options :fallback_fonts [Array<String>]
      #   An array of font names. Each name must be the name of an AFM font or the
      #   name that was used to register a family of external fonts (see
      #   {Prawn::Document#font_families}). If present, then each glyph will be
      #   rendered using the first font that includes the glyph, starting with the
      #   current font and then moving through `:fallback_fonts`.
      # @option options :align [:left, :center, :right, :justify]
      #   (:left if direction is :ltr, :right if direction is :rtl)
      #   Alignment within the bounding box.
      # @option options :valign [:top, :center, :bottom] (:top)
      #   Vertical alignment within the bounding box.
      # @option options :rotate [Number]
      #   The angle to rotate the text.
      # @option options :rotate_around
      #   [:center, :upper_left, :upper_right, :lower_right, :lower_left]
      #   (:upper_left)
      #   The point around which to rotate the text.
      # @option options :leading [Number] (value of document.default_leading)
      #   Additional space between lines.
      # @option options :single_line [Boolean] (false)
      #   If true, then only the first line will be drawn.
      # @option options :overflow [:truncate, :shrink_to_fit, :expand] (:truncate)
      #   This controls the behavior when the amount of text exceeds the available
      #   space.
      # @option options :min_font_size [Number] (5)
      #   The minimum font size to use when `:overflow` is set to `:shrink_to_fit`
      #   (that is the font size will not be reduced to less than this value, even
      #   if it means that some text will be cut off).
      def initialize(string, options = {})
        super([{ text: string }], options)
      end

      # Render text to the document based on the settings defined in
      # constructor.
      #
      # In order to facilitate look-ahead calculations, this method 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.
      #
      # @param flags [Hash{Symbol => any}]
      # @option flags :dry_run [Boolean] (false)
      #   Do not draw the text. Everything else is done.
      # @return [String]
      #   Any text that did not print under the current settings.
      # @raise [Prawn::Text::Formatted::Arranger::BadFontFamily]
      #   If no font family is defined for the current font.
      # @raise [Prawn::Errors::CannotFit]
      #   If not wide enough to print any text.
      def render(flags = {})
        leftover = super(flags)
        leftover.map { |hash| hash[:text] }.join
      end
    end
  end
end