prawn 2.1.0 → 2.2.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 +4 -4
- checksums.yaml.gz.sig +2 -0
- data.tar.gz.sig +0 -0
- data/Gemfile +1 -9
- data/Rakefile +12 -22
- data/lib/prawn.rb +29 -48
- data/lib/prawn/document.rb +148 -123
- data/lib/prawn/document/bounding_box.rb +33 -26
- data/lib/prawn/document/column_box.rb +5 -7
- data/lib/prawn/document/internals.rb +6 -6
- data/lib/prawn/document/span.rb +20 -17
- data/lib/prawn/encoding.rb +65 -67
- data/lib/prawn/errors.rb +10 -7
- data/lib/prawn/font.rb +78 -62
- data/lib/prawn/font/afm.rb +93 -66
- data/lib/prawn/font/dfont.rb +2 -10
- data/lib/prawn/font/ttc.rb +34 -0
- data/lib/prawn/font/ttf.rb +73 -65
- data/lib/prawn/font_metric_cache.rb +9 -8
- data/lib/prawn/graphics.rb +110 -70
- data/lib/prawn/graphics/blend_mode.rb +7 -8
- data/lib/prawn/graphics/cap_style.rb +2 -4
- data/lib/prawn/graphics/color.rb +23 -26
- data/lib/prawn/graphics/dash.rb +22 -12
- data/lib/prawn/graphics/join_style.rb +8 -4
- data/lib/prawn/graphics/patterns.rb +185 -96
- data/lib/prawn/graphics/transformation.rb +11 -9
- data/lib/prawn/graphics/transparency.rb +15 -13
- data/lib/prawn/grid.rb +20 -20
- data/lib/prawn/image_handler.rb +4 -6
- data/lib/prawn/images.rb +22 -15
- data/lib/prawn/images/image.rb +0 -1
- data/lib/prawn/images/jpg.rb +26 -22
- data/lib/prawn/images/png.rb +60 -57
- data/lib/prawn/measurement_extensions.rb +8 -9
- data/lib/prawn/measurements.rb +14 -15
- data/lib/prawn/outline.rb +96 -78
- data/lib/prawn/repeater.rb +12 -10
- data/lib/prawn/security.rb +66 -48
- data/lib/prawn/security/arcfour.rb +1 -3
- data/lib/prawn/soft_mask.rb +23 -25
- data/lib/prawn/stamp.rb +16 -12
- data/lib/prawn/text.rb +59 -45
- data/lib/prawn/text/box.rb +9 -8
- data/lib/prawn/text/formatted.rb +4 -6
- data/lib/prawn/text/formatted/arranger.rb +51 -30
- data/lib/prawn/text/formatted/box.rb +112 -88
- data/lib/prawn/text/formatted/fragment.rb +10 -15
- data/lib/prawn/text/formatted/line_wrap.rb +118 -61
- data/lib/prawn/text/formatted/parser.rb +134 -110
- data/lib/prawn/text/formatted/wrap.rb +42 -32
- data/lib/prawn/transformation_stack.rb +3 -4
- data/lib/prawn/utilities.rb +6 -21
- data/lib/prawn/version.rb +1 -3
- data/lib/prawn/view.rb +4 -2
- data/manual/basic_concepts/adding_pages.rb +4 -7
- data/manual/basic_concepts/basic_concepts.rb +29 -22
- data/manual/basic_concepts/creation.rb +8 -11
- data/manual/basic_concepts/cursor.rb +2 -5
- data/manual/basic_concepts/measurement.rb +3 -6
- data/manual/basic_concepts/origin.rb +3 -6
- data/manual/basic_concepts/other_cursor_helpers.rb +9 -12
- data/manual/basic_concepts/view.rb +20 -16
- data/manual/bounding_box/bounding_box.rb +27 -24
- data/manual/bounding_box/bounds.rb +9 -12
- data/manual/bounding_box/canvas.rb +2 -5
- data/manual/bounding_box/creation.rb +4 -7
- data/manual/bounding_box/indentation.rb +12 -15
- data/manual/bounding_box/nesting.rb +22 -17
- data/manual/bounding_box/russian_boxes.rb +8 -9
- data/manual/bounding_box/stretchy.rb +10 -13
- data/manual/contents.rb +26 -22
- data/manual/cover.rb +22 -20
- data/manual/document_and_page_options/background.rb +9 -13
- data/manual/document_and_page_options/document_and_page_options.rb +23 -20
- data/manual/document_and_page_options/metadata.rb +16 -16
- data/manual/document_and_page_options/page_margins.rb +16 -20
- data/manual/document_and_page_options/page_size.rb +11 -12
- data/manual/document_and_page_options/print_scaling.rb +15 -15
- data/manual/example_helper.rb +2 -4
- data/manual/graphics/blend_mode.rb +10 -9
- data/manual/graphics/circle_and_ellipse.rb +2 -5
- data/manual/graphics/color.rb +5 -9
- data/manual/graphics/common_lines.rb +5 -8
- data/manual/graphics/fill_and_stroke.rb +2 -5
- data/manual/graphics/fill_rules.rb +7 -10
- data/manual/graphics/gradients.rb +25 -21
- data/manual/graphics/graphics.rb +49 -43
- data/manual/graphics/helper.rb +10 -9
- data/manual/graphics/line_width.rb +5 -7
- data/manual/graphics/lines_and_curves.rb +5 -8
- data/manual/graphics/polygon.rb +4 -8
- data/manual/graphics/rectangle.rb +2 -5
- data/manual/graphics/rotate.rb +4 -7
- data/manual/graphics/scale.rb +12 -15
- data/manual/graphics/soft_masks.rb +1 -4
- data/manual/graphics/stroke_cap.rb +3 -6
- data/manual/graphics/stroke_dash.rb +9 -12
- data/manual/graphics/stroke_join.rb +2 -5
- data/manual/graphics/translate.rb +7 -10
- data/manual/graphics/transparency.rb +5 -8
- data/manual/how_to_read_this_manual.rb +4 -6
- data/manual/images/absolute_position.rb +4 -7
- data/manual/images/fit.rb +5 -8
- data/manual/images/horizontal.rb +6 -9
- data/manual/images/images.rb +25 -23
- data/manual/images/plain_image.rb +3 -6
- data/manual/images/scale.rb +7 -10
- data/manual/images/vertical.rb +10 -13
- data/manual/images/width_and_height.rb +8 -11
- data/manual/layout/boxes.rb +3 -6
- data/manual/layout/content.rb +5 -8
- data/manual/layout/layout.rb +16 -16
- data/manual/layout/simple_grid.rb +4 -7
- data/manual/outline/add_subsection_to.rb +18 -21
- data/manual/outline/insert_section_after.rb +13 -16
- data/manual/outline/outline.rb +19 -17
- data/manual/outline/sections_and_pages.rb +15 -18
- data/manual/repeatable_content/alternate_page_numbering.rb +19 -17
- data/manual/repeatable_content/page_numbering.rb +15 -16
- data/manual/repeatable_content/repeatable_content.rb +23 -19
- data/manual/repeatable_content/repeater.rb +12 -15
- data/manual/repeatable_content/stamp.rb +12 -15
- data/manual/security/encryption.rb +7 -10
- data/manual/security/permissions.rb +17 -14
- data/manual/security/security.rb +17 -16
- data/manual/table.rb +2 -4
- data/manual/text/alignment.rb +14 -17
- data/manual/text/color.rb +10 -11
- data/manual/text/column_box.rb +5 -8
- data/manual/text/fallback_fonts.rb +23 -21
- data/manual/text/font.rb +9 -12
- data/manual/text/font_size.rb +11 -14
- data/manual/text/font_style.rb +4 -7
- data/manual/text/formatted_callbacks.rb +23 -21
- data/manual/text/formatted_text.rb +31 -25
- data/manual/text/free_flowing_text.rb +18 -21
- data/manual/text/inline.rb +16 -19
- data/manual/text/kerning_and_character_spacing.rb +12 -15
- data/manual/text/leading.rb +5 -8
- data/manual/text/line_wrapping.rb +33 -17
- data/manual/text/paragraph_indentation.rb +11 -14
- data/manual/text/positioned_text.rb +13 -16
- data/manual/text/registering_families.rb +16 -19
- data/manual/text/rendering_and_color.rb +7 -10
- data/manual/text/right_to_left_text.rb +24 -19
- data/manual/text/rotation.rb +26 -23
- data/manual/text/single_usage.rb +6 -9
- data/manual/text/text.rb +56 -52
- data/manual/text/text_box_excess.rb +18 -17
- data/manual/text/text_box_extensions.rb +16 -15
- data/manual/text/text_box_overflow.rb +15 -18
- data/manual/text/utf8.rb +9 -12
- data/manual/text/win_ansi_charset.rb +18 -19
- data/prawn.gemspec +37 -27
- data/spec/extensions/encoding_helpers.rb +0 -2
- data/spec/manual_spec.rb +33 -0
- data/spec/prawn/document/bounding_box_spec.rb +546 -0
- data/spec/prawn/document/column_box_spec.rb +73 -0
- data/spec/prawn/document/security_spec.rb +173 -0
- data/spec/prawn/document_annotations_spec.rb +74 -0
- data/spec/prawn/document_destinations_spec.rb +13 -0
- data/spec/prawn/document_grid_spec.rb +96 -0
- data/spec/prawn/document_reference_spec.rb +25 -0
- data/spec/prawn/document_span_spec.rb +34 -0
- data/spec/prawn/document_spec.rb +751 -0
- data/spec/prawn/font_metric_cache_spec.rb +52 -0
- data/spec/prawn/font_spec.rb +513 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +61 -0
- data/spec/prawn/graphics/transparency_spec.rb +79 -0
- data/spec/prawn/graphics_spec.rb +817 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +227 -0
- data/spec/{image_handler_spec.rb → prawn/image_handler_spec.rb} +13 -15
- data/spec/prawn/images/jpg_spec.rb +18 -0
- data/spec/prawn/images/png_spec.rb +281 -0
- data/spec/prawn/images_spec.rb +170 -0
- data/spec/prawn/measurements_extensions_spec.rb +22 -0
- data/spec/prawn/outline_spec.rb +408 -0
- data/spec/prawn/repeater_spec.rb +163 -0
- data/spec/prawn/soft_mask_spec.rb +72 -0
- data/spec/prawn/stamp_spec.rb +168 -0
- data/spec/prawn/text/box_spec.rb +1113 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +464 -0
- data/spec/prawn/text/formatted/box_spec.rb +825 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +341 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +491 -0
- data/spec/prawn/text/formatted/parser_spec.rb +667 -0
- data/spec/prawn/text_draw_text_spec.rb +147 -0
- data/spec/prawn/text_rendering_mode_spec.rb +42 -0
- data/spec/prawn/text_spacing_spec.rb +93 -0
- data/spec/prawn/text_spec.rb +601 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +33 -0
- data/spec/{transformation_stack_spec.rb → prawn/transformation_stack_spec.rb} +21 -20
- data/spec/prawn/view_spec.rb +45 -0
- data/spec/spec_helper.rb +16 -16
- metadata +96 -151
- metadata.gz.sig +1 -0
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.color +0 -0
- data/data/images/16bit.png +0 -0
- data/data/images/arrow.png +0 -0
- data/data/images/arrow2.png +0 -0
- data/data/images/blend_modes_bottom_layer.jpg +0 -0
- data/data/images/blend_modes_top_layer.jpg +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.color +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/fractal.jpg +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/indexed_transparency.png +0 -0
- data/data/images/indexed_transparency_alpha.dat +0 -0
- data/data/images/indexed_transparency_color.dat +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/license.md +0 -8
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/images/page_white_text.png +0 -0
- data/data/images/pigs.jpg +0 -0
- data/data/images/prawn.png +0 -0
- data/data/images/ruport.png +0 -0
- data/data/images/ruport_data.dat +0 -0
- data/data/images/ruport_transparent.png +0 -0
- data/data/images/ruport_type0.png +0 -0
- data/data/images/stef.jpg +0 -0
- data/data/images/tru256.bmp +0 -0
- data/data/images/web-links.dat +0 -1
- data/data/images/web-links.png +0 -0
- data/data/pdfs/complex_template.pdf +0 -0
- data/data/pdfs/contains_ttf_font.pdf +0 -0
- data/data/pdfs/encrypted.pdf +0 -0
- data/data/pdfs/form.pdf +1 -819
- data/data/pdfs/hexagon.pdf +0 -61
- data/data/pdfs/indirect_reference.pdf +0 -86
- data/data/pdfs/multipage_template.pdf +0 -127
- data/data/pdfs/nested_pages.pdf +0 -118
- data/data/pdfs/page_without_mediabox.pdf +0 -193
- data/data/pdfs/resources_as_indirect_object.pdf +0 -83
- data/data/pdfs/two_hexagons.pdf +0 -90
- data/data/pdfs/version_1_6.pdf +0 -61
- data/data/shift_jis_text.txt +0 -1
- data/spec/acceptance/png_spec.rb +0 -35
- data/spec/annotations_spec.rb +0 -67
- data/spec/blend_mode_spec.rb +0 -71
- data/spec/bounding_box_spec.rb +0 -501
- data/spec/column_box_spec.rb +0 -59
- data/spec/destinations_spec.rb +0 -13
- data/spec/document_spec.rb +0 -738
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -475
- data/spec/formatted_text_arranger_spec.rb +0 -452
- data/spec/formatted_text_box_spec.rb +0 -716
- data/spec/formatted_text_fragment_spec.rb +0 -299
- data/spec/graphics_spec.rb +0 -705
- data/spec/grid_spec.rb +0 -95
- data/spec/images_spec.rb +0 -167
- data/spec/inline_formatted_text_parser_spec.rb +0 -568
- data/spec/jpg_spec.rb +0 -23
- data/spec/line_wrap_spec.rb +0 -366
- data/spec/measurement_units_spec.rb +0 -22
- data/spec/outline_spec.rb +0 -409
- data/spec/png_spec.rb +0 -257
- data/spec/reference_spec.rb +0 -25
- data/spec/repeater_spec.rb +0 -154
- data/spec/security_spec.rb +0 -151
- data/spec/soft_mask_spec.rb +0 -78
- data/spec/span_spec.rb +0 -43
- data/spec/stamp_spec.rb +0 -179
- data/spec/stroke_styles_spec.rb +0 -208
- data/spec/text_at_spec.rb +0 -142
- data/spec/text_box_spec.rb +0 -1042
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -543
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -91
- data/spec/view_spec.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef80196a96c2bf246a6032cff415fc6f35b255dd
|
4
|
+
data.tar.gz: d7cd7663853aa67831661ed57a6efb4a0a54c183
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20e137ad1d41f8e42e75fc817e82d12fba4a827eaec23e216f164b1ec738a64b1ced7870cbb65f2fd792d0809a6c347add74a9ed8ed99af30bdfc06f7f5d270b
|
7
|
+
data.tar.gz: fac5c7cb9096d1e12f65fb9901901af46401fe33ab27af9406ac1ba4b50f64ca9eed5fdc6b0560cc2dec193ec9757ef209f74a24240b32c0a69db6bd3891dd28
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
Binary file
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler'
|
2
2
|
Bundler.setup
|
3
3
|
|
4
4
|
require 'rake'
|
@@ -7,43 +7,33 @@ require 'yard'
|
|
7
7
|
require 'rubygems/package_task'
|
8
8
|
require 'rubocop/rake_task'
|
9
9
|
|
10
|
-
task :
|
10
|
+
task default: [:spec, :rubocop]
|
11
11
|
|
12
|
-
desc
|
13
|
-
RSpec::Core::RakeTask.new(
|
14
|
-
c.rspec_opts =
|
15
|
-
end
|
16
|
-
|
17
|
-
desc "Show library's code statistics"
|
18
|
-
task :stats do
|
19
|
-
require 'code_statistics/code_statistics'
|
20
|
-
puts CodeStatistics::CodeStatistics.new(
|
21
|
-
[
|
22
|
-
["Prawn", "lib"],
|
23
|
-
["Specs", "spec"]
|
24
|
-
]
|
25
|
-
).to_s
|
12
|
+
desc 'Run all rspec files'
|
13
|
+
RSpec::Core::RakeTask.new('spec') do |c|
|
14
|
+
c.rspec_opts = '-t ~unresolved'
|
26
15
|
end
|
27
16
|
|
28
17
|
YARD::Rake::YardocTask.new do |t|
|
29
18
|
t.options = ['--output-dir', 'doc/html']
|
30
19
|
end
|
31
|
-
task :
|
20
|
+
task docs: :yard
|
32
21
|
|
33
22
|
desc "Generate the 'Prawn by Example' manual"
|
34
23
|
task :manual do
|
35
|
-
puts
|
36
|
-
require File.expand_path(File.join(
|
37
|
-
|
24
|
+
puts 'Building manual...'
|
25
|
+
require File.expand_path(File.join(__dir__, %w[manual contents]))
|
26
|
+
prawn_manual_document.render_file('manual.pdf')
|
27
|
+
puts 'The Prawn manual is available at manual.pdf. Happy Prawning!'
|
38
28
|
end
|
39
29
|
|
40
|
-
spec = Gem::Specification.load
|
30
|
+
spec = Gem::Specification.load 'prawn.gemspec'
|
41
31
|
Gem::PackageTask.new(spec) do |pkg|
|
42
32
|
pkg.need_zip = true
|
43
33
|
pkg.need_tar = true
|
44
34
|
end
|
45
35
|
|
46
|
-
desc
|
36
|
+
desc 'Run a console with Prawn loaded'
|
47
37
|
task :console do
|
48
38
|
require 'irb'
|
49
39
|
require 'irb/completion'
|
data/lib/prawn.rb
CHANGED
@@ -1,19 +1,15 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# Welcome to Prawn, the best PDF Generation library ever.
|
4
2
|
# This documentation covers user level functionality.
|
5
3
|
#
|
6
|
-
require
|
4
|
+
require 'set'
|
7
5
|
|
8
6
|
require 'ttfunk'
|
9
|
-
require
|
7
|
+
require 'pdf/core'
|
10
8
|
|
11
9
|
module Prawn
|
12
|
-
extend self
|
13
|
-
|
14
10
|
file = __FILE__
|
15
11
|
file = File.readlink(file) if File.symlink?(file)
|
16
|
-
dir
|
12
|
+
dir = File.dirname(file)
|
17
13
|
|
18
14
|
# The base source directory for Prawn as installed on the system
|
19
15
|
#
|
@@ -33,58 +29,43 @@ module Prawn
|
|
33
29
|
# Accepted options are: [:page_size, :page_layout, :left_margin, ...]
|
34
30
|
#
|
35
31
|
attr_accessor :debug # @private
|
32
|
+
module_function :debug, :debug=
|
36
33
|
|
37
34
|
def verify_options(accepted, actual) # @private
|
38
35
|
return unless debug || $DEBUG
|
39
36
|
unless (act = Set[*actual.keys]).subset?(acc = Set[*accepted])
|
40
|
-
|
41
|
-
|
42
|
-
|
37
|
+
raise Prawn::Errors::UnknownOption,
|
38
|
+
"\nDetected unknown option(s): #{(act - acc).to_a.inspect}\n" \
|
39
|
+
"Accepted options are: #{accepted.inspect}"
|
43
40
|
end
|
44
41
|
yield if block_given?
|
45
42
|
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
|
43
|
+
module_function :verify_options
|
63
44
|
end
|
64
45
|
|
65
|
-
require_relative
|
46
|
+
require_relative 'prawn/version'
|
66
47
|
|
67
|
-
require_relative
|
48
|
+
require_relative 'prawn/errors'
|
68
49
|
|
69
|
-
require_relative
|
70
|
-
require_relative
|
71
|
-
require_relative
|
72
|
-
require_relative
|
73
|
-
require_relative
|
74
|
-
require_relative
|
75
|
-
require_relative
|
76
|
-
require_relative
|
77
|
-
require_relative
|
78
|
-
require_relative
|
79
|
-
require_relative
|
80
|
-
require_relative
|
81
|
-
require_relative
|
82
|
-
require_relative
|
83
|
-
require_relative
|
84
|
-
require_relative
|
85
|
-
require_relative
|
86
|
-
require_relative
|
87
|
-
require_relative
|
50
|
+
require_relative 'prawn/utilities'
|
51
|
+
require_relative 'prawn/text'
|
52
|
+
require_relative 'prawn/graphics'
|
53
|
+
require_relative 'prawn/images'
|
54
|
+
require_relative 'prawn/images/image'
|
55
|
+
require_relative 'prawn/images/jpg'
|
56
|
+
require_relative 'prawn/images/png'
|
57
|
+
require_relative 'prawn/stamp'
|
58
|
+
require_relative 'prawn/soft_mask'
|
59
|
+
require_relative 'prawn/security'
|
60
|
+
require_relative 'prawn/transformation_stack'
|
61
|
+
require_relative 'prawn/document'
|
62
|
+
require_relative 'prawn/font'
|
63
|
+
require_relative 'prawn/measurements'
|
64
|
+
require_relative 'prawn/repeater'
|
65
|
+
require_relative 'prawn/outline'
|
66
|
+
require_relative 'prawn/grid'
|
67
|
+
require_relative 'prawn/view'
|
68
|
+
require_relative 'prawn/image_handler'
|
88
69
|
|
89
70
|
Prawn.image_handler.register(Prawn::Images::PNG)
|
90
71
|
Prawn.image_handler.register(Prawn::Images::JPG)
|
data/lib/prawn/document.rb
CHANGED
@@ -1,26 +1,24 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
# document.rb : Implements PDF document generation for Prawn
|
4
2
|
#
|
5
3
|
# Copyright April 2008, Gregory Brown. All Rights Reserved.
|
6
4
|
#
|
7
5
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
6
|
|
9
|
-
require
|
7
|
+
require 'stringio'
|
10
8
|
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative
|
14
|
-
require_relative
|
9
|
+
require_relative 'document/bounding_box'
|
10
|
+
require_relative 'document/column_box'
|
11
|
+
require_relative 'document/internals'
|
12
|
+
require_relative 'document/span'
|
15
13
|
|
16
14
|
module Prawn
|
17
15
|
# The Prawn::Document class is how you start creating a PDF document.
|
18
16
|
#
|
19
17
|
# There are three basic ways you can instantiate PDF Documents in Prawn, they
|
20
|
-
# are through assignment, implicit block or explicit block. Below is an
|
21
|
-
# of each type, each example does exactly the same thing, makes a PDF
|
22
|
-
# with all the defaults and puts in the default font "Hello There"
|
23
|
-
# saves it to the current directory as "example.pdf"
|
18
|
+
# are through assignment, implicit block or explicit block. Below is an
|
19
|
+
# example of each type, each example does exactly the same thing, makes a PDF
|
20
|
+
# document with all the defaults and puts in the default font "Hello There"
|
21
|
+
# and then saves it to the current directory as "example.pdf"
|
24
22
|
#
|
25
23
|
# For example, assignment can be like this:
|
26
24
|
#
|
@@ -42,8 +40,8 @@ module Prawn
|
|
42
40
|
# pdf.text words
|
43
41
|
# end
|
44
42
|
#
|
45
|
-
# Usually, the block forms are used when you are simply creating a PDF
|
46
|
-
# that you want to immediately save or render out.
|
43
|
+
# Usually, the block forms are used when you are simply creating a PDF
|
44
|
+
# document that you want to immediately save or render out.
|
47
45
|
#
|
48
46
|
# See the new and generate methods for further details on the above.
|
49
47
|
#
|
@@ -64,10 +62,12 @@ module Prawn
|
|
64
62
|
# NOTE: We probably need to rethink the options validation system, but this
|
65
63
|
# constant temporarily allows for extensions to modify the list.
|
66
64
|
|
67
|
-
VALID_OPTIONS = [
|
68
|
-
|
69
|
-
|
70
|
-
|
65
|
+
VALID_OPTIONS = [
|
66
|
+
:page_size, :page_layout, :margin, :left_margin,
|
67
|
+
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
|
68
|
+
:compress, :background, :info,
|
69
|
+
:text_formatter, :print_scaling
|
70
|
+
].freeze
|
71
71
|
|
72
72
|
# Any module added to this array will be included into instances of
|
73
73
|
# Prawn::Document at the per-object level. These will also be inherited by
|
@@ -153,15 +153,22 @@ module Prawn
|
|
153
153
|
# <tt>:right_margin</tt>:: Sets the right margin in points [0.5 inch]
|
154
154
|
# <tt>:top_margin</tt>:: Sets the top margin in points [0.5 inch]
|
155
155
|
# <tt>:bottom_margin</tt>:: Sets the bottom margin in points [0.5 inch]
|
156
|
-
# <tt>:skip_page_creation</tt>:: Creates a document without starting the
|
157
|
-
#
|
158
|
-
# <tt>:
|
156
|
+
# <tt>:skip_page_creation</tt>:: Creates a document without starting the
|
157
|
+
# first page [false]
|
158
|
+
# <tt>:compress</tt>:: Compresses content streams before rendering them
|
159
|
+
# [false]
|
160
|
+
# <tt>:background</tt>:: An image path to be used as background on all pages
|
161
|
+
# [nil]
|
159
162
|
# <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
|
160
|
-
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties
|
161
|
-
#
|
163
|
+
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties
|
164
|
+
# [nil]
|
165
|
+
# <tt>:text_formatter</tt>: The text formatter to use for
|
166
|
+
# <tt>:inline_format</tt>ted text
|
167
|
+
# [Prawn::Text::Formatted::Parser]
|
162
168
|
#
|
163
|
-
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
164
|
-
# of 100 points on every side except for the left, where
|
169
|
+
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
170
|
+
# result in margins of 100 points on every side except for the left, where
|
171
|
+
# it will be 50.
|
165
172
|
#
|
166
173
|
# The :margin can also be an array much like CSS shorthand:
|
167
174
|
#
|
@@ -172,8 +179,8 @@ module Prawn
|
|
172
179
|
# # Top is 10, right is 20, bottom is 30, left is 40.
|
173
180
|
# :margin => [10, 20, 30, 40]
|
174
181
|
#
|
175
|
-
# Additionally, :page_size can be specified as a simple two value array
|
176
|
-
# the width and height of the document you need in PDF Points.
|
182
|
+
# Additionally, :page_size can be specified as a simple two value array
|
183
|
+
# giving the width and height of the document you need in PDF Points.
|
177
184
|
#
|
178
185
|
# Usage:
|
179
186
|
#
|
@@ -181,13 +188,15 @@ module Prawn
|
|
181
188
|
# pdf = Prawn::Document.new
|
182
189
|
#
|
183
190
|
# # New document, A4 paper, landscaped
|
184
|
-
# pdf = Prawn::Document.new(:
|
191
|
+
# pdf = Prawn::Document.new(page_size: "A4", page_layout: :landscape)
|
185
192
|
#
|
186
193
|
# # New document, Custom size
|
187
|
-
# pdf = Prawn::Document.new(:
|
194
|
+
# pdf = Prawn::Document.new(page_size: [200, 300])
|
188
195
|
#
|
189
196
|
# # New document, with background
|
190
|
-
# pdf = Prawn::Document.new(
|
197
|
+
# pdf = Prawn::Document.new(
|
198
|
+
# background: "#{Prawn::DATADIR}/images/pigs.jpg"
|
199
|
+
# )
|
191
200
|
#
|
192
201
|
def initialize(options = {}, &block)
|
193
202
|
options = options.dup
|
@@ -199,21 +208,22 @@ module Prawn
|
|
199
208
|
|
200
209
|
self.class.extensions.reverse_each { |e| extend e }
|
201
210
|
self.state = PDF::Core::DocumentState.new(options)
|
202
|
-
|
211
|
+
state.populate_pages_from_store(self)
|
203
212
|
renderer.min_version(state.store.min_version) if state.store.min_version
|
204
213
|
|
205
214
|
renderer.min_version(1.6) if options[:print_scaling] == :none
|
206
215
|
|
207
216
|
@background = options[:background]
|
208
217
|
@background_scale = options[:background_scale] || 1
|
209
|
-
@font_size
|
218
|
+
@font_size = 12
|
210
219
|
|
211
|
-
@bounding_box
|
212
|
-
@margin_box
|
220
|
+
@bounding_box = nil
|
221
|
+
@margin_box = nil
|
213
222
|
|
214
223
|
@page_number = 0
|
215
224
|
|
216
|
-
@text_formatter = options.delete(:text_formatter) ||
|
225
|
+
@text_formatter = options.delete(:text_formatter) ||
|
226
|
+
Text::Formatted::Parser
|
217
227
|
|
218
228
|
options[:size] = options.delete(:page_size)
|
219
229
|
options[:layout] = options.delete(:page_layout)
|
@@ -240,24 +250,28 @@ module Prawn
|
|
240
250
|
# pdf.start_new_page(:margin => 100)
|
241
251
|
#
|
242
252
|
def start_new_page(options = {})
|
243
|
-
|
244
|
-
|
245
|
-
|
253
|
+
last_page = state.page
|
254
|
+
if last_page
|
255
|
+
last_page_size = last_page.size
|
256
|
+
last_page_layout = last_page.layout
|
246
257
|
last_page_margins = last_page.margins.dup
|
247
258
|
end
|
248
259
|
|
249
260
|
page_options = {
|
250
|
-
:
|
251
|
-
:
|
252
|
-
:
|
261
|
+
size: options[:size] || last_page_size,
|
262
|
+
layout: options[:layout] || last_page_layout,
|
263
|
+
margins: last_page_margins
|
253
264
|
}
|
254
265
|
if last_page
|
255
|
-
|
266
|
+
if last_page.graphic_state
|
267
|
+
new_graphic_state = last_page.graphic_state.dup
|
268
|
+
end
|
256
269
|
|
257
|
-
# erase the color space so that it gets reset on new page for fussy
|
270
|
+
# erase the color space so that it gets reset on new page for fussy
|
271
|
+
# pdf-readers
|
258
272
|
new_graphic_state.color_space = {} if new_graphic_state
|
259
273
|
|
260
|
-
page_options
|
274
|
+
page_options[:graphic_state] = new_graphic_state
|
261
275
|
end
|
262
276
|
|
263
277
|
state.page = PDF::Core::Page.new(self, page_options)
|
@@ -277,7 +291,11 @@ module Prawn
|
|
277
291
|
state.insert_page(state.page, @page_number)
|
278
292
|
@page_number += 1
|
279
293
|
|
280
|
-
|
294
|
+
if @background
|
295
|
+
canvas do
|
296
|
+
image(@background, scale: @background_scale, at: bounds.top_left)
|
297
|
+
end
|
298
|
+
end
|
281
299
|
@y = @bounding_box.absolute_top
|
282
300
|
|
283
301
|
float do
|
@@ -365,7 +383,7 @@ module Prawn
|
|
365
383
|
# pdf.render_file "foo.pdf"
|
366
384
|
#
|
367
385
|
def render_file(filename)
|
368
|
-
File.open(filename,
|
386
|
+
File.open(filename, 'wb') { |f| render(f) }
|
369
387
|
end
|
370
388
|
|
371
389
|
# The bounds method returns the current bounding box you are currently in,
|
@@ -374,14 +392,15 @@ module Prawn
|
|
374
392
|
# block, the box defined by that call will be returned instead of the
|
375
393
|
# document margin box.
|
376
394
|
#
|
377
|
-
# Another important point about bounding boxes is that all x and
|
378
|
-
# within a bounding box code block are relative to the bottom
|
379
|
-
# bounding box.
|
395
|
+
# Another important point about bounding boxes is that all x and
|
396
|
+
# y measurements within a bounding box code block are relative to the bottom
|
397
|
+
# left corner of the bounding box.
|
380
398
|
#
|
381
399
|
# For example:
|
382
400
|
#
|
383
401
|
# Prawn::Document.new do
|
384
|
-
# # In the default "margin box" of a Prawn document of 0.5in along each
|
402
|
+
# # In the default "margin box" of a Prawn document of 0.5in along each
|
403
|
+
# # edge
|
385
404
|
#
|
386
405
|
# # Draw a border around the page (the manual way)
|
387
406
|
# stroke do
|
@@ -408,8 +427,8 @@ module Prawn
|
|
408
427
|
|
409
428
|
# Sets Document#bounds to the BoundingBox provided. See above for a brief
|
410
429
|
# description of what a bounding box is. This function is useful if you
|
411
|
-
# really need to change the bounding box manually, but usually, just
|
412
|
-
# and exiting bounding box code blocks is good enough.
|
430
|
+
# really need to change the bounding box manually, but usually, just
|
431
|
+
# entering and exiting bounding box code blocks is good enough.
|
413
432
|
#
|
414
433
|
def bounds=(bounding_box)
|
415
434
|
@bounding_box = bounding_box
|
@@ -422,8 +441,8 @@ module Prawn
|
|
422
441
|
self.y += n
|
423
442
|
end
|
424
443
|
|
425
|
-
# Moves down the document by n points relative to the current position
|
426
|
-
# the current bounding box.
|
444
|
+
# Moves down the document by n points relative to the current position
|
445
|
+
# inside the current bounding box.
|
427
446
|
#
|
428
447
|
def move_down(n)
|
429
448
|
self.y -= n
|
@@ -486,50 +505,54 @@ module Prawn
|
|
486
505
|
bounds.indent(left, right, &block)
|
487
506
|
end
|
488
507
|
|
489
|
-
# Places a text box on specified pages for page numbering. This should be
|
490
|
-
# towards the end of document creation, after all your content is
|
491
|
-
# place. In your template string, <page> refers to the current
|
492
|
-
# <total> refers to the total amount of pages in the document.
|
493
|
-
# occur at the end of your Prawn::Document.generate
|
494
|
-
# through existing pages after they are
|
508
|
+
# Places a text box on specified pages for page numbering. This should be
|
509
|
+
# called towards the end of document creation, after all your content is
|
510
|
+
# already in place. In your template string, <page> refers to the current
|
511
|
+
# page, and <total> refers to the total amount of pages in the document.
|
512
|
+
# Page numbering should occur at the end of your Prawn::Document.generate
|
513
|
+
# block because the method iterates through existing pages after they are
|
514
|
+
# created.
|
495
515
|
#
|
496
516
|
# Parameters are:
|
497
517
|
#
|
498
518
|
# <tt>string</tt>:: Template string for page number wording.
|
499
519
|
# Should include '<page>' and, optionally, '<total>'.
|
500
520
|
# <tt>options</tt>:: A hash for page numbering and text box options.
|
501
|
-
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
502
|
-
# Refer to the method 'page_match?'
|
521
|
+
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
522
|
+
# numbers on. Refer to the method 'page_match?'
|
503
523
|
# <tt>:start_count_at</tt>:: The starting count to increment pages from.
|
504
|
-
# <tt>:total_pages</tt>:: If provided, will replace <total> with the
|
505
|
-
# Useful to override the total
|
506
|
-
# the start_count_at
|
524
|
+
# <tt>:total_pages</tt>:: If provided, will replace <total> with the
|
525
|
+
# value given. Useful to override the total
|
526
|
+
# number of pages when using the start_count_at
|
527
|
+
# option.
|
507
528
|
# <tt>:color</tt>:: Text fill color.
|
508
529
|
#
|
509
|
-
# Please refer to Prawn::Text::text_box for additional options
|
510
|
-
# formatting and placement.
|
511
|
-
#
|
512
|
-
# Example: Print page numbers on every page except for the first. Start counting from
|
513
|
-
# five.
|
530
|
+
# Please refer to Prawn::Text::text_box for additional options
|
531
|
+
# concerning text formatting and placement.
|
514
532
|
#
|
515
|
-
#
|
516
|
-
#
|
517
|
-
#
|
518
|
-
#
|
519
|
-
#
|
520
|
-
#
|
521
|
-
#
|
522
|
-
#
|
533
|
+
# Example:
|
534
|
+
# Print page numbers on every page except for the first. Start counting
|
535
|
+
# from five.
|
536
|
+
#
|
537
|
+
# Prawn::Document.generate("page_with_numbering.pdf") do
|
538
|
+
# number_pages "<page> in a total of <total>", {
|
539
|
+
# start_count_at: 5,
|
540
|
+
# page_filter: lambda { |pg| pg != 1 },
|
541
|
+
# at: [bounds.right - 50, 0],
|
542
|
+
# align: :right,
|
543
|
+
# size: 14
|
544
|
+
# }
|
545
|
+
# end
|
523
546
|
#
|
524
547
|
def number_pages(string, options = {})
|
525
548
|
opts = options.dup
|
526
549
|
start_count_at = opts.delete(:start_count_at).to_i
|
527
550
|
|
528
|
-
if opts.key?(:page_filter)
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
551
|
+
page_filter = if opts.key?(:page_filter)
|
552
|
+
opts.delete(:page_filter)
|
553
|
+
else
|
554
|
+
:all
|
555
|
+
end
|
533
556
|
|
534
557
|
total_pages = opts.delete(:total_pages)
|
535
558
|
txtcolor = opts.delete(:color)
|
@@ -549,12 +572,14 @@ module Prawn
|
|
549
572
|
end
|
550
573
|
if page_match?(page_filter, p)
|
551
574
|
go_to_page(p)
|
552
|
-
# have to use fill_color here otherwise text reverts back to default
|
575
|
+
# have to use fill_color here otherwise text reverts back to default
|
576
|
+
# fill color
|
553
577
|
fill_color txtcolor unless txtcolor.nil?
|
554
578
|
total_pages = total_pages.nil? ? page_count : total_pages
|
555
|
-
str = string.gsub(
|
579
|
+
str = string.gsub('<page>', pseudopage.to_s)
|
580
|
+
.gsub('<total>', total_pages.to_s)
|
556
581
|
text_box str, opts
|
557
|
-
start_count = true
|
582
|
+
start_count = true # increment page count as soon as first match found
|
558
583
|
end
|
559
584
|
pseudopage += 1 if start_count
|
560
585
|
end
|
@@ -572,21 +597,21 @@ module Prawn
|
|
572
597
|
# the current page or column.
|
573
598
|
#
|
574
599
|
# @private
|
575
|
-
def group(*
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
600
|
+
def group(*_a)
|
601
|
+
raise NotImplementedError,
|
602
|
+
'Document#group has been disabled because its implementation ' \
|
603
|
+
'lead to corrupted documents whenever a page boundary was ' \
|
604
|
+
'crossed. We will try to work on reimplementing it in a ' \
|
605
|
+
'future release'
|
581
606
|
end
|
582
607
|
|
583
608
|
# @private
|
584
609
|
def transaction
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
610
|
+
raise NotImplementedError,
|
611
|
+
'Document#transaction has been disabled because its implementation ' \
|
612
|
+
'lead to corrupted documents whenever a page boundary was ' \
|
613
|
+
'crossed. We will try to work on reimplementing it in a ' \
|
614
|
+
'future release'
|
590
615
|
end
|
591
616
|
|
592
617
|
# Provides a way to execute a block of code repeatedly based on a
|
@@ -617,8 +642,8 @@ module Prawn
|
|
617
642
|
# @private
|
618
643
|
|
619
644
|
def mask(*fields)
|
620
|
-
# Stores the current state of the named attributes, executes the block,
|
621
|
-
# then restores the original values after the block has executed.
|
645
|
+
# Stores the current state of the named attributes, executes the block,
|
646
|
+
# and then restores the original values after the block has executed.
|
622
647
|
# -- I will remove the nodoc if/when this feature is a little less hacky
|
623
648
|
stored = {}
|
624
649
|
fields.each { |f| stored[f] = send(f) }
|
@@ -630,7 +655,7 @@ module Prawn
|
|
630
655
|
|
631
656
|
def initialize_first_page(options)
|
632
657
|
if options[:skip_page_creation]
|
633
|
-
start_new_page(options.merge(:
|
658
|
+
start_new_page(options.merge(orphan: true))
|
634
659
|
else
|
635
660
|
start_new_page(options)
|
636
661
|
end
|
@@ -648,11 +673,11 @@ module Prawn
|
|
648
673
|
|
649
674
|
private
|
650
675
|
|
651
|
-
# setting override_settings to true ensures that a new graphic state does
|
652
|
-
# previous settings.
|
676
|
+
# setting override_settings to true ensures that a new graphic state does
|
677
|
+
# not end up using previous settings.
|
653
678
|
def use_graphic_settings(override_settings = false)
|
654
|
-
set_fill_color if current_fill_color !=
|
655
|
-
set_stroke_color if current_stroke_color !=
|
679
|
+
set_fill_color if current_fill_color != '000000' || override_settings
|
680
|
+
set_stroke_color if current_stroke_color != '000000' || override_settings
|
656
681
|
write_line_width if line_width != 1 || override_settings
|
657
682
|
write_stroke_cap_style if cap_style != :butt || override_settings
|
658
683
|
write_stroke_join_style if join_style != :miter || override_settings
|
@@ -661,14 +686,16 @@ module Prawn
|
|
661
686
|
|
662
687
|
def generate_margin_box
|
663
688
|
old_margin_box = @margin_box
|
664
|
-
page
|
689
|
+
page = state.page
|
665
690
|
|
666
691
|
@margin_box = BoundingBox.new(
|
667
692
|
self,
|
668
|
-
nil,
|
669
|
-
[
|
670
|
-
:
|
671
|
-
|
693
|
+
nil, # margin box has no parent
|
694
|
+
[page.margins[:left], page.dimensions[-1] - page.margins[:top]],
|
695
|
+
width: page.dimensions[-2] -
|
696
|
+
(page.margins[:left] + page.margins[:right]),
|
697
|
+
height: page.dimensions[-1] -
|
698
|
+
(page.margins[:top] + page.margins[:bottom])
|
672
699
|
)
|
673
700
|
|
674
701
|
# This check maintains indentation settings across page breaks
|
@@ -683,21 +710,19 @@ module Prawn
|
|
683
710
|
end
|
684
711
|
|
685
712
|
def apply_margin_options(options)
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
[
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
state.page.margins[side] = margin
|
700
|
-
end
|
713
|
+
sides = [:top, :right, :bottom, :left]
|
714
|
+
margin = Array(options[:margin])
|
715
|
+
|
716
|
+
# Treat :margin as CSS shorthand with 1-4 values.
|
717
|
+
positions = {
|
718
|
+
4 => [0, 1, 2, 3], 3 => [0, 1, 2, 1],
|
719
|
+
2 => [0, 1, 0, 1], 1 => [0, 0, 0, 0],
|
720
|
+
0 => []
|
721
|
+
}[margin.length]
|
722
|
+
|
723
|
+
sides.zip(positions).each do |side, pos|
|
724
|
+
new_margin = options["#{side}_margin"] || (margin[pos] if pos)
|
725
|
+
state.page.margins[side] = new_margin if new_margin
|
701
726
|
end
|
702
727
|
end
|
703
728
|
|