prawn 0.14.0 → 0.15.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 (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