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,90 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ class PageAnnotations
6
+ attr_reader :pages
7
+
8
+ def self.parse(document)
9
+ receiver = new
10
+ PDF::Reader.string(document.render, receiver)
11
+ return receiver
12
+ end
13
+
14
+ def initialize
15
+ @pages = []
16
+ end
17
+
18
+ def begin_page(params)
19
+ @pages << params
20
+ end
21
+ end
22
+
23
+ describe "When creating annotations" do
24
+
25
+ before(:each) { create_pdf }
26
+
27
+ it "should append annotation to current page" do
28
+ @pdf.start_new_page
29
+ @pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
30
+ obj = PageAnnotations.parse(@pdf)
31
+ obj.pages[0][:Annots].nil?.should == true
32
+ obj.pages[1][:Annots].length.should == 1
33
+ end
34
+
35
+ it "should force :Type to be :Annot" do
36
+ opts = @pdf.annotate(:Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
37
+ opts[:Type].should == :Annot
38
+ opts = @pdf.annotate(:Type => :Bogus, :Rect => [0,0,10,10], :Subtype => :Text, :Contents => "Hello world!")
39
+ opts[:Type].should == :Annot
40
+ end
41
+
42
+ end
43
+
44
+ describe "When creating text annotations" do
45
+
46
+ before(:each) do
47
+ @rect = [0,0,10,10]
48
+ @content = "Hello, world!"
49
+ create_pdf
50
+ end
51
+
52
+ it "should build appropriate annotation" do
53
+ opts = @pdf.text_annotation(@rect, @content)
54
+ opts[:Type].should == :Annot
55
+ opts[:Subtype].should == :Text
56
+ opts[:Rect].should == @rect
57
+ opts[:Contents].should == @content
58
+ end
59
+
60
+ it "should merge extra options" do
61
+ opts = @pdf.text_annotation(@rect, @content, :Open => true, :Subtype => :Bogus)
62
+ opts[:Subtype].should == :Text
63
+ opts[:Open].should == true
64
+ end
65
+
66
+ end
67
+
68
+ describe "When creating link annotations" do
69
+
70
+ before(:each) do
71
+ @rect = [0,0,10,10]
72
+ @dest = "home"
73
+ create_pdf
74
+ end
75
+
76
+ it "should build appropriate annotation" do
77
+ opts = @pdf.link_annotation(@rect, :Dest => @dest)
78
+ opts[:Type].should == :Annot
79
+ opts[:Subtype].should == :Link
80
+ opts[:Rect].should == @rect
81
+ opts[:Dest].should == @dest
82
+ end
83
+
84
+ it "should merge extra options" do
85
+ opts = @pdf.link_annotation(@rect, :Dest => @dest, :Subtype => :Bogus)
86
+ opts[:Subtype].should == :Link
87
+ opts[:Dest].should == @dest
88
+ end
89
+
90
+ end
@@ -0,0 +1,190 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "A bounding box" do
6
+
7
+ before(:each) do
8
+ @x = 100
9
+ @y = 125
10
+ @width = 50
11
+ @height = 75
12
+ @box = Prawn::Document::BoundingBox.new(nil, [@x,@y], :width => @width,
13
+ :height => @height )
14
+ end
15
+
16
+ it "should have an anchor at (x, y - height)" do
17
+ @box.anchor.should == [@x,@y-@height]
18
+ end
19
+
20
+ it "should have a left boundary of 0" do
21
+ @box.left.should == 0
22
+ end
23
+
24
+ it "should have a right boundary equal to the width" do
25
+ @box.right.should == @width
26
+ end
27
+
28
+ it "should have a top boundary of height" do
29
+ @box.top.should == @height
30
+ end
31
+
32
+ it "should have a bottom boundary of 0" do
33
+ @box.bottom.should == 0
34
+ end
35
+
36
+ it "should have a top-left of [0,height]" do
37
+ @box.top_left.should == [0,@height]
38
+ end
39
+
40
+ it "should have a top-right of [width,height]" do
41
+ @box.top_right.should == [@width,@height]
42
+ end
43
+
44
+ it "should have a bottom-left of [0,0]" do
45
+ @box.bottom_left.should == [0,0]
46
+ end
47
+
48
+ it "should have a bottom-right of [width,0]" do
49
+ @box.bottom_right.should == [@width,0]
50
+ end
51
+
52
+ it "should have an absolute left boundary of x" do
53
+ @box.absolute_left.should == @x
54
+ end
55
+
56
+ it "should have an absolute right boundary of x + width" do
57
+ @box.absolute_right.should == @x + @width
58
+ end
59
+
60
+ it "should have an absolute top boundary of y" do
61
+ @box.absolute_top.should == @y
62
+ end
63
+
64
+ it "should have an absolute bottom boundary of y - height" do
65
+ @box.absolute_bottom.should == @y - @height
66
+ end
67
+
68
+ it "should have an absolute bottom-left of [x,y-height]" do
69
+ @box.absolute_bottom_left.should == [@x, @y - @height]
70
+ end
71
+
72
+ it "should have an absolute bottom-right of [x+width,y-height]" do
73
+ @box.absolute_bottom_right.should == [@x + @width , @y - @height]
74
+ end
75
+
76
+ it "should have an absolute top-left of [x,y]" do
77
+ @box.absolute_top_left.should == [@x, @y]
78
+ end
79
+
80
+ it "should have an absolute top-right of [x+width,y]" do
81
+ @box.absolute_top_right.should == [@x + @width, @y]
82
+ end
83
+
84
+ it "should require width to be set" do
85
+ assert_raises(ArgumentError) do
86
+ Prawn::Document::BoundingBox.new(nil, [100,100])
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ describe "drawing bounding boxes" do
93
+
94
+ before(:each) { create_pdf }
95
+
96
+ it "should restore the margin box when bounding box exits" do
97
+ margin_box = @pdf.bounds
98
+
99
+ @pdf.bounding_box [100,500], :width => 100 do
100
+ #nothing
101
+ end
102
+
103
+ @pdf.bounds.should == margin_box
104
+
105
+ end
106
+
107
+ it "should restore the parent bounding box when calls are nested" do
108
+ @pdf.bounding_box [100,500], :width => 300, :height => 300 do
109
+
110
+ @pdf.bounds.absolute_top.should == 500 + @pdf.margin_box.absolute_bottom
111
+ @pdf.bounds.absolute_left.should == 100 + @pdf.margin_box.absolute_left
112
+
113
+ parent_box = @pdf.bounds
114
+
115
+ @pdf.bounding_box [50,200], :width => 100, :height => 100 do
116
+ @pdf.bounds.absolute_top.should == 200 + parent_box.absolute_bottom
117
+ @pdf.bounds.absolute_left.should == 50 + parent_box.absolute_left
118
+ end
119
+
120
+ @pdf.bounds.absolute_top.should == 500 + @pdf.margin_box.absolute_bottom
121
+ @pdf.bounds.absolute_left.should == 100 + @pdf.margin_box.absolute_left
122
+
123
+ end
124
+ end
125
+
126
+ it "should calculate a height if none is specified" do
127
+ @pdf.bounding_box([100, 500], :width => 100) do
128
+ @pdf.text "The rain in Spain falls mainly on the plains."
129
+ end
130
+
131
+ @pdf.y.should.be.close 458.384, 0.001
132
+ end
133
+
134
+ it "should keep track of the max height the box was stretched to" do
135
+ box = @pdf.bounding_box(@pdf.bounds.top_left, :width => 100) do
136
+ @pdf.move_down 100
137
+ @pdf.move_up 15
138
+ end
139
+
140
+ assert_equal 100, box.height
141
+ end
142
+
143
+ end
144
+
145
+ describe "Indentation" do
146
+ before(:each) { create_pdf }
147
+
148
+ it "should temporarily shift the x coordinate and width" do
149
+ @pdf.bounding_box([100,100], :width => 200) do
150
+ @pdf.indent(20) do
151
+ @pdf.bounds.absolute_left.should == 120
152
+ @pdf.bounds.width.should == 180
153
+ end
154
+ end
155
+ end
156
+
157
+ it "should restore the x coordinate and width after block exits" do
158
+ @pdf.bounding_box([100,100], :width => 200) do
159
+ @pdf.indent(20) do
160
+ # no-op
161
+ end
162
+ @pdf.bounds.absolute_left.should == 100
163
+ @pdf.bounds.width.should == 200
164
+ end
165
+ end
166
+
167
+ it "should restore the x coordinate and width on error" do
168
+ @pdf.bounding_box([100,100], :width => 200) do
169
+ begin
170
+ @pdf.indent(20) { raise }
171
+ rescue
172
+ @pdf.bounds.absolute_left.should == 100
173
+ @pdf.bounds.width.should == 200
174
+ end
175
+ end
176
+ end
177
+
178
+ end
179
+
180
+ describe "A canvas" do
181
+ before(:each) { create_pdf }
182
+
183
+ it "should use whatever the last set y position is" do
184
+ @pdf.canvas do
185
+ @pdf.bounding_box([100,500],:width => 200) { @pdf.move_down 50 }
186
+ end
187
+ @pdf.y.should == 450
188
+ end
189
+ end
190
+
@@ -0,0 +1,348 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ module CellHelpers
6
+
7
+ # Build, but do not draw, a cell on @pdf.
8
+ # TODO: differentiate class based on :content.
9
+ def cell(options={})
10
+ at = options[:at] || [0, @pdf.cursor]
11
+ Prawn::Table::Cell::Text.new(@pdf, at, options)
12
+ end
13
+
14
+ def close?(actual, expected, epsilon=0.01)
15
+ (actual - expected).abs < epsilon
16
+ end
17
+
18
+ end
19
+
20
+ describe "Prawn::Table::Cell" do
21
+ before(:each) do
22
+ @pdf = Prawn::Document.new
23
+ end
24
+
25
+ describe "Prawn::Document#cell" do
26
+ include CellHelpers
27
+
28
+ it "should draw the cell" do
29
+ Prawn::Table::Cell::Text.any_instance.expects(:draw).once
30
+ @pdf.cell(:content => "text")
31
+ end
32
+
33
+ it "should return a Cell" do
34
+ @pdf.cell(:content => "text").should.be.a.kind_of Prawn::Table::Cell
35
+ end
36
+
37
+ it "should generate an empty cell from nil content" do
38
+ c = @pdf.cell(:content => nil)
39
+ c.should.be.a.kind_of Prawn::Table::Cell::Text
40
+ c.content.should == ""
41
+ end
42
+
43
+ it "should draw text at the given point plus padding, with the given " +
44
+ "size and style" do
45
+ @pdf.expects(:bounding_box).yields
46
+ @pdf.expects(:move_down)
47
+ @pdf.expects(:draw_text!).with { |text, options| text == "hello world" }
48
+
49
+ @pdf.cell(:content => "hello world",
50
+ :at => [10, 20],
51
+ :padding => [30, 40],
52
+ :size => 7,
53
+ :style => :bold)
54
+ end
55
+ end
56
+
57
+ describe "cell width" do
58
+ include CellHelpers
59
+
60
+ it "should be calculated for text" do
61
+ c = cell(:content => "text")
62
+ c.width.should == @pdf.width_of("text") + c.padding[1] + c.padding[3]
63
+ end
64
+
65
+ it "should be overridden by manual :width" do
66
+ c = cell(:content => "text", :width => 400)
67
+ c.width.should == 400
68
+ end
69
+
70
+ it "should incorporate padding when specified" do
71
+ c = cell(:content => "text", :padding => [1, 2, 3, 4])
72
+ c.width.should.be.close(@pdf.width_of("text") + 6, 0.01)
73
+ end
74
+
75
+ it "should allow width to be reset after it has been calculated" do
76
+ # to ensure that if we memoize width, it can still be overridden
77
+ c = cell(:content => "text")
78
+ c.width
79
+ c.width = 400
80
+ c.width.should == 400
81
+ end
82
+
83
+ it "should return proper width with size set" do
84
+ text = "text " * 4
85
+ c = cell(:content => text, :size => 7)
86
+ c.width.should ==
87
+ @pdf.width_of(text, :size => 7) + c.padding[1] + c.padding[3]
88
+ end
89
+
90
+ it "content_width should exclude padding" do
91
+ c = cell(:content => "text", :padding => 10)
92
+ c.content_width.should == @pdf.width_of("text")
93
+ end
94
+
95
+ it "content_width should exclude padding even with manual :width" do
96
+ c = cell(:content => "text", :padding => 10, :width => 400)
97
+ c.content_width.should.be.close(380, 0.01)
98
+ end
99
+
100
+ it "should have a reasonable minimum width that can fit @content" do
101
+ c = cell(:content => "text", :padding => 10)
102
+ min_content_width = c.min_width - c.padding[1] - c.padding[3]
103
+
104
+ lambda { @pdf.height_of("text", :width => min_content_width) }.
105
+ should.not.raise(Prawn::Errors::CannotFit)
106
+
107
+ @pdf.height_of("text", :width => min_content_width).should.be <
108
+ (5 * @pdf.height_of("text"))
109
+ end
110
+
111
+ end
112
+
113
+ describe "cell height" do
114
+ include CellHelpers
115
+
116
+ it "should be calculated for text" do
117
+ c = cell(:content => "text")
118
+ c.height.should ==
119
+ @pdf.height_of("text", :width => @pdf.width_of("text")) +
120
+ c.padding[0] + c.padding[3]
121
+ end
122
+
123
+ it "should be overridden by manual :height" do
124
+ c = cell(:content => "text", :height => 400)
125
+ c.height.should == 400
126
+ end
127
+
128
+ it "should incorporate :padding when specified" do
129
+ c = cell(:content => "text", :padding => [1, 2, 3, 4])
130
+ c.height.should.be.close(1 + 3 +
131
+ @pdf.height_of("text", :width => @pdf.width_of("text")), 0.01)
132
+ end
133
+
134
+ it "should allow height to be reset after it has been calculated" do
135
+ # to ensure that if we memoize height, it can still be overridden
136
+ c = cell(:content => "text")
137
+ c.height
138
+ c.height = 400
139
+ c.height.should == 400
140
+ end
141
+
142
+ it "should return proper height for blocks of text" do
143
+ content = "words " * 10
144
+ c = cell(:content => content, :width => 100)
145
+ c.height.should == @pdf.height_of(content, :width => 100) +
146
+ c.padding[0] + c.padding[2]
147
+ end
148
+
149
+ it "should return proper height for blocks of text with size set" do
150
+ content = "words " * 10
151
+ c = cell(:content => content, :width => 100, :size => 7)
152
+
153
+ correct_content_height = nil
154
+ @pdf.font_size(7) do
155
+ correct_content_height = @pdf.height_of(content, :width => 100)
156
+ end
157
+
158
+ c.height.should == correct_content_height + c.padding[0] + c.padding[2]
159
+ end
160
+
161
+ it "content_height should exclude padding" do
162
+ c = cell(:content => "text", :padding => 10)
163
+ c.content_height.should == @pdf.height_of("text")
164
+ end
165
+
166
+ it "content_height should exclude padding even with manual :height" do
167
+ c = cell(:content => "text", :padding => 10, :height => 400)
168
+ c.content_height.should.be.close(380, 0.01)
169
+ end
170
+ end
171
+
172
+ describe "cell padding" do
173
+ include CellHelpers
174
+
175
+ it "should default to zero" do
176
+ c = cell(:content => "text")
177
+ c.padding.should == [5, 5, 5, 5]
178
+ end
179
+
180
+ it "should accept a numeric value, setting all padding" do
181
+ c = cell(:content => "text", :padding => 10)
182
+ c.padding.should == [10, 10, 10, 10]
183
+ end
184
+
185
+ it "should accept [v,h]" do
186
+ c = cell(:content => "text", :padding => [20, 30])
187
+ c.padding.should == [20, 30, 20, 30]
188
+ end
189
+
190
+ it "should accept [t,h,b]" do
191
+ c = cell(:content => "text", :padding => [10, 20, 30])
192
+ c.padding.should == [10, 20, 30, 20]
193
+ end
194
+
195
+ it "should accept [t,l,b,r]" do
196
+ c = cell(:content => "text", :padding => [10, 20, 30, 40])
197
+ c.padding.should == [10, 20, 30, 40]
198
+ end
199
+
200
+ it "should reject other formats" do
201
+ lambda{
202
+ cell(:content => "text", :padding => [10])
203
+ }.should.raise(ArgumentError)
204
+ end
205
+ end
206
+
207
+ describe "background_color" do
208
+ include CellHelpers
209
+
210
+ it "should fill a rectangle with the given background color" do
211
+ @pdf.stubs(:mask).yields
212
+ @pdf.expects(:mask).with(:fill_color).yields
213
+
214
+ @pdf.stubs(:fill_color)
215
+ @pdf.expects(:fill_color).with('123456')
216
+ @pdf.expects(:fill_rectangle).with do |(x, y), w, h|
217
+ close?(x, 0) && close?(y, @pdf.cursor) &&
218
+ close?(w, 29.344) && close?(h, 23.872)
219
+ end
220
+ @pdf.cell(:content => "text", :background_color => '123456')
221
+ end
222
+ end
223
+
224
+ describe "color" do
225
+ it "should set fill color when :text_color is provided" do
226
+ pdf = Prawn::Document.new
227
+ pdf.stubs(:fill_color)
228
+ pdf.expects(:fill_color).with('555555')
229
+ pdf.cell :content => 'foo', :text_color => '555555'
230
+ end
231
+
232
+ it "should reset the fill color to the original one" do
233
+ pdf = Prawn::Document.new
234
+ pdf.fill_color = '333333'
235
+ pdf.cell :content => 'foo', :text_color => '555555'
236
+ pdf.fill_color.should == '333333'
237
+ end
238
+ end
239
+
240
+ describe "Borders" do
241
+ it "should draw all borders by default" do
242
+ @pdf.expects(:stroke_line).times(4)
243
+ @pdf.cell(:content => "text")
244
+ end
245
+
246
+ it "should draw all borders when requested" do
247
+ @pdf.expects(:stroke_line).times(4)
248
+ @pdf.cell(:content => "text", :borders => [:top, :right, :bottom, :left])
249
+ end
250
+
251
+ # Only roughly verifying the integer coordinates so that we don't have to
252
+ # do any FP closeness arithmetic. Can plug in that math later if this goes
253
+ # wrong.
254
+ it "should draw top border when requested" do
255
+ @pdf.expects(:stroke_line).with { |*from_and_to|
256
+ # from: x y to: x y
257
+ from_and_to.flatten.map{|x| x.round} == [0, 720, 29, 720]
258
+ }
259
+ @pdf.cell(:content => "text", :borders => [:top])
260
+ end
261
+
262
+ it "should draw bottom border when requested" do
263
+ @pdf.expects(:stroke_line).with { |*from_and_to|
264
+ from_and_to.flatten.map{|x| x.round} == [0, 696, 29, 696]
265
+ }
266
+ @pdf.cell(:content => "text", :borders => [:bottom])
267
+ end
268
+
269
+ it "should draw left border when requested" do
270
+ @pdf.expects(:stroke_line).with { |*from_and_to|
271
+ from_and_to.flatten.map{|x| x.round} == [0, 721, 0, 696]
272
+ }
273
+ @pdf.cell(:content => "text", :borders => [:left])
274
+ end
275
+
276
+ it "should draw right border when requested" do
277
+ @pdf.expects(:stroke_line).with { |*from_and_to|
278
+ from_and_to.flatten.map{|x| x.round} == [29, 721, 29, 696]
279
+ }
280
+ @pdf.cell(:content => "text", :borders => [:right])
281
+ end
282
+ end
283
+
284
+ describe "Text cell attributes" do
285
+ include CellHelpers
286
+
287
+ it "should pass through text options like :align to Text::Box" do
288
+ c = cell(:content => "text", :align => :right)
289
+
290
+ box = Prawn::Text::Box.new("text", :document => @pdf)
291
+
292
+ Prawn::Text::Box.expects(:new).with do |text, options|
293
+ text == "text" && options[:align] == :right
294
+ end.at_least_once.returns(box)
295
+
296
+ c.draw
297
+ end
298
+
299
+ it "should allow inline formatting in cells" do
300
+ c = cell(:content => "foo <b>bar</b> baz", :inline_format => true)
301
+
302
+ box = Prawn::Text::Formatted::Box.new([], :document => @pdf)
303
+
304
+ Prawn::Text::Formatted::Box.expects(:new).with do |array, options|
305
+ array[0][:text] == "foo " && array[0][:styles] == [] &&
306
+ array[1][:text] == "bar" && array[1][:styles] == [:bold] &&
307
+ array[2][:text] == " baz" && array[2][:styles] == []
308
+ end.at_least_once.returns(box)
309
+
310
+ c.draw
311
+ end
312
+
313
+ end
314
+
315
+ describe "Font handling" do
316
+ include CellHelpers
317
+
318
+ it "should allow only :style to be specified, defaulting to the" +
319
+ "document's font" do
320
+ c = cell(:content => "text", :style => :bold)
321
+ c.font.name.should == 'Helvetica-Bold'
322
+ end
323
+
324
+ it "should accept a font name for :font" do
325
+ c = cell(:content => "text", :font => 'Helvetica-Bold')
326
+ c.font.name.should == 'Helvetica-Bold'
327
+ end
328
+
329
+ it "should allow style to be changed after initialize" do
330
+ c = cell(:content => "text")
331
+ c.style = :bold
332
+ c.font.name.should == 'Helvetica-Bold'
333
+ end
334
+
335
+ it "should default to the document's font, if none is specified" do
336
+ c = cell(:content => "text")
337
+ c.font.should == @pdf.font
338
+ end
339
+
340
+ it "should use the metrics of the selected font (even if it is a variant " +
341
+ "of the document's font) to calculate width" do
342
+ c = cell(:content => "text", :style => :bold)
343
+ font = @pdf.find_font('Helvetica-Bold')
344
+ c.content_width.should == font.compute_width_of("text")
345
+ end
346
+ end
347
+
348
+ end