prawn 2.3.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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