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,350 @@
1
+ # encoding: utf-8
2
+
3
+ # cell.rb: Table cell drawing.
4
+ #
5
+ # Copyright December 2009, Gregory Brown and Brad Ediger. 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
+ # Instantiates and draws a cell on the document.
13
+ #
14
+ # cell(:content => "Hello world!", :at => [12, 34])
15
+ #
16
+ # See Prawn::Table::Cell.make for full options.
17
+ #
18
+ def cell(options={})
19
+ cell = Table::Cell.make(self, options.delete(:content), options)
20
+ cell.draw
21
+ cell
22
+ end
23
+
24
+ end
25
+
26
+ class Table
27
+
28
+ # A Cell is a rectangular area of the page into which content is drawn. It
29
+ # has a framework for sizing itself and adding padding and simple styling.
30
+ # There are several standard Cell subclasses that handle things like text,
31
+ # Tables, and (in the future) stamps, images, and arbitrary content.
32
+ #
33
+ # Cells are a basic building block for table support (see Prawn::Table).
34
+ #
35
+ # Please subclass me if you want new content types! I'm designed to be very
36
+ # extensible. See the different standard Cell subclasses in
37
+ # lib/prawn/table/cell/*.rb for a template.
38
+ #
39
+ class Cell
40
+
41
+ # Amount of dead space (in PDF points) inside the borders but outside the
42
+ # content. Padding defaults to 5pt.
43
+ #
44
+ attr_reader :padding
45
+
46
+ # If provided, the minimum width that this cell will permit.
47
+ #
48
+ attr_reader :min_width
49
+
50
+ # If provided, the maximum width that this cell can be drawn in.
51
+ #
52
+ attr_reader :max_width
53
+
54
+ # Manually specify the cell's height.
55
+ #
56
+ attr_writer :height
57
+
58
+ # Specifies which borders to enable. Must be an array of zero or more of:
59
+ # <tt>[:left, :right, :top, :bottom]</tt>.
60
+ #
61
+ attr_accessor :borders
62
+
63
+ # Specifies the width, in PDF points, of the cell's borders.
64
+ #
65
+ attr_accessor :border_width
66
+
67
+ # Specifies the color of the cell borders. Given in HTML RGB format, e.g.,
68
+ # "ccffff".
69
+ #
70
+ attr_accessor :border_color
71
+
72
+ # Specifies the content for the cell. Must be a "cellable" object. See the
73
+ # "Data" section of the Prawn::Table documentation for details on cellable
74
+ # objects.
75
+ #
76
+ attr_accessor :content
77
+
78
+ # The background color, if any, for this cell. Specified in HTML RGB
79
+ # format, e.g., "ccffff". The background is drawn under the whole cell,
80
+ # including any padding.
81
+ #
82
+ attr_accessor :background_color
83
+
84
+ # Instantiates a Cell based on the given options. The particular class of
85
+ # cell returned depends on the :content argument. See the Prawn::Table
86
+ # documentation under "Data" for allowable content types.
87
+ #
88
+ def self.make(pdf, content, options={})
89
+ at = options.delete(:at) || [0, pdf.cursor]
90
+ content = "" if content.nil?
91
+ options[:content] = content
92
+
93
+ case content
94
+ when Prawn::Table::Cell
95
+ content
96
+ when String
97
+ Cell::Text.new(pdf, at, options)
98
+ when Prawn::Table
99
+ Cell::Subtable.new(pdf, at, options)
100
+ when Array
101
+ subtable = Prawn::Table.new(options[:content], pdf, {})
102
+ Cell::Subtable.new(pdf, at, options.merge(:content => subtable))
103
+ else
104
+ # TODO: other types of content
105
+ raise ArgumentError, "Content type not recognized: #{content.inspect}"
106
+ end
107
+ end
108
+
109
+ # A small amount added to the bounding box width to cover over floating-
110
+ # point errors when round-tripping from content_width to width and back.
111
+ # This does not change cell positioning; it only slightly expands each
112
+ # cell's bounding box width so that rounding error does not prevent a cell
113
+ # from rendering.
114
+ #
115
+ FPTolerance = 1
116
+
117
+ # Sets up a cell on the document +pdf+, at the given x/y location +point+,
118
+ # with the given +options+. Cell, like Table, follows the "options set
119
+ # accessors" paradigm (see "Options" under the Table documentation), so
120
+ # any cell accessor <tt>cell.foo = :bar</tt> can be set by providing the
121
+ # option <tt>:foo => :bar</tt> here.
122
+ #
123
+ def initialize(pdf, point, options={})
124
+ @pdf = pdf
125
+ @point = point
126
+
127
+ # Set defaults; these can be changed by options
128
+ @padding = [5, 5, 5, 5]
129
+ @borders = [:top, :bottom, :left, :right]
130
+ @border_width = 1
131
+ @border_color = '000000'
132
+
133
+ options.each { |k, v| send("#{k}=", v) }
134
+
135
+ # Sensible defaults for min / max.
136
+ @min_width = padding_left + padding_right
137
+ @max_width = @pdf.bounds.width
138
+ end
139
+
140
+ # Returns the cell's width in points, inclusive of padding.
141
+ #
142
+ def width
143
+ # We can't ||= here because the FP error accumulates on the round-trip
144
+ # from #content_width.
145
+ @width || (content_width + padding_left + padding_right)
146
+ end
147
+
148
+ # Manually sets the cell's width, inclusive of padding.
149
+ #
150
+ def width=(w)
151
+ @width = @min_width = @max_width = w
152
+ end
153
+
154
+ # Returns the width of the bare content in the cell, excluding padding.
155
+ #
156
+ def content_width
157
+ if @width # manually set
158
+ return @width - padding_left - padding_right
159
+ end
160
+
161
+ natural_content_width
162
+ end
163
+
164
+ # Returns the width this cell would naturally take on, absent other
165
+ # constraints. Must be implemented in subclasses.
166
+ #
167
+ def natural_content_width
168
+ raise NotImplementedError,
169
+ "subclasses must implement natural_content_width"
170
+ end
171
+
172
+ # Returns the cell's height in points, inclusive of padding.
173
+ #
174
+ def height
175
+ # We can't ||= here because the FP error accumulates on the round-trip
176
+ # from #content_height.
177
+ @height || (content_height + padding_top + padding_bottom)
178
+ end
179
+
180
+ # Returns the height of the bare content in the cell, excluding padding.
181
+ #
182
+ def content_height
183
+ if @height # manually set
184
+ return @height - padding_top - padding_bottom
185
+ end
186
+
187
+ natural_content_height
188
+ end
189
+
190
+ # Returns the height this cell would naturally take on, absent
191
+ # constraints. Must be implemented in subclasses.
192
+ #
193
+ def natural_content_height
194
+ raise NotImplementedError,
195
+ "subclasses must implement natural_content_height"
196
+ end
197
+
198
+ # Draws the cell onto the document. Pass in a point [x,y] to override the
199
+ # location at which the cell is drawn.
200
+ #
201
+ def draw(pt=[x, y])
202
+ draw_background(pt)
203
+ draw_borders(pt)
204
+ @pdf.bounding_box([pt[0] + padding_left, pt[1] - padding_top],
205
+ :width => content_width + FPTolerance,
206
+ :height => content_height + FPTolerance) do
207
+ draw_content
208
+ end
209
+ end
210
+
211
+ # x-position of the cell within the parent bounds.
212
+ #
213
+ def x
214
+ @point[0]
215
+ end
216
+
217
+ # Set the x-position of the cell within the parent bounds.
218
+ #
219
+ def x=(val)
220
+ @point[0] = val
221
+ end
222
+
223
+ # y-position of the cell within the parent bounds.
224
+ #
225
+ def y
226
+ @point[1]
227
+ end
228
+
229
+ # Set the y-position of the cell within the parent bounds.
230
+ #
231
+ def y=(val)
232
+ @point[1] = val
233
+ end
234
+
235
+ # Sets padding on this cell. The argument can be one of:
236
+ #
237
+ # * an integer (sets all padding)
238
+ # * a two-element array [vertical, horizontal]
239
+ # * a three-element array [top, horizontal, bottom]
240
+ # * a four-element array [top, right, bottom, left]
241
+ #
242
+ def padding=(pad)
243
+ @padding = case
244
+ when pad.nil?
245
+ [0, 0, 0, 0]
246
+ when Numeric === pad # all padding
247
+ [pad, pad, pad, pad]
248
+ when pad.length == 2 # vert, horiz
249
+ [pad[0], pad[1], pad[0], pad[1]]
250
+ when pad.length == 3 # top, horiz, bottom
251
+ [pad[0], pad[1], pad[2], pad[1]]
252
+ when pad.length == 4 # top, right, bottom, left
253
+ [pad[0], pad[1], pad[2], pad[3]]
254
+ else
255
+ raise ArgumentError, ":padding must be a number or an array [v,h] " +
256
+ "or [t,r,b,l]"
257
+ end
258
+ end
259
+
260
+ protected
261
+
262
+ # Draws the cell's background color.
263
+ #
264
+ def draw_background(pt)
265
+ x, y = pt
266
+ margin = @border_width / 2
267
+ if @background_color
268
+ @pdf.mask(:fill_color) do
269
+ @pdf.fill_color @background_color
270
+ h = @borders.include?(:bottom) ? height - (2*margin) :
271
+ height + margin
272
+ @pdf.fill_rectangle [x, y], width, h
273
+ end
274
+ end
275
+ end
276
+
277
+ # Draws borders around the cell. Borders are centered on the bounds of
278
+ # the cell outside of any padding, so the caller is responsible for
279
+ # setting appropriate padding to ensure the border does not overlap with
280
+ # cell content.
281
+ #
282
+ def draw_borders(pt)
283
+ x, y = pt
284
+ return if @border_width <= 0
285
+ # Draw left / right borders one-half border width beyond the center of
286
+ # the corner, so that the corners end up square.
287
+ margin = @border_width / 2.0
288
+
289
+ @pdf.mask(:line_width, :stroke_color) do
290
+ @pdf.line_width = @border_width
291
+ @pdf.stroke_color = @border_color if @border_color
292
+
293
+ @borders.each do |border|
294
+ from, to = case border
295
+ when :top
296
+ [[x, y], [x+width, y]]
297
+ when :bottom
298
+ [[x, y-height], [x+width, y-height]]
299
+ when :left
300
+ [[x, y+margin], [x, y-height-margin]]
301
+ when :right
302
+ [[x+width, y+margin], [x+width, y-height-margin]]
303
+ end
304
+ @pdf.stroke_line(from, to)
305
+ end
306
+ end
307
+ end
308
+
309
+ # Draws cell content within the cell's bounding box. Must be implemented
310
+ # in subclasses.
311
+ #
312
+ def draw_content
313
+ raise NotImplementedError, "subclasses must implement draw_content"
314
+ end
315
+
316
+ def padding_top
317
+ @padding[0]
318
+ end
319
+
320
+ def padding_top=(val)
321
+ @padding[0] = val
322
+ end
323
+
324
+ def padding_right
325
+ @padding[1]
326
+ end
327
+
328
+ def padding_right=(val)
329
+ @padding[1] = val
330
+ end
331
+
332
+ def padding_bottom
333
+ @padding[2]
334
+ end
335
+
336
+ def padding_bottom=(val)
337
+ @padding[2] = val
338
+ end
339
+
340
+ def padding_left
341
+ @padding[3]
342
+ end
343
+
344
+ def padding_left=(val)
345
+ @padding[3] = val
346
+ end
347
+
348
+ end
349
+ end
350
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ # Accessors for using a Cell inside a Table.
4
+
5
+ module Prawn
6
+ class Table
7
+ class Cell
8
+
9
+ # This module extends Cell objects when they are used in a table (as
10
+ # opposed to standalone). Its properties apply to cells-in-tables but not
11
+ # cells themselves.
12
+ #
13
+ module InTable
14
+
15
+ # Row number (0-based).
16
+ #
17
+ attr_accessor :row
18
+
19
+ # Column number (0-based).
20
+ #
21
+ attr_accessor :column
22
+
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ # subtable.rb: Yo dawg.
4
+ #
5
+ # Copyright January 2010, Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # A Cell that contains another table.
13
+ #
14
+ class Subtable < Cell
15
+
16
+ attr_reader :subtable
17
+
18
+ def initialize(pdf, point, options={})
19
+ super
20
+ @subtable = options[:content]
21
+
22
+ # Subtable padding defaults to zero
23
+ @padding = [0, 0, 0, 0]
24
+ end
25
+
26
+ # Sets the text color of the entire subtable.
27
+ #
28
+ def text_color=(color)
29
+ @subtable.cells.text_color = color
30
+ end
31
+
32
+ # Proxied to subtable.
33
+ #
34
+ def natural_content_width
35
+ @subtable.cells.width
36
+ end
37
+
38
+ # Proxied to subtable.
39
+ #
40
+ def min_width
41
+ @subtable.cells.min_width
42
+ end
43
+
44
+ # Proxied to subtable.
45
+ #
46
+ def max_width
47
+ @subtable.cells.max_width
48
+ end
49
+
50
+ # Proxied to subtable.
51
+ #
52
+ def natural_content_height
53
+ @subtable.cells.height
54
+ end
55
+
56
+ # Draws the subtable.
57
+ #
58
+ def draw_content
59
+ @subtable.draw
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,125 @@
1
+ # encoding: utf-8
2
+
3
+ # text.rb: Text table cells.
4
+ #
5
+ # Copyright December 2009, Gregory Brown and Brad Ediger. All Rights Reserved.
6
+ #
7
+ # This is free software. Please see the LICENSE and COPYING files for details.
8
+ module Prawn
9
+ class Table
10
+ class Cell
11
+
12
+ # A Cell that contains text. Has some limited options to set font family,
13
+ # size, and style.
14
+ #
15
+ class Text < Cell
16
+
17
+ TextOptions = [:inline_format, :kerning, :size, :style,
18
+ :align, :valign, :rotate, :rotate_around, :leading, :single_line,
19
+ :skip_encoding, :overflow, :min_font_size]
20
+
21
+ TextOptions.each do |option|
22
+ define_method("#{option}=") { |v| @text_options[option] = v }
23
+ define_method(option) { @text_options[option] }
24
+ end
25
+
26
+ attr_writer :font, :text_color
27
+
28
+ def initialize(pdf, point, options={})
29
+ @text_options = {}
30
+ super
31
+
32
+ # Sets a reasonable minimum width. If the cell has any content, make
33
+ # sure we have enough width to be at least one character wide. This is
34
+ # a bit of a hack, but it should work well enough.
35
+ min_content_width = [natural_content_width, styled_width_of("M")].min
36
+ @min_width = padding_left + padding_right + min_content_width
37
+ end
38
+
39
+ # Returns the font that will be used to draw this cell.
40
+ #
41
+ def font
42
+ with_font { @pdf.font }
43
+ end
44
+
45
+ # Returns the width of this text with no wrapping. This will be far off
46
+ # from the final width if the text is long.
47
+ #
48
+ def natural_content_width
49
+ [styled_width_of(@content), @pdf.bounds.width].min
50
+ end
51
+
52
+ # Returns the natural height of this block of text, wrapped to the
53
+ # preset width.
54
+ #
55
+ def natural_content_height
56
+ with_font do
57
+ b = text_box(:width => content_width + FPTolerance)
58
+ b.render(:dry_run => true)
59
+ b.height
60
+ end
61
+ end
62
+
63
+ # Draws the text content into its bounding box.
64
+ #
65
+ def draw_content
66
+ with_font do
67
+ @pdf.move_down((@pdf.font.line_gap + @pdf.font.descender)/2)
68
+ with_text_color do
69
+ text_box(:width => content_width + FPTolerance,
70
+ :height => content_height + FPTolerance,
71
+ :at => [0, @pdf.cursor]).render
72
+ end
73
+ end
74
+ end
75
+
76
+ protected
77
+
78
+ def with_font
79
+ @pdf.save_font do
80
+ options = {}
81
+ options[:style] = @text_options[:style] if @text_options[:style]
82
+
83
+ @pdf.font(@font || @pdf.font.name, options)
84
+
85
+ yield
86
+ end
87
+ end
88
+
89
+ def with_text_color
90
+ old_color = @pdf.fill_color || '000000'
91
+ @pdf.fill_color(@text_color) if @text_color
92
+ yield
93
+ ensure
94
+ @pdf.fill_color(old_color)
95
+ end
96
+
97
+ def text_box(extra_options={})
98
+ if @text_options[:inline_format]
99
+ options = @text_options.dup
100
+ options.delete(:inline_format)
101
+
102
+ array = ::Prawn::Text::Formatted::Parser.to_array(@content)
103
+ ::Prawn::Text::Formatted::Box.new(array,
104
+ options.merge(extra_options).merge(:document => @pdf))
105
+ else
106
+ ::Prawn::Text::Box.new(@content, @text_options.merge(extra_options).
107
+ merge(:document => @pdf))
108
+ end
109
+ end
110
+
111
+ # Returns the width of +text+ under the given text options.
112
+ #
113
+ def styled_width_of(text)
114
+ with_font do
115
+ options = {}
116
+ options[:size] = @text_options[:size] if @text_options[:size]
117
+
118
+ @pdf.font.compute_width_of(text, options)
119
+ end
120
+ end
121
+
122
+ end
123
+ end
124
+ end
125
+ end