prawn 0.11.1.pre → 0.11.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +2 -340
- data/HACKING +1 -1
- data/LICENSE +3 -3
- data/Rakefile +17 -6
- data/data/encodings/win_ansi.txt +1 -1
- data/data/images/prawn.png +0 -0
- data/data/pdfs/form.pdf +820 -0
- data/data/pdfs/multipage_template.pdf +127 -0
- data/examples/bounding_box/bounding_boxes.rb +4 -3
- data/examples/bounding_box/indentation.rb +2 -1
- data/examples/bounding_box/russian_boxes.rb +3 -2
- data/examples/bounding_box/stretched_nesting.rb +2 -1
- data/examples/general/background.rb +2 -1
- data/examples/general/canvas.rb +2 -1
- data/examples/general/context_sensitive_headers.rb +2 -1
- data/examples/general/float.rb +2 -1
- data/examples/general/margin.rb +2 -1
- data/examples/general/measurement_units.rb +2 -1
- data/examples/general/metadata-info.rb +2 -1
- data/examples/general/multi_page_layout.rb +2 -1
- data/examples/general/outlines.rb +2 -1
- data/examples/general/page_geometry.rb +2 -1
- data/examples/general/page_numbering.rb +27 -2
- data/examples/general/page_templates.rb +20 -0
- data/examples/general/repeaters.rb +2 -1
- data/examples/general/stamp.rb +4 -3
- data/examples/general/templates.rb +2 -1
- data/examples/graphics/basic_images.rb +2 -1
- data/examples/graphics/cmyk.rb +2 -1
- data/examples/graphics/curves.rb +4 -3
- data/examples/graphics/gradient.rb +23 -0
- data/examples/graphics/hexagon.rb +3 -2
- data/examples/graphics/image_fit.rb +3 -2
- data/examples/graphics/image_flow.rb +2 -1
- data/examples/graphics/image_position.rb +3 -2
- data/examples/graphics/line.rb +2 -1
- data/examples/graphics/png_types.rb +3 -2
- data/examples/graphics/polygons.rb +3 -2
- data/examples/graphics/remote_images.rb +2 -1
- data/examples/graphics/rounded_polygons.rb +2 -1
- data/examples/graphics/rounded_rectangle.rb +2 -1
- data/examples/graphics/ruport_style_helpers.rb +3 -2
- data/examples/graphics/stroke_bounds.rb +2 -1
- data/examples/graphics/stroke_cap_and_join.rb +2 -1
- data/examples/graphics/stroke_dash.rb +2 -1
- data/examples/graphics/transformations.rb +2 -1
- data/examples/graphics/transparency.rb +4 -3
- data/examples/grid/bounding_boxes.rb +2 -1
- data/examples/grid/column_gutter_grid.rb +2 -1
- data/examples/grid/multi_boxes.rb +2 -1
- data/examples/grid/show_grid.rb +2 -1
- data/examples/grid/simple_grid.rb +2 -1
- data/examples/m17n/chinese_text_wrapping.rb +2 -1
- data/examples/m17n/euro.rb +3 -2
- data/examples/m17n/full_win_ansi_character_list.rb +20 -0
- data/examples/m17n/sjis.rb +2 -1
- data/examples/m17n/utf8.rb +3 -2
- data/examples/m17n/win_ansi_charset.rb +2 -1
- data/examples/security/hello_foo.rb +2 -1
- data/examples/table/bill.rb +2 -1
- data/examples/table/borders.rb +25 -0
- data/examples/table/cell.rb +3 -2
- data/examples/table/checkerboard.rb +2 -1
- data/examples/table/header.rb +3 -2
- data/examples/table/inline_format_table.rb +2 -1
- data/examples/table/multi_page_table.rb +2 -1
- data/examples/table/simple_table.rb +2 -1
- data/examples/table/subtable.rb +2 -1
- data/examples/table/widths.rb +2 -1
- data/examples/text/alignment.rb +2 -1
- data/examples/text/character_spacing.rb +2 -1
- data/examples/text/dfont.rb +2 -1
- data/examples/text/family_based_styling.rb +3 -2
- data/examples/text/font_calculations.rb +2 -1
- data/examples/text/font_size.rb +2 -1
- data/examples/text/hyphenation.rb +2 -2
- data/examples/text/indent_paragraphs.rb +7 -5
- data/examples/text/inline_format.rb +7 -6
- data/examples/text/kerning.rb +2 -1
- data/examples/text/rendering_mode.rb +21 -0
- data/examples/text/rotated.rb +2 -1
- data/examples/text/shaped_text_box.rb +2 -1
- data/examples/text/simple_text.rb +2 -1
- data/examples/text/simple_text_ttf.rb +2 -1
- data/examples/text/span.rb +3 -2
- data/examples/text/text_box.rb +7 -5
- data/examples/text/text_box_returning_excess.rb +4 -3
- data/examples/text/text_flow.rb +2 -1
- data/lib/prawn.rb +1 -1
- data/lib/prawn/core/object_store.rb +42 -14
- data/lib/prawn/core/page.rb +22 -8
- data/lib/prawn/core/text.rb +141 -13
- data/lib/prawn/core/text/formatted/arranger.rb +39 -12
- data/lib/prawn/core/text/formatted/line_wrap.rb +205 -60
- data/lib/prawn/core/text/formatted/wrap.rb +72 -35
- data/lib/prawn/document.rb +174 -70
- data/lib/prawn/document/bounding_box.rb +122 -83
- data/lib/prawn/document/column_box.rb +113 -0
- data/lib/prawn/document/graphics_state.rb +90 -2
- data/lib/prawn/document/internals.rb +5 -3
- data/lib/prawn/errors.rb +5 -0
- data/lib/prawn/font.rb +4 -4
- data/lib/prawn/font/afm.rb +11 -0
- data/lib/prawn/font/ttf.rb +5 -0
- data/lib/prawn/graphics.rb +77 -14
- data/lib/prawn/graphics/cap_style.rb +13 -5
- data/lib/prawn/graphics/color.rb +54 -35
- data/lib/prawn/graphics/dash.rb +27 -16
- data/lib/prawn/graphics/gradient.rb +84 -0
- data/lib/prawn/graphics/join_style.rb +12 -3
- data/lib/prawn/graphics/transparency.rb +4 -4
- data/lib/prawn/images.rb +18 -160
- data/lib/prawn/images/jpg.rb +39 -0
- data/lib/prawn/images/png.rb +130 -0
- data/lib/prawn/repeater.rb +6 -13
- data/lib/prawn/security.rb +6 -1
- data/lib/prawn/stamp.rb +12 -4
- data/lib/prawn/table.rb +36 -4
- data/lib/prawn/table/cell.rb +224 -63
- data/lib/prawn/table/cell/text.rb +20 -10
- data/lib/prawn/table/cells.rb +23 -6
- data/lib/prawn/text.rb +54 -91
- data/lib/prawn/text/box.rb +29 -283
- data/lib/prawn/text/formatted/box.rb +349 -24
- data/lib/prawn/text/formatted/fragment.rb +63 -2
- data/lib/prawn/text/formatted/parser.rb +2 -1
- data/prawn.gemspec +21 -5
- data/spec/bounding_box_spec.rb +61 -28
- data/spec/cell_spec.rb +168 -30
- data/spec/document_spec.rb +187 -3
- data/spec/extensions/mocha.rb +45 -0
- data/spec/font_spec.rb +32 -1
- data/spec/formatted_text_arranger_spec.rb +35 -40
- data/spec/formatted_text_box_spec.rb +287 -443
- data/spec/formatted_text_fragment_spec.rb +87 -0
- data/spec/graphics_spec.rb +128 -12
- data/spec/grid_spec.rb +1 -1
- data/spec/images_spec.rb +11 -3
- data/spec/inline_formatted_text_parser_spec.rb +8 -0
- data/spec/line_wrap_spec.rb +200 -208
- data/spec/object_store_spec.rb +10 -0
- data/spec/outline_spec.rb +7 -3
- data/spec/repeater_spec.rb +58 -10
- data/spec/security_spec.rb +6 -0
- data/spec/spec_helper.rb +12 -8
- data/spec/stamp_spec.rb +52 -1
- data/spec/stroke_styles_spec.rb +30 -0
- data/spec/table_spec.rb +93 -3
- data/spec/template_spec.rb +132 -6
- data/spec/text_at_spec.rb +14 -4
- data/spec/text_box_spec.rb +309 -70
- data/spec/text_rendering_mode_spec.rb +45 -0
- data/spec/text_spec.rb +60 -17
- data/spec/text_with_inline_formatting_spec.rb +4 -162
- metadata +241 -241
- data/lib/prawn/core/text/line_wrap.rb +0 -211
- data/lib/prawn/core/text/wrap.rb +0 -82
- data/vendor/pdf-inspector/README +0 -18
- data/vendor/pdf-inspector/lib/pdf/inspector.rb +0 -26
- data/vendor/pdf-inspector/lib/pdf/inspector/extgstate.rb +0 -18
- data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +0 -131
- data/vendor/pdf-inspector/lib/pdf/inspector/page.rb +0 -25
- data/vendor/pdf-inspector/lib/pdf/inspector/text.rb +0 -46
- data/vendor/pdf-inspector/lib/pdf/inspector/xobject.rb +0 -19
- data/vendor/ttfunk/data/fonts/DejaVuSans.ttf +0 -0
- data/vendor/ttfunk/data/fonts/comicsans.ttf +0 -0
- data/vendor/ttfunk/example.rb +0 -45
- data/vendor/ttfunk/lib/ttfunk.rb +0 -102
- data/vendor/ttfunk/lib/ttfunk/directory.rb +0 -17
- data/vendor/ttfunk/lib/ttfunk/encoding/mac_roman.rb +0 -88
- data/vendor/ttfunk/lib/ttfunk/encoding/windows_1252.rb +0 -69
- data/vendor/ttfunk/lib/ttfunk/reader.rb +0 -44
- data/vendor/ttfunk/lib/ttfunk/resource_file.rb +0 -78
- data/vendor/ttfunk/lib/ttfunk/subset.rb +0 -18
- data/vendor/ttfunk/lib/ttfunk/subset/base.rb +0 -141
- data/vendor/ttfunk/lib/ttfunk/subset/mac_roman.rb +0 -50
- data/vendor/ttfunk/lib/ttfunk/subset/unicode.rb +0 -48
- data/vendor/ttfunk/lib/ttfunk/subset/unicode_8bit.rb +0 -63
- data/vendor/ttfunk/lib/ttfunk/subset/windows_1252.rb +0 -55
- data/vendor/ttfunk/lib/ttfunk/subset_collection.rb +0 -72
- data/vendor/ttfunk/lib/ttfunk/table.rb +0 -46
- data/vendor/ttfunk/lib/ttfunk/table/cmap.rb +0 -34
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format00.rb +0 -54
- data/vendor/ttfunk/lib/ttfunk/table/cmap/format04.rb +0 -126
- data/vendor/ttfunk/lib/ttfunk/table/cmap/subtable.rb +0 -79
- data/vendor/ttfunk/lib/ttfunk/table/glyf.rb +0 -64
- data/vendor/ttfunk/lib/ttfunk/table/glyf/compound.rb +0 -81
- data/vendor/ttfunk/lib/ttfunk/table/glyf/simple.rb +0 -37
- data/vendor/ttfunk/lib/ttfunk/table/head.rb +0 -44
- data/vendor/ttfunk/lib/ttfunk/table/hhea.rb +0 -41
- data/vendor/ttfunk/lib/ttfunk/table/hmtx.rb +0 -47
- data/vendor/ttfunk/lib/ttfunk/table/kern.rb +0 -79
- data/vendor/ttfunk/lib/ttfunk/table/kern/format0.rb +0 -62
- data/vendor/ttfunk/lib/ttfunk/table/loca.rb +0 -43
- data/vendor/ttfunk/lib/ttfunk/table/maxp.rb +0 -40
- data/vendor/ttfunk/lib/ttfunk/table/name.rb +0 -125
- data/vendor/ttfunk/lib/ttfunk/table/os2.rb +0 -78
- data/vendor/ttfunk/lib/ttfunk/table/post.rb +0 -91
- data/vendor/ttfunk/lib/ttfunk/table/post/format10.rb +0 -43
- data/vendor/ttfunk/lib/ttfunk/table/post/format20.rb +0 -35
- data/vendor/ttfunk/lib/ttfunk/table/post/format25.rb +0 -23
- data/vendor/ttfunk/lib/ttfunk/table/post/format30.rb +0 -17
- data/vendor/ttfunk/lib/ttfunk/table/post/format40.rb +0 -17
- data/vendor/ttfunk/lib/ttfunk/table/simple.rb +0 -14
@@ -8,34 +8,34 @@
|
|
8
8
|
|
9
9
|
module Prawn
|
10
10
|
class Document
|
11
|
-
|
12
|
-
# :call-seq:
|
13
|
-
# bounding_box(point, options={}, &block)
|
11
|
+
|
12
|
+
# :call-seq:
|
13
|
+
# bounding_box(point, options={}, &block)
|
14
14
|
#
|
15
15
|
# A bounding box serves two important purposes:
|
16
16
|
# * Provide bounds for flowing text, starting at a given point
|
17
17
|
# * Translate the origin (0,0) for graphics primitives
|
18
18
|
#
|
19
|
-
# A point and :width must be provided. :height is optional.
|
19
|
+
# A point and :width must be provided. :height is optional.
|
20
20
|
# (See stretchyness below)
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# ==Positioning
|
23
|
-
#
|
23
|
+
#
|
24
24
|
# Bounding boxes are positioned relative to their top left corner and
|
25
25
|
# the width measurement is towards the right and height measurement is
|
26
26
|
# downwards.
|
27
|
-
#
|
27
|
+
#
|
28
28
|
# Usage:
|
29
|
-
#
|
30
|
-
# * Bounding box 100pt x 100pt in the absolute bottom left of the
|
29
|
+
#
|
30
|
+
# * Bounding box 100pt x 100pt in the absolute bottom left of the
|
31
31
|
# containing box:
|
32
|
-
#
|
32
|
+
#
|
33
33
|
# pdf.bounding_box([0,100], :width => 100, :height => 100)
|
34
34
|
# stroke_bounds
|
35
35
|
# end
|
36
|
-
#
|
36
|
+
#
|
37
37
|
# * Bounding box 200pt x 400pt high in the center of the page:
|
38
|
-
#
|
38
|
+
#
|
39
39
|
# x_pos = ((bounds.width / 2) - 150)
|
40
40
|
# y_pos = ((bounds.height / 2) + 200)
|
41
41
|
# pdf.bounding_box([x_pos, y_pos], :width => 300, :height => 400) do
|
@@ -64,7 +64,7 @@ module Prawn
|
|
64
64
|
# will want to look at span() and text_box() instead
|
65
65
|
#
|
66
66
|
# ==Translating Coordinates
|
67
|
-
#
|
67
|
+
#
|
68
68
|
# When translating coordinates, the idea is to allow the user to draw
|
69
69
|
# relative to the origin, and then translate their drawing to a specified
|
70
70
|
# area of the document, rather than adjust all their drawing coordinates
|
@@ -104,30 +104,30 @@ module Prawn
|
|
104
104
|
# move this drawing around the document, we simply need to recalculate the
|
105
105
|
# top-left corner of the rectangular bounding-box, and all of our graphics
|
106
106
|
# calls remain unmodified.
|
107
|
-
#
|
107
|
+
#
|
108
108
|
# ==Nesting Bounding Boxes
|
109
|
-
#
|
110
|
-
# At the top level, bounding boxes are specified relative to the document's
|
109
|
+
#
|
110
|
+
# At the top level, bounding boxes are specified relative to the document's
|
111
111
|
# margin_box (which is itself a bounding box). You can also nest bounding
|
112
112
|
# boxes, allowing you to build components which are relative to each other
|
113
113
|
#
|
114
114
|
# Usage:
|
115
|
-
#
|
115
|
+
#
|
116
116
|
# pdf.bounding_box([200,450], :width => 200, :height => 250) do
|
117
|
-
# pdf.stroke_bounds # Show the containing bounding box
|
117
|
+
# pdf.stroke_bounds # Show the containing bounding box
|
118
118
|
# pdf.bounding_box([50,200], :width => 50, :height => 50) do
|
119
|
-
# # a 50x50 bounding box that starts 50 pixels left and 50 pixels down
|
119
|
+
# # a 50x50 bounding box that starts 50 pixels left and 50 pixels down
|
120
120
|
# # the parent bounding box.
|
121
121
|
# pdf.stroke_bounds
|
122
122
|
# end
|
123
123
|
# end
|
124
|
-
#
|
124
|
+
#
|
125
125
|
# ==Stretchyness
|
126
|
-
#
|
126
|
+
#
|
127
127
|
# If you do not specify a height to a bounding box, it will become stretchy
|
128
128
|
# and its height will be calculated automatically as you stretch the box
|
129
129
|
# downwards.
|
130
|
-
#
|
130
|
+
#
|
131
131
|
# pdf.bounding_box([100,400], :width => 400) do
|
132
132
|
# pdf.text("The height of this box is #{pdf.bounds.height}")
|
133
133
|
# pdf.text('this is some text')
|
@@ -135,9 +135,9 @@ module Prawn
|
|
135
135
|
# pdf.text('and finally a bit more')
|
136
136
|
# pdf.text("Now the height of this box is #{pdf.bounds.height}")
|
137
137
|
# end
|
138
|
-
#
|
138
|
+
#
|
139
139
|
# ==Absolute Positioning
|
140
|
-
#
|
140
|
+
#
|
141
141
|
# If you wish to position the bounding boxes at absolute coordinates rather
|
142
142
|
# than relative to the margins or other bounding boxes, you can use canvas()
|
143
143
|
#
|
@@ -154,13 +154,13 @@ module Prawn
|
|
154
154
|
# Of course, if you use canvas, you will be responsible for ensuring that
|
155
155
|
# you remain within the printable area of your document.
|
156
156
|
#
|
157
|
-
def bounding_box(*args, &block)
|
158
|
-
init_bounding_box(block) do |
|
159
|
-
map_to_absolute!(args[0])
|
160
|
-
@bounding_box = BoundingBox.new(self, *args)
|
157
|
+
def bounding_box(*args, &block)
|
158
|
+
init_bounding_box(block) do |parent_box|
|
159
|
+
map_to_absolute!(args[0])
|
160
|
+
@bounding_box = BoundingBox.new(self, parent_box, *args)
|
161
161
|
end
|
162
|
-
end
|
163
|
-
|
162
|
+
end
|
163
|
+
|
164
164
|
# A shortcut to produce a bounding box which is mapped to the document's
|
165
165
|
# absolute coordinates, regardless of how things are nested or margin sizes.
|
166
166
|
#
|
@@ -168,30 +168,31 @@ module Prawn
|
|
168
168
|
# pdf.line pdf.bounds.bottom_left, pdf.bounds.top_right
|
169
169
|
# end
|
170
170
|
#
|
171
|
-
def canvas(&block)
|
171
|
+
def canvas(&block)
|
172
172
|
init_bounding_box(block, :hold_position => true) do |_|
|
173
|
-
|
174
|
-
|
175
|
-
:
|
176
|
-
|
173
|
+
# Canvas bbox acts like margin_box in that its parent bounds are unset.
|
174
|
+
@bounding_box = BoundingBox.new(self, nil, [0,page.dimensions[3]],
|
175
|
+
:width => page.dimensions[2],
|
176
|
+
:height => page.dimensions[3]
|
177
|
+
)
|
177
178
|
end
|
178
|
-
end
|
179
|
-
|
179
|
+
end
|
180
|
+
|
180
181
|
private
|
181
|
-
|
182
|
+
|
182
183
|
def init_bounding_box(user_block, options={}, &init_block)
|
183
|
-
parent_box = @bounding_box
|
184
|
+
parent_box = @bounding_box
|
184
185
|
|
185
|
-
init_block.call(parent_box)
|
186
|
+
init_block.call(parent_box)
|
186
187
|
|
187
|
-
self.y = @bounding_box.absolute_top
|
188
|
-
user_block.call
|
188
|
+
self.y = @bounding_box.absolute_top
|
189
|
+
user_block.call
|
189
190
|
self.y = @bounding_box.absolute_bottom unless options[:hold_position]
|
190
191
|
|
191
192
|
created_box, @bounding_box = @bounding_box, parent_box
|
192
193
|
|
193
194
|
return created_box
|
194
|
-
end
|
195
|
+
end
|
195
196
|
|
196
197
|
# Low level layout helper that simplifies coordinate math.
|
197
198
|
#
|
@@ -199,38 +200,45 @@ module Prawn
|
|
199
200
|
# is used for.
|
200
201
|
#
|
201
202
|
class BoundingBox
|
202
|
-
|
203
|
-
def initialize(parent, point, options={}) #:nodoc:
|
203
|
+
|
204
|
+
def initialize(document, parent, point, options={}) #:nodoc:
|
204
205
|
unless options[:width]
|
205
206
|
raise ArgumentError, "BoundingBox needs the :width option to be set"
|
206
207
|
end
|
207
208
|
|
209
|
+
@document = document
|
208
210
|
@parent = parent
|
209
211
|
@x, @y = point
|
210
212
|
@width, @height = options[:width], options[:height]
|
211
|
-
|
213
|
+
@total_left_padding = 0
|
214
|
+
@total_right_padding = 0
|
215
|
+
@stretched_height = nil
|
212
216
|
end
|
213
217
|
|
214
|
-
attr_reader :parent
|
215
|
-
|
218
|
+
attr_reader :document, :parent
|
219
|
+
# The current indentation of the left side of the bounding box.
|
220
|
+
attr_reader :total_left_padding
|
221
|
+
# The current indentation of the right side of the bounding box.
|
222
|
+
attr_reader :total_right_padding
|
223
|
+
|
216
224
|
# The translated origin (x,y-height) which describes the location
|
217
225
|
# of the bottom left corner of the bounding box
|
218
226
|
#
|
219
227
|
def anchor
|
220
228
|
[@x, @y - height]
|
221
229
|
end
|
222
|
-
|
230
|
+
|
223
231
|
# Relative left x-coordinate of the bounding box. (Always 0)
|
224
|
-
#
|
232
|
+
#
|
225
233
|
# Example, position some text 3 pts from the left of the containing box:
|
226
|
-
#
|
234
|
+
#
|
227
235
|
# draw_text('hello', :at => [(bounds.left + 3), 0])
|
228
236
|
#
|
229
237
|
def left
|
230
238
|
0
|
231
239
|
end
|
232
|
-
|
233
|
-
|
240
|
+
|
241
|
+
|
234
242
|
# Temporarily adjust the @x coordinate to allow for left_padding
|
235
243
|
#
|
236
244
|
# Example:
|
@@ -242,39 +250,69 @@ module Prawn
|
|
242
250
|
# end
|
243
251
|
# end
|
244
252
|
#
|
245
|
-
|
246
|
-
|
247
|
-
|
253
|
+
# indent 20, 20 do
|
254
|
+
# text "indented on both sides"
|
255
|
+
# end
|
256
|
+
#
|
257
|
+
def indent(left_padding, right_padding = 0, &block)
|
258
|
+
add_left_padding(left_padding)
|
259
|
+
add_right_padding(right_padding)
|
248
260
|
yield
|
249
261
|
ensure
|
262
|
+
@document.bounds.subtract_left_padding(left_padding)
|
263
|
+
@document.bounds.subtract_right_padding(right_padding)
|
264
|
+
end
|
265
|
+
|
266
|
+
# Increase the left padding of the bounding box.
|
267
|
+
def add_left_padding(left_padding)
|
268
|
+
@total_left_padding += left_padding
|
269
|
+
@x += left_padding
|
270
|
+
@width -= left_padding
|
271
|
+
end
|
272
|
+
|
273
|
+
# Decrease the left padding of the bounding box.
|
274
|
+
def subtract_left_padding(left_padding)
|
275
|
+
@total_left_padding -= left_padding
|
250
276
|
@x -= left_padding
|
251
277
|
@width += left_padding
|
252
278
|
end
|
253
|
-
|
279
|
+
|
280
|
+
# Increase the right padding of the bounding box.
|
281
|
+
def add_right_padding(right_padding)
|
282
|
+
@total_right_padding += right_padding
|
283
|
+
@width -= right_padding
|
284
|
+
end
|
285
|
+
|
286
|
+
# Decrease the right padding of the bounding box.
|
287
|
+
def subtract_right_padding(right_padding)
|
288
|
+
@total_right_padding -= right_padding
|
289
|
+
@width += right_padding
|
290
|
+
end
|
291
|
+
|
254
292
|
# Relative right x-coordinate of the bounding box. (Equal to the box width)
|
255
|
-
#
|
293
|
+
#
|
256
294
|
# Example, position some text 3 pts from the right of the containing box:
|
257
|
-
#
|
295
|
+
#
|
258
296
|
# draw_text('hello', :at => [(bounds.right - 3), 0])
|
259
297
|
#
|
260
298
|
def right
|
261
299
|
@width
|
262
300
|
end
|
263
|
-
|
301
|
+
|
264
302
|
# Relative top y-coordinate of the bounding box. (Equal to the box height)
|
265
303
|
#
|
266
304
|
# Example, position some text 3 pts from the top of the containing box:
|
267
|
-
#
|
305
|
+
#
|
268
306
|
# draw_text('hello', :at => [0, (bounds.top - 3)])
|
269
307
|
#
|
270
308
|
def top
|
271
309
|
height
|
272
310
|
end
|
273
|
-
|
311
|
+
|
274
312
|
# Relative bottom y-coordinate of the bounding box (Always 0)
|
275
313
|
#
|
276
314
|
# Example, position some text 3 pts from the bottom of the containing box:
|
277
|
-
#
|
315
|
+
#
|
278
316
|
# draw_text('hello', :at => [0, (bounds.bottom + 3)])
|
279
317
|
#
|
280
318
|
def bottom
|
@@ -283,9 +321,9 @@ module Prawn
|
|
283
321
|
|
284
322
|
# Relative top-left point of the bounding_box
|
285
323
|
#
|
286
|
-
# Example, draw a line from the top left of the box diagonally to the
|
324
|
+
# Example, draw a line from the top left of the box diagonally to the
|
287
325
|
# bottom right:
|
288
|
-
#
|
326
|
+
#
|
289
327
|
# stroke do
|
290
328
|
# line(bounds.top_left, bounds.bottom_right)
|
291
329
|
# end
|
@@ -296,9 +334,9 @@ module Prawn
|
|
296
334
|
|
297
335
|
# Relative top-right point of the bounding box
|
298
336
|
#
|
299
|
-
# Example, draw a line from the top_right of the box diagonally to the
|
337
|
+
# Example, draw a line from the top_right of the box diagonally to the
|
300
338
|
# bottom left:
|
301
|
-
#
|
339
|
+
#
|
302
340
|
# stroke do
|
303
341
|
# line(bounds.top_right, bounds.bottom_left)
|
304
342
|
# end
|
@@ -310,7 +348,7 @@ module Prawn
|
|
310
348
|
# Relative bottom-right point of the bounding box
|
311
349
|
#
|
312
350
|
# Example, draw a line along the right hand side of the page:
|
313
|
-
#
|
351
|
+
#
|
314
352
|
# stroke do
|
315
353
|
# line(bounds.bottom_right, bounds.top_right)
|
316
354
|
# end
|
@@ -322,7 +360,7 @@ module Prawn
|
|
322
360
|
# Relative bottom-left point of the bounding box
|
323
361
|
#
|
324
362
|
# Example, draw a line along the left hand side of the page:
|
325
|
-
#
|
363
|
+
#
|
326
364
|
# stroke do
|
327
365
|
# line(bounds.bottom_left, bounds.top_left)
|
328
366
|
# end
|
@@ -330,25 +368,25 @@ module Prawn
|
|
330
368
|
def bottom_left
|
331
369
|
[left,bottom]
|
332
370
|
end
|
333
|
-
|
371
|
+
|
334
372
|
# Absolute left x-coordinate of the bounding box
|
335
373
|
#
|
336
374
|
def absolute_left
|
337
375
|
@x
|
338
376
|
end
|
339
|
-
|
377
|
+
|
340
378
|
# Absolute right x-coordinate of the bounding box
|
341
379
|
#
|
342
380
|
def absolute_right
|
343
381
|
@x + width
|
344
382
|
end
|
345
|
-
|
383
|
+
|
346
384
|
# Absolute top y-coordinate of the bounding box
|
347
385
|
#
|
348
386
|
def absolute_top
|
349
387
|
@y
|
350
388
|
end
|
351
|
-
|
389
|
+
|
352
390
|
# Absolute bottom y-coordinate of the bottom box
|
353
391
|
#
|
354
392
|
def absolute_bottom
|
@@ -378,21 +416,22 @@ module Prawn
|
|
378
416
|
def absolute_bottom_right
|
379
417
|
[absolute_right, absolute_bottom]
|
380
418
|
end
|
381
|
-
|
419
|
+
|
382
420
|
# Width of the bounding box
|
383
421
|
#
|
384
422
|
def width
|
385
423
|
@width
|
386
424
|
end
|
387
|
-
|
425
|
+
|
388
426
|
# Height of the bounding box. If the box is 'stretchy' (unspecified
|
389
427
|
# height attribute), height is calculated as the distance from the top of
|
390
428
|
# the box to the current drawing position.
|
391
429
|
#
|
392
|
-
def height
|
430
|
+
def height
|
393
431
|
return @height if @height
|
394
|
-
@stretched_height = [(absolute_top - @
|
395
|
-
|
432
|
+
@stretched_height = [(absolute_top - @document.y),
|
433
|
+
@stretched_height.to_f].max
|
434
|
+
end
|
396
435
|
|
397
436
|
# an alias for absolute_left
|
398
437
|
def left_side
|
@@ -406,20 +445,20 @@ module Prawn
|
|
406
445
|
|
407
446
|
# starts a new page
|
408
447
|
def move_past_bottom
|
409
|
-
|
448
|
+
@document.start_new_page
|
410
449
|
end
|
411
450
|
|
412
451
|
|
413
452
|
alias_method :update_height, :height
|
414
|
-
|
453
|
+
|
415
454
|
# Returns +false+ when the box has a defined height, +true+ when the height
|
416
455
|
# is being calculated on the fly based on the current vertical position.
|
417
456
|
#
|
418
457
|
def stretchy?
|
419
|
-
!@height
|
458
|
+
!@height
|
420
459
|
end
|
421
460
|
|
422
|
-
end
|
423
|
-
|
461
|
+
end
|
462
|
+
|
424
463
|
end
|
425
464
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
#
|
3
|
+
# column_box.rb: Extends BoundingBox to allow for columns of text
|
4
|
+
#
|
5
|
+
# Author Paul Ostazeski.
|
6
|
+
|
7
|
+
require "prawn/document/bounding_box"
|
8
|
+
module Prawn
|
9
|
+
class Document
|
10
|
+
|
11
|
+
# A column box is a bounding box with the additional property that when
|
12
|
+
# text flows past the bottom, it will wrap first to another column on the
|
13
|
+
# same page, and only flow to the next page when all the columns are
|
14
|
+
# filled.
|
15
|
+
#
|
16
|
+
# column_box accepts the same parameters as bounding_box, as well as the
|
17
|
+
# number of :columns and a :spacer (in points) between columns.
|
18
|
+
#
|
19
|
+
# Defaults are :columns = 3 and :spacer = font_size
|
20
|
+
#
|
21
|
+
# Under PDF::Writer, "spacer" was known as "gutter"
|
22
|
+
#
|
23
|
+
def column_box(*args, &block)
|
24
|
+
init_column_box(block) do |parent_box|
|
25
|
+
map_to_absolute!(args[0])
|
26
|
+
@bounding_box = ColumnBox.new(self, parent_box, *args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def init_column_box(user_block, options={}, &init_block)
|
33
|
+
parent_box = @bounding_box
|
34
|
+
|
35
|
+
init_block.call(parent_box)
|
36
|
+
|
37
|
+
self.y = @bounding_box.absolute_top
|
38
|
+
user_block.call
|
39
|
+
self.y = @bounding_box.absolute_bottom unless options[:hold_position]
|
40
|
+
|
41
|
+
@bounding_box = parent_box
|
42
|
+
end
|
43
|
+
|
44
|
+
# Template methods to support ColumnBox extensions
|
45
|
+
class BoundingBox
|
46
|
+
|
47
|
+
# an alias for absolute_left
|
48
|
+
def left_side
|
49
|
+
absolute_left
|
50
|
+
end
|
51
|
+
|
52
|
+
# an alias for absolute_right
|
53
|
+
def right_side
|
54
|
+
absolute_right
|
55
|
+
end
|
56
|
+
|
57
|
+
# starts a new page
|
58
|
+
def move_past_bottom
|
59
|
+
@document.start_new_page
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Implements the necessary functionality to allow Document#column_box to
|
64
|
+
# work.
|
65
|
+
#
|
66
|
+
class ColumnBox < BoundingBox
|
67
|
+
|
68
|
+
def initialize(document, parent, point, options={}) #:nodoc:
|
69
|
+
super
|
70
|
+
@columns = options[:columns] || 3
|
71
|
+
@spacer = options[:spacer] || @document.font_size
|
72
|
+
@current_column = 0
|
73
|
+
end
|
74
|
+
|
75
|
+
# The column width, not the width of the whole box. Used to calculate
|
76
|
+
# how long a line of text can be.
|
77
|
+
#
|
78
|
+
def width
|
79
|
+
super / @columns - @spacer
|
80
|
+
end
|
81
|
+
|
82
|
+
# Column width including the spacer.
|
83
|
+
#
|
84
|
+
def width_of_column
|
85
|
+
width + @spacer
|
86
|
+
end
|
87
|
+
|
88
|
+
# x coordinate of the left edge of the current column
|
89
|
+
#
|
90
|
+
def left_side
|
91
|
+
absolute_left + (width_of_column * @current_column)
|
92
|
+
end
|
93
|
+
|
94
|
+
# x co-orordinate of the right edge of the current column
|
95
|
+
#
|
96
|
+
def right_side
|
97
|
+
columns_from_right = @columns - (1 + @current_column)
|
98
|
+
absolute_right - (width_of_column * columns_from_right)
|
99
|
+
end
|
100
|
+
|
101
|
+
# Moves to the next column or starts a new page if currently positioned at
|
102
|
+
# the rightmost column.
|
103
|
+
def move_past_bottom
|
104
|
+
@current_column = (@current_column + 1) % @columns
|
105
|
+
@document.y = @y
|
106
|
+
if 0 == @current_column
|
107
|
+
@document.start_new_page
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|