alphasights-prawn 0.10.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 (244) hide show
  1. data/COPYING +340 -0
  2. data/HACKING +50 -0
  3. data/LICENSE +56 -0
  4. data/README +141 -0
  5. data/Rakefile +52 -0
  6. data/data/encodings/win_ansi.txt +29 -0
  7. data/data/fonts/Action Man.dfont +0 -0
  8. data/data/fonts/Activa.ttf +0 -0
  9. data/data/fonts/Chalkboard.ttf +0 -0
  10. data/data/fonts/Courier-Bold.afm +342 -0
  11. data/data/fonts/Courier-BoldOblique.afm +342 -0
  12. data/data/fonts/Courier-Oblique.afm +342 -0
  13. data/data/fonts/Courier.afm +342 -0
  14. data/data/fonts/DejaVuSans.ttf +0 -0
  15. data/data/fonts/Dustismo_Roman.ttf +0 -0
  16. data/data/fonts/Helvetica-Bold.afm +2827 -0
  17. data/data/fonts/Helvetica-BoldOblique.afm +2827 -0
  18. data/data/fonts/Helvetica-Oblique.afm +3051 -0
  19. data/data/fonts/Helvetica.afm +3051 -0
  20. data/data/fonts/MustRead.html +19 -0
  21. data/data/fonts/Symbol.afm +213 -0
  22. data/data/fonts/Times-Bold.afm +2588 -0
  23. data/data/fonts/Times-BoldItalic.afm +2384 -0
  24. data/data/fonts/Times-Italic.afm +2667 -0
  25. data/data/fonts/Times-Roman.afm +2419 -0
  26. data/data/fonts/ZapfDingbats.afm +225 -0
  27. data/data/fonts/comicsans.ttf +0 -0
  28. data/data/fonts/gkai00mp.ttf +0 -0
  29. data/data/images/16bit.alpha +0 -0
  30. data/data/images/16bit.dat +0 -0
  31. data/data/images/16bit.png +0 -0
  32. data/data/images/arrow.png +0 -0
  33. data/data/images/arrow2.png +0 -0
  34. data/data/images/barcode_issue.png +0 -0
  35. data/data/images/dice.alpha +0 -0
  36. data/data/images/dice.dat +0 -0
  37. data/data/images/dice.png +0 -0
  38. data/data/images/dice_interlaced.png +0 -0
  39. data/data/images/fractal.jpg +0 -0
  40. data/data/images/letterhead.jpg +0 -0
  41. data/data/images/page_white_text.alpha +0 -0
  42. data/data/images/page_white_text.dat +0 -0
  43. data/data/images/page_white_text.png +0 -0
  44. data/data/images/pigs.jpg +0 -0
  45. data/data/images/rails.dat +0 -0
  46. data/data/images/rails.png +0 -0
  47. data/data/images/ruport.png +0 -0
  48. data/data/images/ruport_data.dat +0 -0
  49. data/data/images/ruport_transparent.png +0 -0
  50. data/data/images/ruport_type0.png +0 -0
  51. data/data/images/stef.jpg +0 -0
  52. data/data/images/tru256.bmp +0 -0
  53. data/data/images/web-links.dat +1 -0
  54. data/data/images/web-links.png +0 -0
  55. data/data/pdfs/complex_template.pdf +0 -0
  56. data/data/pdfs/contains_ttf_font.pdf +0 -0
  57. data/data/pdfs/encrypted.pdf +0 -0
  58. data/data/pdfs/hexagon.pdf +61 -0
  59. data/data/pdfs/indirect_reference.pdf +86 -0
  60. data/data/pdfs/nested_pages.pdf +118 -0
  61. data/data/pdfs/resources_as_indirect_object.pdf +83 -0
  62. data/data/pdfs/two_hexagons.pdf +90 -0
  63. data/data/pdfs/version_1_6.pdf +61 -0
  64. data/data/shift_jis_text.txt +1 -0
  65. data/examples/bounding_box/bounding_boxes.rb +43 -0
  66. data/examples/bounding_box/indentation.rb +34 -0
  67. data/examples/bounding_box/russian_boxes.rb +36 -0
  68. data/examples/bounding_box/stretched_nesting.rb +67 -0
  69. data/examples/builder/simple.rb +28 -0
  70. data/examples/example_helper.rb +4 -0
  71. data/examples/general/background.rb +23 -0
  72. data/examples/general/canvas.rb +15 -0
  73. data/examples/general/context_sensitive_headers.rb +37 -0
  74. data/examples/general/float.rb +11 -0
  75. data/examples/general/margin.rb +36 -0
  76. data/examples/general/measurement_units.rb +51 -0
  77. data/examples/general/metadata-info.rb +16 -0
  78. data/examples/general/multi_page_layout.rb +18 -0
  79. data/examples/general/outlines.rb +50 -0
  80. data/examples/general/page_geometry.rb +31 -0
  81. data/examples/general/page_numbering.rb +15 -0
  82. data/examples/general/repeaters.rb +47 -0
  83. data/examples/general/stamp.rb +41 -0
  84. data/examples/general/templates.rb +13 -0
  85. data/examples/graphics/basic_images.rb +23 -0
  86. data/examples/graphics/chunkable.rb +38 -0
  87. data/examples/graphics/cmyk.rb +12 -0
  88. data/examples/graphics/curves.rb +11 -0
  89. data/examples/graphics/hexagon.rb +13 -0
  90. data/examples/graphics/image_fit.rb +15 -0
  91. data/examples/graphics/image_flow.rb +37 -0
  92. data/examples/graphics/image_position.rb +17 -0
  93. data/examples/graphics/line.rb +32 -0
  94. data/examples/graphics/png_types.rb +22 -0
  95. data/examples/graphics/polygons.rb +16 -0
  96. data/examples/graphics/remote_images.rb +12 -0
  97. data/examples/graphics/rounded_polygons.rb +19 -0
  98. data/examples/graphics/rounded_rectangle.rb +20 -0
  99. data/examples/graphics/ruport_style_helpers.rb +19 -0
  100. data/examples/graphics/stroke_bounds.rb +20 -0
  101. data/examples/graphics/stroke_cap_and_join.rb +45 -0
  102. data/examples/graphics/stroke_dash.rb +42 -0
  103. data/examples/graphics/transformations.rb +52 -0
  104. data/examples/graphics/transparency.rb +26 -0
  105. data/examples/m17n/chinese_text_wrapping.rb +17 -0
  106. data/examples/m17n/euro.rb +15 -0
  107. data/examples/m17n/sjis.rb +28 -0
  108. data/examples/m17n/utf8.rb +13 -0
  109. data/examples/m17n/win_ansi_charset.rb +54 -0
  110. data/examples/security/hello_foo.rb +8 -0
  111. data/examples/table/bill.rb +53 -0
  112. data/examples/table/cell.rb +12 -0
  113. data/examples/table/checkerboard.rb +22 -0
  114. data/examples/table/header.rb +14 -0
  115. data/examples/table/inline_format_table.rb +12 -0
  116. data/examples/table/multi_page_table.rb +9 -0
  117. data/examples/table/simple_table.rb +24 -0
  118. data/examples/table/subtable.rb +12 -0
  119. data/examples/table/widths.rb +20 -0
  120. data/examples/text/alignment.rb +18 -0
  121. data/examples/text/character_spacing.rb +12 -0
  122. data/examples/text/dfont.rb +48 -0
  123. data/examples/text/family_based_styling.rb +24 -0
  124. data/examples/text/font_calculations.rb +91 -0
  125. data/examples/text/font_size.rb +33 -0
  126. data/examples/text/hyphenation.rb +45 -0
  127. data/examples/text/indent_paragraphs.rb +22 -0
  128. data/examples/text/inline_format.rb +103 -0
  129. data/examples/text/kerning.rb +30 -0
  130. data/examples/text/rotated.rb +98 -0
  131. data/examples/text/shaped_text_box.rb +31 -0
  132. data/examples/text/simple_text.rb +17 -0
  133. data/examples/text/simple_text_ttf.rb +17 -0
  134. data/examples/text/text_box.rb +88 -0
  135. data/examples/text/text_box_returning_excess.rb +51 -0
  136. data/examples/text/text_flow.rb +67 -0
  137. data/lib/prawn.rb +27 -0
  138. data/lib/prawn/canvas.rb +119 -0
  139. data/lib/prawn/chunkable.rb +37 -0
  140. data/lib/prawn/compatibility.rb +51 -0
  141. data/lib/prawn/core.rb +85 -0
  142. data/lib/prawn/core/annotations.rb +61 -0
  143. data/lib/prawn/core/byte_string.rb +9 -0
  144. data/lib/prawn/core/chunk.rb +36 -0
  145. data/lib/prawn/core/destinations.rb +90 -0
  146. data/lib/prawn/core/document_state.rb +78 -0
  147. data/lib/prawn/core/literal_string.rb +16 -0
  148. data/lib/prawn/core/name_tree.rb +165 -0
  149. data/lib/prawn/core/object_store.rb +236 -0
  150. data/lib/prawn/core/page.rb +179 -0
  151. data/lib/prawn/core/pdf_object.rb +108 -0
  152. data/lib/prawn/core/reference.rb +112 -0
  153. data/lib/prawn/core/text.rb +140 -0
  154. data/lib/prawn/core/text/formatted/arranger.rb +266 -0
  155. data/lib/prawn/core/text/formatted/line_wrap.rb +127 -0
  156. data/lib/prawn/core/text/formatted/wrap.rb +112 -0
  157. data/lib/prawn/core/text/line_wrap.rb +209 -0
  158. data/lib/prawn/core/text/wrap.rb +80 -0
  159. data/lib/prawn/document.rb +573 -0
  160. data/lib/prawn/document/bounding_box.rb +425 -0
  161. data/lib/prawn/document/graphics_state.rb +48 -0
  162. data/lib/prawn/document/internals.rb +170 -0
  163. data/lib/prawn/document/page_geometry.rb +136 -0
  164. data/lib/prawn/document/snapshot.rb +87 -0
  165. data/lib/prawn/document_builder.rb +51 -0
  166. data/lib/prawn/document_builder/command.rb +38 -0
  167. data/lib/prawn/document_builder/constructs.rb +2 -0
  168. data/lib/prawn/document_builder/constructs/flowing_text_construct.rb +18 -0
  169. data/lib/prawn/document_builder/constructs/path_construct.rb +9 -0
  170. data/lib/prawn/document_builder/layout.rb +25 -0
  171. data/lib/prawn/document_builder/modifications.rb +2 -0
  172. data/lib/prawn/document_builder/modifications/layout_modification.rb +9 -0
  173. data/lib/prawn/document_builder/modifications/path_modification.rb +9 -0
  174. data/lib/prawn/encoding.rb +121 -0
  175. data/lib/prawn/errors.rb +94 -0
  176. data/lib/prawn/font.rb +341 -0
  177. data/lib/prawn/font/afm.rb +225 -0
  178. data/lib/prawn/font/dfont.rb +42 -0
  179. data/lib/prawn/font/ttf.rb +350 -0
  180. data/lib/prawn/graphics.rb +325 -0
  181. data/lib/prawn/graphics/cap_style.rb +38 -0
  182. data/lib/prawn/graphics/color.rb +205 -0
  183. data/lib/prawn/graphics/dash.rb +71 -0
  184. data/lib/prawn/graphics/join_style.rb +38 -0
  185. data/lib/prawn/graphics/transformation.rb +156 -0
  186. data/lib/prawn/graphics/transparency.rb +99 -0
  187. data/lib/prawn/images.rb +348 -0
  188. data/lib/prawn/images/jpg.rb +46 -0
  189. data/lib/prawn/images/png.rb +226 -0
  190. data/lib/prawn/measurement_extensions.rb +46 -0
  191. data/lib/prawn/measurements.rb +71 -0
  192. data/lib/prawn/outline.rb +278 -0
  193. data/lib/prawn/repeater.rb +129 -0
  194. data/lib/prawn/security.rb +262 -0
  195. data/lib/prawn/security/arcfour.rb +51 -0
  196. data/lib/prawn/stamp.rb +126 -0
  197. data/lib/prawn/table.rb +421 -0
  198. data/lib/prawn/table/accessors.rb +180 -0
  199. data/lib/prawn/table/cell.rb +350 -0
  200. data/lib/prawn/table/cell/in_table.rb +27 -0
  201. data/lib/prawn/table/cell/subtable.rb +65 -0
  202. data/lib/prawn/table/cell/text.rb +125 -0
  203. data/lib/prawn/text.rb +449 -0
  204. data/lib/prawn/text/box.rb +392 -0
  205. data/lib/prawn/text/formatted.rb +4 -0
  206. data/lib/prawn/text/formatted/box.rb +228 -0
  207. data/lib/prawn/text/formatted/fragment.rb +181 -0
  208. data/lib/prawn/text/formatted/parser.rb +213 -0
  209. data/spec/annotations_spec.rb +90 -0
  210. data/spec/bounding_box_spec.rb +190 -0
  211. data/spec/cell_spec.rb +348 -0
  212. data/spec/destinations_spec.rb +15 -0
  213. data/spec/document_spec.rb +473 -0
  214. data/spec/font_spec.rb +324 -0
  215. data/spec/formatted_text_arranger_spec.rb +426 -0
  216. data/spec/formatted_text_box_spec.rb +756 -0
  217. data/spec/formatted_text_fragment_spec.rb +211 -0
  218. data/spec/graphics_spec.rb +446 -0
  219. data/spec/images_spec.rb +96 -0
  220. data/spec/inline_formatted_text_parser_spec.rb +502 -0
  221. data/spec/jpg_spec.rb +25 -0
  222. data/spec/line_wrap_spec.rb +341 -0
  223. data/spec/measurement_units_spec.rb +23 -0
  224. data/spec/name_tree_spec.rb +112 -0
  225. data/spec/object_store_spec.rb +160 -0
  226. data/spec/outline_spec.rb +269 -0
  227. data/spec/pdf_object_spec.rb +170 -0
  228. data/spec/png_spec.rb +237 -0
  229. data/spec/reference_spec.rb +82 -0
  230. data/spec/repeater_spec.rb +96 -0
  231. data/spec/security_spec.rb +120 -0
  232. data/spec/snapshot_spec.rb +138 -0
  233. data/spec/spec_helper.rb +26 -0
  234. data/spec/stamp_spec.rb +108 -0
  235. data/spec/stroke_styles_spec.rb +163 -0
  236. data/spec/table_spec.rb +598 -0
  237. data/spec/template_spec.rb +158 -0
  238. data/spec/text_at_spec.rb +119 -0
  239. data/spec/text_box_spec.rb +742 -0
  240. data/spec/text_spacing_spec.rb +75 -0
  241. data/spec/text_spec.rb +333 -0
  242. data/spec/text_with_inline_formatting_spec.rb +193 -0
  243. data/spec/transparency_spec.rb +89 -0
  244. metadata +331 -0
@@ -0,0 +1,425 @@
1
+ # encoding: utf-8
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
+ module Prawn
10
+ class Document
11
+
12
+ # :call-seq:
13
+ # bounding_box(point, options={}, &block)
14
+ #
15
+ # A bounding box serves two important purposes:
16
+ # * Provide bounds for flowing text, starting at a given point
17
+ # * Translate the origin (0,0) for graphics primitives
18
+ #
19
+ # A point and :width must be provided. :height is optional.
20
+ # (See stretchyness below)
21
+ #
22
+ # ==Positioning
23
+ #
24
+ # Bounding boxes are positioned relative to their top left corner and
25
+ # the width measurement is towards the right and height measurement is
26
+ # downwards.
27
+ #
28
+ # Usage:
29
+ #
30
+ # * Bounding box 100pt x 100pt in the absolute bottom left of the
31
+ # containing box:
32
+ #
33
+ # pdf.bounding_box([0,100], :width => 100, :height => 100)
34
+ # stroke_bounds
35
+ # end
36
+ #
37
+ # * Bounding box 200pt x 400pt high in the center of the page:
38
+ #
39
+ # x_pos = ((bounds.width / 2) - 150)
40
+ # y_pos = ((bounds.height / 2) + 200)
41
+ # pdf.bounding_box([x_pos, y_pos], :width => 300, :height => 400) do
42
+ # stroke_bounds
43
+ # end
44
+ #
45
+ # ==Flowing Text
46
+ #
47
+ # When flowing text, the usage of a bounding box is simple. Text will
48
+ # begin at the point specified, flowing the width of the bounding box.
49
+ # After the block exits, the cursor position will be moved to
50
+ # the bottom of the bounding box (y - height). If flowing text exceeds
51
+ # the height of the bounding box, the text will be continued on the next
52
+ # page, starting again at the top-left corner of the bounding box.
53
+ #
54
+ # Usage:
55
+ #
56
+ # pdf.bounding_box([100,500], :width => 100, :height => 300) do
57
+ # pdf.text "This text will flow in a very narrow box starting" +
58
+ # "from [100,500]. The pointer will then be moved to [100,200]" +
59
+ # "and return to the margin_box"
60
+ # end
61
+ #
62
+ # Note, this is a low level tool and is designed primarily for building
63
+ # other abstractions. If you just need to flow text on the page, you
64
+ # will want to look at text_box() instead
65
+ #
66
+ # ==Translating Coordinates
67
+ #
68
+ # When translating coordinates, the idea is to allow the user to draw
69
+ # relative to the origin, and then translate their drawing to a specified
70
+ # area of the document, rather than adjust all their drawing coordinates
71
+ # to match this new region.
72
+ #
73
+ # Take for example two triangles which share one point, drawn from the
74
+ # origin:
75
+ #
76
+ # pdf.polygon [0,250], [0,0], [150,100]
77
+ # pdf.polygon [100,0], [150,100], [200,0]
78
+ #
79
+ # It would be easy enough to translate these triangles to another point,
80
+ # e.g [200,200]
81
+ #
82
+ # pdf.polygon [200,450], [200,200], [350,300]
83
+ # pdf.polygon [300,200], [350,300], [400,200]
84
+ #
85
+ # However, each time you want to move the drawing, you'd need to alter
86
+ # every point in the drawing calls, which as you might imagine, can become
87
+ # tedious.
88
+ #
89
+ # If instead, we think of the drawing as being bounded by a box, we can
90
+ # see that the image is 200 points wide by 250 points tall.
91
+ #
92
+ # To translate it to a new origin, we simply select a point at (x,y+height)
93
+ #
94
+ # Using the [200,200] example:
95
+ #
96
+ # pdf.bounding_box([200,450], :width => 200, :height => 250) do
97
+ # pdf.stroke do
98
+ # pdf.polygon [0,250], [0,0], [150,100]
99
+ # pdf.polygon [100,0], [150,100], [200,0]
100
+ # end
101
+ # end
102
+ #
103
+ # Notice that the drawing is still relative to the origin. If we want to
104
+ # move this drawing around the document, we simply need to recalculate the
105
+ # top-left corner of the rectangular bounding-box, and all of our graphics
106
+ # calls remain unmodified.
107
+ #
108
+ # ==Nesting Bounding Boxes
109
+ #
110
+ # At the top level, bounding boxes are specified relative to the document's
111
+ # margin_box (which is itself a bounding box). You can also nest bounding
112
+ # boxes, allowing you to build components which are relative to each other
113
+ #
114
+ # Usage:
115
+ #
116
+ # pdf.bounding_box([200,450], :width => 200, :height => 250) do
117
+ # pdf.stroke_bounds # Show the containing bounding box
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
120
+ # # the parent bounding box.
121
+ # pdf.stroke_bounds
122
+ # end
123
+ # end
124
+ #
125
+ # ==Stretchyness
126
+ #
127
+ # If you do not specify a height to a bounding box, it will become stretchy
128
+ # and its height will be calculated automatically as you stretch the box
129
+ # downwards.
130
+ #
131
+ # pdf.bounding_box([100,400], :width => 400) do
132
+ # pdf.text("The height of this box is #{pdf.bounds.height}")
133
+ # pdf.text('this is some text')
134
+ # pdf.text('this is some more text')
135
+ # pdf.text('and finally a bit more')
136
+ # pdf.text("Now the height of this box is #{pdf.bounds.height}")
137
+ # end
138
+ #
139
+ # ==Absolute Positioning
140
+ #
141
+ # If you wish to position the bounding boxes at absolute coordinates rather
142
+ # than relative to the margins or other bounding boxes, you can use canvas()
143
+ #
144
+ # pdf.bounding_box([50,500], :width => 200, :height => 300) do
145
+ # pdf.stroke_bounds
146
+ # pdf.canvas do
147
+ # Positioned outside the containing box at the 'real' (300,450)
148
+ # pdf.bounding_box([300,450], :width => 200, :height => 200) do
149
+ # pdf.stroke_bounds
150
+ # end
151
+ # end
152
+ # end
153
+ #
154
+ # Of course, if you use canvas, you will be responsible for ensuring that
155
+ # you remain within the printable area of your document.
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)
161
+ end
162
+ end
163
+
164
+ # A shortcut to produce a bounding box which is mapped to the document's
165
+ # absolute coordinates, regardless of how things are nested or margin sizes.
166
+ #
167
+ # pdf.canvas do
168
+ # pdf.line pdf.bounds.bottom_left, pdf.bounds.top_right
169
+ # end
170
+ #
171
+ def canvas(&block)
172
+ init_bounding_box(block, :hold_position => true) do |_|
173
+ @bounding_box = BoundingBox.new(self, [0,page.dimensions[3]],
174
+ :width => page.dimensions[2],
175
+ :height => page.dimensions[3]
176
+ )
177
+ end
178
+ end
179
+
180
+ private
181
+
182
+ def init_bounding_box(user_block, options={}, &init_block)
183
+ parent_box = @bounding_box
184
+
185
+ init_block.call(parent_box)
186
+
187
+ self.y = @bounding_box.absolute_top
188
+ user_block.call
189
+ self.y = @bounding_box.absolute_bottom unless options[:hold_position]
190
+
191
+ created_box, @bounding_box = @bounding_box, parent_box
192
+
193
+ return created_box
194
+ end
195
+
196
+ # Low level layout helper that simplifies coordinate math.
197
+ #
198
+ # See Prawn::Document#bounding_box for a description of what this class
199
+ # is used for.
200
+ #
201
+ class BoundingBox
202
+
203
+ def initialize(parent, point, options={}) #:nodoc:
204
+ unless options[:width]
205
+ raise ArgumentError, "BoundingBox needs the :width option to be set"
206
+ end
207
+
208
+ @parent = parent
209
+ @x, @y = point
210
+ @width, @height = options[:width], options[:height]
211
+ @stretched_height = nil
212
+ end
213
+
214
+ attr_reader :parent
215
+
216
+ # The translated origin (x,y-height) which describes the location
217
+ # of the bottom left corner of the bounding box
218
+ #
219
+ def anchor
220
+ [@x, @y - height]
221
+ end
222
+
223
+ # Relative left x-coordinate of the bounding box. (Always 0)
224
+ #
225
+ # Example, position some text 3 pts from the left of the containing box:
226
+ #
227
+ # draw_text('hello', :at => [(bounds.left + 3), 0])
228
+ #
229
+ def left
230
+ 0
231
+ end
232
+
233
+
234
+ # Temporarily adjust the @x coordinate to allow for left_padding
235
+ #
236
+ # Example:
237
+ #
238
+ # indent 20 do
239
+ # text "20 points in"
240
+ # indent 30 do
241
+ # text "50 points in"
242
+ # end
243
+ # end
244
+ #
245
+ def indent(left_padding, &block)
246
+ @x += left_padding
247
+ @width -= left_padding
248
+ yield
249
+ ensure
250
+ @x -= left_padding
251
+ @width += left_padding
252
+ end
253
+
254
+ # Relative right x-coordinate of the bounding box. (Equal to the box width)
255
+ #
256
+ # Example, position some text 3 pts from the right of the containing box:
257
+ #
258
+ # draw_text('hello', :at => [(bounds.right - 3), 0])
259
+ #
260
+ def right
261
+ @width
262
+ end
263
+
264
+ # Relative top y-coordinate of the bounding box. (Equal to the box height)
265
+ #
266
+ # Example, position some text 3 pts from the top of the containing box:
267
+ #
268
+ # draw_text('hello', :at => [0, (bounds.top - 3)])
269
+ #
270
+ def top
271
+ height
272
+ end
273
+
274
+ # Relative bottom y-coordinate of the bounding box (Always 0)
275
+ #
276
+ # Example, position some text 3 pts from the bottom of the containing box:
277
+ #
278
+ # draw_text('hello', :at => [0, (bounds.bottom + 3)])
279
+ #
280
+ def bottom
281
+ 0
282
+ end
283
+
284
+ # Relative top-left point of the bounding_box
285
+ #
286
+ # Example, draw a line from the top left of the box diagonally to the
287
+ # bottom right:
288
+ #
289
+ # stroke do
290
+ # line(bounds.top_left, bounds.bottom_right)
291
+ # end
292
+ #
293
+ def top_left
294
+ [left,top]
295
+ end
296
+
297
+ # Relative top-right point of the bounding box
298
+ #
299
+ # Example, draw a line from the top_right of the box diagonally to the
300
+ # bottom left:
301
+ #
302
+ # stroke do
303
+ # line(bounds.top_right, bounds.bottom_left)
304
+ # end
305
+ #
306
+ def top_right
307
+ [right,top]
308
+ end
309
+
310
+ # Relative bottom-right point of the bounding box
311
+ #
312
+ # Example, draw a line along the right hand side of the page:
313
+ #
314
+ # stroke do
315
+ # line(bounds.bottom_right, bounds.top_right)
316
+ # end
317
+ #
318
+ def bottom_right
319
+ [right,bottom]
320
+ end
321
+
322
+ # Relative bottom-left point of the bounding box
323
+ #
324
+ # Example, draw a line along the left hand side of the page:
325
+ #
326
+ # stroke do
327
+ # line(bounds.bottom_left, bounds.top_left)
328
+ # end
329
+ #
330
+ def bottom_left
331
+ [left,bottom]
332
+ end
333
+
334
+ # Absolute left x-coordinate of the bounding box
335
+ #
336
+ def absolute_left
337
+ @x
338
+ end
339
+
340
+ # Absolute right x-coordinate of the bounding box
341
+ #
342
+ def absolute_right
343
+ @x + width
344
+ end
345
+
346
+ # Absolute top y-coordinate of the bounding box
347
+ #
348
+ def absolute_top
349
+ @y
350
+ end
351
+
352
+ # Absolute bottom y-coordinate of the bottom box
353
+ #
354
+ def absolute_bottom
355
+ @y - height
356
+ end
357
+
358
+ # Absolute top-left point of the bounding box
359
+ #
360
+ def absolute_top_left
361
+ [absolute_left, absolute_top]
362
+ end
363
+
364
+ # Absolute top-right point of the bounding box
365
+ #
366
+ def absolute_top_right
367
+ [absolute_right, absolute_top]
368
+ end
369
+
370
+ # Absolute bottom-left point of the bounding box
371
+ #
372
+ def absolute_bottom_left
373
+ [absolute_left, absolute_bottom]
374
+ end
375
+
376
+ # Absolute bottom-left point of the bounding box
377
+ #
378
+ def absolute_bottom_right
379
+ [absolute_right, absolute_bottom]
380
+ end
381
+
382
+ # Width of the bounding box
383
+ #
384
+ def width
385
+ @width
386
+ end
387
+
388
+ # Height of the bounding box. If the box is 'stretchy' (unspecified
389
+ # height attribute), height is calculated as the distance from the top of
390
+ # the box to the current drawing position.
391
+ #
392
+ def height
393
+ return @height if @height
394
+ @stretched_height = [(absolute_top - @parent.y), @stretched_height.to_f].max
395
+ end
396
+
397
+ # an alias for absolute_left
398
+ def left_side
399
+ absolute_left
400
+ end
401
+
402
+ # an alias for absolute_right
403
+ def right_side
404
+ absolute_right
405
+ end
406
+
407
+ # starts a new page
408
+ def move_past_bottom
409
+ @parent.start_new_page
410
+ end
411
+
412
+
413
+ alias_method :update_height, :height
414
+
415
+ # Returns +false+ when the box has a defined height, +true+ when the height
416
+ # is being calculated on the fly based on the current vertical position.
417
+ #
418
+ def stretchy?
419
+ !@height
420
+ end
421
+
422
+ end
423
+
424
+ end
425
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ #
3
+ # graphics_state.rb: Implements graphics state saving and restoring
4
+ #
5
+ # Copyright January 2010, Michael Witrant. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ #
9
+
10
+ module Prawn
11
+ class Document
12
+ module GraphicsState
13
+
14
+ # Pushes the current graphics state on to the graphics state stack so we
15
+ # can restore it when finished with a change we want to isolate (such as
16
+ # modifying the transformation matrix). Used in pairs with
17
+ # restore_graphics_state or passed a block
18
+ #
19
+ # Example without a block:
20
+ #
21
+ # save_graphics_state
22
+ # rotate 30
23
+ # text "rotated text"
24
+ # restore_graphics_state
25
+ #
26
+ # Example with a block:
27
+ #
28
+ # save_graphics_state do
29
+ # rotate 30
30
+ # text "rotated text"
31
+ # end
32
+ #
33
+ def save_graphics_state
34
+ add_content "q"
35
+ if block_given?
36
+ yield
37
+ restore_graphics_state
38
+ end
39
+ end
40
+
41
+ # Pops the last saved graphics state off the graphics state stack and
42
+ # restores the state to those values
43
+ def restore_graphics_state
44
+ add_content "Q"
45
+ end
46
+ end
47
+ end
48
+ end