prawn-core 0.6.2 → 0.6.3

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'rake/testtask'
4
4
  require "rake/rdoctask"
5
5
  require "rake/gempackagetask"
6
6
 
7
- PRAWN_VERSION = "0.6.2"
7
+ PRAWN_VERSION = "0.6.3"
8
8
 
9
9
  task :default => [:test]
10
10
 
@@ -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.2"
28
+ VERSION = "0.6.3"
29
29
 
30
30
  extend self
31
31
 
@@ -73,6 +73,10 @@ module Prawn
73
73
  @extensions ||= []
74
74
  end
75
75
 
76
+ def self.inherited(base)
77
+ extensions.each { |e| base.extensions << e }
78
+ end
79
+
76
80
  # Creates and renders a PDF document.
77
81
  #
78
82
  # When using the implicit block form, Prawn will evaluate the block
@@ -170,6 +174,7 @@ module Prawn
170
174
  @version = 1.3
171
175
  @store = ObjectStore.new(options[:info])
172
176
  @trailer = {}
177
+ @before_render_callbacks = []
173
178
 
174
179
  @page_size = options[:page_size] || "LETTER"
175
180
  @page_layout = options[:page_layout] || :portrait
@@ -23,7 +23,7 @@ module Prawn
23
23
  def annotate(options)
24
24
  current_page.data[:Annots] ||= []
25
25
  options = sanitize_annotation_hash(options)
26
- current_page.data[:Annots] << ref(options)
26
+ current_page.data[:Annots] << ref!(options)
27
27
  return options
28
28
  end
29
29
 
@@ -21,13 +21,8 @@ module Prawn
21
21
  #
22
22
  # Returns the identifier which points to the reference in the ObjectStore
23
23
  #
24
- # If a block is given, it will be invoked just before the object is written
25
- # out to the PDF document stream. This allows you to do deferred processing
26
- # on some references (such as fonts, which you might know all the details
27
- # about until the last page of the document is finished).
28
- #
29
- def ref(data, &block)
30
- ref!(data, &block).identifier
24
+ def ref(data)
25
+ ref!(data).identifier
31
26
  end
32
27
 
33
28
  # Like ref, but returns the actual reference instead of its identifier.
@@ -38,8 +33,8 @@ module Prawn
38
33
  # if needed. If you take this approach, Prawn::Document::Snapshot
39
34
  # will probably work with your extension
40
35
  #
41
- def ref!(data, &block)
42
- @store.ref(data, &block)
36
+ def ref!(data)
37
+ @store.ref(data)
43
38
  end
44
39
 
45
40
  # Grabs the reference for the current page content
@@ -96,6 +91,12 @@ module Prawn
96
91
  @store.root.data[:Names] ||= ref!(:Type => :Names)
97
92
  end
98
93
 
94
+ # Defines a block to be called just before the document is rendered.
95
+ #
96
+ def before_render(&block)
97
+ @before_render_callbacks << block
98
+ end
99
+
99
100
  def go_to_page(k) # :nodoc:
100
101
  jump_to = @store.pages.data[:Kids][k]
101
102
  @current_page = jump_to.identifier
@@ -125,6 +126,8 @@ module Prawn
125
126
  # Write out the PDF Header, as per spec 3.4.1
126
127
  #
127
128
  def render_header(output)
129
+ @before_render_callbacks.each{ |c| c.call(self) }
130
+
128
131
  # pdf version
129
132
  output << "%PDF-#{@version}\n"
130
133
 
@@ -222,7 +222,13 @@ module Prawn
222
222
 
223
223
  def register(subset)
224
224
  temp_name = @ttf.name.postscript_name.gsub("\0","").to_sym
225
- @document.ref!(:Type => :Font, :BaseFont => temp_name) { |ref| embed(ref, subset) }
225
+ ref = @document.ref!(:Type => :Font, :BaseFont => temp_name)
226
+
227
+ # Embed the font metrics in the document after everything has been
228
+ # drawn, just before the document is emitted.
229
+ @document.before_render { |doc| embed(ref, subset) }
230
+
231
+ ref
226
232
  end
227
233
 
228
234
  def embed(reference, subset)
@@ -15,17 +15,15 @@ module Prawn
15
15
  attr_accessor :gen, :data, :offset, :stream
16
16
  attr_reader :identifier
17
17
 
18
- def initialize(id, data, &block)
18
+ def initialize(id, data)
19
19
  @identifier = id
20
20
  @gen = 0
21
21
  @data = data
22
22
  @compressed = false
23
- @on_encode = block
24
23
  @stream = nil
25
24
  end
26
25
 
27
26
  def object
28
- @on_encode.call(self) if @on_encode
29
27
  output = "#{@identifier} #{gen} obj\n" <<
30
28
  Prawn::PdfObject(data) << "\n"
31
29
  if @stream
@@ -22,13 +22,37 @@ describe "The cursor" do
22
22
  end
23
23
 
24
24
  describe "when generating a document from a subclass" do
25
- it "should be an instance_eval of the subclass" do
25
+ it "should be an instance of the subclass" do
26
26
  custom_document = Class.new(Prawn::Document)
27
27
  custom_document.generate(Tempfile.new("generate_test").path) do |e|
28
28
  e.class.should == custom_document
29
29
  e.should.be.kind_of(Prawn::Document)
30
30
  end
31
31
  end
32
+
33
+ it "should retain any extensions found on Prawn::Document" do
34
+ mod1 = Module.new { attr_reader :test_extensions1 }
35
+ mod2 = Module.new { attr_reader :test_extensions2 }
36
+
37
+ Prawn::Document.extensions << mod1 << mod2
38
+
39
+ custom_document = Class.new(Prawn::Document)
40
+ assert_equal [mod1, mod2], custom_document.extensions
41
+
42
+ # remove the extensions we added to prawn document
43
+ Prawn::Document.extensions.delete(mod1)
44
+ Prawn::Document.extensions.delete(mod2)
45
+
46
+ assert ! Prawn::Document.new.respond_to?(:test_extensions1)
47
+ assert ! Prawn::Document.new.respond_to?(:test_extensions2)
48
+
49
+ # verify these still exist on custom class
50
+ assert_equal [mod1, mod2], custom_document.extensions
51
+
52
+ assert custom_document.new.respond_to?(:test_extensions1)
53
+ assert custom_document.new.respond_to?(:test_extensions2)
54
+ end
55
+
32
56
  end
33
57
 
34
58
 
@@ -226,6 +250,22 @@ describe "The render() feature" do
226
250
  str.encoding.to_s.should == "ASCII-8BIT"
227
251
  end
228
252
  end
253
+
254
+ it "should trigger before_render callbacks just before rendering" do
255
+ pdf = Prawn::Document.new
256
+
257
+ seq = sequence("callback_order")
258
+
259
+ # Verify the order: finalize -> fire callbacks -> render body
260
+ pdf.expects(:finalize_all_page_contents).in_sequence(seq)
261
+ trigger = mock()
262
+ trigger.expects(:fire).in_sequence(seq)
263
+ pdf.expects(:render_body).in_sequence(seq)
264
+
265
+ pdf.before_render{ trigger.fire }
266
+
267
+ pdf.render
268
+ end
229
269
  end
230
270
 
231
271
  describe "PDF file versions" do
@@ -230,6 +230,33 @@ describe "TTF fonts" do
230
230
 
231
231
  end
232
232
 
233
+ describe "when used with snapshots or transactions" do
234
+
235
+ it "should allow TTF fonts to be used alongside document transactions" do
236
+ lambda {
237
+ Prawn::Document.new do
238
+ font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
239
+ text "Hi there"
240
+ transaction { text "Nice, thank you" }
241
+ end
242
+ }.should.not.raise
243
+ end
244
+
245
+ it "should allow TTF fonts to be used inside transactions" do
246
+ pdf = Prawn::Document.new do
247
+ transaction do
248
+ font "#{Prawn::BASEDIR}/data/fonts/DejaVuSans.ttf"
249
+ text "Hi there"
250
+ end
251
+ end
252
+
253
+ text = PDF::Inspector::Text.analyze(pdf.render)
254
+ name = text.font_settings.map { |e| e[:name] }.first.to_s
255
+ name = name.sub(/\w+\+/, "subset+")
256
+ name.should == "subset+DejaVuSans"
257
+ end
258
+
259
+ end
233
260
 
234
261
  end
235
262
 
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.2
4
+ version: 0.6.3
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-13 00:00:00 -05:00
12
+ date: 2009-11-17 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15