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,15 @@
1
+ # encoding: utf-8
2
+
3
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
4
+
5
+ describe "When creating destinations" do
6
+
7
+ before(:each) { create_pdf }
8
+
9
+ it "should add entry to Dests name tree" do
10
+ @pdf.dests.data.empty?.should == true
11
+ @pdf.add_dest "candy", "chocolate"
12
+ @pdf.dests.data.size.should == 1
13
+ end
14
+
15
+ end
@@ -0,0 +1,473 @@
1
+ # encoding: utf-8
2
+ require "tempfile"
3
+
4
+ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
5
+
6
+ describe "The cursor" do
7
+ it "should equal pdf.y - bounds.absolute_bottom" do
8
+ pdf = Prawn::Document.new
9
+ pdf.cursor.should == pdf.bounds.top
10
+
11
+ pdf.y = 300
12
+ pdf.cursor.should == pdf.y - pdf.bounds.absolute_bottom
13
+ end
14
+
15
+ it "should be able to move relative to the bottom margin" do
16
+ pdf = Prawn::Document.new
17
+ pdf.move_cursor_to(10)
18
+
19
+ pdf.cursor.should == 10
20
+ pdf.y.should == pdf.cursor + pdf.bounds.absolute_bottom
21
+ end
22
+ end
23
+
24
+ describe "when generating a document from a subclass" do
25
+ it "should be an instance of the subclass" do
26
+ custom_document = Class.new(Prawn::Document)
27
+ custom_document.generate(Tempfile.new("generate_test").path) do |e|
28
+ e.class.should == custom_document
29
+ e.should.be.kind_of(Prawn::Document)
30
+ end
31
+ end
32
+
33
+ it "should retain any extensions found on Prawn::Document" do
34
+ mod1 = Module.new { attr_reader :test_extensions1 }
35
+ mod2 = Module.new { attr_reader :test_extensions2 }
36
+
37
+ Prawn::Document.extensions << mod1 << mod2
38
+
39
+ custom_document = Class.new(Prawn::Document)
40
+ assert_equal [mod1, mod2], custom_document.extensions
41
+
42
+ # remove the extensions we added to prawn document
43
+ Prawn::Document.extensions.delete(mod1)
44
+ Prawn::Document.extensions.delete(mod2)
45
+
46
+ assert ! Prawn::Document.new.respond_to?(:test_extensions1)
47
+ assert ! Prawn::Document.new.respond_to?(:test_extensions2)
48
+
49
+ # verify these still exist on custom class
50
+ assert_equal [mod1, mod2], custom_document.extensions
51
+
52
+ assert custom_document.new.respond_to?(:test_extensions1)
53
+ assert custom_document.new.respond_to?(:test_extensions2)
54
+ end
55
+
56
+ end
57
+
58
+ describe "When creating multi-page documents" do
59
+ before(:each) { create_pdf }
60
+
61
+ it "should initialize with a single page" do
62
+ page_counter = PDF::Inspector::Page.analyze(@pdf.render)
63
+
64
+ page_counter.pages.size.should == 1
65
+ @pdf.page_count.should == 1
66
+ end
67
+
68
+ it "should provide an accurate page_count" do
69
+ 3.times { @pdf.start_new_page }
70
+ page_counter = PDF::Inspector::Page.analyze(@pdf.render)
71
+
72
+ page_counter.pages.size.should == 4
73
+ @pdf.page_count.should == 4
74
+ end
75
+ end
76
+
77
+ describe "When beginning each new page" do
78
+
79
+ describe "Background template feature" do
80
+ before(:each) do
81
+ @filename = "#{Prawn::BASEDIR}/data/images/pigs.jpg"
82
+ @pdf = Prawn::Document.new(:background => @filename)
83
+ end
84
+ it "should place a background image if it is in options block" do
85
+ output = @pdf.render
86
+ images = PDF::Inspector::XObject.analyze(output)
87
+ # there should be 2 images in the page resources
88
+ images.page_xobjects.first.size.should == 1
89
+ end
90
+ it "should place a background image if it is in options block" do
91
+ @pdf.instance_variable_defined?(:@background).should == true
92
+ @pdf.instance_variable_get(:@background).should == @filename
93
+ end
94
+
95
+
96
+ end
97
+
98
+
99
+ end
100
+
101
+ describe "The page_number method" do
102
+ it "should be 1 for a new document" do
103
+ pdf = Prawn::Document.new
104
+ pdf.page_number.should == 1
105
+ end
106
+
107
+ it "should be 0 for documents with no pages" do
108
+ pdf = Prawn::Document.new(:skip_page_creation => true)
109
+ pdf.page_number.should == 0
110
+ end
111
+
112
+ it "should be changed by go_to_page" do
113
+ pdf = Prawn::Document.new
114
+ 10.times { pdf.start_new_page }
115
+ pdf.go_to_page 3
116
+ pdf.page_number.should == 3
117
+ end
118
+
119
+ end
120
+
121
+ describe "on_page_create callback" do
122
+ before do
123
+ create_pdf
124
+ end
125
+
126
+ it "should be invoked with document" do
127
+ called_with = nil
128
+
129
+ @pdf.on_page_create { |*args| called_with = args }
130
+
131
+ @pdf.start_new_page
132
+
133
+ called_with.should == [@pdf]
134
+ end
135
+
136
+ it "should be invoked for each new page" do
137
+ trigger = mock()
138
+ trigger.expects(:fire).times(5)
139
+
140
+ @pdf.on_page_create { trigger.fire }
141
+
142
+ 5.times { @pdf.start_new_page }
143
+ end
144
+
145
+ it "should be replaceable" do
146
+ trigger1 = mock()
147
+ trigger1.expects(:fire).times(1)
148
+
149
+ trigger2 = mock()
150
+ trigger2.expects(:fire).times(1)
151
+
152
+ @pdf.on_page_create { trigger1.fire }
153
+
154
+ @pdf.start_new_page
155
+
156
+ @pdf.on_page_create { trigger2.fire }
157
+
158
+ @pdf.start_new_page
159
+ end
160
+
161
+ it "should be clearable by calling on_page_create without a block" do
162
+ trigger = mock()
163
+ trigger.expects(:fire).times(1)
164
+
165
+ @pdf.on_page_create { trigger.fire }
166
+
167
+ @pdf.start_new_page
168
+
169
+ @pdf.on_page_create
170
+
171
+ @pdf.start_new_page
172
+ end
173
+
174
+ end
175
+
176
+ describe "Document compression" do
177
+
178
+ it "should not compress the page content stream if compression is disabled" do
179
+
180
+ pdf = Prawn::Document.new(:compress => false)
181
+ pdf.page.content.stubs(:compress_stream).returns(true)
182
+ pdf.page.content.expects(:compress_stream).never
183
+
184
+ pdf.text "Hi There" * 20
185
+ pdf.render
186
+ end
187
+
188
+ it "should compress the page content stream if compression is enabled" do
189
+
190
+ pdf = Prawn::Document.new(:compress => true)
191
+ pdf.page.content.stubs(:compress_stream).returns(true)
192
+ pdf.page.content.expects(:compress_stream).once
193
+
194
+ pdf.text "Hi There" * 20
195
+ pdf.render
196
+ end
197
+
198
+ it "should result in a smaller file size when compressed" do
199
+ doc_uncompressed = Prawn::Document.new
200
+ doc_compressed = Prawn::Document.new(:compress => true)
201
+ [doc_compressed, doc_uncompressed].each do |pdf|
202
+ pdf.font "#{Prawn::BASEDIR}/data/fonts/gkai00mp.ttf"
203
+ pdf.text "更可怕的是,同质化竞争对手可以按照URL中后面这个ID来遍历" * 10
204
+ end
205
+
206
+ doc_compressed.render.length.should.be < doc_uncompressed.render.length
207
+ end
208
+
209
+ end
210
+
211
+ describe "Document metadata" do
212
+ it "should output strings as UTF-16 with a byte order mark" do
213
+ pdf = Prawn::Document.new(:info => {:Author => "Lóránt"})
214
+ pdf.state.store.info.object.should =~
215
+ # UTF-16: BOM L ó r á n t
216
+ %r{/Author\s*<feff004c00f3007200e1006e0074>}i
217
+ end
218
+ end
219
+
220
+ describe "When reopening pages" do
221
+ it "should modify the content stream size" do
222
+ @pdf = Prawn::Document.new do |pdf|
223
+ pdf.text "Page 1"
224
+ pdf.start_new_page
225
+ pdf.text "Page 2"
226
+ pdf.go_to_page 1
227
+ pdf.text "More for page 1"
228
+ end
229
+
230
+ # MalformedPDFError raised if content stream actual length does not match
231
+ # dictionary length
232
+ lambda{ PDF::Inspector::Page.analyze(@pdf.render) }.
233
+ should.not.raise(PDF::Reader::MalformedPDFError)
234
+ end
235
+
236
+ it "should insert pages after the current page when calling start_new_page" do
237
+ pdf = Prawn::Document.new
238
+ 3.times { |i| pdf.text "Old page #{i+1}"; pdf.start_new_page }
239
+ pdf.go_to_page 1
240
+ pdf.start_new_page
241
+ pdf.text "New page 2"
242
+
243
+ pdf.page_number.should == 2
244
+
245
+ pages = PDF::Inspector::Page.analyze(pdf.render).pages
246
+ pages.size.should == 5
247
+ pages[1][:strings].should == ["New page 2"]
248
+ pages[2][:strings].should == ["Old page 2"]
249
+ end
250
+ end
251
+
252
+ describe "When setting page size" do
253
+ it "should default to LETTER" do
254
+ @pdf = Prawn::Document.new
255
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
256
+ pages.first[:size].should == Prawn::Document::PageGeometry::SIZES["LETTER"]
257
+ end
258
+
259
+ (Prawn::Document::PageGeometry::SIZES.keys - ["LETTER"]).each do |k|
260
+ it "should provide #{k} geometry" do
261
+ @pdf = Prawn::Document.new(:page_size => k)
262
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
263
+ pages.first[:size].should == Prawn::Document::PageGeometry::SIZES[k]
264
+ end
265
+ end
266
+
267
+ it "should allow custom page size" do
268
+ @pdf = Prawn::Document.new(:page_size => [1920, 1080] )
269
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
270
+ pages.first[:size].should == [1920, 1080]
271
+ end
272
+
273
+
274
+ it "should retain page size by default when starting a new page" do
275
+ @pdf = Prawn::Document.new(:page_size => "LEGAL")
276
+ @pdf.start_new_page
277
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
278
+ pages.each do |page|
279
+ page[:size].should == Prawn::Document::PageGeometry::SIZES["LEGAL"]
280
+ end
281
+ end
282
+
283
+ end
284
+
285
+ describe "When setting page layout" do
286
+ it "should reverse coordinates for landscape" do
287
+ @pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)
288
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
289
+ pages.first[:size].should == Prawn::Document::PageGeometry::SIZES["A4"].reverse
290
+ end
291
+
292
+ it "should retain page layout by default when starting a new page" do
293
+ @pdf = Prawn::Document.new(:page_layout => :landscape)
294
+ @pdf.start_new_page(:trace => true)
295
+ pages = PDF::Inspector::Page.analyze(@pdf.render).pages
296
+ pages.each do |page|
297
+ page[:size].should == Prawn::Document::PageGeometry::SIZES["LETTER"].reverse
298
+ end
299
+ end
300
+ end
301
+
302
+ describe "The mask() feature" do
303
+ it "should allow transactional restoration of attributes" do
304
+ @pdf = Prawn::Document.new
305
+ y, line_width = @pdf.y, @pdf.line_width
306
+ @pdf.mask(:y, :line_width) do
307
+ @pdf.y = y + 1
308
+ @pdf.line_width = line_width + 1
309
+ @pdf.y.should.not == y
310
+ @pdf.line_width.should.not == line_width
311
+ end
312
+ @pdf.y.should == y
313
+ @pdf.line_width.should == line_width
314
+ end
315
+ end
316
+
317
+ describe "The group() feature" do
318
+ it "should group a simple block on a single page" do
319
+ pdf = Prawn::Document.new do
320
+ self.y = 50
321
+ group do
322
+ text "Hello"
323
+ text "World"
324
+ end
325
+ end
326
+ pages = PDF::Inspector::Page.analyze(pdf.render).pages
327
+ pages.size.should == 2
328
+ pages[0][:strings].should == []
329
+ pages[1][:strings].should == ["Hello", "World"]
330
+ end
331
+
332
+ it "should raise CannotGroup if the content is too tall" do
333
+ lambda {
334
+ Prawn::Document.new do
335
+ group do
336
+ 100.times { text "Too long" }
337
+ end
338
+ end.render
339
+ }.should.raise(Prawn::Errors::CannotGroup)
340
+ end
341
+ end
342
+
343
+ describe "The render() feature" do
344
+ if "spec".respond_to?(:encode!)
345
+ it "should return a 8 bit encoded string on a m17n aware VM" do
346
+ @pdf = Prawn::Document.new(:page_size => "A4", :page_layout => :landscape)
347
+ @pdf.line [100,100], [200,200]
348
+ str = @pdf.render
349
+ str.encoding.to_s.should == "ASCII-8BIT"
350
+ end
351
+ end
352
+
353
+ it "should trigger before_render callbacks just before rendering" do
354
+ pdf = Prawn::Document.new
355
+
356
+ seq = sequence("callback_order")
357
+
358
+ # Verify the order: finalize -> fire callbacks -> render body
359
+ pdf.expects(:finalize_all_page_contents).in_sequence(seq)
360
+ trigger = mock()
361
+ trigger.expects(:fire).in_sequence(seq)
362
+
363
+ # Store away the render_body method to be called below
364
+ render_body = pdf.method(:render_body)
365
+ pdf.expects(:render_body).in_sequence(seq)
366
+
367
+ pdf.before_render{ trigger.fire }
368
+
369
+ # Render the body to set up object offsets
370
+ render_body.call(StringIO.new)
371
+ pdf.render
372
+ end
373
+ end
374
+
375
+ describe "The :optimize_objects option" do
376
+ before(:all) do
377
+ @wasteful_doc = lambda do |pdf|
378
+ pdf.transaction do
379
+ pdf.start_new_page
380
+ pdf.text "Hidden text"
381
+ pdf.rollback
382
+ end
383
+
384
+ pdf.text "Hello world"
385
+ end
386
+ end
387
+
388
+ it "should result in fewer objects when enabled" do
389
+ wasteful_pdf = Prawn::Document.new(&@wasteful_doc)
390
+ frugal_pdf = Prawn::Document.new(:optimize_objects => true,
391
+ &@wasteful_doc)
392
+ frugal_pdf.render.size.should.be < wasteful_pdf.render.size
393
+ end
394
+
395
+ it "should default to :false" do
396
+ default_pdf = Prawn::Document.new(&@wasteful_doc)
397
+ wasteful_pdf = Prawn::Document.new(:optimize_objects => false,
398
+ &@wasteful_doc)
399
+ default_pdf.render.size.should == wasteful_pdf.render.size
400
+ end
401
+
402
+ end
403
+
404
+ describe "PDF file versions" do
405
+ it "should default to 1.3" do
406
+ @pdf = Prawn::Document.new
407
+ str = @pdf.render
408
+ str[0,8].should == "%PDF-1.3"
409
+ end
410
+
411
+ it "should allow the default to be changed" do
412
+ @pdf = Prawn::Document.new
413
+ @pdf.__send__(:min_version, 1.4)
414
+ str = @pdf.render
415
+ str[0,8].should == "%PDF-1.4"
416
+ end
417
+ end
418
+
419
+ describe "Documents that use go_to_page" do
420
+ it "should have 2 pages after calling start_new_page and go_to_page" do
421
+ @pdf = Prawn::Document.new
422
+ @pdf.text "James"
423
+ @pdf.start_new_page
424
+ @pdf.text "Anthony"
425
+ @pdf.go_to_page(1)
426
+ @pdf.text "Healy"
427
+
428
+ page_counter = PDF::Inspector::Page.analyze(@pdf.render)
429
+ page_counter.pages.size.should == 2
430
+ end
431
+
432
+ it "should correctly add text to pages" do
433
+ @pdf = Prawn::Document.new
434
+ @pdf.text "James"
435
+ @pdf.start_new_page
436
+ @pdf.text "Anthony"
437
+ @pdf.go_to_page(1)
438
+ @pdf.text "Healy"
439
+
440
+ text = PDF::Inspector::Text.analyze(@pdf.render)
441
+
442
+ text.strings.size.should == 3
443
+ text.strings.include?("James").should == true
444
+ text.strings.include?("Anthony").should == true
445
+ text.strings.include?("Healy").should == true
446
+ end
447
+ end
448
+
449
+ describe "content stream characteristics" do
450
+ it "should have 1 single content stream for a single page PDF with no templates" do
451
+ @pdf = Prawn::Document.new
452
+ @pdf.text "James"
453
+ output = StringIO.new(@pdf.render)
454
+ hash = PDF::Hash.new(output)
455
+
456
+ streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
457
+
458
+ streams.size.should == 1
459
+ end
460
+
461
+ it "should have 1 single content stream for a single page PDF with no templates, even if go_to_page is used" do
462
+ @pdf = Prawn::Document.new
463
+ @pdf.text "James"
464
+ @pdf.go_to_page(1)
465
+ @pdf.text "Healy"
466
+ output = StringIO.new(@pdf.render)
467
+ hash = PDF::Hash.new(output)
468
+
469
+ streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
470
+
471
+ streams.size.should == 1
472
+ end
473
+ end