prawn-core 0.6.1 → 0.6.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/examples/general/measurement_units.pdf +4667 -0
- data/examples/general/stamp.rb +4 -8
- data/lib/prawn/core.rb +1 -1
- data/lib/prawn/document.rb +6 -8
- data/lib/prawn/document/internals.rb +16 -22
- data/lib/prawn/document/snapshot.rb +2 -1
- data/lib/prawn/font.rb +1 -2
- data/lib/prawn/images.rb +0 -3
- data/lib/prawn/object_store.rb +1 -1
- data/lib/prawn/stamp.rb +21 -19
- data/spec/document_spec.rb +22 -9
- data/spec/snapshot_spec.rb +13 -1
- data/spec/stamp_spec.rb +12 -23
- metadata +4 -3
data/examples/general/stamp.rb
CHANGED
@@ -4,25 +4,21 @@
|
|
4
4
|
#
|
5
5
|
require "#{File.dirname(__FILE__)}/../example_helper.rb"
|
6
6
|
|
7
|
-
Prawn::Document.generate("stamp.pdf") do
|
8
|
-
|
9
|
-
create_stamp("page_template") do
|
10
|
-
text "This is my page template", :at => [0, bounds.top - 4 * font.height]
|
11
|
-
text "This is also in my page template", :at => [0, 0]
|
12
|
-
end
|
7
|
+
Prawn::Document.generate("stamp.pdf", :skip_page_creation => true) do
|
13
8
|
|
14
9
|
create_stamp("odd_page_template") do
|
15
10
|
text "This is the odd page template",
|
16
|
-
:at => [0, bounds.top -
|
11
|
+
:at => [0, bounds.top - font.height]
|
17
12
|
text "This is also in the odd page template", :at => [0, 0]
|
18
13
|
end
|
19
14
|
|
20
15
|
create_stamp("even_page_template") do
|
21
16
|
text "This is the even page template",
|
22
|
-
:at => [0, bounds.top -
|
17
|
+
:at => [0, bounds.top - font.height]
|
23
18
|
text "This is also in the even page template", :at => [0, 0]
|
24
19
|
end
|
25
20
|
|
21
|
+
start_new_page
|
26
22
|
stamp("odd_page_template")
|
27
23
|
|
28
24
|
create_stamp("MyStamp") do
|
data/lib/prawn/core.rb
CHANGED
data/lib/prawn/document.rb
CHANGED
@@ -224,7 +224,6 @@ module Prawn
|
|
224
224
|
end
|
225
225
|
end
|
226
226
|
|
227
|
-
finish_page_content if @page_content
|
228
227
|
build_new_page_content
|
229
228
|
|
230
229
|
@store.pages.data[:Kids] << current_page
|
@@ -279,7 +278,7 @@ module Prawn
|
|
279
278
|
#
|
280
279
|
def render
|
281
280
|
output = StringIO.new
|
282
|
-
|
281
|
+
finalize_all_page_contents
|
283
282
|
|
284
283
|
render_header(output)
|
285
284
|
render_body(output)
|
@@ -474,12 +473,6 @@ module Prawn
|
|
474
473
|
end
|
475
474
|
end
|
476
475
|
|
477
|
-
def go_to_page(k) # :nodoc:
|
478
|
-
jump_to = @store.pages.data[:Kids][k]
|
479
|
-
@current_page = jump_to.identifier
|
480
|
-
@page_content = jump_to.data[:Contents].identifier
|
481
|
-
end
|
482
|
-
|
483
476
|
# Returns true if content streams will be compressed before rendering,
|
484
477
|
# false otherwise
|
485
478
|
#
|
@@ -499,6 +492,11 @@ module Prawn
|
|
499
492
|
:Parent => @store.pages,
|
500
493
|
:MediaBox => page_dimensions,
|
501
494
|
:Contents => page_content)
|
495
|
+
|
496
|
+
# include all proc sets, all the time (recommended by PDF 1.4 Reference
|
497
|
+
# section 9.1)
|
498
|
+
page_resources[:ProcSet] = [:PDF, :Text, :ImageB, :ImageC, :ImageI]
|
499
|
+
|
502
500
|
update_colors
|
503
501
|
undash if dashed?
|
504
502
|
end
|
@@ -42,14 +42,6 @@ module Prawn
|
|
42
42
|
@store.ref(data, &block)
|
43
43
|
end
|
44
44
|
|
45
|
-
def page_content
|
46
|
-
@store[@page_content]
|
47
|
-
end
|
48
|
-
|
49
|
-
def current_page
|
50
|
-
@store[@current_page]
|
51
|
-
end
|
52
|
-
|
53
45
|
# Grabs the reference for the current page content
|
54
46
|
#
|
55
47
|
def page_content
|
@@ -74,13 +66,6 @@ module Prawn
|
|
74
66
|
page_content << str << "\n"
|
75
67
|
end
|
76
68
|
|
77
|
-
# Add a new type to the current pages ProcSet
|
78
|
-
#
|
79
|
-
def proc_set(*types)
|
80
|
-
current_page.data[:ProcSet] ||= ref!([])
|
81
|
-
current_page.data[:ProcSet].data |= types
|
82
|
-
end
|
83
|
-
|
84
69
|
# The Resources dictionary for the current page
|
85
70
|
#
|
86
71
|
def page_resources
|
@@ -111,14 +96,23 @@ module Prawn
|
|
111
96
|
@store.root.data[:Names] ||= ref!(:Type => :Names)
|
112
97
|
end
|
113
98
|
|
99
|
+
def go_to_page(k) # :nodoc:
|
100
|
+
jump_to = @store.pages.data[:Kids][k]
|
101
|
+
@current_page = jump_to.identifier
|
102
|
+
@page_content = jump_to.data[:Contents].identifier
|
103
|
+
end
|
104
|
+
|
114
105
|
private
|
115
|
-
|
116
|
-
def
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
106
|
+
|
107
|
+
def finalize_all_page_contents
|
108
|
+
page_count.times do |i|
|
109
|
+
go_to_page i
|
110
|
+
@header.draw if defined?(@header) and @header
|
111
|
+
@footer.draw if defined?(@footer) and @footer
|
112
|
+
add_content "Q"
|
113
|
+
page_content.compress_stream if compression_enabled?
|
114
|
+
page_content.data[:Length] = page_content.stream.size
|
115
|
+
end
|
122
116
|
end
|
123
117
|
|
124
118
|
# raise the PDF version of the file we're going to generate.
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# snapshot.rb : Implements transactional rendering for Prawn
|
4
4
|
#
|
5
|
-
# Copyright August
|
5
|
+
# Copyright August 2009, Brad Ediger. All Rights Reserved.
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
require 'delegate'
|
@@ -59,6 +59,7 @@ module Prawn
|
|
59
59
|
|
60
60
|
@current_page = shot[:current_page].identifier
|
61
61
|
current_page.replace shot[:current_page]
|
62
|
+
current_page.data[:Contents] = page_content
|
62
63
|
|
63
64
|
@store.pages.data[:Kids] = shot[:page_kids].map{|id| @store[id]}
|
64
65
|
@store.pages.data[:Count] = shot[:page_kids].size
|
data/lib/prawn/font.rb
CHANGED
@@ -30,7 +30,7 @@ module Prawn
|
|
30
30
|
def font(name=nil, options={})
|
31
31
|
return((defined?(@font) && @font) || font("Helvetica")) if name.nil?
|
32
32
|
|
33
|
-
raise Errors::NotOnPage unless
|
33
|
+
raise Errors::NotOnPage unless current_page
|
34
34
|
new_font = find_font(name, options)
|
35
35
|
|
36
36
|
if block_given?
|
@@ -226,7 +226,6 @@ module Prawn
|
|
226
226
|
|
227
227
|
@family = options[:family]
|
228
228
|
|
229
|
-
@document.proc_set :PDF, :Text
|
230
229
|
@identifier = :"F#{@document.font_registry.size + 1}"
|
231
230
|
|
232
231
|
@references = {}
|
data/lib/prawn/images.rb
CHANGED
@@ -70,9 +70,6 @@ module Prawn
|
|
70
70
|
|
71
71
|
image_sha1 = Digest::SHA1.hexdigest(image_content)
|
72
72
|
|
73
|
-
# register the fact that the current page uses images
|
74
|
-
proc_set :ImageC
|
75
|
-
|
76
73
|
# if this image has already been embedded, just reuse it
|
77
74
|
if image_registry[image_sha1]
|
78
75
|
info = image_registry[image_sha1][:info]
|
data/lib/prawn/object_store.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
# object_store.rb : Implements PDF object repository for Prawn
|
4
4
|
#
|
5
|
-
# Copyright August
|
5
|
+
# Copyright August 2009, Brad Ediger. All Rights Reserved.
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
module Prawn
|
data/lib/prawn/stamp.rb
CHANGED
@@ -11,32 +11,37 @@ module Prawn
|
|
11
11
|
module Stamp
|
12
12
|
|
13
13
|
def stamp(user_defined_name)
|
14
|
-
stamp_at(user_defined_name, [0, 0])
|
15
|
-
end
|
16
|
-
|
17
|
-
def stamp_at(user_defined_name, point)
|
18
14
|
raise Prawn::Errors::InvalidName if user_defined_name.empty?
|
19
15
|
unless stamp_dictionary_registry[user_defined_name]
|
20
16
|
raise Prawn::Errors::UndefinedObjectName
|
21
17
|
end
|
22
18
|
|
23
|
-
add_content "q"
|
24
|
-
|
25
|
-
x,y = point
|
26
|
-
translate_position = "1 0 0 1 %.3f %.3f cm" % [x, y]
|
27
|
-
add_content translate_position
|
28
|
-
|
29
19
|
dict = stamp_dictionary_registry[user_defined_name]
|
30
20
|
|
31
21
|
stamp_dictionary_name = dict[:stamp_dictionary_name]
|
32
22
|
stamp_dictionary = dict[:stamp_dictionary]
|
33
23
|
|
34
24
|
add_content "/#{stamp_dictionary_name} Do"
|
35
|
-
|
36
|
-
|
25
|
+
|
37
26
|
page_xobjects.merge!(stamp_dictionary_name => stamp_dictionary)
|
38
27
|
end
|
39
28
|
|
29
|
+
def stamp_at(user_defined_name, point)
|
30
|
+
# Save the graphics state
|
31
|
+
add_content "q"
|
32
|
+
|
33
|
+
# Translate the user space
|
34
|
+
x,y = point
|
35
|
+
translate_position = "1 0 0 1 %.3f %.3f cm" % [x, y]
|
36
|
+
add_content translate_position
|
37
|
+
|
38
|
+
# Draw the stamp in the now translated user space
|
39
|
+
stamp(user_defined_name)
|
40
|
+
|
41
|
+
# Restore the graphics state to remove the translation
|
42
|
+
add_content "Q"
|
43
|
+
end
|
44
|
+
|
40
45
|
def create_stamp(user_defined_name="", &block)
|
41
46
|
raise Prawn::Errors::InvalidName if user_defined_name.empty?
|
42
47
|
|
@@ -44,9 +49,12 @@ module Prawn
|
|
44
49
|
raise Prawn::Errors::NameTaken
|
45
50
|
end
|
46
51
|
|
52
|
+
# BBox origin is the lower left margin of the page, so we need
|
53
|
+
# it to be the full dimension of the page, or else things that
|
54
|
+
# should appear near the top or right margin are invisible
|
47
55
|
stamp_dictionary = ref!(:Type => :XObject,
|
48
56
|
:Subtype => :Form,
|
49
|
-
:BBox => [0, 0,
|
57
|
+
:BBox => [0, 0, page_dimensions[2], page_dimensions[3]])
|
50
58
|
|
51
59
|
stamp_dictionary_name = "Stamp#{next_stamp_dictionary_id}"
|
52
60
|
|
@@ -64,13 +72,7 @@ module Prawn
|
|
64
72
|
stamp_dictionary << @active_stamp_stream
|
65
73
|
|
66
74
|
@active_stamp_stream = nil
|
67
|
-
# The ProcSet needs to be assigned at the page level
|
68
|
-
procs = @active_stamp_dictionary.data[:ProcSet]
|
69
|
-
@active_stamp_dictionary.data.delete(:ProcSet)
|
70
75
|
@active_stamp_dictionary = nil
|
71
|
-
|
72
|
-
# The ProcSet needs to be assigned at the page level
|
73
|
-
proc_set(procs) if procs
|
74
76
|
end
|
75
77
|
|
76
78
|
private
|
data/spec/document_spec.rb
CHANGED
@@ -74,16 +74,14 @@ describe "When beginning each new page" do
|
|
74
74
|
|
75
75
|
end
|
76
76
|
|
77
|
-
describe "
|
77
|
+
describe "Document compression" do
|
78
78
|
|
79
79
|
it "should not compress the page content stream if compression is disabled" do
|
80
80
|
|
81
81
|
pdf = Prawn::Document.new(:compress => false)
|
82
|
-
|
83
|
-
|
84
|
-
content_stub.expects(:compress_stream).never
|
82
|
+
pdf.page_content.stubs(:compress_stream).returns(true)
|
83
|
+
pdf.page_content.expects(:compress_stream).never
|
85
84
|
|
86
|
-
pdf.instance_variable_set("@page_content", content_stub.identifier)
|
87
85
|
pdf.text "Hi There" * 20
|
88
86
|
pdf.render
|
89
87
|
end
|
@@ -91,11 +89,9 @@ describe "When ending each page" do
|
|
91
89
|
it "should compress the page content stream if compression is enabled" do
|
92
90
|
|
93
91
|
pdf = Prawn::Document.new(:compress => true)
|
94
|
-
|
95
|
-
|
96
|
-
content_stub.expects(:compress_stream).once
|
92
|
+
pdf.page_content.stubs(:compress_stream).returns(true)
|
93
|
+
pdf.page_content.expects(:compress_stream).once
|
97
94
|
|
98
|
-
pdf.instance_variable_set("@page_content", content_stub.identifier)
|
99
95
|
pdf.text "Hi There" * 20
|
100
96
|
pdf.render
|
101
97
|
end
|
@@ -113,6 +109,23 @@ describe "When ending each page" do
|
|
113
109
|
|
114
110
|
end
|
115
111
|
|
112
|
+
describe "When reopening pages" do
|
113
|
+
it "should modify the content stream size" do
|
114
|
+
@pdf = Prawn::Document.new do |pdf|
|
115
|
+
pdf.text "Page 1"
|
116
|
+
pdf.start_new_page
|
117
|
+
pdf.text "Page 2"
|
118
|
+
pdf.go_to_page 0
|
119
|
+
pdf.text "More for page 1"
|
120
|
+
end
|
121
|
+
|
122
|
+
# MalformedPDFError raised if content stream actual length does not match
|
123
|
+
# dictionary length
|
124
|
+
lambda{ PDF::Inspector::Page.analyze(@pdf.render) }.
|
125
|
+
should.not.raise(PDF::Reader::MalformedPDFError)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
116
129
|
describe "When setting page size" do
|
117
130
|
it "should default to LETTER" do
|
118
131
|
@pdf = Prawn::Document.new
|
data/spec/snapshot_spec.rb
CHANGED
@@ -81,9 +81,21 @@ describe "Prawn::Document#transaction" do
|
|
81
81
|
page_content.identifier.should == old_page_content_id
|
82
82
|
end
|
83
83
|
|
84
|
-
|
85
84
|
end
|
86
85
|
|
86
|
+
it "page object should refer to the page_content object after restore" do
|
87
|
+
|
88
|
+
Prawn::Document.new do
|
89
|
+
transaction do
|
90
|
+
start_new_page
|
91
|
+
rollback
|
92
|
+
end
|
93
|
+
|
94
|
+
# should be the exact same object, not a clone
|
95
|
+
current_page.data[:Contents].should == page_content
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
87
99
|
|
88
100
|
describe "with a stamp dictionary present" do
|
89
101
|
|
data/spec/stamp_spec.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
1
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")
|
2
|
+
|
3
|
+
describe "create_stamp before any page is added" do
|
4
|
+
it "should work with the font class" do
|
5
|
+
@pdf = Prawn::Document.new(:skip_page_creation => true)
|
6
|
+
lambda {
|
7
|
+
@pdf.create_stamp("my_stamp") do
|
8
|
+
@pdf.font.height
|
9
|
+
end
|
10
|
+
}.should.not.raise(Prawn::Errors::NotOnPage)
|
11
|
+
end
|
12
|
+
end
|
2
13
|
|
3
14
|
describe "Document with a stamp" do
|
4
15
|
it "should raise NameTaken error when attempt to create stamp "+
|
@@ -73,26 +84,4 @@ describe "Document with a stamp" do
|
|
73
84
|
end
|
74
85
|
end
|
75
86
|
end
|
76
|
-
|
77
|
-
it "if ProcSet changes are made, they should be added to the Page "+
|
78
|
-
"object, not the stamp XObject" do
|
79
|
-
create_pdf
|
80
|
-
@pdf.create_stamp("MyStamp") do
|
81
|
-
@pdf.text("hello")
|
82
|
-
end
|
83
|
-
@pdf.stamp("MyStamp")
|
84
|
-
|
85
|
-
# Inspector::XObject does not give information about ProcSet, so
|
86
|
-
# resorting to string matching
|
87
|
-
|
88
|
-
output = @pdf.render
|
89
|
-
objects = output.split("endobj")
|
90
|
-
objects.each do |object|
|
91
|
-
if object =~ /\/Type \/Page$/
|
92
|
-
object.should =~ /\/ProcSet/
|
93
|
-
elsif object =~ /\/Type \/XObject$/
|
94
|
-
object.should.not =~ /\/ProcSet/
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
87
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: prawn-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gregory Brown
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-13 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -34,6 +34,7 @@ files:
|
|
34
34
|
- examples/general/background.rb
|
35
35
|
- examples/general/canvas.rb
|
36
36
|
- examples/general/margin.rb
|
37
|
+
- examples/general/measurement_units.pdf
|
37
38
|
- examples/general/measurement_units.rb
|
38
39
|
- examples/general/metadata-info.rb
|
39
40
|
- examples/general/multi_page_layout.rb
|
@@ -263,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
263
264
|
requirements: []
|
264
265
|
|
265
266
|
rubyforge_project: prawn
|
266
|
-
rubygems_version: 1.3.
|
267
|
+
rubygems_version: 1.3.5
|
267
268
|
signing_key:
|
268
269
|
specification_version: 3
|
269
270
|
summary: A fast and nimble PDF generator for Ruby
|