prawn 2.3.0 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (203) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/prawn/document/bounding_box.rb +223 -143
  4. data/lib/prawn/document/column_box.rb +61 -26
  5. data/lib/prawn/document/internals.rb +25 -16
  6. data/lib/prawn/document/span.rb +21 -18
  7. data/lib/prawn/document.rb +273 -182
  8. data/lib/prawn/encoding.rb +2 -5
  9. data/lib/prawn/errors.rb +23 -34
  10. data/lib/prawn/font.rb +254 -139
  11. data/lib/prawn/font_metric_cache.rb +18 -16
  12. data/lib/prawn/fonts/afm.rb +99 -57
  13. data/lib/prawn/fonts/dfont.rb +7 -1
  14. data/lib/prawn/fonts/otf.rb +4 -1
  15. data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
  16. data/lib/prawn/fonts/ttc.rb +7 -2
  17. data/lib/prawn/fonts/ttf.rb +345 -107
  18. data/lib/prawn/fonts.rb +14 -0
  19. data/lib/prawn/graphics/blend_mode.rb +25 -28
  20. data/lib/prawn/graphics/cap_style.rb +9 -12
  21. data/lib/prawn/graphics/color.rb +75 -50
  22. data/lib/prawn/graphics/dash.rb +45 -42
  23. data/lib/prawn/graphics/join_style.rb +18 -12
  24. data/lib/prawn/graphics/patterns.rb +239 -110
  25. data/lib/prawn/graphics/transformation.rb +51 -44
  26. data/lib/prawn/graphics/transparency.rb +16 -40
  27. data/lib/prawn/graphics.rb +370 -260
  28. data/lib/prawn/grid.rb +219 -57
  29. data/lib/prawn/image_handler.rb +27 -10
  30. data/lib/prawn/images/image.rb +8 -10
  31. data/lib/prawn/images/jpg.rb +46 -20
  32. data/lib/prawn/images/png.rb +94 -42
  33. data/lib/prawn/images.rb +70 -81
  34. data/lib/prawn/measurement_extensions.rb +39 -8
  35. data/lib/prawn/measurements.rb +60 -5
  36. data/lib/prawn/outline.rb +120 -113
  37. data/lib/prawn/repeater.rb +52 -36
  38. data/lib/prawn/security/arcfour.rb +4 -4
  39. data/lib/prawn/security.rb +106 -98
  40. data/lib/prawn/soft_mask.rb +42 -30
  41. data/lib/prawn/stamp.rb +38 -42
  42. data/lib/prawn/text/box.rb +156 -105
  43. data/lib/prawn/text/formatted/arranger.rb +121 -41
  44. data/lib/prawn/text/formatted/box.rb +239 -163
  45. data/lib/prawn/text/formatted/fragment.rb +130 -14
  46. data/lib/prawn/text/formatted/line_wrap.rb +49 -38
  47. data/lib/prawn/text/formatted/parser.rb +116 -74
  48. data/lib/prawn/text/formatted/wrap.rb +25 -26
  49. data/lib/prawn/text/formatted.rb +75 -0
  50. data/lib/prawn/text.rb +456 -211
  51. data/lib/prawn/transformation_stack.rb +29 -10
  52. data/lib/prawn/utilities.rb +13 -13
  53. data/lib/prawn/version.rb +2 -1
  54. data/lib/prawn/view.rb +69 -54
  55. data/lib/prawn.rb +24 -18
  56. data.tar.gz.sig +0 -0
  57. metadata +55 -262
  58. metadata.gz.sig +3 -4
  59. data/.yardopts +0 -10
  60. data/Gemfile +0 -5
  61. data/Rakefile +0 -54
  62. data/manual/absolute_position.pdf +0 -0
  63. data/manual/basic_concepts/adding_pages.rb +0 -26
  64. data/manual/basic_concepts/basic_concepts.rb +0 -43
  65. data/manual/basic_concepts/creation.rb +0 -38
  66. data/manual/basic_concepts/cursor.rb +0 -32
  67. data/manual/basic_concepts/measurement.rb +0 -24
  68. data/manual/basic_concepts/origin.rb +0 -37
  69. data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
  70. data/manual/basic_concepts/view.rb +0 -48
  71. data/manual/bounding_box/bounding_box.rb +0 -41
  72. data/manual/bounding_box/bounds.rb +0 -48
  73. data/manual/bounding_box/canvas.rb +0 -23
  74. data/manual/bounding_box/creation.rb +0 -22
  75. data/manual/bounding_box/indentation.rb +0 -45
  76. data/manual/bounding_box/nesting.rb +0 -52
  77. data/manual/bounding_box/russian_boxes.rb +0 -40
  78. data/manual/bounding_box/stretchy.rb +0 -29
  79. data/manual/contents.rb +0 -35
  80. data/manual/cover.rb +0 -43
  81. data/manual/document_and_page_options/background.rb +0 -25
  82. data/manual/document_and_page_options/document_and_page_options.rb +0 -34
  83. data/manual/document_and_page_options/metadata.rb +0 -25
  84. data/manual/document_and_page_options/page_margins.rb +0 -36
  85. data/manual/document_and_page_options/page_size.rb +0 -34
  86. data/manual/document_and_page_options/print_scaling.rb +0 -22
  87. data/manual/example_helper.rb +0 -8
  88. data/manual/graphics/blend_mode.rb +0 -52
  89. data/manual/graphics/circle_and_ellipse.rb +0 -21
  90. data/manual/graphics/color.rb +0 -22
  91. data/manual/graphics/common_lines.rb +0 -29
  92. data/manual/graphics/fill_and_stroke.rb +0 -41
  93. data/manual/graphics/fill_rules.rb +0 -37
  94. data/manual/graphics/gradients.rb +0 -43
  95. data/manual/graphics/graphics.rb +0 -64
  96. data/manual/graphics/helper.rb +0 -27
  97. data/manual/graphics/line_width.rb +0 -36
  98. data/manual/graphics/lines_and_curves.rb +0 -40
  99. data/manual/graphics/polygon.rb +0 -27
  100. data/manual/graphics/rectangle.rb +0 -20
  101. data/manual/graphics/rotate.rb +0 -25
  102. data/manual/graphics/scale.rb +0 -42
  103. data/manual/graphics/soft_masks.rb +0 -44
  104. data/manual/graphics/stroke_cap.rb +0 -30
  105. data/manual/graphics/stroke_dash.rb +0 -47
  106. data/manual/graphics/stroke_join.rb +0 -29
  107. data/manual/graphics/translate.rb +0 -28
  108. data/manual/graphics/transparency.rb +0 -33
  109. data/manual/how_to_read_this_manual.rb +0 -39
  110. data/manual/images/absolute_position.rb +0 -22
  111. data/manual/images/fit.rb +0 -20
  112. data/manual/images/horizontal.rb +0 -24
  113. data/manual/images/images.rb +0 -41
  114. data/manual/images/plain_image.rb +0 -17
  115. data/manual/images/scale.rb +0 -21
  116. data/manual/images/vertical.rb +0 -27
  117. data/manual/images/width_and_height.rb +0 -24
  118. data/manual/layout/boxes.rb +0 -26
  119. data/manual/layout/content.rb +0 -24
  120. data/manual/layout/layout.rb +0 -27
  121. data/manual/layout/simple_grid.rb +0 -22
  122. data/manual/outline/add_subsection_to.rb +0 -60
  123. data/manual/outline/insert_section_after.rb +0 -46
  124. data/manual/outline/outline.rb +0 -33
  125. data/manual/outline/sections_and_pages.rb +0 -66
  126. data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
  127. data/manual/repeatable_content/page_numbering.rb +0 -55
  128. data/manual/repeatable_content/repeatable_content.rb +0 -35
  129. data/manual/repeatable_content/repeater.rb +0 -54
  130. data/manual/repeatable_content/stamp.rb +0 -40
  131. data/manual/security/encryption.rb +0 -28
  132. data/manual/security/permissions.rb +0 -41
  133. data/manual/security/security.rb +0 -28
  134. data/manual/table.rb +0 -16
  135. data/manual/text/alignment.rb +0 -43
  136. data/manual/text/color.rb +0 -24
  137. data/manual/text/column_box.rb +0 -30
  138. data/manual/text/fallback_fonts.rb +0 -41
  139. data/manual/text/font.rb +0 -40
  140. data/manual/text/font_size.rb +0 -44
  141. data/manual/text/font_style.rb +0 -22
  142. data/manual/text/formatted_callbacks.rb +0 -65
  143. data/manual/text/formatted_text.rb +0 -58
  144. data/manual/text/free_flowing_text.rb +0 -50
  145. data/manual/text/inline.rb +0 -40
  146. data/manual/text/kerning_and_character_spacing.rb +0 -38
  147. data/manual/text/leading.rb +0 -24
  148. data/manual/text/line_wrapping.rb +0 -60
  149. data/manual/text/paragraph_indentation.rb +0 -32
  150. data/manual/text/positioned_text.rb +0 -37
  151. data/manual/text/registering_families.rb +0 -51
  152. data/manual/text/rendering_and_color.rb +0 -36
  153. data/manual/text/right_to_left_text.rb +0 -54
  154. data/manual/text/rotation.rb +0 -47
  155. data/manual/text/single_usage.rb +0 -36
  156. data/manual/text/text.rb +0 -75
  157. data/manual/text/text_box_excess.rb +0 -35
  158. data/manual/text/text_box_extensions.rb +0 -48
  159. data/manual/text/text_box_overflow.rb +0 -49
  160. data/manual/text/utf8.rb +0 -27
  161. data/manual/text/win_ansi_charset.rb +0 -62
  162. data/prawn.gemspec +0 -57
  163. data/spec/data/curves.pdf +0 -66
  164. data/spec/extensions/encoding_helpers.rb +0 -11
  165. data/spec/prawn/document/bounding_box_spec.rb +0 -546
  166. data/spec/prawn/document/column_box_spec.rb +0 -75
  167. data/spec/prawn/document/security_spec.rb +0 -176
  168. data/spec/prawn/document_annotations_spec.rb +0 -76
  169. data/spec/prawn/document_destinations_spec.rb +0 -15
  170. data/spec/prawn/document_grid_spec.rb +0 -99
  171. data/spec/prawn/document_reference_spec.rb +0 -27
  172. data/spec/prawn/document_span_spec.rb +0 -36
  173. data/spec/prawn/document_spec.rb +0 -802
  174. data/spec/prawn/font_metric_cache_spec.rb +0 -54
  175. data/spec/prawn/font_spec.rb +0 -542
  176. data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
  177. data/spec/prawn/graphics/transparency_spec.rb +0 -81
  178. data/spec/prawn/graphics_spec.rb +0 -837
  179. data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
  180. data/spec/prawn/image_handler_spec.rb +0 -53
  181. data/spec/prawn/images/jpg_spec.rb +0 -20
  182. data/spec/prawn/images/png_spec.rb +0 -283
  183. data/spec/prawn/images_spec.rb +0 -224
  184. data/spec/prawn/measurements_extensions_spec.rb +0 -24
  185. data/spec/prawn/outline_spec.rb +0 -412
  186. data/spec/prawn/repeater_spec.rb +0 -165
  187. data/spec/prawn/soft_mask_spec.rb +0 -74
  188. data/spec/prawn/stamp_spec.rb +0 -172
  189. data/spec/prawn/text/box_spec.rb +0 -1112
  190. data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
  191. data/spec/prawn/text/formatted/box_spec.rb +0 -846
  192. data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
  193. data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -494
  194. data/spec/prawn/text/formatted/parser_spec.rb +0 -697
  195. data/spec/prawn/text_draw_text_spec.rb +0 -149
  196. data/spec/prawn/text_rendering_mode_spec.rb +0 -48
  197. data/spec/prawn/text_spacing_spec.rb +0 -95
  198. data/spec/prawn/text_spec.rb +0 -603
  199. data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
  200. data/spec/prawn/transformation_stack_spec.rb +0 -66
  201. data/spec/prawn/view_spec.rb +0 -63
  202. data/spec/prawn_manual_spec.rb +0 -35
  203. data/spec/spec_helper.rb +0 -48
@@ -10,139 +10,172 @@
10
10
  module Prawn
11
11
  module Text
12
12
  module Formatted
13
- # @group Stable API
14
-
15
- # Draws the requested formatted text into a box. When the text overflows
16
- # the rectangle shrink to fit or truncate the text. Text boxes are
17
- # independent of the document y position.
18
- #
19
- # == Formatted Text Array
20
- #
21
- # Formatted text is comprised of an array of hashes, where each hash
22
- # defines text and format information. As of the time of writing, the
23
- # following hash options are supported:
24
- #
25
- # <tt>:text</tt>::
26
- # the text to format according to the other hash options
27
- # <tt>:styles</tt>::
28
- # an array of styles to apply to this text. Available styles include
29
- # :bold, :italic, :underline, :strikethrough, :subscript, and
30
- # :superscript
31
- # <tt>:size</tt>::
32
- # a number denoting the font size to apply to this text
33
- # <tt>:character_spacing</tt>::
34
- # a number denoting how much to increase or decrease the default
35
- # spacing between characters
36
- # <tt>:font</tt>::
37
- # the name of a font. The name must be an AFM font with the desired
38
- # faces or must be a font that is already registered using
39
- # Prawn::Document#font_families
40
- # <tt>:color</tt>::
41
- # anything compatible with Prawn::Graphics::Color#fill_color and
42
- # Prawn::Graphics::Color#stroke_color
43
- # <tt>:link</tt>::
44
- # a URL to which to create a link. A clickable link will be created
45
- # to that URL. Note that you must explicitly underline and color using
46
- # the appropriate tags if you which to draw attention to the link
47
- # <tt>:anchor</tt>::
48
- # a destination that has already been or will be registered using
49
- # PDF::Core::Destinations#add_dest. A clickable link will be
50
- # created to that destination. Note that you must explicitly underline
51
- # and color using the appropriate tags if you which to draw attention
52
- # to the link
53
- # <tt>:local</tt>::
54
- # a file or application to be opened locally. A clickable link will be
55
- # created to the provided local file or application. If the file is
56
- # another PDF, it will be opened in a new window. Note that you must
57
- # explicitly underline and color using the appropriate tags if you
58
- # which to draw attention to the link
59
- # <tt>:draw_text_callback</tt>:
60
- # if provided, this Proc will be called instead of #draw_text! once
61
- # per fragment for every low-level addition of text to the page.
62
- # <tt>:callback</tt>::
63
- # an object (or array of such objects) with two methods:
64
- # #render_behind and #render_in_front, which are called immediately
65
- # prior to and immediately after rendring the text fragment and which
66
- # are passed the fragment as an argument
67
- #
68
- # == Example
69
- #
70
- # formatted_text_box([{ :text => "hello" },
71
- # { :text => "world",
72
- # :size => 24,
73
- # :styles => [:bold, :italic] }])
74
- #
75
- # == Options
76
- #
77
- # Accepts the same options as Text::Box with the below exceptions
78
- #
79
- # == Returns
80
- #
81
- # Returns a formatted text array representing any text that did not print
82
- # under the current settings.
83
- #
84
- # == Exceptions
85
- #
86
- # Raises "Bad font family" if no font family is defined for the current
87
- # font
88
- #
89
- # Raises <tt>Prawn::Errors::CannotFit</tt> if not wide enough to print
90
- # any text
91
- #
92
- def formatted_text_box(array, options = {})
93
- Text::Formatted::Box.new(array, options.merge(document: self)).render
94
- end
95
-
96
- # Generally, one would use the Prawn::Text::Formatted#formatted_text_box
97
- # convenience method. However, using Text::Formatted::Box.new in
98
- # conjunction with #render(:dry_run => true) enables one to do look-ahead
99
- # calculations prior to placing text on the page, or to determine how much
100
- # vertical space was consumed by the printed text
13
+ # Formatted text box.
101
14
  #
15
+ # Generally, one would use the {Prawn::Text::Formatted#formatted_text_box}
16
+ # convenience method. However, using `Text::Formatted::Box.new` in
17
+ # conjunction with `#render(dry_run: true)` enables one to do calculations
18
+ # prior to placing text on the page, or to determine how much vertical
19
+ # space was consumed by the printed text
102
20
  class Box
103
21
  include Prawn::Text::Formatted::Wrap
104
22
 
105
23
  # @group Experimental API
106
24
 
107
- # The text that was successfully printed (or, if <tt>dry_run</tt> was
108
- # used, the text that would have been successfully printed)
25
+ # The text that was successfully printed (or, if `:dry_run` was
26
+ # used, the text that would have been successfully printed).
27
+ # @return [Array<Hash>]
109
28
  attr_reader :text
110
29
 
111
- # True if nothing printed (or, if <tt>dry_run</tt> was
112
- # used, nothing would have been successfully printed)
30
+ # True if nothing printed (or, if `:dry_run` was used, nothing would
31
+ # have been successfully printed).
32
+ #
33
+ # @return [Boolean]
113
34
  def nothing_printed?
114
35
  @nothing_printed
115
36
  end
116
37
 
117
- # True if everything printed (or, if <tt>dry_run</tt> was
118
- # used, everything would have been successfully printed)
38
+ # True if everything printed (or, if `:dry_run` was used, everything
39
+ # would have been successfully printed).
40
+ #
41
+ # @return [Boolean]
119
42
  def everything_printed?
120
43
  @everything_printed
121
44
  end
122
45
 
123
- # The upper left corner of the text box
46
+ # The upper left corner of the text box.
47
+ # @return [Array(Number, Number)]
124
48
  attr_reader :at
125
- # The line height of the last line printed
49
+
50
+ # The line height of the last line printed.
51
+ # @return [Number]
126
52
  attr_reader :line_height
127
- # The height of the ascender of the last line printed
53
+
54
+ # The height of the ascender of the last line printed.
55
+ # @return [Number]
128
56
  attr_reader :ascender
129
- # The height of the descender of the last line printed
57
+
58
+ # The height of the descender of the last line printed.
59
+ # @return [Number]
130
60
  attr_reader :descender
131
- # The leading used during printing
61
+
62
+ # The leading used during printing.
63
+ # @return [Number]
132
64
  attr_reader :leading
133
65
 
66
+ # Gap between adjacent lines of text.
67
+ #
68
+ # @return [Number]
134
69
  def line_gap
135
70
  line_height - (ascender + descender)
136
71
  end
137
72
 
138
73
  # See Prawn::Text#text_box for valid options
139
74
  #
75
+ # @param formatted_text [Array<Hash{Symbol => any}>]
76
+ # Formatted text is an array of hashes, where each hash defines text
77
+ # and format information. The following hash options are supported:
78
+ #
79
+ # - `:text` --- the text to format according to the other hash
80
+ # options.
81
+ # - `:styles` --- an array of styles to apply to this text. Available
82
+ # styles include `:bold`, `:italic`, `:underline`, `:strikethrough`,
83
+ # `:subscript`, and `:superscript`.
84
+ # - `:size` ---a number denoting the font size to apply to this text.
85
+ # - `:character_spacing` --- a number denoting how much to increase or
86
+ # decrease the default spacing between characters.
87
+ # - `:font` --- the name of a font. The name must be an AFM font with
88
+ # the desired faces or must be a font that is already registered
89
+ # using {Prawn::Document#font_families}.
90
+ # - `:color` --- anything compatible with
91
+ # {Prawn::Graphics::Color#fill_color} and
92
+ # {Prawn::Graphics::Color#stroke_color}.
93
+ # - :link` --- a URL to which to create a link. A clickable link will
94
+ # be created to that URL. Note that you must explicitly underline
95
+ # and color using the appropriate tags if you which to draw
96
+ # attention to the link.
97
+ # - `:anchor` --- a destination that has already been or will be
98
+ # registered using `PDF::Core::Destinations#add_dest`. A clickable
99
+ # link will be created to that destination. Note that you must
100
+ # explicitly underline and color using the appropriate tags if you
101
+ # which to draw attention to the link.
102
+ # - `:local` --- a file or application to be opened locally.
103
+ # A clickable link will be created to the provided local file or
104
+ # application. If the file is another PDF, it will be opened in
105
+ # a new window. Note that you must explicitly underline and color
106
+ # using the appropriate options if you which to draw attention to
107
+ # the link.
108
+ # - `:draw_text_callback` --- if provided, this Proc will be called
109
+ # instead of {Prawn::Document#draw_text!} once per fragment for
110
+ # every low-level addition of text to the page.
111
+ # - `:callback` --- an object (or array of such objects) with two
112
+ # methods: `render_behind` and `render_in_front`, which are called
113
+ # immediately prior to and immediately after rendering the text
114
+ # fragment and which are passed the fragment as an argument.
115
+ # @param options [Hash{Symbol => any}]
116
+ # @option options :document [Prawn::Document] Owning document.
117
+ # @option options :kerning [Boolean]
118
+ # (value of document.default_kerning?)
119
+ # Whether or not to use kerning (if it is available with the current
120
+ # font).
121
+ # @option options :size [Number] (current font size)
122
+ # The font size to use.
123
+ # @option options :character_spacing [Number] (0)
124
+ # The amount of space to add to or remove from the default character
125
+ # spacing.
126
+ # @option options :disable_wrap_by_char [Boolean] (false)
127
+ # Whether or not to prevent mid-word breaks when text does not fit in
128
+ # box.
129
+ # @option options :mode [Symbol] (:fill)
130
+ # The text rendering mode. See documentation for
131
+ # {Prawn::Document#text_rendering_mode} for a list of valid options.
132
+ # @option option :style [Symbol] (current style)
133
+ # The style to use. The requested style must be part of the current
134
+ # font family.
135
+ # @option option :at [Array(Number, Number)] (bounds top left corner)
136
+ # The upper left corner of the box.
137
+ # @option options :width [Number] (bounds.right - at[0])
138
+ # The width of the box.
139
+ # @option options :height [Number] (default_height())
140
+ # The height of the box.
141
+ # @option options :direction [:ltr, :rtl]
142
+ # (value of document.text_direction)
143
+ # Direction of the text (left-to-right or right-to-left).
144
+ # @option options :fallback_fonts [Array<String>]
145
+ # An array of font names. Each name must be the name of an AFM font or
146
+ # the name that was used to register a family of external fonts (see
147
+ # {Prawn::Document#font_families}). If present, then each glyph will
148
+ # be rendered using the first font that includes the glyph, starting
149
+ # with the current font and then moving through `:fallback_fonts`.
150
+ # @option options :align [:left, :center, :right, :justify]
151
+ # (:left if direction is :ltr, :right if direction is :rtl)
152
+ # Alignment within the bounding box.
153
+ # @option options :valign [:top, :center, :bottom] (:top)
154
+ # Vertical alignment within the bounding box.
155
+ # @option options :rotate [Number]
156
+ # The angle to rotate the text.
157
+ # @option options :rotate_around
158
+ # [:center, :upper_left, :upper_right, :lower_right, :lower_left]
159
+ # (:upper_left)
160
+ # The point around which to rotate the text.
161
+ # @option options :leading [Number] (value of document.default_leading)
162
+ # Additional space between lines.
163
+ # @option options :single_line [Boolean] (false)
164
+ # If true, then only the first line will be drawn.
165
+ # @option options :overflow [:truncate, :shrink_to_fit, :expand]
166
+ # (:truncate)
167
+ # This controls the behavior when the amount of text exceeds the
168
+ # available space.
169
+ # @option options :min_font_size [Number] (5)
170
+ # The minimum font size to use when `:overflow` is set to
171
+ # `:shrink_to_fit` (that is the font size will not be reduced to less
172
+ # than this value, even if it means that some text will be cut off).
140
173
  def initialize(formatted_text, options = {})
141
174
  @inked = false
142
175
  Prawn.verify_options(valid_options, options)
143
176
  options = options.dup
144
177
 
145
- self.class.extensions.reverse_each { |e| extend e }
178
+ self.class.extensions.reverse_each { |e| extend(e) }
146
179
 
147
180
  @overflow = options[:overflow] || :truncate
148
181
  @disable_wrap_by_char = options[:disable_wrap_by_char]
@@ -158,7 +191,7 @@ module Prawn
158
191
  options[:at] || [@document.bounds.left, @document.bounds.top]
159
192
  ).dup
160
193
  @width = options[:width] ||
161
- @document.bounds.right - @at[0]
194
+ (@document.bounds.right - @at[0])
162
195
  @height = options[:height] || default_height
163
196
  @align = options[:align] ||
164
197
  (@direction == :rtl ? :right : :left)
@@ -191,23 +224,30 @@ module Prawn
191
224
  @options = {
192
225
  kerning: options[:kerning],
193
226
  size: options[:size],
194
- style: options[:style]
227
+ style: options[:style],
195
228
  }
196
229
 
197
230
  super(formatted_text, options)
198
231
  end
199
232
 
200
233
  # Render text to the document based on the settings defined in
201
- # initialize.
234
+ # constructor.
202
235
  #
203
- # In order to facilitate look-ahead calculations, <tt>render</tt>
204
- # accepts a <tt>:dry_run => true</tt> option. If provided, then
205
- # everything is executed as if rendering, with the exception that
206
- # nothing is drawn on the page. Useful for look-ahead computations of
207
- # height, unprinted text, etc.
208
- #
209
- # Returns any text that did not print under the current settings.
236
+ # In order to facilitate look-ahead calculations, this method accepts
237
+ # a `dry_run: true` option. If provided, then everything is executed as
238
+ # if rendering, with the exception that nothing is drawn on the page.
239
+ # Useful for look-ahead computations of height, unprinted text, etc.
210
240
  #
241
+ # @param flags [Hash{Symbol => any}]
242
+ # @option flags :dry_run [Boolean] (false)
243
+ # Do not draw the text. Everything else is done.
244
+ # @return [Array<Hash>]
245
+ # A formatted text array representing any text that did not print
246
+ # under the current settings.
247
+ # @raise [Prawn::Text::Formatted::Arranger::BadFontFamily]
248
+ # If no font family is defined for the current font.
249
+ # @raise [Prawn::Errors::CannotFit]
250
+ # If not wide enough to print any text.
211
251
  def render(flags = {})
212
252
  unprinted_text = []
213
253
 
@@ -222,11 +262,12 @@ module Prawn
222
262
  shrink_to_fit(text) if @overflow == :shrink_to_fit
223
263
  process_vertical_alignment(text)
224
264
  @inked = true unless flags[:dry_run]
225
- unprinted_text = if @rotate != 0 && @inked
226
- render_rotated(text)
227
- else
228
- wrap(text)
229
- end
265
+ unprinted_text =
266
+ if @rotate != 0 && @inked
267
+ render_rotated(text)
268
+ else
269
+ wrap(text)
270
+ end
230
271
  @inked = false
231
272
  end
232
273
  end
@@ -238,38 +279,45 @@ module Prawn
238
279
  end
239
280
  end
240
281
 
241
- # The width available at this point in the box
282
+ # The width available at this point in the box.
242
283
  #
284
+ # @return [Number]
243
285
  def available_width
244
286
  @width
245
287
  end
246
288
 
247
- # The height actually used during the previous <tt>render</tt>
289
+ # The height actually used during the previous {render}.
248
290
  #
291
+ # @return [Number]
249
292
  def height
250
293
  return 0 if @baseline_y.nil? || @descender.nil?
251
294
 
252
295
  (@baseline_y - @descender).abs
253
296
  end
254
297
 
255
- # <tt>fragment</tt> is a Prawn::Text::Formatted::Fragment object
256
- #
298
+ # @private
299
+ # @param fragment [Prawn::Text::Formatted::Fragment]
300
+ # @param accumulated_width [Number]
301
+ # @param line_width [Number]
302
+ # @param word_spacing [Number]
303
+ # @return [void]
257
304
  def draw_fragment(
258
305
  fragment, accumulated_width = 0, line_width = 0, word_spacing = 0
259
- ) #:nodoc:
306
+ )
260
307
  case @align
261
308
  when :left
262
309
  x = @at[0]
263
310
  when :center
264
- x = @at[0] + @width * 0.5 - line_width * 0.5
311
+ x = @at[0] + (@width * 0.5) - (line_width * 0.5)
265
312
  when :right
266
313
  x = @at[0] + @width - line_width
267
314
  when :justify
268
- x = if @direction == :ltr
269
- @at[0]
270
- else
271
- @at[0] + @width - line_width
272
- end
315
+ x =
316
+ if @direction == :ltr
317
+ @at[0]
318
+ else
319
+ @at[0] + @width - line_width
320
+ end
273
321
  else
274
322
  raise ArgumentError,
275
323
  'align must be one of :left, :right, :center or :justify symbols'
@@ -290,13 +338,15 @@ module Prawn
290
338
  @document.word_spacing(word_spacing) do
291
339
  if @draw_text_callback
292
340
  @draw_text_callback.call(
293
- fragment.text, at: [x, y],
294
- kerning: @kerning
341
+ fragment.text,
342
+ at: [x, y],
343
+ kerning: @kerning,
295
344
  )
296
345
  else
297
346
  @document.draw_text!(
298
- fragment.text, at: [x, y],
299
- kerning: @kerning
347
+ fragment.text,
348
+ at: [x, y],
349
+ kerning: @kerning,
300
350
  )
301
351
  end
302
352
  end
@@ -307,42 +357,48 @@ module Prawn
307
357
 
308
358
  # @group Extension API
309
359
 
310
- # Example (see Prawn::Text::Core::Formatted::Wrap for what is required
311
- # of the wrap method if you want to override the default wrapping
312
- # algorithm):
313
- #
360
+ # Text box extensions.
314
361
  #
315
- # module MyWrap
316
- #
317
- # def wrap(array)
318
- # initialize_wrap([{ :text => 'all your base are belong to us' }])
319
- # @line_wrap.wrap_line(:document => @document,
320
- # :kerning => @kerning,
321
- # :width => 10000,
322
- # :arranger => @arranger)
323
- # fragment = @arranger.retrieve_fragment
324
- # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
325
- # []
326
- # end
362
+ # Example:
327
363
  #
364
+ # ```ruby
365
+ # module MyWrap
366
+ # def wrap(array)
367
+ # initialize_wrap([{ text: 'all your base are belong to us' }])
368
+ # @line_wrap.wrap_line(
369
+ # document: @document,
370
+ # kerning: @kerning,
371
+ # width: 10000,
372
+ # arranger: @arranger
373
+ # )
374
+ # fragment = @arranger.retrieve_fragment
375
+ # format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)
376
+ # []
328
377
  # end
378
+ # end
329
379
  #
330
- # Prawn::Text::Formatted::Box.extensions << MyWrap
380
+ # Prawn::Text::Formatted::Box.extensions << MyWrap
331
381
  #
332
- # box = Prawn::Text::Formatted::Box.new('hello world')
333
- # box.render('why can't I print anything other than' +
334
- # '"all your base are belong to us"?')
382
+ # box = Prawn::Text::Formatted::Box.new('hello world')
383
+ # box.render("why can't I print anything other than" +
384
+ # '"all your base are belong to us"?')
385
+ # ```
335
386
  #
387
+ # See {Prawn::Text::Formatted::Wrap} for what is required of the
388
+ # wrap method if you want to override the default wrapping algorithm.
336
389
  #
390
+ # @return [Array<Module>]
337
391
  def self.extensions
338
392
  @extensions ||= []
339
393
  end
340
394
 
341
395
  # @private
342
396
  def self.inherited(base)
397
+ super
343
398
  extensions.each { |e| base.extensions << e }
344
399
  end
345
400
 
401
+ # @private
346
402
  def valid_options
347
403
  PDF::Core::Text::VALID_OPTIONS + %i[
348
404
  at
@@ -371,7 +427,7 @@ module Prawn
371
427
  end
372
428
 
373
429
  def original_text
374
- @original_array.collect(&:dup)
430
+ @original_array.map(&:dup)
375
431
  end
376
432
 
377
433
  def original_text=(formatted_text)
@@ -414,6 +470,8 @@ module Prawn
414
470
 
415
471
  original_font = @document.font.family
416
472
  fragment_font = hash[:font] || original_font
473
+ fragment_font_options =
474
+ (fragment_font_style = font_style(hash[:styles])) == :normal ? {} : { style: fragment_font_style }
417
475
 
418
476
  fallback_fonts = @fallback_fonts.dup
419
477
  # always default back to the current font if the glyph is missing from
@@ -426,9 +484,10 @@ module Prawn
426
484
  find_font_for_this_glyph(
427
485
  char,
428
486
  fragment_font,
429
- fallback_fonts.dup
487
+ fallback_fonts.dup,
488
+ fragment_font_options,
430
489
  ),
431
- char
490
+ char,
432
491
  ]
433
492
  end
434
493
  end
@@ -443,12 +502,26 @@ module Prawn
443
502
  form_fragments_from_like_font_glyph_pairs(font_glyph_pairs, hash)
444
503
  end
445
504
 
446
- def find_font_for_this_glyph(char, current_font, fallback_fonts)
447
- @document.font(current_font)
505
+ def font_style(styles)
506
+ if styles
507
+ if styles.include?(:bold)
508
+ styles.include?(:italic) ? :bold_italic : :bold
509
+ elsif styles.include?(:italic)
510
+ :italic
511
+ else
512
+ :normal
513
+ end
514
+ else
515
+ :normal
516
+ end
517
+ end
518
+
519
+ def find_font_for_this_glyph(char, current_font, fallback_fonts, current_font_options = {})
520
+ @document.font(current_font, current_font_options)
448
521
  if fallback_fonts.empty? || @document.font.glyph_present?(char)
449
522
  current_font
450
523
  else
451
- find_font_for_this_glyph(char, fallback_fonts.shift, fallback_fonts)
524
+ find_font_for_this_glyph(char, fallback_fonts.shift, fallback_fonts, current_font_options)
452
525
  end
453
526
  end
454
527
 
@@ -514,6 +587,9 @@ module Prawn
514
587
  @at[1] -= (@height - height + @descender) * 0.5
515
588
  when :bottom
516
589
  @at[1] -= (@height - height)
590
+ else
591
+ raise ArgumentError,
592
+ 'valign must be one of :left, :right or :center symbols'
517
593
  end
518
594
 
519
595
  @height = height
@@ -554,8 +630,8 @@ module Prawn
554
630
 
555
631
  case @rotate_around
556
632
  when :center
557
- x = @at[0] + @width * 0.5
558
- y = @at[1] - @height * 0.5
633
+ x = @at[0] + (@width * 0.5)
634
+ y = @at[1] - (@height * 0.5)
559
635
  when :upper_right
560
636
  x = @at[0] + @width
561
637
  y = @at[1]
@@ -602,8 +678,8 @@ module Prawn
602
678
  A: {
603
679
  Type: :Action,
604
680
  S: :URI,
605
- URI: PDF::Core::LiteralString.new(fragment.link)
606
- }
681
+ URI: PDF::Core::LiteralString.new(fragment.link),
682
+ },
607
683
  )
608
684
  end
609
685
 
@@ -614,7 +690,7 @@ module Prawn
614
690
  @document.link_annotation(
615
691
  box,
616
692
  Border: [0, 0, 0],
617
- Dest: fragment.anchor
693
+ Dest: fragment.anchor,
618
694
  )
619
695
  end
620
696
 
@@ -629,8 +705,8 @@ module Prawn
629
705
  Type: :Action,
630
706
  S: :Launch,
631
707
  F: PDF::Core::LiteralString.new(fragment.local),
632
- NewWindow: true
633
- }
708
+ NewWindow: true,
709
+ },
634
710
  )
635
711
  end
636
712