prawn 1.0.0.rc2 → 1.0.0
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.
- checksums.yaml +7 -0
- data/.yardopts +9 -0
- data/COPYING +2 -2
- data/Gemfile +8 -15
- data/LICENSE +1 -1
- data/Rakefile +25 -16
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/license.md +8 -0
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/lib/prawn.rb +85 -23
- data/lib/prawn/document.rb +134 -116
- data/lib/prawn/document/bounding_box.rb +33 -4
- data/lib/prawn/document/column_box.rb +18 -6
- data/lib/prawn/document/graphics_state.rb +11 -74
- data/lib/prawn/document/internals.rb +24 -23
- data/lib/prawn/document/span.rb +12 -10
- data/lib/prawn/encoding.rb +8 -9
- data/lib/prawn/errors.rb +13 -32
- data/lib/prawn/font.rb +137 -105
- data/lib/prawn/font/afm.rb +76 -32
- data/lib/prawn/font/dfont.rb +4 -3
- data/lib/prawn/font/ttf.rb +33 -25
- data/lib/prawn/font_metric_cache.rb +47 -0
- data/lib/prawn/graphics.rb +177 -57
- data/lib/prawn/graphics/cap_style.rb +4 -3
- data/lib/prawn/graphics/color.rb +5 -4
- data/lib/prawn/graphics/dash.rb +53 -31
- data/lib/prawn/graphics/join_style.rb +9 -7
- data/lib/prawn/graphics/patterns.rb +4 -15
- data/lib/prawn/graphics/transformation.rb +10 -9
- data/lib/prawn/graphics/transparency.rb +3 -1
- data/lib/prawn/{layout/grid.rb → grid.rb} +72 -54
- data/lib/prawn/image_handler.rb +42 -0
- data/lib/prawn/images.rb +58 -54
- data/lib/prawn/images/image.rb +6 -22
- data/lib/prawn/images/jpg.rb +20 -14
- data/lib/prawn/images/png.rb +58 -121
- data/lib/prawn/layout.rb +12 -15
- data/lib/prawn/measurement_extensions.rb +10 -6
- data/lib/prawn/measurements.rb +27 -21
- data/lib/prawn/outline.rb +108 -147
- data/lib/prawn/repeater.rb +10 -8
- data/lib/prawn/security.rb +59 -40
- data/lib/prawn/security/arcfour.rb +52 -0
- data/lib/prawn/soft_mask.rb +4 -4
- data/lib/prawn/stamp.rb +5 -3
- data/lib/prawn/table.rb +83 -60
- data/lib/prawn/table/cell.rb +17 -21
- data/lib/prawn/table/cell/image.rb +2 -3
- data/lib/prawn/table/cell/in_table.rb +8 -2
- data/lib/prawn/table/cell/span_dummy.rb +5 -0
- data/lib/prawn/table/cell/subtable.rb +3 -2
- data/lib/prawn/table/cell/text.rb +14 -12
- data/lib/prawn/table/cells.rb +58 -14
- data/lib/prawn/table/column_width_calculator.rb +61 -0
- data/lib/prawn/text.rb +27 -26
- data/lib/prawn/text/box.rb +12 -6
- data/lib/prawn/text/formatted.rb +5 -4
- data/lib/prawn/text/formatted/arranger.rb +290 -0
- data/lib/prawn/text/formatted/box.rb +85 -57
- data/lib/prawn/text/formatted/fragment.rb +11 -11
- data/lib/prawn/text/formatted/line_wrap.rb +266 -0
- data/lib/prawn/text/formatted/parser.rb +11 -4
- data/lib/prawn/text/formatted/wrap.rb +156 -0
- data/lib/prawn/utilities.rb +5 -3
- data/manual/document_and_page_options/document_and_page_options.rb +2 -1
- data/manual/document_and_page_options/metadata.rb +3 -3
- data/manual/document_and_page_options/page_size.rb +2 -2
- data/manual/document_and_page_options/print_scaling.rb +20 -0
- data/manual/example_file.rb +2 -7
- data/manual/example_helper.rb +62 -81
- data/manual/graphics/common_lines.rb +2 -0
- data/manual/graphics/helper.rb +11 -4
- data/manual/graphics/stroke_dash.rb +19 -14
- data/manual/manual/cover.rb +16 -0
- data/manual/manual/manual.rb +1 -5
- data/manual/text/fallback_fonts.rb +4 -4
- data/manual/text/formatted_text.rb +5 -5
- data/manual/text/inline.rb +2 -4
- data/manual/text/registering_families.rb +12 -12
- data/manual/text/single_usage.rb +4 -4
- data/manual/text/text.rb +0 -2
- data/prawn.gemspec +21 -13
- data/spec/acceptance/png.rb +23 -0
- data/spec/annotations_spec.rb +16 -32
- data/spec/bounding_box_spec.rb +22 -5
- data/spec/cell_spec.rb +49 -5
- data/spec/column_box_spec.rb +32 -0
- data/spec/destinations_spec.rb +5 -5
- data/spec/document_spec.rb +112 -118
- data/spec/extensions/encoding_helpers.rb +5 -2
- data/spec/font_metric_cache_spec.rb +52 -0
- data/spec/font_spec.rb +121 -120
- data/spec/formatted_text_arranger_spec.rb +24 -24
- data/spec/formatted_text_box_spec.rb +31 -32
- data/spec/formatted_text_fragment_spec.rb +2 -2
- data/spec/graphics_spec.rb +63 -45
- data/spec/grid_spec.rb +24 -13
- data/spec/image_handler_spec.rb +54 -0
- data/spec/images_spec.rb +34 -21
- data/spec/inline_formatted_text_parser_spec.rb +69 -20
- data/spec/jpg_spec.rb +3 -3
- data/spec/line_wrap_spec.rb +25 -14
- data/spec/measurement_units_spec.rb +5 -5
- data/spec/outline_spec.rb +68 -64
- data/spec/png_spec.rb +15 -18
- data/spec/reference_spec.rb +2 -82
- data/spec/repeater_spec.rb +1 -1
- data/spec/security_spec.rb +41 -9
- data/spec/soft_mask_spec.rb +0 -40
- data/spec/span_spec.rb +6 -11
- data/spec/spec_helper.rb +20 -2
- data/spec/stamp_spec.rb +19 -20
- data/spec/stroke_styles_spec.rb +31 -13
- data/spec/table/span_dummy_spec.rb +17 -0
- data/spec/table_spec.rb +268 -43
- data/spec/text_at_spec.rb +13 -27
- data/spec/text_box_spec.rb +35 -30
- data/spec/text_spec.rb +56 -40
- data/spec/transparency_spec.rb +5 -5
- metadata +214 -217
- data/README.md +0 -98
- data/data/fonts/Action Man.dfont +0 -0
- data/data/fonts/Activa.ttf +0 -0
- data/data/fonts/Chalkboard.ttf +0 -0
- data/data/fonts/DejaVuSans.ttf +0 -0
- data/data/fonts/Dustismo_Roman.ttf +0 -0
- data/data/fonts/comicsans.ttf +0 -0
- data/data/fonts/gkai00mp.ttf +0 -0
- data/data/images/16bit.dat +0 -0
- data/data/images/barcode_issue.png +0 -0
- data/data/images/dice.dat +0 -0
- data/data/images/page_white_text.dat +0 -0
- data/data/images/rails.dat +0 -0
- data/data/images/rails.png +0 -0
- data/lib/prawn/compatibility.rb +0 -87
- data/lib/prawn/core.rb +0 -87
- data/lib/prawn/core/annotations.rb +0 -61
- data/lib/prawn/core/byte_string.rb +0 -9
- data/lib/prawn/core/destinations.rb +0 -90
- data/lib/prawn/core/document_state.rb +0 -79
- data/lib/prawn/core/literal_string.rb +0 -16
- data/lib/prawn/core/name_tree.rb +0 -177
- data/lib/prawn/core/object_store.rb +0 -320
- data/lib/prawn/core/page.rb +0 -212
- data/lib/prawn/core/pdf_object.rb +0 -125
- data/lib/prawn/core/reference.rb +0 -119
- data/lib/prawn/core/text.rb +0 -268
- data/lib/prawn/core/text/formatted/arranger.rb +0 -294
- data/lib/prawn/core/text/formatted/line_wrap.rb +0 -288
- data/lib/prawn/core/text/formatted/wrap.rb +0 -153
- data/lib/prawn/document/page_geometry.rb +0 -136
- data/lib/prawn/document/snapshot.rb +0 -89
- data/manual/manual/foreword.rb +0 -13
- data/manual/templates/full_template.rb +0 -23
- data/manual/templates/page_template.rb +0 -47
- data/manual/templates/templates.rb +0 -26
- data/manual/text/group.rb +0 -29
- data/spec/name_tree_spec.rb +0 -112
- data/spec/object_store_spec.rb +0 -170
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/snapshot_spec.rb +0 -186
- data/spec/template_spec.rb +0 -351
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: edf9e637f24e5c4554e995712cb589f0b21737fb
|
|
4
|
+
data.tar.gz: 97750f73864c853ff874f8a5a0f7984a6f9d8279
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: bd80b65ac0360fa6786b6bffacfc34a87511cc8d79e260dfd8db78b86a5003182a41d5ad559e5c1403724273c83b71b29d426c31a422fd7b1e5986a859ac1a5d
|
|
7
|
+
data.tar.gz: 4b63fc53c8481155ed173cb3e4b8146ac052173e0bd91f4fa27aece66525ad5f6968a48230addbb5ae2a043a3bc33829c79c9447a8c734f3bd2da45468b913da
|
data/.yardopts
ADDED
data/COPYING
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Prawn may be used under Matz's terms for Ruby, or GPLv2 or GPLv3.
|
|
2
|
-
for Matz's terms, or GPLv2 and GPLv3 files.
|
|
1
|
+
Prawn may be used under Matz's original licensing terms for Ruby, or GPLv2 or GPLv3.
|
|
2
|
+
See LICENSE for Matz's terms, or GPLv2 and GPLv3 files.
|
data/Gemfile
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
source
|
|
1
|
+
source "https://rubygems.org"
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
gem "pdf-reader", "~> 1.2"
|
|
5
|
-
gem "ruby-rc4"
|
|
6
|
-
gem "afm"
|
|
3
|
+
gemspec
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
gem "pdf-inspector", "~> 1.0.2", :require => "pdf/inspector"
|
|
15
|
-
gem "rspec"
|
|
16
|
-
gem "mocha", :require => false
|
|
17
|
-
gem "rake"
|
|
5
|
+
if ENV["CI"]
|
|
6
|
+
platforms :rbx do
|
|
7
|
+
gem "rubysl-singleton", "~> 2.0"
|
|
8
|
+
gem "rubysl-digest", "~> 2.0"
|
|
9
|
+
gem "rubysl-enumerator", "~> 2.0"
|
|
10
|
+
end
|
|
18
11
|
end
|
data/LICENSE
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Prawn is copyrighted free software produced by Gregory Brown along with
|
|
2
2
|
community contributions. See git log for authorship information.
|
|
3
3
|
|
|
4
|
-
Licensing terms follow
|
|
4
|
+
Licensing terms follow:
|
|
5
5
|
|
|
6
6
|
You can redistribute Prawn and/or modify it under either the terms of the GPLv2
|
|
7
7
|
or GPLv3 (see GPLv2 and GPLv3 files), or the conditions below:
|
data/Rakefile
CHANGED
|
@@ -3,32 +3,29 @@ Bundler.setup
|
|
|
3
3
|
|
|
4
4
|
require 'rake'
|
|
5
5
|
require 'rspec/core/rake_task'
|
|
6
|
-
require '
|
|
6
|
+
require 'yard'
|
|
7
7
|
require 'rubygems/package_task'
|
|
8
8
|
|
|
9
9
|
task :default => [:spec]
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
desc "Run all rspec files"
|
|
12
|
-
RSpec::Core::RakeTask.new("spec")
|
|
12
|
+
RSpec::Core::RakeTask.new("spec") do |c|
|
|
13
|
+
c.rspec_opts = "-t ~unresolved"
|
|
14
|
+
end
|
|
13
15
|
|
|
14
16
|
desc "Show library's code statistics"
|
|
15
17
|
task :stats do
|
|
16
|
-
|
|
17
|
-
CodeStatistics::TEST_TYPES << "Specs"
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
require 'code_statistics'
|
|
19
|
+
CodeStatistics::TEST_TYPES << "Specs"
|
|
20
|
+
CodeStatistics.new( ["Prawn", "lib"],
|
|
21
|
+
["Specs", "spec"] ).to_s
|
|
20
22
|
end
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
rdoc.rdoc_files.include( "README",
|
|
25
|
-
"COPYING",
|
|
26
|
-
"LICENSE",
|
|
27
|
-
"HACKING", "lib/" )
|
|
28
|
-
rdoc.main = "README"
|
|
29
|
-
rdoc.rdoc_dir = "doc/html"
|
|
30
|
-
rdoc.title = "Prawn Documentation"
|
|
24
|
+
YARD::Rake::YardocTask.new do |t|
|
|
25
|
+
t.options = ['--output-dir', 'doc/html']
|
|
31
26
|
end
|
|
27
|
+
task :docs => :yard
|
|
28
|
+
|
|
32
29
|
|
|
33
30
|
desc "Generate the 'Prawn by Example' manual"
|
|
34
31
|
task :manual do
|
|
@@ -43,3 +40,15 @@ Gem::PackageTask.new(spec) do |pkg|
|
|
|
43
40
|
pkg.need_zip = true
|
|
44
41
|
pkg.need_tar = true
|
|
45
42
|
end
|
|
43
|
+
|
|
44
|
+
desc "Run a console with Prawn loaded"
|
|
45
|
+
task :console do
|
|
46
|
+
require 'irb'
|
|
47
|
+
require 'irb/completion'
|
|
48
|
+
require_relative 'lib/prawn'
|
|
49
|
+
Prawn.debug = true
|
|
50
|
+
|
|
51
|
+
ARGV.clear
|
|
52
|
+
IRB.start
|
|
53
|
+
end
|
|
54
|
+
|
data/data/images/16bit.alpha
CHANGED
|
Binary file
|
|
Binary file
|
data/data/images/dice.alpha
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
All images distributed with Prawn need to be freely distributable under
|
|
2
|
+
a license that is compatible with our own (see LICENSE and COPYING files).
|
|
3
|
+
|
|
4
|
+
It is our understanding that all files in this folder are compatible
|
|
5
|
+
with our licensing, but if you notice any problems, please
|
|
6
|
+
file an issue in our tracker on Github and we will promptly address it:
|
|
7
|
+
|
|
8
|
+
https://github.com/prawnpdf/prawn/issues
|
|
Binary file
|
|
Binary file
|
data/lib/prawn.rb
CHANGED
|
@@ -1,29 +1,91 @@
|
|
|
1
1
|
# Welcome to Prawn, the best PDF Generation library ever.
|
|
2
2
|
# This documentation covers user level functionality.
|
|
3
3
|
#
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
4
|
+
require "set"
|
|
5
|
+
|
|
6
|
+
require 'ttfunk'
|
|
7
|
+
require "pdf/core"
|
|
8
|
+
|
|
9
|
+
module Prawn
|
|
10
|
+
VERSION = "1.0.0"
|
|
11
|
+
|
|
12
|
+
extend self
|
|
13
|
+
|
|
14
|
+
file = __FILE__
|
|
15
|
+
file = File.readlink(file) if File.symlink?(file)
|
|
16
|
+
dir = File.dirname(file)
|
|
17
|
+
|
|
18
|
+
# The base source directory for Prawn as installed on the system
|
|
19
|
+
#
|
|
20
|
+
#
|
|
21
|
+
BASEDIR = File.expand_path(File.join(dir, '..'))
|
|
22
|
+
DATADIR = File.expand_path(File.join(dir, '..', 'data'))
|
|
23
|
+
|
|
24
|
+
FLOAT_PRECISION = 1.0e-9
|
|
25
|
+
|
|
26
|
+
# Whe set to true, Prawn will verify hash options to ensure only valid keys
|
|
27
|
+
# are used. Off by default.
|
|
28
|
+
#
|
|
29
|
+
# Example:
|
|
30
|
+
# >> Prawn::Document.new(:tomato => "Juicy")
|
|
31
|
+
# Prawn::Errors::UnknownOption:
|
|
32
|
+
# Detected unknown option(s): [:tomato]
|
|
33
|
+
# Accepted options are: [:page_size, :page_layout, :left_margin, ...]
|
|
34
|
+
#
|
|
35
|
+
attr_accessor :debug # @private
|
|
36
|
+
|
|
37
|
+
def verify_options(accepted, actual) # @private
|
|
38
|
+
return unless debug || $DEBUG
|
|
39
|
+
unless (act=Set[*actual.keys]).subset?(acc=Set[*accepted])
|
|
40
|
+
raise Prawn::Errors::UnknownOption,
|
|
41
|
+
"\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" <<
|
|
42
|
+
"Accepted options are: #{accepted.inspect}"
|
|
43
|
+
end
|
|
44
|
+
yield if block_given?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
module Configurable # @private
|
|
48
|
+
def configuration(*args)
|
|
49
|
+
@config ||= Marshal.load(Marshal.dump(default_configuration))
|
|
50
|
+
if Hash === args[0]
|
|
51
|
+
@config.update(args[0])
|
|
52
|
+
elsif args.length > 1
|
|
53
|
+
@config.values_at(*args)
|
|
54
|
+
elsif args.length == 1
|
|
55
|
+
@config[args[0]]
|
|
56
|
+
else
|
|
57
|
+
@config
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
alias_method :C, :configuration
|
|
62
|
+
end
|
|
9
63
|
end
|
|
10
64
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
65
|
+
require_relative "prawn/errors"
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
require_relative "prawn/utilities"
|
|
69
|
+
require_relative "prawn/text"
|
|
70
|
+
require_relative "prawn/graphics"
|
|
71
|
+
require_relative "prawn/images"
|
|
72
|
+
require_relative "prawn/images/image"
|
|
73
|
+
require_relative "prawn/images/jpg"
|
|
74
|
+
require_relative "prawn/images/png"
|
|
75
|
+
require_relative "prawn/stamp"
|
|
76
|
+
require_relative "prawn/soft_mask"
|
|
77
|
+
require_relative "prawn/security"
|
|
78
|
+
require_relative "prawn/document"
|
|
79
|
+
require_relative "prawn/font"
|
|
80
|
+
require_relative "prawn/encoding"
|
|
81
|
+
require_relative "prawn/measurements"
|
|
82
|
+
require_relative "prawn/repeater"
|
|
83
|
+
require_relative "prawn/outline"
|
|
84
|
+
require_relative "prawn/layout"
|
|
85
|
+
|
|
86
|
+
require_relative "prawn/image_handler"
|
|
87
|
+
|
|
88
|
+
|
|
29
89
|
|
|
90
|
+
Prawn.image_handler.register(Prawn::Images::PNG)
|
|
91
|
+
Prawn.image_handler.register(Prawn::Images::JPG)
|
data/lib/prawn/document.rb
CHANGED
|
@@ -7,13 +7,12 @@
|
|
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
|
8
8
|
|
|
9
9
|
require "stringio"
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
require "prawn/document/graphics_state"
|
|
10
|
+
|
|
11
|
+
require_relative "document/bounding_box"
|
|
12
|
+
require_relative "document/column_box"
|
|
13
|
+
require_relative "document/internals"
|
|
14
|
+
require_relative "document/span"
|
|
15
|
+
require_relative "document/graphics_state"
|
|
17
16
|
|
|
18
17
|
module Prawn
|
|
19
18
|
|
|
@@ -52,9 +51,8 @@ module Prawn
|
|
|
52
51
|
#
|
|
53
52
|
class Document
|
|
54
53
|
include Prawn::Document::Internals
|
|
55
|
-
include
|
|
56
|
-
include
|
|
57
|
-
include Prawn::Document::Snapshot
|
|
54
|
+
include PDF::Core::Annotations
|
|
55
|
+
include PDF::Core::Destinations
|
|
58
56
|
include Prawn::Document::GraphicsState
|
|
59
57
|
include Prawn::Document::Security
|
|
60
58
|
include Prawn::Text
|
|
@@ -63,6 +61,16 @@ module Prawn
|
|
|
63
61
|
include Prawn::Stamp
|
|
64
62
|
include Prawn::SoftMask
|
|
65
63
|
|
|
64
|
+
# @group Extension API
|
|
65
|
+
|
|
66
|
+
# NOTE: We probably need to rethink the options validation system, but this
|
|
67
|
+
# constant temporarily allows for extensions to modify the list.
|
|
68
|
+
|
|
69
|
+
VALID_OPTIONS = [:page_size, :page_layout, :margin, :left_margin,
|
|
70
|
+
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
|
|
71
|
+
:compress, :skip_encoding, :background, :info,
|
|
72
|
+
:text_formatter, :print_scaling]
|
|
73
|
+
|
|
66
74
|
# Any module added to this array will be included into instances of
|
|
67
75
|
# Prawn::Document at the per-object level. These will also be inherited by
|
|
68
76
|
# any subclasses.
|
|
@@ -83,14 +91,28 @@ module Prawn
|
|
|
83
91
|
# party!
|
|
84
92
|
# end
|
|
85
93
|
#
|
|
94
|
+
#
|
|
86
95
|
def self.extensions
|
|
87
96
|
@extensions ||= []
|
|
88
97
|
end
|
|
89
98
|
|
|
90
|
-
|
|
99
|
+
# @private
|
|
100
|
+
def self.inherited(base)
|
|
91
101
|
extensions.each { |e| base.extensions << e }
|
|
92
102
|
end
|
|
93
103
|
|
|
104
|
+
# @group Stable Attributes
|
|
105
|
+
|
|
106
|
+
attr_accessor :margin_box
|
|
107
|
+
attr_reader :margins, :y
|
|
108
|
+
attr_accessor :page_number
|
|
109
|
+
|
|
110
|
+
# @group Extension Attributes
|
|
111
|
+
|
|
112
|
+
attr_accessor :text_formatter
|
|
113
|
+
|
|
114
|
+
# @group Stable API
|
|
115
|
+
|
|
94
116
|
# Creates and renders a PDF document.
|
|
95
117
|
#
|
|
96
118
|
# When using the implicit block form, Prawn will evaluate the block
|
|
@@ -135,11 +157,10 @@ module Prawn
|
|
|
135
157
|
# <tt>:bottom_margin</tt>:: Sets the bottom margin in points [0.5 inch]
|
|
136
158
|
# <tt>:skip_page_creation</tt>:: Creates a document without starting the first page [false]
|
|
137
159
|
# <tt>:compress</tt>:: Compresses content streams before rendering them [false]
|
|
138
|
-
# <tt>:optimize_objects</tt>:: Reduce number of PDF objects in output, at expense of render time [false]
|
|
139
160
|
# <tt>:background</tt>:: An image path to be used as background on all pages [nil]
|
|
140
161
|
# <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
|
|
141
162
|
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties [nil]
|
|
142
|
-
# <tt>:
|
|
163
|
+
# <tt>:text_formatter</tt>: The text formatter to use for <tt>:inline_format</tt>ted text [Prawn::Text::Formatted::Parser]
|
|
143
164
|
#
|
|
144
165
|
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will result in margins
|
|
145
166
|
# of 100 points on every side except for the left, where it will be 50.
|
|
@@ -173,19 +194,18 @@ module Prawn
|
|
|
173
194
|
def initialize(options={},&block)
|
|
174
195
|
options = options.dup
|
|
175
196
|
|
|
176
|
-
Prawn.verify_options
|
|
177
|
-
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
|
|
178
|
-
:compress, :skip_encoding, :background, :info,
|
|
179
|
-
:optimize_objects, :template], options
|
|
197
|
+
Prawn.verify_options VALID_OPTIONS, options
|
|
180
198
|
|
|
181
199
|
# need to fix, as the refactoring breaks this
|
|
182
200
|
# raise NotImplementedError if options[:skip_page_creation]
|
|
183
201
|
|
|
184
202
|
self.class.extensions.reverse_each { |e| extend e }
|
|
185
|
-
@internal_state =
|
|
203
|
+
@internal_state = PDF::Core::DocumentState.new(options)
|
|
186
204
|
@internal_state.populate_pages_from_store(self)
|
|
187
205
|
min_version(state.store.min_version) if state.store.min_version
|
|
188
206
|
|
|
207
|
+
min_version(1.6) if options[:print_scaling] == :none
|
|
208
|
+
|
|
189
209
|
@background = options[:background]
|
|
190
210
|
@background_scale = options[:background_scale] || 1
|
|
191
211
|
@font_size = 12
|
|
@@ -195,19 +215,12 @@ module Prawn
|
|
|
195
215
|
|
|
196
216
|
@page_number = 0
|
|
197
217
|
|
|
218
|
+
@text_formatter = options.delete(:text_formatter) || Text::Formatted::Parser
|
|
219
|
+
|
|
198
220
|
options[:size] = options.delete(:page_size)
|
|
199
221
|
options[:layout] = options.delete(:page_layout)
|
|
200
222
|
|
|
201
|
-
|
|
202
|
-
fresh_content_streams(options)
|
|
203
|
-
go_to_page(1)
|
|
204
|
-
else
|
|
205
|
-
if options[:skip_page_creation] || options[:template]
|
|
206
|
-
start_new_page(options.merge(:orphan => true))
|
|
207
|
-
else
|
|
208
|
-
start_new_page(options)
|
|
209
|
-
end
|
|
210
|
-
end
|
|
223
|
+
initialize_first_page(options)
|
|
211
224
|
|
|
212
225
|
@bounding_box = @margin_box
|
|
213
226
|
|
|
@@ -216,18 +229,7 @@ module Prawn
|
|
|
216
229
|
end
|
|
217
230
|
end
|
|
218
231
|
|
|
219
|
-
|
|
220
|
-
attr_reader :margins, :y
|
|
221
|
-
attr_writer :font_size
|
|
222
|
-
attr_accessor :page_number
|
|
223
|
-
|
|
224
|
-
def state
|
|
225
|
-
@internal_state
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def page
|
|
229
|
-
state.page
|
|
230
|
-
end
|
|
232
|
+
# @group Stable API
|
|
231
233
|
|
|
232
234
|
# Creates and advances to a new page in the document.
|
|
233
235
|
#
|
|
@@ -239,14 +241,6 @@ module Prawn
|
|
|
239
241
|
# pdf.start_new_page(:left_margin => 50, :right_margin => 50)
|
|
240
242
|
# pdf.start_new_page(:margin => 100)
|
|
241
243
|
#
|
|
242
|
-
# A template for a page can be specified by pointing to the path of and existing pdf.
|
|
243
|
-
# One can also specify which page of the template which defaults otherwise to 1.
|
|
244
|
-
#
|
|
245
|
-
# pdf.start_new_page(:template => multipage_template.pdf, :template_page => 2)
|
|
246
|
-
#
|
|
247
|
-
# Note: templates get indexed by either the object_id of the filename or stream
|
|
248
|
-
# entered so that if you reuse the same template multiple times be sure to use the
|
|
249
|
-
# same instance for more efficient use of resources and smaller rendered pdfs.
|
|
250
244
|
def start_new_page(options = {})
|
|
251
245
|
if last_page = state.page
|
|
252
246
|
last_page_size = last_page.size
|
|
@@ -258,14 +252,13 @@ module Prawn
|
|
|
258
252
|
:layout => options[:layout] || last_page_layout,
|
|
259
253
|
:margins => last_page_margins}
|
|
260
254
|
if last_page
|
|
261
|
-
new_graphic_state = last_page.graphic_state.dup
|
|
255
|
+
new_graphic_state = last_page.graphic_state.dup if last_page.graphic_state
|
|
262
256
|
#erase the color space so that it gets reset on new page for fussy pdf-readers
|
|
263
|
-
new_graphic_state.color_space = {}
|
|
257
|
+
new_graphic_state.color_space = {} if new_graphic_state
|
|
264
258
|
page_options.merge!(:graphic_state => new_graphic_state)
|
|
265
259
|
end
|
|
266
|
-
merge_template_options(page_options, options) if options[:template]
|
|
267
260
|
|
|
268
|
-
state.page =
|
|
261
|
+
state.page = PDF::Core::Page.new(self, page_options)
|
|
269
262
|
|
|
270
263
|
apply_margin_options(options)
|
|
271
264
|
generate_margin_box
|
|
@@ -276,8 +269,7 @@ module Prawn
|
|
|
276
269
|
@bounding_box = @margin_box
|
|
277
270
|
end
|
|
278
271
|
|
|
279
|
-
|
|
280
|
-
use_graphic_settings(options[:template])
|
|
272
|
+
use_graphic_settings
|
|
281
273
|
|
|
282
274
|
unless options[:orphan]
|
|
283
275
|
state.insert_page(state.page, @page_number)
|
|
@@ -354,19 +346,26 @@ module Prawn
|
|
|
354
346
|
self.y = original_y
|
|
355
347
|
end
|
|
356
348
|
|
|
357
|
-
# Renders the PDF document to string
|
|
349
|
+
# Renders the PDF document to string.
|
|
350
|
+
# Pass an open file descriptor to render to file.
|
|
358
351
|
#
|
|
359
|
-
def render
|
|
360
|
-
output
|
|
352
|
+
def render(output = StringIO.new)
|
|
353
|
+
if output.instance_of?(StringIO)
|
|
354
|
+
output.set_encoding(::Encoding::ASCII_8BIT)
|
|
355
|
+
end
|
|
361
356
|
finalize_all_page_contents
|
|
362
357
|
|
|
363
358
|
render_header(output)
|
|
364
359
|
render_body(output)
|
|
365
360
|
render_xref(output)
|
|
366
361
|
render_trailer(output)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
362
|
+
if output.instance_of?(StringIO)
|
|
363
|
+
str = output.string
|
|
364
|
+
str.force_encoding(::Encoding::ASCII_8BIT)
|
|
365
|
+
return str
|
|
366
|
+
else
|
|
367
|
+
return nil
|
|
368
|
+
end
|
|
370
369
|
end
|
|
371
370
|
|
|
372
371
|
# Renders the PDF document to file.
|
|
@@ -374,8 +373,7 @@ module Prawn
|
|
|
374
373
|
# pdf.render_file "foo.pdf"
|
|
375
374
|
#
|
|
376
375
|
def render_file(filename)
|
|
377
|
-
|
|
378
|
-
File.open(filename,mode) { |f| f << render }
|
|
376
|
+
File.open(filename, "wb") { |f| render(f) }
|
|
379
377
|
end
|
|
380
378
|
|
|
381
379
|
# The bounds method returns the current bounding box you are currently in,
|
|
@@ -411,6 +409,7 @@ module Prawn
|
|
|
411
409
|
|
|
412
410
|
# Returns the innermost non-stretchy bounding box.
|
|
413
411
|
#
|
|
412
|
+
# @private
|
|
414
413
|
def reference_bounds
|
|
415
414
|
@bounding_box.reference_bounds
|
|
416
415
|
end
|
|
@@ -496,47 +495,6 @@ module Prawn
|
|
|
496
495
|
bounds.indent(left, right, &block)
|
|
497
496
|
end
|
|
498
497
|
|
|
499
|
-
|
|
500
|
-
def mask(*fields) # :nodoc:
|
|
501
|
-
# Stores the current state of the named attributes, executes the block, and
|
|
502
|
-
# then restores the original values after the block has executed.
|
|
503
|
-
# -- I will remove the nodoc if/when this feature is a little less hacky
|
|
504
|
-
stored = {}
|
|
505
|
-
fields.each { |f| stored[f] = send(f) }
|
|
506
|
-
yield
|
|
507
|
-
fields.each { |f| send("#{f}=", stored[f]) }
|
|
508
|
-
end
|
|
509
|
-
|
|
510
|
-
# Attempts to group the given block vertically within the current context.
|
|
511
|
-
# First attempts to render it in the current position on the current page.
|
|
512
|
-
# If that attempt overflows, it is tried anew after starting a new context
|
|
513
|
-
# (page or column). Returns a logically true value if the content fits in
|
|
514
|
-
# one page/column, false if a new page or column was needed.
|
|
515
|
-
#
|
|
516
|
-
# Raises CannotGroup if the provided content is too large to fit alone in
|
|
517
|
-
# the current page or column.
|
|
518
|
-
#
|
|
519
|
-
def group(second_attempt=false)
|
|
520
|
-
old_bounding_box = @bounding_box
|
|
521
|
-
@bounding_box = SimpleDelegator.new(@bounding_box)
|
|
522
|
-
|
|
523
|
-
def @bounding_box.move_past_bottom
|
|
524
|
-
raise RollbackTransaction
|
|
525
|
-
end
|
|
526
|
-
|
|
527
|
-
success = transaction { yield }
|
|
528
|
-
|
|
529
|
-
@bounding_box = old_bounding_box
|
|
530
|
-
|
|
531
|
-
unless success
|
|
532
|
-
raise Prawn::Errors::CannotGroup if second_attempt
|
|
533
|
-
old_bounding_box.move_past_bottom
|
|
534
|
-
group(second_attempt=true) { yield }
|
|
535
|
-
end
|
|
536
|
-
|
|
537
|
-
success
|
|
538
|
-
end
|
|
539
|
-
|
|
540
498
|
# Places a text box on specified pages for page numbering. This should be called
|
|
541
499
|
# towards the end of document creation, after all your content is already in
|
|
542
500
|
# place. In your template string, <page> refers to the current page, and
|
|
@@ -609,6 +567,42 @@ module Prawn
|
|
|
609
567
|
end
|
|
610
568
|
end
|
|
611
569
|
|
|
570
|
+
# Returns true if content streams will be compressed before rendering,
|
|
571
|
+
# false otherwise
|
|
572
|
+
#
|
|
573
|
+
def compression_enabled?
|
|
574
|
+
!!state.compress
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
# @group Experimental API
|
|
578
|
+
|
|
579
|
+
# Attempts to group the given block vertically within the current context.
|
|
580
|
+
# First attempts to render it in the current position on the current page.
|
|
581
|
+
# If that attempt overflows, it is tried anew after starting a new context
|
|
582
|
+
# (page or column). Returns a logically true value if the content fits in
|
|
583
|
+
# one page/column, false if a new page or column was needed.
|
|
584
|
+
#
|
|
585
|
+
# Raises CannotGroup if the provided content is too large to fit alone in
|
|
586
|
+
# the current page or column.
|
|
587
|
+
#
|
|
588
|
+
# @private
|
|
589
|
+
def group(*a, &b)
|
|
590
|
+
raise NotImplementedError,
|
|
591
|
+
"Document#group has been disabled because its implementation "+
|
|
592
|
+
"lead to corrupted documents whenever a page boundary was "+
|
|
593
|
+
"crossed. We will try to work on reimplementing it in a "+
|
|
594
|
+
"future release"
|
|
595
|
+
end
|
|
596
|
+
|
|
597
|
+
# @private
|
|
598
|
+
def transaction
|
|
599
|
+
raise NotImplementedError,
|
|
600
|
+
"Document#transaction has been disabled because its implementation "+
|
|
601
|
+
"lead to corrupted documents whenever a page boundary was "+
|
|
602
|
+
"crossed. We will try to work on reimplementing it in a "+
|
|
603
|
+
"future release"
|
|
604
|
+
end
|
|
605
|
+
|
|
612
606
|
# Provides a way to execute a block of code repeatedly based on a
|
|
613
607
|
# page_filter.
|
|
614
608
|
#
|
|
@@ -634,23 +628,45 @@ module Prawn
|
|
|
634
628
|
end
|
|
635
629
|
end
|
|
636
630
|
|
|
631
|
+
# @private
|
|
632
|
+
|
|
633
|
+
def mask(*fields)
|
|
634
|
+
# Stores the current state of the named attributes, executes the block, and
|
|
635
|
+
# then restores the original values after the block has executed.
|
|
636
|
+
# -- I will remove the nodoc if/when this feature is a little less hacky
|
|
637
|
+
stored = {}
|
|
638
|
+
fields.each { |f| stored[f] = send(f) }
|
|
639
|
+
yield
|
|
640
|
+
fields.each { |f| send("#{f}=", stored[f]) }
|
|
641
|
+
end
|
|
637
642
|
|
|
638
|
-
#
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
+
# @group Extension API
|
|
644
|
+
|
|
645
|
+
def initialize_first_page(options)
|
|
646
|
+
if options[:skip_page_creation]
|
|
647
|
+
start_new_page(options.merge(:orphan => true))
|
|
648
|
+
else
|
|
649
|
+
start_new_page(options)
|
|
650
|
+
end
|
|
643
651
|
end
|
|
644
652
|
|
|
645
|
-
|
|
653
|
+
## Internals. Don't depend on them!
|
|
646
654
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
655
|
+
# @private
|
|
656
|
+
def state
|
|
657
|
+
@internal_state
|
|
650
658
|
end
|
|
651
659
|
|
|
660
|
+
# @private
|
|
661
|
+
def page
|
|
662
|
+
state.page
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
private
|
|
666
|
+
|
|
667
|
+
|
|
652
668
|
# setting override_settings to true ensures that a new graphic state does not end up using
|
|
653
|
-
# previous settings
|
|
669
|
+
# previous settings.
|
|
654
670
|
def use_graphic_settings(override_settings = false)
|
|
655
671
|
set_fill_color if current_fill_color != "000000" || override_settings
|
|
656
672
|
set_stroke_color if current_stroke_color != "000000" || override_settings
|
|
@@ -680,9 +696,7 @@ module Prawn
|
|
|
680
696
|
|
|
681
697
|
# we must update bounding box if not flowing from the previous page
|
|
682
698
|
#
|
|
683
|
-
|
|
684
|
-
# when the bounding box exits.
|
|
685
|
-
@bounding_box = @margin_box if old_margin_box == @bounding_box
|
|
699
|
+
@bounding_box = @margin_box unless @bounding_box && @bounding_box.parent
|
|
686
700
|
end
|
|
687
701
|
|
|
688
702
|
def apply_margin_options(options)
|
|
@@ -703,5 +717,9 @@ module Prawn
|
|
|
703
717
|
end
|
|
704
718
|
end
|
|
705
719
|
end
|
|
720
|
+
|
|
721
|
+
def font_metric_cache #:nodoc:
|
|
722
|
+
@font_metric_cache ||= FontMetricCache.new( self )
|
|
723
|
+
end
|
|
706
724
|
end
|
|
707
725
|
end
|