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.
- checksums.yaml +4 -4
- data/.yardopts +2 -1
- data/Rakefile +12 -0
- data/lib/prawn.rb +9 -21
- data/lib/prawn/document.rb +95 -68
- data/lib/prawn/document/bounding_box.rb +22 -4
- data/lib/prawn/document/column_box.rb +2 -0
- data/lib/prawn/document/graphics_state.rb +1 -1
- data/lib/prawn/document/internals.rb +2 -2
- data/lib/prawn/document/snapshot.rb +2 -1
- data/lib/prawn/document/span.rb +2 -0
- data/lib/prawn/encoding.rb +1 -1
- data/lib/prawn/font.rb +89 -75
- data/lib/prawn/font/afm.rb +3 -0
- data/lib/prawn/font/dfont.rb +1 -0
- data/lib/prawn/font/ttf.rb +2 -0
- data/lib/prawn/font_metric_cache.rb +3 -1
- data/lib/prawn/graphics.rb +2 -14
- data/lib/prawn/graphics/cap_style.rb +1 -0
- data/lib/prawn/graphics/color.rb +1 -0
- data/lib/prawn/graphics/dash.rb +3 -2
- data/lib/prawn/graphics/join_style.rb +2 -0
- data/lib/prawn/graphics/patterns.rb +1 -0
- data/lib/prawn/graphics/transformation.rb +1 -0
- data/lib/prawn/graphics/transparency.rb +2 -0
- data/lib/prawn/image_handler.rb +2 -0
- data/lib/prawn/images.rb +5 -0
- data/lib/prawn/images/image.rb +1 -0
- data/lib/prawn/images/jpg.rb +3 -0
- data/lib/prawn/images/png.rb +2 -0
- data/lib/prawn/layout.rb +8 -13
- data/lib/prawn/layout/grid.rb +15 -3
- data/lib/prawn/measurement_extensions.rb +4 -0
- data/lib/prawn/measurements.rb +2 -0
- data/lib/prawn/outline.rb +3 -1
- data/lib/prawn/repeater.rb +3 -1
- data/lib/prawn/security.rb +15 -7
- data/lib/prawn/security/arcfour.rb +52 -0
- data/lib/prawn/soft_mask.rb +3 -1
- data/lib/prawn/stamp.rb +2 -0
- data/lib/prawn/table.rb +2 -0
- data/lib/prawn/table/cell.rb +4 -1
- data/lib/prawn/table/cell/image.rb +1 -2
- data/lib/prawn/table/cell/in_table.rb +2 -0
- data/lib/prawn/table/cell/span_dummy.rb +1 -0
- data/lib/prawn/table/cells.rb +7 -2
- data/lib/prawn/table/column_width_calculator.rb +8 -2
- data/lib/prawn/text.rb +4 -2
- data/lib/prawn/text/box.rb +3 -0
- data/lib/prawn/text/formatted/arranger.rb +2 -0
- data/lib/prawn/text/formatted/box.rb +55 -50
- data/lib/prawn/text/formatted/fragment.rb +2 -0
- data/lib/prawn/text/formatted/line_wrap.rb +1 -0
- data/lib/prawn/text/formatted/parser.rb +2 -0
- data/lib/prawn/text/formatted/wrap.rb +2 -0
- data/lib/prawn/utilities.rb +5 -3
- data/manual/graphics/common_lines.rb +2 -0
- data/manual/text/group.rb +2 -0
- data/manual/text/text.rb +1 -1
- data/prawn.gemspec +4 -3
- data/spec/grid_spec.rb +11 -0
- data/spec/object_store_spec.rb +1 -96
- data/spec/reference_spec.rb +0 -57
- data/spec/spec_helper.rb +7 -0
- data/spec/table_spec.rb +26 -0
- metadata +172 -185
- data/lib/pdf/core.rb +0 -35
- data/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -79
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -89
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -311
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -99
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/prawn/templates.rb +0 -75
- data/spec/filters_spec.rb +0 -34
- data/spec/name_tree_spec.rb +0 -112
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/stream_spec.rb +0 -58
- 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
|