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.
@@ -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 - 4 * font.height]
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 - 4 * font.height]
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
@@ -25,7 +25,7 @@ module Prawn
25
25
  # The base source directory for Prawn as installed on the system
26
26
  BASEDIR = File.expand_path(File.join(dir, '..', '..'))
27
27
 
28
- VERSION = "0.6.1"
28
+ VERSION = "0.6.2"
29
29
 
30
30
  extend self
31
31
 
@@ -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
- finish_page_content
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 finish_page_content
117
- @header.draw if defined?(@header) and @header
118
- @footer.draw if defined?(@footer) and @footer
119
- add_content "Q"
120
- page_content.compress_stream if compression_enabled?
121
- page_content.data[:Length] = page_content.stream.size
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 2008, Brad Ediger. All Rights Reserved.
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
@@ -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 defined?(@current_page) && @current_page
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 = {}
@@ -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]
@@ -2,7 +2,7 @@
2
2
 
3
3
  # object_store.rb : Implements PDF object repository for Prawn
4
4
  #
5
- # Copyright August 2008, Brad Ediger. All Rights Reserved.
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
@@ -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
- add_content "Q"
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, bounds.width, bounds.height])
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
@@ -74,16 +74,14 @@ describe "When beginning each new page" do
74
74
 
75
75
  end
76
76
 
77
- describe "When ending each page" do
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
- content_stub = pdf.ref!({})
83
- content_stub.stubs(:compress_stream).returns(true)
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
- content_stub = pdf.ref!({})
95
- content_stub.stubs(:compress_stream).returns(true)
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
@@ -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
 
@@ -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.1
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-10 00:00:00 -05:00
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.4
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