prawn-core 0.7.2 → 0.8.4
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.
- data/Rakefile +1 -1
- data/examples/general/background.rb +1 -1
- data/examples/general/measurement_units.rb +2 -2
- data/examples/general/outlines.rb +50 -0
- data/examples/general/repeaters.rb +11 -7
- data/examples/general/stamp.rb +6 -6
- data/examples/graphics/basic_images.rb +1 -1
- data/examples/graphics/curves.rb +1 -1
- data/examples/graphics/rounded_polygons.rb +19 -0
- data/examples/graphics/rounded_rectangle.rb +20 -0
- data/examples/graphics/transformations.rb +52 -0
- data/examples/m17n/win_ansi_charset.rb +1 -1
- data/examples/text/font_calculations.rb +3 -3
- data/examples/text/indent_paragraphs.rb +18 -0
- data/examples/text/kerning.rb +4 -4
- data/examples/text/rotated.rb +98 -0
- data/examples/text/simple_text.rb +3 -3
- data/examples/text/simple_text_ttf.rb +1 -1
- data/lib/prawn/byte_string.rb +1 -0
- data/lib/prawn/core.rb +12 -5
- data/lib/prawn/core/object_store.rb +99 -0
- data/lib/prawn/core/page.rb +96 -0
- data/lib/prawn/core/text.rb +75 -0
- data/lib/prawn/document.rb +71 -78
- data/lib/prawn/document/annotations.rb +2 -2
- data/lib/prawn/document/bounding_box.rb +19 -9
- data/lib/prawn/document/column_box.rb +13 -12
- data/lib/prawn/document/graphics_state.rb +49 -0
- data/lib/prawn/document/internals.rb +5 -40
- data/lib/prawn/document/page_geometry.rb +1 -18
- data/lib/prawn/document/snapshot.rb +12 -7
- data/lib/prawn/errors.rb +18 -0
- data/lib/prawn/font.rb +4 -2
- data/lib/prawn/font/afm.rb +8 -0
- data/lib/prawn/font/dfont.rb +12 -4
- data/lib/prawn/font/ttf.rb +9 -0
- data/lib/prawn/graphics.rb +66 -9
- data/lib/prawn/graphics/color.rb +1 -1
- data/lib/prawn/graphics/transformation.rb +156 -0
- data/lib/prawn/graphics/transparency.rb +3 -7
- data/lib/prawn/images.rb +4 -3
- data/lib/prawn/images/png.rb +2 -2
- data/lib/prawn/outline.rb +278 -0
- data/lib/prawn/pdf_object.rb +5 -3
- data/lib/prawn/repeater.rb +25 -13
- data/lib/prawn/stamp.rb +6 -29
- data/lib/prawn/text.rb +139 -121
- data/lib/prawn/text/box.rb +168 -102
- data/spec/bounding_box_spec.rb +7 -2
- data/spec/document_spec.rb +7 -5
- data/spec/font_spec.rb +9 -1
- data/spec/graphics_spec.rb +229 -0
- data/spec/object_store_spec.rb +5 -5
- data/spec/outline_spec.rb +229 -0
- data/spec/repeater_spec.rb +18 -1
- data/spec/snapshot_spec.rb +7 -7
- data/spec/span_spec.rb +6 -2
- data/spec/spec_helper.rb +7 -3
- data/spec/stamp_spec.rb +13 -0
- data/spec/text_at_spec.rb +119 -0
- data/spec/text_box_spec.rb +257 -4
- data/spec/text_spec.rb +278 -180
- data/vendor/pdf-inspector/lib/pdf/inspector/graphics.rb +12 -0
- metadata +16 -3
- data/lib/prawn/object_store.rb +0 -92
data/spec/font_spec.rb
CHANGED
@@ -12,6 +12,14 @@ describe "Font behavior" do
|
|
12
12
|
|
13
13
|
end
|
14
14
|
|
15
|
+
describe "#font_size" do
|
16
|
+
it "should allow setting font size in DSL style" do
|
17
|
+
create_pdf
|
18
|
+
@pdf.font_size 20
|
19
|
+
@pdf.font_size.should == 20
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
15
23
|
describe "font style support" do
|
16
24
|
before(:each) { create_pdf }
|
17
25
|
|
@@ -115,7 +123,7 @@ describe "Document#page_fonts" do
|
|
115
123
|
end
|
116
124
|
|
117
125
|
def page_includes_font?(font)
|
118
|
-
@pdf.
|
126
|
+
@pdf.page.fonts.values.map { |e| e.data[:BaseFont] }.include?(font.to_sym)
|
119
127
|
end
|
120
128
|
|
121
129
|
def page_should_include_font(font)
|
data/spec/graphics_spec.rb
CHANGED
@@ -113,7 +113,39 @@ describe "When drawing a curve" do
|
|
113
113
|
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
114
114
|
curve.coords.should == [100.0, 100.0, 20.0, 90.0, 90.0, 75.0, 50.0, 50.0]
|
115
115
|
end
|
116
|
+
|
116
117
|
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "When drawing a rounded rectangle" do
|
121
|
+
before(:each) do
|
122
|
+
create_pdf
|
123
|
+
@pdf.rounded_rectangle([50, 550], 50, 100, 10)
|
124
|
+
curve = PDF::Inspector::Graphics::Curve.analyze(@pdf.render)
|
125
|
+
curve_points = []
|
126
|
+
curve.coords.each_slice(2) {|p| curve_points << p}
|
127
|
+
@original_point = curve_points.shift
|
128
|
+
curves = []
|
129
|
+
curve_points.each_slice(3) {|c| curves << c}
|
130
|
+
line_points = PDF::Inspector::Graphics::Line.analyze(@pdf.render).points
|
131
|
+
line_points.shift
|
132
|
+
@all_coords = []
|
133
|
+
line_points.zip(curves).flatten.each_slice(2) {|p| @all_coords << p }
|
134
|
+
@all_coords.unshift @original_point
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should draw a rectangle by connecting lines with rounded bezier curves" do
|
138
|
+
@all_coords.should == [[60.0, 550.0],[90.0, 550.0], [95.523, 550.0], [100.0, 545.523], [100.0, 540.0],
|
139
|
+
[100.0, 460.0], [100.0, 454.477], [95.523, 450.0], [90.0, 450.0],
|
140
|
+
[60.0, 450.0], [54.477, 450.0], [50.0, 454.477], [50.0, 460.0],
|
141
|
+
[50.0, 540.0], [50.0, 545.523], [54.477, 550.0], [60.0, 550.0]]
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should start and end with the same point" do
|
145
|
+
@original_point.should == @all_coords.last
|
146
|
+
end
|
147
|
+
|
148
|
+
|
117
149
|
end
|
118
150
|
|
119
151
|
describe "When drawing an ellipse" do
|
@@ -207,3 +239,200 @@ describe "When using painting shortcuts" do
|
|
207
239
|
should.raise(NoMethodError)
|
208
240
|
end
|
209
241
|
end
|
242
|
+
|
243
|
+
describe "When using graphics states" do
|
244
|
+
before(:each) { create_pdf }
|
245
|
+
|
246
|
+
it "should add the right content on save_graphics_state" do
|
247
|
+
@pdf.expects(:add_content).with('q')
|
248
|
+
|
249
|
+
@pdf.save_graphics_state
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should add the right content on restore_graphics_state" do
|
253
|
+
@pdf.expects(:add_content).with('Q')
|
254
|
+
|
255
|
+
@pdf.restore_graphics_state
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should save and restore when save_graphics_state is used with a block" do
|
259
|
+
state = sequence "state"
|
260
|
+
@pdf.expects(:add_content).with('q').in_sequence(state)
|
261
|
+
@pdf.expects(:foo).in_sequence(state)
|
262
|
+
@pdf.expects(:add_content).with('Q').in_sequence(state)
|
263
|
+
|
264
|
+
@pdf.save_graphics_state do
|
265
|
+
@pdf.foo
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "When using transformation matrix" do
|
271
|
+
before(:each) { create_pdf }
|
272
|
+
|
273
|
+
# Note: The (approximate) number of significant decimal digits of precision in fractional
|
274
|
+
# part is 5 (PDF Reference, Third Edition, p. 706)
|
275
|
+
|
276
|
+
it "should send the right content on transformation_matrix" do
|
277
|
+
@pdf.expects(:add_content).with('1.00000 0.00000 0.12346 -1.00000 5.50000 20.00000 cm')
|
278
|
+
@pdf.transformation_matrix 1, 0, 0.123456789, -1.0, 5.5, 20
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should use fixed digits with very small number" do
|
282
|
+
values = Array.new(6, 0.000000000001)
|
283
|
+
string = Array.new(6, "0.00000").join " "
|
284
|
+
@pdf.expects(:add_content).with("#{string} cm")
|
285
|
+
@pdf.transformation_matrix *values
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should be received by the inspector" do
|
289
|
+
@pdf.transformation_matrix 1, 0, 0, -1, 5.5, 20
|
290
|
+
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
|
291
|
+
matrices.matrices.should == [[1, 0, 0, -1, 5.5, 20]]
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should save the graphics state inside the given block" do
|
295
|
+
values = Array.new(6, 0.000000000001)
|
296
|
+
string = Array.new(6, "0.00000").join " "
|
297
|
+
process = sequence "process"
|
298
|
+
|
299
|
+
@pdf.expects(:save_graphics_state).with().in_sequence(process)
|
300
|
+
@pdf.expects(:add_content).with("#{string} cm").in_sequence(process)
|
301
|
+
@pdf.expects(:do_something).with().in_sequence(process)
|
302
|
+
@pdf.expects(:restore_graphics_state).with().in_sequence(process)
|
303
|
+
@pdf.transformation_matrix(*values) do
|
304
|
+
@pdf.do_something
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
end
|
309
|
+
|
310
|
+
describe "When using transformations shortcuts" do
|
311
|
+
before(:each) do
|
312
|
+
create_pdf
|
313
|
+
@x, @y = 12, 54.32
|
314
|
+
@angle = 12.32
|
315
|
+
@cos = Math.cos(@angle * Math::PI / 180)
|
316
|
+
@sin = Math.sin(@angle * Math::PI / 180)
|
317
|
+
@factor = 0.12
|
318
|
+
end
|
319
|
+
|
320
|
+
describe "#rotate" do
|
321
|
+
it "should rotate" do
|
322
|
+
@pdf.expects(:transformation_matrix).with(@cos, @sin, -@sin, @cos, 0, 0)
|
323
|
+
@pdf.rotate(@angle)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
describe "#rotate with :origin option" do
|
328
|
+
it "should rotate around the origin" do
|
329
|
+
x_prime = @x * @cos - @y * @sin
|
330
|
+
y_prime = @x * @sin + @y * @cos
|
331
|
+
|
332
|
+
@pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
|
333
|
+
|
334
|
+
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
|
335
|
+
matrices.matrices[0].should == [1, 0, 0, 1,
|
336
|
+
reduce_precision(@x - x_prime),
|
337
|
+
reduce_precision(@y - y_prime)]
|
338
|
+
matrices.matrices[1].should == [reduce_precision(@cos),
|
339
|
+
reduce_precision(@sin),
|
340
|
+
reduce_precision(-@sin),
|
341
|
+
reduce_precision(@cos), 0, 0]
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should rotate around the origin in a document with a margin" do
|
345
|
+
@pdf = Prawn::Document.new
|
346
|
+
|
347
|
+
@pdf.rotate(@angle, :origin => [@x, @y]) { @pdf.text('hello world') }
|
348
|
+
|
349
|
+
x = @x + @pdf.bounds.absolute_left
|
350
|
+
y = @y + @pdf.bounds.absolute_bottom
|
351
|
+
x_prime = x * @cos - y * @sin
|
352
|
+
y_prime = x * @sin + y * @cos
|
353
|
+
|
354
|
+
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
|
355
|
+
matrices.matrices[0].should == [1, 0, 0, 1,
|
356
|
+
reduce_precision(x - x_prime),
|
357
|
+
reduce_precision(y - y_prime)]
|
358
|
+
matrices.matrices[1].should == [reduce_precision(@cos),
|
359
|
+
reduce_precision(@sin),
|
360
|
+
reduce_precision(-@sin),
|
361
|
+
reduce_precision(@cos), 0, 0]
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should raise BlockRequired if no block is given" do
|
365
|
+
lambda {
|
366
|
+
@pdf.rotate(@angle, :origin => [@x, @y])
|
367
|
+
}.should.raise(Prawn::Errors::BlockRequired)
|
368
|
+
end
|
369
|
+
|
370
|
+
def reduce_precision(float)
|
371
|
+
("%.5f" % float).to_f
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
describe "#translate" do
|
376
|
+
it "should translate" do
|
377
|
+
x, y = 12, 54.32
|
378
|
+
@pdf.expects(:transformation_matrix).with(1, 0, 0, 1, x, y)
|
379
|
+
@pdf.translate(x, y)
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
describe "#scale" do
|
384
|
+
it "should scale" do
|
385
|
+
@pdf.expects(:transformation_matrix).with(@factor, 0, 0, @factor, 0, 0)
|
386
|
+
@pdf.scale(@factor)
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
describe "#scale with :origin option" do
|
391
|
+
it "should scale from the origin" do
|
392
|
+
x_prime = @factor * @x
|
393
|
+
y_prime = @factor * @y
|
394
|
+
|
395
|
+
@pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
|
396
|
+
|
397
|
+
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
|
398
|
+
matrices.matrices[0].should == [1, 0, 0, 1,
|
399
|
+
reduce_precision(@x - x_prime),
|
400
|
+
reduce_precision(@y - y_prime)]
|
401
|
+
matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should scale from the origin in a document with a margin" do
|
405
|
+
@pdf = Prawn::Document.new
|
406
|
+
x = @x + @pdf.bounds.absolute_left
|
407
|
+
y = @y + @pdf.bounds.absolute_bottom
|
408
|
+
x_prime = @factor * x
|
409
|
+
y_prime = @factor * y
|
410
|
+
|
411
|
+
@pdf.scale(@factor, :origin => [@x, @y]) { @pdf.text('hello world') }
|
412
|
+
|
413
|
+
matrices = PDF::Inspector::Graphics::Matrix.analyze(@pdf.render)
|
414
|
+
matrices.matrices[0].should == [1, 0, 0, 1,
|
415
|
+
reduce_precision(x - x_prime),
|
416
|
+
reduce_precision(y - y_prime)]
|
417
|
+
matrices.matrices[1].should == [@factor, 0, 0, @factor, 0, 0]
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should raise BlockRequired if no block is given" do
|
421
|
+
lambda {
|
422
|
+
@pdf.scale(@factor, :origin => [@x, @y])
|
423
|
+
}.should.raise(Prawn::Errors::BlockRequired)
|
424
|
+
end
|
425
|
+
|
426
|
+
def reduce_precision(float)
|
427
|
+
("%.5f" % float).to_f
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
# describe "skew" do
|
432
|
+
# it "should skew" do
|
433
|
+
# a, b = 30, 50.2
|
434
|
+
# @pdf.expects(:transformation_matrix).with(1, Math.tan(a * Math::PI / 180), Math.tan(b * Math::PI / 180), 1, 0, 0)
|
435
|
+
# @pdf.skew(a, b)
|
436
|
+
# end
|
437
|
+
# end
|
438
|
+
end
|
data/spec/object_store_spec.rb
CHANGED
@@ -4,11 +4,11 @@ require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
|
4
4
|
|
5
5
|
describe "Prawn::ObjectStore" do
|
6
6
|
before(:each) do
|
7
|
-
@store = Prawn::ObjectStore.new
|
7
|
+
@store = Prawn::Core::ObjectStore.new
|
8
8
|
end
|
9
9
|
|
10
10
|
it "should create required roots by default, including info passed to new" do
|
11
|
-
store = Prawn::ObjectStore.new(:Test => 3)
|
11
|
+
store = Prawn::Core::ObjectStore.new(:Test => 3)
|
12
12
|
store.size.should == 3 # 3 default roots
|
13
13
|
store.info.data[:Test].should == 3
|
14
14
|
store.pages.data[:Count].should == 0
|
@@ -43,7 +43,7 @@ end
|
|
43
43
|
|
44
44
|
describe "Prawn::ObjectStore#compact" do
|
45
45
|
it "should do nothing to an ObjectStore with all live refs" do
|
46
|
-
store = Prawn::ObjectStore.new
|
46
|
+
store = Prawn::Core::ObjectStore.new
|
47
47
|
store.info.data[:Blah] = store.ref(:some => "structure")
|
48
48
|
old_size = store.size
|
49
49
|
store.compact
|
@@ -52,7 +52,7 @@ describe "Prawn::ObjectStore#compact" do
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should remove dead objects, renumbering live objects from 1" do
|
55
|
-
store = Prawn::ObjectStore.new
|
55
|
+
store = Prawn::Core::ObjectStore.new
|
56
56
|
store.ref(:some => "structure")
|
57
57
|
old_size = store.size
|
58
58
|
store.compact
|
@@ -62,7 +62,7 @@ describe "Prawn::ObjectStore#compact" do
|
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should detect and remove dead objects that were once live" do
|
65
|
-
store = Prawn::ObjectStore.new
|
65
|
+
store = Prawn::Core::ObjectStore.new
|
66
66
|
store.info.data[:Blah] = store.ref(:some => "structure")
|
67
67
|
store.info.data[:Blah] = :overwritten
|
68
68
|
old_size = store.size
|
@@ -0,0 +1,229 @@
|
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe "Outline" do
|
4
|
+
before(:each) do
|
5
|
+
@pdf = Prawn::Document.new() do
|
6
|
+
text "Page 1. This is the first Chapter. "
|
7
|
+
start_new_page
|
8
|
+
text "Page 2. More in the first Chapter. "
|
9
|
+
start_new_page
|
10
|
+
define_outline do
|
11
|
+
section 'Chapter 1', :page => 1, :closed => true do
|
12
|
+
page 1, :title => 'Page 1'
|
13
|
+
page 2, :title => 'Page 2'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
describe "#generate_outline" do
|
19
|
+
before(:each) do
|
20
|
+
render_and_find_objects
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should create a root outline dictionary item" do
|
24
|
+
assert_not_nil @outline_root
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should set the first and last top items of the root outline dictionary item" do
|
28
|
+
referenced_object(@outline_root[:First]).should == @section_1
|
29
|
+
referenced_object(@outline_root[:Last]).should == @section_1
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#create_outline_item" do
|
33
|
+
it "should create outline items for each section and page" do
|
34
|
+
[@section_1, @page_1, @page_2].each {|item| assert_not_nil item}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#set_relations, #set_variables_for_block, and #reset_parent" do
|
39
|
+
it "should link sibling items" do
|
40
|
+
referenced_object(@page_1[:Next]).should == @page_2
|
41
|
+
referenced_object(@page_2[:Prev]).should == @page_1
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should link child items to parent item" do
|
45
|
+
[@page_1, @page_2].each {|page| referenced_object(page[:Parent]).should == @section_1 }
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set the first and last child items for parent item" do
|
49
|
+
referenced_object(@section_1[:First]).should == @page_1
|
50
|
+
referenced_object(@section_1[:Last]).should == @page_2
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "#increase_count" do
|
55
|
+
|
56
|
+
it "should add the count of all descendant items" do
|
57
|
+
@outline_root[:Count].should == 3
|
58
|
+
@section_1[:Count].should.abs == 2
|
59
|
+
@page_1[:Count].should == 0
|
60
|
+
@page_2[:Count].should == 0
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "closed option" do
|
66
|
+
|
67
|
+
it "should set the item's integer count to negative" do
|
68
|
+
@section_1[:Count].should == -2
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#outline.add_section" do
|
76
|
+
before(:each) do
|
77
|
+
@pdf.start_new_page
|
78
|
+
@pdf.text "Page 3. An added section "
|
79
|
+
@pdf.outline.add_section do
|
80
|
+
section 'Added Section', :page => 3 do
|
81
|
+
page 3, :title => 'Page 3'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
render_and_find_objects
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should add new outline items to document" do
|
88
|
+
[@section_2, @page_3].each { |item| assert_not_nil item}
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should reset the last items for root outline dictionary" do
|
92
|
+
referenced_object(@outline_root[:First]).should == @section_1
|
93
|
+
referenced_object(@outline_root[:Last]).should == @section_2
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should reset the next relation for the previous last top level item" do
|
97
|
+
referenced_object(@section_1[:Next]).should == @section_2
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should set the previous relation of the addded to section" do
|
101
|
+
referenced_object(@section_2[:Prev]).should == @section_1
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should increase the count of root outline dictionary" do
|
105
|
+
@outline_root[:Count].should == 5
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#outline.insert_section_after" do
|
111
|
+
describe "inserting in the middle of another section" do
|
112
|
+
before(:each) do
|
113
|
+
@pdf.go_to_page 1
|
114
|
+
@pdf.start_new_page
|
115
|
+
@pdf.text "Inserted Page"
|
116
|
+
@pdf.outline.insert_section_after 'Page 1' do
|
117
|
+
page page_number, :title => "Inserted Page"
|
118
|
+
end
|
119
|
+
render_and_find_objects
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should insert new outline items to document" do
|
123
|
+
assert_not_nil @inserted_page
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should adjust the count of all ancestors" do
|
127
|
+
@outline_root[:Count].should == 4
|
128
|
+
@section_1[:Count].should.abs == 3
|
129
|
+
end
|
130
|
+
|
131
|
+
describe "#adjust_relations" do
|
132
|
+
|
133
|
+
it "should reset the sibling relations of adjoining items to inserted item" do
|
134
|
+
referenced_object(@page_1[:Next]).should == @inserted_page
|
135
|
+
referenced_object(@page_2[:Prev]).should == @inserted_page
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should set the sibling relation of added item to adjoining items" do
|
139
|
+
referenced_object(@inserted_page[:Next]).should == @page_2
|
140
|
+
referenced_object(@inserted_page[:Prev]).should == @page_1
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should not affect the first and last relations of parent item" do
|
144
|
+
referenced_object(@section_1[:First]).should == @page_1
|
145
|
+
referenced_object(@section_1[:Last]).should == @page_2
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "inserting at the end of another section" do
|
153
|
+
before(:each) do
|
154
|
+
@pdf.go_to_page 2
|
155
|
+
@pdf.start_new_page
|
156
|
+
@pdf.text "Inserted Page"
|
157
|
+
@pdf.outline.insert_section_after 'Page 2' do
|
158
|
+
page page_number, :title => "Inserted Page"
|
159
|
+
end
|
160
|
+
render_and_find_objects
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#adjust_relations" do
|
164
|
+
|
165
|
+
it "should reset the sibling relations of adjoining item to inserted item" do
|
166
|
+
referenced_object(@page_2[:Next]).should == @inserted_page
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should set the sibling relation of added item to adjoining items" do
|
170
|
+
assert_nil referenced_object(@inserted_page[:Next])
|
171
|
+
referenced_object(@inserted_page[:Prev]).should == @page_2
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should adjust the last relation of parent item" do
|
175
|
+
referenced_object(@section_1[:Last]).should == @inserted_page
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should require an existing title" do
|
182
|
+
assert_raise Prawn::Errors::UnknownOutlineTitle do
|
183
|
+
@pdf.go_to_page 1
|
184
|
+
@pdf.start_new_page
|
185
|
+
@pdf.text "Inserted Page"
|
186
|
+
@pdf.outline.insert_section_after 'Wrong page' do
|
187
|
+
page page_number, :title => "Inserted Page"
|
188
|
+
end
|
189
|
+
render_and_find_objects
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
describe "#page" do
|
196
|
+
it "should require a title option to be set" do
|
197
|
+
assert_raise Prawn::Errors::RequiredOption do
|
198
|
+
@pdf = Prawn::Document.new() do
|
199
|
+
text "Page 1. This is the first Chapter. "
|
200
|
+
define_outline do
|
201
|
+
page 1, :title => nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def render_and_find_objects
|
210
|
+
output = StringIO.new(@pdf.render, 'r+')
|
211
|
+
@hash = PDF::Hash.new(output)
|
212
|
+
@outline_root = @hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Outlines}
|
213
|
+
@pages = @hash.values.find {|obj| obj.is_a?(Hash) && obj[:Type] == :Pages}[:Kids]
|
214
|
+
@section_1 = find_by_title('Chapter 1')
|
215
|
+
@page_1 = find_by_title('Page 1')
|
216
|
+
@page_2 = find_by_title('Page 2')
|
217
|
+
@section_2 = find_by_title('Added Section')
|
218
|
+
@page_3 = find_by_title('Page 3')
|
219
|
+
@inserted_page = find_by_title('Inserted Page')
|
220
|
+
end
|
221
|
+
|
222
|
+
def find_by_title(title)
|
223
|
+
@hash.values.find {|obj| obj.is_a?(Hash) && obj[:Title] == title}
|
224
|
+
end
|
225
|
+
|
226
|
+
def referenced_object(reference)
|
227
|
+
@hash[reference]
|
228
|
+
end
|
229
|
+
|