prawn 0.14.0 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +2 -1
  3. data/Rakefile +12 -0
  4. data/lib/prawn.rb +9 -21
  5. data/lib/prawn/document.rb +95 -68
  6. data/lib/prawn/document/bounding_box.rb +22 -4
  7. data/lib/prawn/document/column_box.rb +2 -0
  8. data/lib/prawn/document/graphics_state.rb +1 -1
  9. data/lib/prawn/document/internals.rb +2 -2
  10. data/lib/prawn/document/snapshot.rb +2 -1
  11. data/lib/prawn/document/span.rb +2 -0
  12. data/lib/prawn/encoding.rb +1 -1
  13. data/lib/prawn/font.rb +89 -75
  14. data/lib/prawn/font/afm.rb +3 -0
  15. data/lib/prawn/font/dfont.rb +1 -0
  16. data/lib/prawn/font/ttf.rb +2 -0
  17. data/lib/prawn/font_metric_cache.rb +3 -1
  18. data/lib/prawn/graphics.rb +2 -14
  19. data/lib/prawn/graphics/cap_style.rb +1 -0
  20. data/lib/prawn/graphics/color.rb +1 -0
  21. data/lib/prawn/graphics/dash.rb +3 -2
  22. data/lib/prawn/graphics/join_style.rb +2 -0
  23. data/lib/prawn/graphics/patterns.rb +1 -0
  24. data/lib/prawn/graphics/transformation.rb +1 -0
  25. data/lib/prawn/graphics/transparency.rb +2 -0
  26. data/lib/prawn/image_handler.rb +2 -0
  27. data/lib/prawn/images.rb +5 -0
  28. data/lib/prawn/images/image.rb +1 -0
  29. data/lib/prawn/images/jpg.rb +3 -0
  30. data/lib/prawn/images/png.rb +2 -0
  31. data/lib/prawn/layout.rb +8 -13
  32. data/lib/prawn/layout/grid.rb +15 -3
  33. data/lib/prawn/measurement_extensions.rb +4 -0
  34. data/lib/prawn/measurements.rb +2 -0
  35. data/lib/prawn/outline.rb +3 -1
  36. data/lib/prawn/repeater.rb +3 -1
  37. data/lib/prawn/security.rb +15 -7
  38. data/lib/prawn/security/arcfour.rb +52 -0
  39. data/lib/prawn/soft_mask.rb +3 -1
  40. data/lib/prawn/stamp.rb +2 -0
  41. data/lib/prawn/table.rb +2 -0
  42. data/lib/prawn/table/cell.rb +4 -1
  43. data/lib/prawn/table/cell/image.rb +1 -2
  44. data/lib/prawn/table/cell/in_table.rb +2 -0
  45. data/lib/prawn/table/cell/span_dummy.rb +1 -0
  46. data/lib/prawn/table/cells.rb +7 -2
  47. data/lib/prawn/table/column_width_calculator.rb +8 -2
  48. data/lib/prawn/text.rb +4 -2
  49. data/lib/prawn/text/box.rb +3 -0
  50. data/lib/prawn/text/formatted/arranger.rb +2 -0
  51. data/lib/prawn/text/formatted/box.rb +55 -50
  52. data/lib/prawn/text/formatted/fragment.rb +2 -0
  53. data/lib/prawn/text/formatted/line_wrap.rb +1 -0
  54. data/lib/prawn/text/formatted/parser.rb +2 -0
  55. data/lib/prawn/text/formatted/wrap.rb +2 -0
  56. data/lib/prawn/utilities.rb +5 -3
  57. data/manual/graphics/common_lines.rb +2 -0
  58. data/manual/text/group.rb +2 -0
  59. data/manual/text/text.rb +1 -1
  60. data/prawn.gemspec +4 -3
  61. data/spec/grid_spec.rb +11 -0
  62. data/spec/object_store_spec.rb +1 -96
  63. data/spec/reference_spec.rb +0 -57
  64. data/spec/spec_helper.rb +7 -0
  65. data/spec/table_spec.rb +26 -0
  66. metadata +172 -185
  67. data/lib/pdf/core.rb +0 -35
  68. data/lib/pdf/core/annotations.rb +0 -60
  69. data/lib/pdf/core/byte_string.rb +0 -9
  70. data/lib/pdf/core/destinations.rb +0 -90
  71. data/lib/pdf/core/document_state.rb +0 -79
  72. data/lib/pdf/core/filter_list.rb +0 -51
  73. data/lib/pdf/core/filters.rb +0 -36
  74. data/lib/pdf/core/graphics_state.rb +0 -89
  75. data/lib/pdf/core/literal_string.rb +0 -16
  76. data/lib/pdf/core/name_tree.rb +0 -177
  77. data/lib/pdf/core/object_store.rb +0 -311
  78. data/lib/pdf/core/outline.rb +0 -315
  79. data/lib/pdf/core/page.rb +0 -212
  80. data/lib/pdf/core/page_geometry.rb +0 -126
  81. data/lib/pdf/core/pdf_object.rb +0 -99
  82. data/lib/pdf/core/reference.rb +0 -103
  83. data/lib/pdf/core/stream.rb +0 -98
  84. data/lib/pdf/core/text.rb +0 -275
  85. data/lib/prawn/templates.rb +0 -75
  86. data/spec/filters_spec.rb +0 -34
  87. data/spec/name_tree_spec.rb +0 -112
  88. data/spec/pdf_object_spec.rb +0 -172
  89. data/spec/stream_spec.rb +0 -58
  90. data/spec/template_spec_obsolete.rb +0 -352
@@ -1,352 +0,0 @@
1
- require_relative "spec_helper"
2
- require_relative "../lib/prawn/templates"
3
-
4
- describe "Document built from a template" do
5
- it "should have the same page count as the source document" do
6
- filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
7
- @pdf = Prawn::Document.new(:template => filename)
8
- page_counter = PDF::Inspector::Page.analyze(@pdf.render)
9
-
10
- page_counter.pages.size.should == 1
11
- end
12
-
13
- it "should not set the template page's parent to the document pages catalog (especially with nested pages)" do
14
- filename = "#{Prawn::DATADIR}/pdfs/nested_pages.pdf"
15
- @pdf = Prawn::Document.new(:template => filename, :skip_page_creation => true)
16
- @pdf.state.page.dictionary.data[:Parent].should_not == @pdf.state.store.pages
17
- end
18
-
19
-
20
- it "should have start with the Y cursor at the top of the document" do
21
- filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
22
-
23
- @pdf = Prawn::Document.new(:template => filename)
24
- (@pdf.y == nil).should == false
25
- end
26
-
27
- it "should respect margins set by Prawn" do
28
- filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
29
-
30
- @pdf = Prawn::Document.new(:template => filename, :margin => 0)
31
- @pdf.page.margins.should == { :left => 0,
32
- :right => 0,
33
- :top => 0,
34
- :bottom => 0 }
35
-
36
- @pdf = Prawn::Document.new(:template => filename, :left_margin => 0)
37
-
38
- @pdf.page.margins.should == { :left => 0,
39
- :right => 36,
40
- :top => 36,
41
- :bottom => 36 }
42
-
43
- @pdf.start_new_page(:right_margin => 0)
44
-
45
- @pdf.page.margins.should == { :left => 0,
46
- :right => 0,
47
- :top => 36,
48
- :bottom => 36 }
49
-
50
-
51
-
52
- end
53
-
54
- it "should not add an extra restore_graphics_state operator to the end of any content stream" do
55
- filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
56
-
57
- @pdf = Prawn::Document.new(:template => filename)
58
- output = StringIO.new(@pdf.render)
59
- hash = PDF::Reader::ObjectHash.new(output)
60
-
61
- hash.each_value do |obj|
62
- next unless obj.kind_of?(PDF::Reader::Stream)
63
-
64
- data = obj.data.tr(" \n\r","")
65
- data.include?("QQ").should == false
66
- end
67
- end
68
-
69
- it "should have a single page object if importing a single page template" do
70
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
71
-
72
- @pdf = Prawn::Document.new(:template => filename)
73
- output = StringIO.new(@pdf.render)
74
- hash = PDF::Reader::ObjectHash.new(output)
75
-
76
- pages = hash.values.select { |obj| obj.kind_of?(Hash) && obj[:Type] == :Page }
77
-
78
- pages.size.should == 1
79
- end
80
-
81
- it "should have two content streams if importing a single page template" do
82
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
83
-
84
- @pdf = Prawn::Document.new(:template => filename)
85
- output = StringIO.new(@pdf.render)
86
- hash = PDF::Reader::ObjectHash.new(output)
87
-
88
- streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
89
-
90
- streams.size.should == 2
91
- end
92
-
93
- it "should not die if using this PDF as a template" do
94
- filename = "#{Prawn::DATADIR}/pdfs/complex_template.pdf"
95
-
96
- lambda {
97
- @pdf = Prawn::Document.new(:template => filename)
98
- }.should_not raise_error
99
- end
100
-
101
-
102
- it "should have balance q/Q operators on all content streams" do
103
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
104
-
105
- @pdf = Prawn::Document.new(:template => filename)
106
- output = StringIO.new(@pdf.render)
107
- hash = PDF::Reader::ObjectHash.new(output)
108
-
109
- streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
110
-
111
- streams.each do |stream|
112
- data = stream.unfiltered_data
113
- data.scan("q").size.should == 1
114
- data.scan("Q").size.should == 1
115
- end
116
- end
117
-
118
- it "should allow text to be added to a single page template" do
119
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
120
-
121
- @pdf = Prawn::Document.new(:template => filename)
122
-
123
- @pdf.text "Adding some text"
124
-
125
- text = PDF::Inspector::Text.analyze(@pdf.render)
126
- text.strings.first.should == "Adding some text"
127
- end
128
-
129
- it "should allow PDFs with page resources behind an indirect object to be used as templates" do
130
- filename = "#{Prawn::DATADIR}/pdfs/resources_as_indirect_object.pdf"
131
-
132
- @pdf = Prawn::Document.new(:template => filename)
133
-
134
- @pdf.text "Adding some text"
135
-
136
- text = PDF::Inspector::Text.analyze(@pdf.render)
137
- all_text = text.strings.join
138
- all_text.include?("Adding some text").should == true
139
- end
140
-
141
- it "should copy the PDF version from the template file" do
142
- filename = "#{Prawn::DATADIR}/pdfs/version_1_6.pdf"
143
-
144
- @pdf = Prawn::Document.new(:template => filename)
145
- str = @pdf.render
146
- str[0,8].should == "%PDF-1.6"
147
- end
148
-
149
- it "should correctly add a TTF font to a template that has existing fonts" do
150
- filename = "#{Prawn::DATADIR}/pdfs/contains_ttf_font.pdf"
151
- @pdf = Prawn::Document.new(:template => filename)
152
- @pdf.font "#{Prawn::DATADIR}/fonts/Chalkboard.ttf"
153
- @pdf.move_down(40)
154
- @pdf.text "Hi There"
155
-
156
- output = StringIO.new(@pdf.render)
157
- hash = PDF::Reader::ObjectHash.new(output)
158
-
159
- page_dict = hash.values.detect{ |obj| obj.is_a?(Hash) && obj[:Type] == :Page }
160
- resources = page_dict[:Resources]
161
- fonts = resources[:Font]
162
- fonts.size.should == 2
163
- end
164
-
165
- it "should correctly import a template file that is missing a MediaBox entry" do
166
- filename = "#{Prawn::DATADIR}/pdfs/page_without_mediabox.pdf"
167
-
168
- @pdf = Prawn::Document.new(:template => filename)
169
- str = @pdf.render
170
- str[0,4].should == "%PDF"
171
- end
172
-
173
- context "with the template as a stream" do
174
- it "should correctly import a template file from a stream" do
175
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
176
- io = StringIO.new(File.binread(filename))
177
- @pdf = Prawn::Document.new(:template => io)
178
- str = @pdf.render
179
- str[0,4].should == "%PDF"
180
- end
181
- end
182
-
183
- it "merges metadata info" do
184
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
185
- info = { :Title => "Sample METADATA",
186
- :Author => "Me",
187
- :Subject => "Not Working",
188
- :CreationDate => Time.now }
189
-
190
- @pdf = Prawn::Document.new(:template => filename, :info => info)
191
- output = StringIO.new(@pdf.render)
192
- hash = PDF::Reader::ObjectHash.new(output)
193
- info.keys.each { |k| hash[hash.trailer[:Info]].keys.include?(k).should == true }
194
- end
195
-
196
- end
197
-
198
- describe "Document#start_new_page with :template option" do
199
- filename = "#{Prawn::BASEDIR}/spec/data/curves.pdf"
200
-
201
- it "should set the imported page's parent to the document pages catalog" do
202
- @pdf = Prawn::Document.new()
203
- @pdf.start_new_page(:template => filename)
204
- @pdf.state.page.dictionary.data[:Parent].should == @pdf.state.store.pages
205
- end
206
-
207
- it "should set start the Y cursor at the top of the page" do
208
- @pdf = Prawn::Document.new()
209
- @pdf.start_new_page(:template => filename)
210
- (@pdf.y == nil).should == false
211
- end
212
-
213
- it "should respect margins set by Prawn" do
214
- @pdf = Prawn::Document.new(:margin => 0)
215
- @pdf.start_new_page(:template => filename)
216
- @pdf.page.margins.should == { :left => 0,
217
- :right => 0,
218
- :top => 0,
219
- :bottom => 0 }
220
-
221
- @pdf = Prawn::Document.new(:left_margin => 0)
222
- @pdf.start_new_page(:template => filename)
223
- @pdf.page.margins.should == { :left => 0,
224
- :right => 36,
225
- :top => 36,
226
- :bottom => 36 }
227
- @pdf.start_new_page(:template => filename, :right_margin => 0)
228
- @pdf.page.margins.should == { :left => 0,
229
- :right => 0,
230
- :top => 36,
231
- :bottom => 36 }
232
- end
233
-
234
- it "should not add an extra restore_graphics_state operator to the end of any content stream" do
235
- @pdf = Prawn::Document.new
236
- @pdf.start_new_page(:template => filename)
237
- output = StringIO.new(@pdf.render)
238
- hash = PDF::Reader::ObjectHash.new(output)
239
-
240
- hash.each_value do |obj|
241
- next unless obj.kind_of?(PDF::Reader::Stream)
242
-
243
- data = obj.data.tr(" \n\r","")
244
- data.include?("QQ").should == false
245
- end
246
- end
247
-
248
- it "should have two content streams if importing a single page template" do
249
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
250
- @pdf = Prawn::Document.new()
251
- @pdf.start_new_page(:template => filename)
252
- output = StringIO.new(@pdf.render)
253
- hash = PDF::Reader::ObjectHash.new(output)
254
- pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
255
- template_page = hash[pages[1]]
256
- template_page[:Contents].size.should == 2
257
- end
258
-
259
- it "should have balance q/Q operators on all content streams" do
260
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
261
-
262
- @pdf = Prawn::Document.new()
263
- @pdf.start_new_page(:template => filename)
264
- output = StringIO.new(@pdf.render)
265
- hash = PDF::Reader::ObjectHash.new(output)
266
-
267
- streams = hash.values.select { |obj| obj.kind_of?(PDF::Reader::Stream) }
268
-
269
- streams.each do |stream|
270
- data = stream.unfiltered_data
271
- data.scan("q").size.should == 1
272
- data.scan("Q").size.should == 1
273
- end
274
- end
275
-
276
- it "should allow text to be added to a single page template" do
277
-
278
- @pdf = Prawn::Document.new()
279
- @pdf.start_new_page(:template => filename)
280
-
281
- @pdf.text "Adding some text"
282
-
283
- text = PDF::Inspector::Text.analyze(@pdf.render)
284
- text.strings.first.should == "Adding some text"
285
- end
286
-
287
- it "should allow PDFs with page resources behind an indirect object to be used as templates" do
288
- filename = "#{Prawn::DATADIR}/pdfs/resources_as_indirect_object.pdf"
289
-
290
- @pdf = Prawn::Document.new()
291
- @pdf.start_new_page(:template => filename)
292
-
293
- @pdf.text "Adding some text"
294
-
295
- text = PDF::Inspector::Text.analyze(@pdf.render)
296
- all_text = text.strings.join
297
- all_text.include?("Adding some text").should == true
298
- end
299
-
300
- it "should correctly add a TTF font to a template that has existing fonts" do
301
- filename = "#{Prawn::DATADIR}/pdfs/contains_ttf_font.pdf"
302
- @pdf = Prawn::Document.new()
303
- @pdf.start_new_page(:template => filename)
304
- @pdf.font "#{Prawn::DATADIR}/fonts/Chalkboard.ttf"
305
- @pdf.move_down(40)
306
- @pdf.text "Hi There"
307
-
308
- output = StringIO.new(@pdf.render)
309
- hash = PDF::Reader::ObjectHash.new(output)
310
- hash = PDF::Reader::ObjectHash.new(output)
311
- pages = hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
312
- template_page = hash[pages[1]]
313
- resources = template_page[:Resources]
314
- fonts = resources[:Font]
315
- fonts.size.should == 2
316
- end
317
-
318
- it "indexes template pages when used multiple times" do
319
- filename = "#{Prawn::DATADIR}/pdfs/multipage_template.pdf"
320
- @repeated_pdf = Prawn::Document.new()
321
- 3.times { @repeated_pdf.start_new_page(:template => filename) }
322
- repeated_hash = PDF::Reader::ObjectHash.new(StringIO.new(@repeated_pdf.render))
323
- @sequential_pdf = Prawn::Document.new()
324
- (1..3).each { |p| @sequential_pdf.start_new_page(:template => filename, :template_page => p ) }
325
- sequential_hash = PDF::Reader::ObjectHash.new(StringIO.new(@sequential_pdf.render))
326
- (repeated_hash.size < sequential_hash.size).should == true
327
- end
328
-
329
- context "with the template as a stream" do
330
- it "should correctly import a template file from a stream" do
331
- filename = "#{Prawn::DATADIR}/pdfs/hexagon.pdf"
332
- io = StringIO.new(File.binread(filename))
333
-
334
- @pdf = Prawn::Document.new()
335
- @pdf.start_new_page(:template => io)
336
-
337
- str = @pdf.render
338
- str[0,4].should == "%PDF"
339
- end
340
- end
341
-
342
- context "using template_page option" do
343
- it "uses the specified page option" do
344
- filename = "#{Prawn::DATADIR}/pdfs/multipage_template.pdf"
345
- @pdf = Prawn::Document.new()
346
- @pdf.start_new_page(:template => filename, :template_page => 2)
347
- text = PDF::Inspector::Text.analyze(@pdf.render)
348
- text.strings.first.should == "This is template page 2"
349
- end
350
- end
351
-
352
- end