prawn 2.4.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 +213 -141
  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 +20 -18
  7. data/lib/prawn/document.rb +257 -171
  8. data/lib/prawn/encoding.rb +2 -5
  9. data/lib/prawn/errors.rb +23 -34
  10. data/lib/prawn/font.rb +248 -135
  11. data/lib/prawn/font_metric_cache.rb +11 -10
  12. data/lib/prawn/fonts/afm.rb +85 -45
  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 +305 -93
  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 +57 -34
  22. data/lib/prawn/graphics/dash.rb +45 -42
  23. data/lib/prawn/graphics/join_style.rb +17 -11
  24. data/lib/prawn/graphics/patterns.rb +190 -69
  25. data/lib/prawn/graphics/transformation.rb +48 -41
  26. data/lib/prawn/graphics/transparency.rb +16 -40
  27. data/lib/prawn/graphics.rb +363 -253
  28. data/lib/prawn/grid.rb +184 -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 +42 -19
  32. data/lib/prawn/images/png.rb +92 -41
  33. data/lib/prawn/images.rb +44 -57
  34. data/lib/prawn/measurement_extensions.rb +39 -8
  35. data/lib/prawn/measurements.rb +60 -5
  36. data/lib/prawn/outline.rb +114 -108
  37. data/lib/prawn/repeater.rb +51 -35
  38. data/lib/prawn/security/arcfour.rb +4 -4
  39. data/lib/prawn/security.rb +75 -70
  40. data/lib/prawn/soft_mask.rb +42 -30
  41. data/lib/prawn/stamp.rb +38 -42
  42. data/lib/prawn/text/box.rb +146 -96
  43. data/lib/prawn/text/formatted/arranger.rb +87 -26
  44. data/lib/prawn/text/formatted/box.rb +221 -150
  45. data/lib/prawn/text/formatted/fragment.rb +130 -14
  46. data/lib/prawn/text/formatted/line_wrap.rb +33 -24
  47. data/lib/prawn/text/formatted/parser.rb +112 -72
  48. data/lib/prawn/text/formatted/wrap.rb +12 -17
  49. data/lib/prawn/text/formatted.rb +75 -0
  50. data/lib/prawn/text.rb +441 -196
  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 +68 -53
  55. data/lib/prawn.rb +23 -18
  56. data.tar.gz.sig +0 -0
  57. metadata +54 -177
  58. metadata.gz.sig +0 -0
  59. data/.yardopts +0 -10
  60. data/Gemfile +0 -5
  61. data/Rakefile +0 -25
  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 -29
  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 -23
  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 -38
  94. data/manual/graphics/gradients.rb +0 -43
  95. data/manual/graphics/graphics.rb +0 -64
  96. data/manual/graphics/helper.rb +0 -34
  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 -29
  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 -30
  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 -43
  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 -25
  142. data/manual/text/formatted_callbacks.rb +0 -70
  143. data/manual/text/formatted_text.rb +0 -61
  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 -31
  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 -52
  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 -51
  160. data/manual/text/utf8.rb +0 -27
  161. data/manual/text/win_ansi_charset.rb +0 -62
  162. data/prawn.gemspec +0 -51
  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 -550
  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 -44
  173. data/spec/prawn/document_spec.rb +0 -805
  174. data/spec/prawn/font_metric_cache_spec.rb +0 -54
  175. data/spec/prawn/font_spec.rb +0 -544
  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 -872
  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 -229
  184. data/spec/prawn/measurements_extensions_spec.rb +0 -24
  185. data/spec/prawn/outline_spec.rb +0 -512
  186. data/spec/prawn/repeater_spec.rb +0 -166
  187. data/spec/prawn/soft_mask_spec.rb +0 -74
  188. data/spec/prawn/stamp_spec.rb +0 -173
  189. data/spec/prawn/text/box_spec.rb +0 -1110
  190. data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
  191. data/spec/prawn/text/formatted/box_spec.rb +0 -849
  192. data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
  193. data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -495
  194. data/spec/prawn/text/formatted/parser_spec.rb +0 -697
  195. data/spec/prawn/text_draw_text_spec.rb +0 -150
  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
@@ -1,26 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # bounding_box.rb : Implements a mechanism for shifting the coordinate space
4
- #
5
- # Copyright May 2008, Gregory Brown. All Rights Reserved.
6
- #
7
- # This is free software. Please see the LICENSE and COPYING files for details.
8
-
9
3
  module Prawn
10
- class Document
4
+ class Document # rubocop: disable Style/Documentation
11
5
  # @group Stable API
12
6
 
13
- # :call-seq:
14
- # bounding_box(point, options={}, &block)
15
- #
16
7
  # A bounding box serves two important purposes:
17
8
  # * Provide bounds for flowing text, starting at a given point
18
- # * Translate the origin (0,0) for graphics primitives
19
- #
20
- # A point and :width must be provided. :height is optional.
21
- # (See stretchyness below)
9
+ # * Translate the origin (0, 0) for graphics primitives
22
10
  #
23
- # ==Positioning
11
+ # #### Positioning
24
12
  #
25
13
  # Bounding boxes are positioned relative to their top left corner and
26
14
  # the width measurement is towards the right and height measurement is
@@ -28,22 +16,26 @@ module Prawn
28
16
  #
29
17
  # Usage:
30
18
  #
31
- # * Bounding box 100pt x 100pt in the absolute bottom left of the
19
+ # * Bounding box 100pt×100pt in the absolute bottom left of the
32
20
  # containing box:
33
21
  #
34
- # pdf.bounding_box([0,100], :width => 100, :height => 100)
22
+ # ```ruby
23
+ # pdf.bounding_box([0, 100], width: 100, height: 100)
35
24
  # stroke_bounds
36
25
  # end
26
+ # ```
37
27
  #
38
- # * Bounding box 200pt x 400pt high in the center of the page:
28
+ # * Bounding box 200pt×400pt high in the center of the page:
39
29
  #
30
+ # ```ruby
40
31
  # x_pos = ((bounds.width / 2) - 150)
41
32
  # y_pos = ((bounds.height / 2) + 200)
42
- # pdf.bounding_box([x_pos, y_pos], :width => 300, :height => 400) do
33
+ # pdf.bounding_box([x_pos, y_pos], width: 300, height: 400) do
43
34
  # stroke_bounds
44
35
  # end
36
+ # ```
45
37
  #
46
- # ==Flowing Text
38
+ # #### Flowing Text
47
39
  #
48
40
  # When flowing text, the usage of a bounding box is simple. Text will
49
41
  # begin at the point specified, flowing the width of the bounding box.
@@ -54,17 +46,19 @@ module Prawn
54
46
  #
55
47
  # Usage:
56
48
  #
57
- # pdf.bounding_box([100,500], :width => 100, :height => 300) do
58
- # pdf.text "This text will flow in a very narrow box starting" +
59
- # "from [100,500]. The pointer will then be moved to [100,200]" +
60
- # "and return to the margin_box"
61
- # end
49
+ # ```ruby
50
+ # pdf.bounding_box([100, 500], width: 100, height: 300) do
51
+ # pdf.text "This text will flow in a very narrow box starting" +
52
+ # "from [100, 500]. The pointer will then be moved to [100, 200]" +
53
+ # "and return to the margin_box"
54
+ # end
55
+ # ```
62
56
  #
63
57
  # Note, this is a low level tool and is designed primarily for building
64
- # other abstractions. If you just need to flow text on the page, you
65
- # will want to look at span() and text_box() instead
58
+ # other abstractions. If you just need to flow text on the page, you
59
+ # will want to look at {span} and {text_box} instead.
66
60
  #
67
- # ==Translating Coordinates
61
+ # #### Translating Coordinates
68
62
  #
69
63
  # When translating coordinates, the idea is to allow the user to draw
70
64
  # relative to the origin, and then translate their drawing to a specified
@@ -74,14 +68,18 @@ module Prawn
74
68
  # Take for example two triangles which share one point, drawn from the
75
69
  # origin:
76
70
  #
77
- # pdf.polygon [0,250], [0,0], [150,100]
78
- # pdf.polygon [100,0], [150,100], [200,0]
71
+ # ```ruby
72
+ # pdf.polygon [0, 250], [0, 0], [150, 100]
73
+ # pdf.polygon [100, 0], [150, 100], [200, 0]
74
+ # ```
79
75
  #
80
76
  # It would be easy enough to translate these triangles to another point,
81
- # e.g [200,200]
77
+ # e.g `[200, 200]`
82
78
  #
83
- # pdf.polygon [200,450], [200,200], [350,300]
84
- # pdf.polygon [300,200], [350,300], [400,200]
79
+ # ```ruby
80
+ # pdf.polygon [200, 450], [200, 200], [350, 300]
81
+ # pdf.polygon [300, 200], [350, 300], [400, 200]
82
+ # ```
85
83
  #
86
84
  # However, each time you want to move the drawing, you'd need to alter
87
85
  # every point in the drawing calls, which as you might imagine, can become
@@ -90,46 +88,51 @@ module Prawn
90
88
  # If instead, we think of the drawing as being bounded by a box, we can
91
89
  # see that the image is 200 points wide by 250 points tall.
92
90
  #
93
- # To translate it to a new origin, we simply select a point at (x,y+height)
91
+ # To translate it to a new origin, we simply select a point at
92
+ # (x, y + height).
94
93
  #
95
- # Using the [200,200] example:
94
+ # Using the [200, 200] example:
96
95
  #
97
- # pdf.bounding_box([200,450], :width => 200, :height => 250) do
98
- # pdf.stroke do
99
- # pdf.polygon [0,250], [0,0], [150,100]
100
- # pdf.polygon [100,0], [150,100], [200,0]
101
- # end
96
+ # ```ruby
97
+ # pdf.bounding_box([200, 450], width: 200, height: 250) do
98
+ # pdf.stroke do
99
+ # pdf.polygon [0, 250], [0, 0], [150, 100]
100
+ # pdf.polygon [100, 0], [150, 100], [200, 0]
102
101
  # end
102
+ # end
103
+ # ```
103
104
  #
104
105
  # Notice that the drawing is still relative to the origin. If we want to
105
106
  # move this drawing around the document, we simply need to recalculate the
106
107
  # top-left corner of the rectangular bounding-box, and all of our graphics
107
108
  # calls remain unmodified.
108
109
  #
109
- # ==Nesting Bounding Boxes
110
+ # #### Nesting Bounding Boxes
110
111
  #
111
112
  # At the top level, bounding boxes are specified relative to the document's
112
- # margin_box (which is itself a bounding box). You can also nest bounding
113
+ # margin_box (which is itself a bounding box). You can also nest bounding
113
114
  # boxes, allowing you to build components which are relative to each other
114
115
  #
115
116
  # Usage:
116
117
  #
117
- # pdf.bounding_box([200,450], :width => 200, :height => 250) do
118
- # pdf.stroke_bounds # Show the containing bounding box
119
- # pdf.bounding_box([50,200], :width => 50, :height => 50) do
120
- # # a 50x50 bounding box that starts 50 pixels left and 50 pixels down
121
- # # the parent bounding box.
122
- # pdf.stroke_bounds
123
- # end
124
- # end
118
+ # ```ruby
119
+ # pdf.bounding_box([200, 450], width: 200, height: 250) do
120
+ # pdf.stroke_bounds # Show the containing bounding box
121
+ # pdf.bounding_box([50, 200], width: 50, height: 50) do
122
+ # # a 50x50 bounding box that starts 50 pixels left and 50 pixels down
123
+ # # the parent bounding box.
124
+ # pdf.stroke_bounds
125
+ # end
126
+ # end
127
+ # ```
125
128
  #
126
- # ==Stretchyness
129
+ # #### Stretchiness
127
130
  #
128
131
  # If you do not specify a height to a bounding box, it will become stretchy
129
132
  # and its height will be calculated automatically as you stretch the box
130
133
  # downwards.
131
134
  #
132
- # pdf.bounding_box([100,400], :width => 400) do
135
+ # pdf.bounding_box([100, 400], width: 400) do
133
136
  # pdf.text("The height of this box is #{pdf.bounds.height}")
134
137
  # pdf.text('this is some text')
135
138
  # pdf.text('this is some more text')
@@ -137,24 +140,37 @@ module Prawn
137
140
  # pdf.text("Now the height of this box is #{pdf.bounds.height}")
138
141
  # end
139
142
  #
140
- # ==Absolute Positioning
143
+ # #### Absolute Positioning
141
144
  #
142
145
  # If you wish to position the bounding boxes at absolute coordinates rather
143
146
  # than relative to the margins or other bounding boxes, you can use canvas()
144
147
  #
145
- # pdf.bounding_box([50,500], :width => 200, :height => 300) do
146
- # pdf.stroke_bounds
147
- # pdf.canvas do
148
- # Positioned outside the containing box at the 'real' (300,450)
149
- # pdf.bounding_box([300,450], :width => 200, :height => 200) do
150
- # pdf.stroke_bounds
151
- # end
152
- # end
153
- # end
148
+ # ```ruby
149
+ # pdf.bounding_box([50, 500], width: 200, height: 300) do
150
+ # pdf.stroke_bounds
151
+ # pdf.canvas do
152
+ # Positioned outside the containing box at the 'real' (300, 450)
153
+ # pdf.bounding_box([300, 450], width: 200, height: 200) do
154
+ # pdf.stroke_bounds
155
+ # end
156
+ # end
157
+ # end
158
+ # ```
154
159
  #
155
160
  # Of course, if you use canvas, you will be responsible for ensuring that
156
161
  # you remain within the printable area of your document.
157
162
  #
163
+ # @overload bounding_box(point, options = {}, &block)
164
+ # @param point [Array(Number, Number)]
165
+ # top left corner of the new bounding box
166
+ # @param options [Hash{Symbol => any}]
167
+ # @option options :width [Number]
168
+ # width of the new bounding box, must be specified.
169
+ # @option options :height [Number]
170
+ # height of the new bounding box, stretchy box if omitted.
171
+ # @yieldparam parent_box [BoundingBox] parent bounding box
172
+ # @yieldreturn [void]
173
+ # @return [void]
158
174
  def bounding_box(point, *args, &block)
159
175
  init_bounding_box(block) do |parent_box|
160
176
  point = map_to_absolute(point)
@@ -165,10 +181,13 @@ module Prawn
165
181
  # A shortcut to produce a bounding box which is mapped to the document's
166
182
  # absolute coordinates, regardless of how things are nested or margin sizes.
167
183
  #
184
+ # @example
168
185
  # pdf.canvas do
169
186
  # pdf.line pdf.bounds.bottom_left, pdf.bounds.top_right
170
187
  # end
171
188
  #
189
+ # @yieldreturn [void]
190
+ # @return [void]
172
191
  def canvas(&block)
173
192
  init_bounding_box(block, hold_position: true) do |_|
174
193
  # Canvas bbox acts like margin_box in that its parent bounds are unset.
@@ -177,7 +196,7 @@ module Prawn
177
196
  nil,
178
197
  [0, page.dimensions[3]],
179
198
  width: page.dimensions[2],
180
- height: page.dimensions[3]
199
+ height: page.dimensions[3],
181
200
  )
182
201
  end
183
202
  end
@@ -219,10 +238,10 @@ module Prawn
219
238
 
220
239
  # Low level layout helper that simplifies coordinate math.
221
240
  #
222
- # See Prawn::Document#bounding_box for a description of what this class
241
+ # See {Prawn::Document#bounding_box} for a description of what this class
223
242
  # is used for.
224
- #
225
243
  class BoundingBox
244
+ # Indicates absence of a reference bounding box of a fixed height.
226
245
  class NoReferenceBounds < StandardError
227
246
  def initialize(message = "Can't find reference bounds: my parent is unset")
228
247
  super
@@ -230,6 +249,12 @@ module Prawn
230
249
  end
231
250
 
232
251
  # @private
252
+ # @param document [Prawn::Document] ownding document
253
+ # @param parent [BoundingBox?] parent bounding box
254
+ # @param point [Array(Number, Number)] coordinates of the top left corner
255
+ # @param options [Hash{Symbol => any}]
256
+ # @option options :width [Number] width
257
+ # @option options :height [Number] optional height
233
258
  def initialize(document, parent, point, options = {})
234
259
  unless options[:width]
235
260
  raise ArgumentError, 'BoundingBox needs the :width option to be set'
@@ -245,52 +270,67 @@ module Prawn
245
270
  @stretched_height = nil
246
271
  end
247
272
 
273
+ # Owning document.
274
+ #
248
275
  # @private
276
+ # @return [Prawn::Document]
277
+ attr_reader :document
249
278
 
250
- attr_reader :document, :parent
251
-
279
+ # Parent bounding box.
280
+ #
252
281
  # @private
282
+ # @return [BoundingBox?]
283
+ attr_reader :parent
284
+
253
285
  # The current indentation of the left side of the bounding box.
286
+ #
287
+ # @private
288
+ # @return [Number]
254
289
  attr_reader :total_left_padding
255
290
 
256
- # @private
257
291
  # The current indentation of the right side of the bounding box.
292
+ #
293
+ # @private
294
+ # @return [Number]
258
295
  attr_reader :total_right_padding
259
296
 
260
- # The translated origin (x,y-height) which describes the location
261
- # of the bottom left corner of the bounding box
297
+ # The translated origin (x, y - height) which describes the location of
298
+ # the bottom left corner of the bounding box.
262
299
  #
263
300
  # @private
301
+ # @return [Array(Number, Number)]
264
302
  def anchor
265
303
  [@x, @y - height]
266
304
  end
267
305
 
268
- # Relative left x-coordinate of the bounding box. (Always 0)
306
+ # Relative left x-coordinate of the bounding box. Always 0.
269
307
  #
270
- # Example, position some text 3 pts from the left of the containing box:
271
- #
272
- # draw_text('hello', :at => [(bounds.left + 3), 0])
308
+ # @example Position some text 3 pts from the left of the containing box
309
+ # draw_text('hello', at: [(bounds.left + 3), 0])
273
310
  #
311
+ # @return [Number]
274
312
  def left
275
313
  0
276
314
  end
277
315
 
278
- # Temporarily adjust the @x coordinate to allow for left_padding
279
- #
280
- # Example:
316
+ # Temporarily adjust the x coordinate to allow for left padding
281
317
  #
282
- # indent 20 do
318
+ # @example
319
+ # indent 20 do
283
320
  # text "20 points in"
284
321
  # indent 30 do
285
322
  # text "50 points in"
286
323
  # end
287
324
  # end
288
325
  #
289
- # indent 20, 20 do
290
- # text "indented on both sides"
291
- # end
326
+ # indent 20, 20 do
327
+ # text "indented on both sides"
328
+ # end
292
329
  #
293
330
  # @private
331
+ # @param left_padding [Number]
332
+ # @param right_padding [Number]
333
+ # @return [void]
294
334
  def indent(left_padding, right_padding = 0)
295
335
  add_left_padding(left_padding)
296
336
  add_right_padding(right_padding)
@@ -301,7 +341,10 @@ module Prawn
301
341
  end
302
342
 
303
343
  # Increase the left padding of the bounding box.
344
+ #
304
345
  # @private
346
+ # @param left_padding [Number]
347
+ # @return [void]
305
348
  def add_left_padding(left_padding)
306
349
  @total_left_padding += left_padding
307
350
  @x += left_padding
@@ -309,7 +352,10 @@ module Prawn
309
352
  end
310
353
 
311
354
  # Decrease the left padding of the bounding box.
355
+ #
312
356
  # @private
357
+ # @param left_padding [Number]
358
+ # @return [void]
313
359
  def subtract_left_padding(left_padding)
314
360
  @total_left_padding -= left_padding
315
361
  @x -= left_padding
@@ -317,172 +363,190 @@ module Prawn
317
363
  end
318
364
 
319
365
  # Increase the right padding of the bounding box.
366
+ #
320
367
  # @private
368
+ # @param right_padding [Number]
369
+ # @return [void]
321
370
  def add_right_padding(right_padding)
322
371
  @total_right_padding += right_padding
323
372
  @width -= right_padding
324
373
  end
325
374
 
326
375
  # Decrease the right padding of the bounding box.
376
+ #
327
377
  # @private
378
+ # @param right_padding [Number]
379
+ # @return [void]
328
380
  def subtract_right_padding(right_padding)
329
381
  @total_right_padding -= right_padding
330
382
  @width += right_padding
331
383
  end
332
384
 
333
- # Relative right x-coordinate of the bounding box. (Equal to the box
334
- # width)
335
- #
336
- # Example, position some text 3 pts from the right of the containing box:
385
+ # Relative right x-coordinate of the bounding box. Equal to the box width.
337
386
  #
338
- # draw_text('hello', :at => [(bounds.right - 3), 0])
387
+ # @example Position some text 3 pts from the right of the containing box
388
+ # draw_text('hello', at: [(bounds.right - 3), 0])
339
389
  #
390
+ # @return [Number]
340
391
  def right
341
392
  @width
342
393
  end
343
394
 
344
- # Relative top y-coordinate of the bounding box. (Equal to the box height)
345
- #
346
- # Example, position some text 3 pts from the top of the containing box:
395
+ # Relative top y-coordinate of the bounding box. Equal to the box height.
347
396
  #
348
- # draw_text('hello', :at => [0, (bounds.top - 3)])
397
+ # @example Position some text 3 pts from the top of the containing box
398
+ # draw_text('hello', at: [0, (bounds.top - 3)])
349
399
  #
400
+ # @return [Number]
350
401
  def top
351
402
  height
352
403
  end
353
404
 
354
- # Relative bottom y-coordinate of the bounding box (Always 0)
405
+ # Relative bottom y-coordinate of the bounding box. Always 0.
355
406
  #
356
- # Example, position some text 3 pts from the bottom of the containing box:
357
- #
358
- # draw_text('hello', :at => [0, (bounds.bottom + 3)])
407
+ # @example Position some text 3 pts from the bottom of the containing box
408
+ # draw_text('hello', at: [0, (bounds.bottom + 3)])
359
409
  #
410
+ # @return [Number]
360
411
  def bottom
361
412
  0
362
413
  end
363
414
 
364
- # Relative top-left point of the bounding_box
365
- #
366
- # Example, draw a line from the top left of the box diagonally to the
367
- # bottom right:
415
+ # Relative top-left point of the bounding_box.
368
416
  #
369
- # stroke do
370
- # line(bounds.top_left, bounds.bottom_right)
371
- # end
417
+ # @example Draw a line from the top left of the box diagonally to the bottom right
418
+ # stroke do
419
+ # line(bounds.top_left, bounds.bottom_right)
420
+ # end
372
421
  #
422
+ # @return [Array(Number, Number)]
373
423
  def top_left
374
424
  [left, top]
375
425
  end
376
426
 
377
- # Relative top-right point of the bounding box
378
- #
379
- # Example, draw a line from the top_right of the box diagonally to the
380
- # bottom left:
427
+ # Relative top-right point of the bounding box.
381
428
  #
382
- # stroke do
383
- # line(bounds.top_right, bounds.bottom_left)
384
- # end
429
+ # @example Draw a line from the top_right of the box diagonally to the bottom left
430
+ # stroke do
431
+ # line(bounds.top_right, bounds.bottom_left)
432
+ # end
385
433
  #
434
+ # @return [Array(Number, Number)]
386
435
  def top_right
387
436
  [right, top]
388
437
  end
389
438
 
390
- # Relative bottom-right point of the bounding box
439
+ # Relative bottom-right point of the bounding box.
391
440
  #
392
- # Example, draw a line along the right hand side of the page:
393
- #
394
- # stroke do
395
- # line(bounds.bottom_right, bounds.top_right)
396
- # end
441
+ # @example Draw a line along the right hand side of the page
442
+ # stroke do
443
+ # line(bounds.bottom_right, bounds.top_right)
444
+ # end
397
445
  #
446
+ # @return [Array(Number, Number)]
398
447
  def bottom_right
399
448
  [right, bottom]
400
449
  end
401
450
 
402
- # Relative bottom-left point of the bounding box
451
+ # Relative bottom-left point of the bounding box.
403
452
  #
404
- # Example, draw a line along the left hand side of the page:
405
- #
406
- # stroke do
407
- # line(bounds.bottom_left, bounds.top_left)
408
- # end
453
+ # @example Draw a line along the left hand side of the page
454
+ # stroke do
455
+ # line(bounds.bottom_left, bounds.top_left)
456
+ # end
409
457
  #
458
+ # @return [Array(Number, Number)]
410
459
  def bottom_left
411
460
  [left, bottom]
412
461
  end
413
462
 
414
- # Absolute left x-coordinate of the bounding box
463
+ # Absolute left x-coordinate of the bounding box.
415
464
  #
465
+ # @return [Number]
416
466
  def absolute_left
417
467
  @x
418
468
  end
419
469
 
420
- # Absolute right x-coordinate of the bounding box
470
+ # Absolute right x-coordinate of the bounding box.
421
471
  #
472
+ # @return [Number]
422
473
  def absolute_right
423
474
  @x + width
424
475
  end
425
476
 
426
- # Absolute top y-coordinate of the bounding box
477
+ # Absolute top y-coordinate of the bounding box.
427
478
  #
479
+ # @return [Number]
428
480
  def absolute_top
429
481
  @y
430
482
  end
431
483
 
432
- # Absolute bottom y-coordinate of the bottom box
484
+ # Absolute bottom y-coordinate of the bottom box.
433
485
  #
486
+ # @return [Number]
434
487
  def absolute_bottom
435
488
  @y - height
436
489
  end
437
490
 
438
- # Absolute top-left point of the bounding box
491
+ # Absolute top-left point of the bounding box.
439
492
  #
493
+ # @return [Array(Number, Number)]
440
494
  def absolute_top_left
441
495
  [absolute_left, absolute_top]
442
496
  end
443
497
 
444
- # Absolute top-right point of the bounding box
498
+ # Absolute top-right point of the bounding box.
445
499
  #
500
+ # @return [Array(Number, Number)]
446
501
  def absolute_top_right
447
502
  [absolute_right, absolute_top]
448
503
  end
449
504
 
450
- # Absolute bottom-left point of the bounding box
505
+ # Absolute bottom-left point of the bounding box.
451
506
  #
507
+ # @return [Array(Number, Number)]
452
508
  def absolute_bottom_left
453
509
  [absolute_left, absolute_bottom]
454
510
  end
455
511
 
456
- # Absolute bottom-left point of the bounding box
512
+ # Absolute bottom-left point of the bounding box.
457
513
  #
514
+ # @return [Array(Number, Number)]
458
515
  def absolute_bottom_right
459
516
  [absolute_right, absolute_bottom]
460
517
  end
461
518
 
462
- # Width of the bounding box
519
+ # Width of the bounding box.
520
+ #
521
+ # @return [Number]
463
522
  attr_reader :width
464
523
 
465
- # Height of the bounding box. If the box is 'stretchy' (unspecified
524
+ # Height of the bounding box. If the box is 'stretchy' (unspecified
466
525
  # height attribute), height is calculated as the distance from the top of
467
526
  # the box to the current drawing position.
468
527
  #
528
+ # @return [Number]
469
529
  def height
470
530
  return @height if @height
471
531
 
472
532
  @stretched_height = [
473
533
  (absolute_top - @document.y),
474
- @stretched_height.to_f
534
+ Float(@stretched_height || 0.0),
475
535
  ].max
476
536
  end
477
537
 
478
- # an alias for absolute_left
538
+ # An alias for {absolute_left}.
539
+ #
479
540
  # @private
541
+ # @return [Number]
480
542
  def left_side
481
543
  absolute_left
482
544
  end
483
545
 
484
- # an alias for absolute_right
546
+ # An alias for {absolute_right}.
547
+ #
485
548
  # @private
549
+ # @return [Number]
486
550
  def right_side
487
551
  absolute_right
488
552
  end
@@ -492,6 +556,7 @@ module Prawn
492
556
  # Moves to the top of the next page of the document, starting a new page
493
557
  # if necessary.
494
558
  #
559
+ # @return [void]
495
560
  def move_past_bottom
496
561
  if @document.page_number == @document.page_count
497
562
  @document.start_new_page
@@ -500,16 +565,19 @@ module Prawn
500
565
  end
501
566
  end
502
567
 
503
- # Returns +false+ when the box has a defined height, +true+ when the
568
+ # Returns `false` when the box has a defined height, `true` when the
504
569
  # height is being calculated on the fly based on the current vertical
505
570
  # position.
506
571
  #
572
+ # @return [Boolean]
507
573
  def stretchy?
508
574
  !@height
509
575
  end
510
576
 
511
577
  # Returns the innermost non-stretchy bounding box.
512
578
  #
579
+ # @return [BoundingBox]
580
+ # @raise [NoReferenceBounds]
513
581
  def reference_bounds
514
582
  if stretchy?
515
583
  raise NoReferenceBounds unless @parent
@@ -526,26 +594,30 @@ module Prawn
526
594
  # not copying the reference to the Document).
527
595
  #
528
596
  # @private
597
+ # @return [BoundingBox]
529
598
  def deep_copy
530
599
  copy = dup
531
600
  # Deep-copy the parent bounds
532
601
  copy.instance_variable_set(
533
- '@parent',
602
+ :@parent,
534
603
  if @parent.is_a?(BoundingBox)
535
604
  @parent.deep_copy
536
- end
605
+ end,
537
606
  )
538
- copy.instance_variable_set('@document', nil)
607
+ copy.instance_variable_set(:@document, nil)
539
608
  copy
540
609
  end
541
610
 
542
- # Restores a copy of the bounds taken by BoundingBox.deep_copy in the
543
- # context of the given +document+. Does *not* set the bounds of the
544
- # document to the resulting BoundingBox, only returns it.
611
+ # Restores a copy of the bounds taken by {BoundingBox#deep_copy} in the
612
+ # context of the given `document`. Does *not* set the bounds of the
613
+ # document to the resulting {BoundingBox}, only returns it.
545
614
  #
546
615
  # @private
616
+ # @param bounds [BoundingBox]
617
+ # @param document [Prawn::Document]
618
+ # @return [BoundingBox]
547
619
  def self.restore_deep_copy(bounds, document)
548
- bounds.instance_variable_set('@document', document)
620
+ bounds.instance_variable_set(:@document, document)
549
621
  bounds
550
622
  end
551
623
  end