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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/prawn/document/bounding_box.rb +213 -141
- data/lib/prawn/document/column_box.rb +61 -26
- data/lib/prawn/document/internals.rb +25 -16
- data/lib/prawn/document/span.rb +20 -18
- data/lib/prawn/document.rb +257 -171
- data/lib/prawn/encoding.rb +2 -5
- data/lib/prawn/errors.rb +23 -34
- data/lib/prawn/font.rb +248 -135
- data/lib/prawn/font_metric_cache.rb +11 -10
- data/lib/prawn/fonts/afm.rb +85 -45
- data/lib/prawn/fonts/dfont.rb +7 -1
- data/lib/prawn/fonts/otf.rb +4 -1
- data/lib/prawn/fonts/to_unicode_cmap.rb +151 -0
- data/lib/prawn/fonts/ttc.rb +7 -2
- data/lib/prawn/fonts/ttf.rb +305 -93
- data/lib/prawn/fonts.rb +14 -0
- data/lib/prawn/graphics/blend_mode.rb +25 -28
- data/lib/prawn/graphics/cap_style.rb +9 -12
- data/lib/prawn/graphics/color.rb +57 -34
- data/lib/prawn/graphics/dash.rb +45 -42
- data/lib/prawn/graphics/join_style.rb +17 -11
- data/lib/prawn/graphics/patterns.rb +190 -69
- data/lib/prawn/graphics/transformation.rb +48 -41
- data/lib/prawn/graphics/transparency.rb +16 -40
- data/lib/prawn/graphics.rb +363 -253
- data/lib/prawn/grid.rb +184 -57
- data/lib/prawn/image_handler.rb +27 -10
- data/lib/prawn/images/image.rb +8 -10
- data/lib/prawn/images/jpg.rb +42 -19
- data/lib/prawn/images/png.rb +92 -41
- data/lib/prawn/images.rb +44 -57
- data/lib/prawn/measurement_extensions.rb +39 -8
- data/lib/prawn/measurements.rb +60 -5
- data/lib/prawn/outline.rb +114 -108
- data/lib/prawn/repeater.rb +51 -35
- data/lib/prawn/security/arcfour.rb +4 -4
- data/lib/prawn/security.rb +75 -70
- data/lib/prawn/soft_mask.rb +42 -30
- data/lib/prawn/stamp.rb +38 -42
- data/lib/prawn/text/box.rb +146 -96
- data/lib/prawn/text/formatted/arranger.rb +87 -26
- data/lib/prawn/text/formatted/box.rb +221 -150
- data/lib/prawn/text/formatted/fragment.rb +130 -14
- data/lib/prawn/text/formatted/line_wrap.rb +33 -24
- data/lib/prawn/text/formatted/parser.rb +112 -72
- data/lib/prawn/text/formatted/wrap.rb +12 -17
- data/lib/prawn/text/formatted.rb +75 -0
- data/lib/prawn/text.rb +441 -196
- data/lib/prawn/transformation_stack.rb +29 -10
- data/lib/prawn/utilities.rb +13 -13
- data/lib/prawn/version.rb +2 -1
- data/lib/prawn/view.rb +68 -53
- data/lib/prawn.rb +23 -18
- data.tar.gz.sig +0 -0
- metadata +54 -177
- metadata.gz.sig +0 -0
- data/.yardopts +0 -10
- data/Gemfile +0 -5
- data/Rakefile +0 -25
- data/manual/absolute_position.pdf +0 -0
- data/manual/basic_concepts/adding_pages.rb +0 -26
- data/manual/basic_concepts/basic_concepts.rb +0 -43
- data/manual/basic_concepts/creation.rb +0 -38
- data/manual/basic_concepts/cursor.rb +0 -32
- data/manual/basic_concepts/measurement.rb +0 -24
- data/manual/basic_concepts/origin.rb +0 -37
- data/manual/basic_concepts/other_cursor_helpers.rb +0 -39
- data/manual/basic_concepts/view.rb +0 -48
- data/manual/bounding_box/bounding_box.rb +0 -41
- data/manual/bounding_box/bounds.rb +0 -48
- data/manual/bounding_box/canvas.rb +0 -23
- data/manual/bounding_box/creation.rb +0 -22
- data/manual/bounding_box/indentation.rb +0 -45
- data/manual/bounding_box/nesting.rb +0 -52
- data/manual/bounding_box/russian_boxes.rb +0 -40
- data/manual/bounding_box/stretchy.rb +0 -29
- data/manual/contents.rb +0 -35
- data/manual/cover.rb +0 -43
- data/manual/document_and_page_options/background.rb +0 -29
- data/manual/document_and_page_options/document_and_page_options.rb +0 -34
- data/manual/document_and_page_options/metadata.rb +0 -25
- data/manual/document_and_page_options/page_margins.rb +0 -36
- data/manual/document_and_page_options/page_size.rb +0 -34
- data/manual/document_and_page_options/print_scaling.rb +0 -23
- data/manual/example_helper.rb +0 -8
- data/manual/graphics/blend_mode.rb +0 -52
- data/manual/graphics/circle_and_ellipse.rb +0 -21
- data/manual/graphics/color.rb +0 -22
- data/manual/graphics/common_lines.rb +0 -29
- data/manual/graphics/fill_and_stroke.rb +0 -41
- data/manual/graphics/fill_rules.rb +0 -38
- data/manual/graphics/gradients.rb +0 -43
- data/manual/graphics/graphics.rb +0 -64
- data/manual/graphics/helper.rb +0 -34
- data/manual/graphics/line_width.rb +0 -36
- data/manual/graphics/lines_and_curves.rb +0 -40
- data/manual/graphics/polygon.rb +0 -27
- data/manual/graphics/rectangle.rb +0 -20
- data/manual/graphics/rotate.rb +0 -25
- data/manual/graphics/scale.rb +0 -42
- data/manual/graphics/soft_masks.rb +0 -44
- data/manual/graphics/stroke_cap.rb +0 -30
- data/manual/graphics/stroke_dash.rb +0 -47
- data/manual/graphics/stroke_join.rb +0 -29
- data/manual/graphics/translate.rb +0 -29
- data/manual/graphics/transparency.rb +0 -33
- data/manual/how_to_read_this_manual.rb +0 -39
- data/manual/images/absolute_position.rb +0 -22
- data/manual/images/fit.rb +0 -20
- data/manual/images/horizontal.rb +0 -24
- data/manual/images/images.rb +0 -41
- data/manual/images/plain_image.rb +0 -17
- data/manual/images/scale.rb +0 -21
- data/manual/images/vertical.rb +0 -30
- data/manual/images/width_and_height.rb +0 -24
- data/manual/layout/boxes.rb +0 -26
- data/manual/layout/content.rb +0 -24
- data/manual/layout/layout.rb +0 -27
- data/manual/layout/simple_grid.rb +0 -22
- data/manual/outline/add_subsection_to.rb +0 -60
- data/manual/outline/insert_section_after.rb +0 -46
- data/manual/outline/outline.rb +0 -33
- data/manual/outline/sections_and_pages.rb +0 -66
- data/manual/repeatable_content/alternate_page_numbering.rb +0 -36
- data/manual/repeatable_content/page_numbering.rb +0 -55
- data/manual/repeatable_content/repeatable_content.rb +0 -35
- data/manual/repeatable_content/repeater.rb +0 -54
- data/manual/repeatable_content/stamp.rb +0 -40
- data/manual/security/encryption.rb +0 -28
- data/manual/security/permissions.rb +0 -43
- data/manual/security/security.rb +0 -28
- data/manual/table.rb +0 -16
- data/manual/text/alignment.rb +0 -43
- data/manual/text/color.rb +0 -24
- data/manual/text/column_box.rb +0 -30
- data/manual/text/fallback_fonts.rb +0 -41
- data/manual/text/font.rb +0 -40
- data/manual/text/font_size.rb +0 -44
- data/manual/text/font_style.rb +0 -25
- data/manual/text/formatted_callbacks.rb +0 -70
- data/manual/text/formatted_text.rb +0 -61
- data/manual/text/free_flowing_text.rb +0 -50
- data/manual/text/inline.rb +0 -40
- data/manual/text/kerning_and_character_spacing.rb +0 -38
- data/manual/text/leading.rb +0 -24
- data/manual/text/line_wrapping.rb +0 -60
- data/manual/text/paragraph_indentation.rb +0 -31
- data/manual/text/positioned_text.rb +0 -37
- data/manual/text/registering_families.rb +0 -51
- data/manual/text/rendering_and_color.rb +0 -36
- data/manual/text/right_to_left_text.rb +0 -54
- data/manual/text/rotation.rb +0 -52
- data/manual/text/single_usage.rb +0 -36
- data/manual/text/text.rb +0 -75
- data/manual/text/text_box_excess.rb +0 -35
- data/manual/text/text_box_extensions.rb +0 -48
- data/manual/text/text_box_overflow.rb +0 -51
- data/manual/text/utf8.rb +0 -27
- data/manual/text/win_ansi_charset.rb +0 -62
- data/prawn.gemspec +0 -51
- data/spec/data/curves.pdf +0 -66
- data/spec/extensions/encoding_helpers.rb +0 -11
- data/spec/prawn/document/bounding_box_spec.rb +0 -550
- data/spec/prawn/document/column_box_spec.rb +0 -75
- data/spec/prawn/document/security_spec.rb +0 -176
- data/spec/prawn/document_annotations_spec.rb +0 -76
- data/spec/prawn/document_destinations_spec.rb +0 -15
- data/spec/prawn/document_grid_spec.rb +0 -99
- data/spec/prawn/document_reference_spec.rb +0 -27
- data/spec/prawn/document_span_spec.rb +0 -44
- data/spec/prawn/document_spec.rb +0 -805
- data/spec/prawn/font_metric_cache_spec.rb +0 -54
- data/spec/prawn/font_spec.rb +0 -544
- data/spec/prawn/graphics/blend_mode_spec.rb +0 -63
- data/spec/prawn/graphics/transparency_spec.rb +0 -81
- data/spec/prawn/graphics_spec.rb +0 -872
- data/spec/prawn/graphics_stroke_styles_spec.rb +0 -229
- data/spec/prawn/image_handler_spec.rb +0 -53
- data/spec/prawn/images/jpg_spec.rb +0 -20
- data/spec/prawn/images/png_spec.rb +0 -283
- data/spec/prawn/images_spec.rb +0 -229
- data/spec/prawn/measurements_extensions_spec.rb +0 -24
- data/spec/prawn/outline_spec.rb +0 -512
- data/spec/prawn/repeater_spec.rb +0 -166
- data/spec/prawn/soft_mask_spec.rb +0 -74
- data/spec/prawn/stamp_spec.rb +0 -173
- data/spec/prawn/text/box_spec.rb +0 -1110
- data/spec/prawn/text/formatted/arranger_spec.rb +0 -466
- data/spec/prawn/text/formatted/box_spec.rb +0 -849
- data/spec/prawn/text/formatted/fragment_spec.rb +0 -343
- data/spec/prawn/text/formatted/line_wrap_spec.rb +0 -495
- data/spec/prawn/text/formatted/parser_spec.rb +0 -697
- data/spec/prawn/text_draw_text_spec.rb +0 -150
- data/spec/prawn/text_rendering_mode_spec.rb +0 -48
- data/spec/prawn/text_spacing_spec.rb +0 -95
- data/spec/prawn/text_spec.rb +0 -603
- data/spec/prawn/text_with_inline_formatting_spec.rb +0 -35
- data/spec/prawn/transformation_stack_spec.rb +0 -66
- data/spec/prawn/view_spec.rb +0 -63
- data/spec/prawn_manual_spec.rb +0 -35
- 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
|
-
#
|
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
|
19
|
+
# * Bounding box 100pt×100pt in the absolute bottom left of the
|
32
20
|
# containing box:
|
33
21
|
#
|
34
|
-
#
|
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
|
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], :
|
33
|
+
# pdf.bounding_box([x_pos, y_pos], width: 300, height: 400) do
|
43
34
|
# stroke_bounds
|
44
35
|
# end
|
36
|
+
# ```
|
45
37
|
#
|
46
|
-
#
|
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
|
-
#
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
#
|
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.
|
65
|
-
# will want to look at span
|
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
|
-
#
|
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
|
-
#
|
78
|
-
#
|
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
|
-
#
|
84
|
-
#
|
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
|
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
|
-
#
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
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
|
-
#
|
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).
|
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
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
121
|
-
#
|
122
|
-
#
|
123
|
-
#
|
124
|
-
#
|
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
|
-
#
|
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], :
|
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
|
-
#
|
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
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
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
|
-
|
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
|
-
#
|
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.
|
306
|
+
# Relative left x-coordinate of the bounding box. Always 0.
|
269
307
|
#
|
270
|
-
#
|
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
|
279
|
-
#
|
280
|
-
# Example:
|
316
|
+
# Temporarily adjust the x coordinate to allow for left padding
|
281
317
|
#
|
282
|
-
#
|
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
|
-
#
|
290
|
-
#
|
291
|
-
#
|
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.
|
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
|
-
#
|
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.
|
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
|
-
#
|
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
|
405
|
+
# Relative bottom y-coordinate of the bounding box. Always 0.
|
355
406
|
#
|
356
|
-
#
|
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
|
-
#
|
370
|
-
#
|
371
|
-
#
|
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
|
-
#
|
383
|
-
#
|
384
|
-
#
|
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
|
-
#
|
393
|
-
#
|
394
|
-
#
|
395
|
-
#
|
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
|
-
#
|
405
|
-
#
|
406
|
-
#
|
407
|
-
#
|
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.
|
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.
|
534
|
+
Float(@stretched_height || 0.0),
|
475
535
|
].max
|
476
536
|
end
|
477
537
|
|
478
|
-
#
|
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
|
-
#
|
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
|
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
|
-
|
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(
|
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
|
543
|
-
# context of the given
|
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(
|
620
|
+
bounds.instance_variable_set(:@document, document)
|
549
621
|
bounds
|
550
622
|
end
|
551
623
|
end
|