prawn-core 0.6.2 → 0.6.3

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 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