prawn 0.13.0 → 2.4.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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data/.yardopts +10 -0
- data/GPLv2 +20 -21
- data/Gemfile +3 -16
- data/Rakefile +17 -39
- data/lib/prawn/document/bounding_box.rb +85 -42
- data/lib/prawn/document/column_box.rb +21 -11
- data/lib/prawn/document/internals.rb +40 -147
- data/lib/prawn/document/span.rb +25 -17
- data/lib/prawn/document.rb +286 -245
- data/lib/prawn/encoding.rb +68 -101
- data/lib/prawn/errors.rb +47 -43
- data/lib/prawn/font.rb +204 -155
- data/lib/prawn/font_metric_cache.rb +25 -21
- data/lib/prawn/fonts/afm.rb +292 -0
- data/lib/prawn/{font → fonts}/dfont.rb +7 -13
- data/lib/prawn/fonts/otf.rb +11 -0
- data/lib/prawn/fonts/ttc.rb +36 -0
- data/lib/prawn/{font → fonts}/ttf.rb +142 -80
- data/lib/prawn/graphics/blend_mode.rb +65 -0
- data/lib/prawn/graphics/cap_style.rb +6 -5
- data/lib/prawn/graphics/color.rb +47 -44
- data/lib/prawn/graphics/dash.rb +30 -13
- data/lib/prawn/graphics/join_style.rb +13 -6
- data/lib/prawn/graphics/patterns.rb +221 -90
- data/lib/prawn/graphics/transformation.rb +21 -12
- data/lib/prawn/graphics/transparency.rb +21 -17
- data/lib/prawn/graphics.rb +155 -128
- data/lib/prawn/{layout/grid.rb → grid.rb} +110 -47
- data/lib/prawn/image_handler.rb +16 -2
- data/lib/prawn/images/image.rb +4 -2
- data/lib/prawn/images/jpg.rb +39 -30
- data/lib/prawn/images/png.rb +132 -169
- data/lib/prawn/images.rb +70 -62
- data/lib/prawn/measurement_extensions.rb +15 -10
- data/lib/prawn/measurements.rb +22 -23
- data/lib/prawn/outline.rb +301 -13
- data/lib/prawn/repeater.rb +19 -17
- data/lib/prawn/security/arcfour.rb +54 -0
- data/lib/prawn/security.rb +108 -86
- data/lib/prawn/soft_mask.rb +40 -41
- data/lib/prawn/stamp.rb +29 -12
- data/lib/prawn/text/box.rb +27 -29
- data/lib/prawn/text/formatted/arranger.rb +110 -67
- data/lib/prawn/text/formatted/box.rb +233 -165
- data/lib/prawn/text/formatted/fragment.rb +27 -27
- data/lib/prawn/text/formatted/line_wrap.rb +137 -97
- data/lib/prawn/text/formatted/parser.rb +149 -127
- data/lib/prawn/text/formatted/wrap.rb +57 -37
- data/lib/prawn/text/formatted.rb +6 -4
- data/lib/prawn/text.rb +105 -73
- data/lib/prawn/transformation_stack.rb +44 -0
- data/lib/prawn/utilities.rb +11 -21
- data/lib/prawn/version.rb +5 -0
- data/lib/prawn/view.rb +101 -0
- data/lib/prawn.rb +42 -68
- data/{data/images/fractal.jpg → manual/absolute_position.pdf} +0 -0
- data/manual/basic_concepts/adding_pages.rb +9 -10
- data/manual/basic_concepts/basic_concepts.rb +33 -24
- data/manual/basic_concepts/creation.rb +10 -11
- data/manual/basic_concepts/cursor.rb +9 -10
- data/manual/basic_concepts/measurement.rb +10 -11
- data/manual/basic_concepts/origin.rb +8 -9
- data/manual/basic_concepts/other_cursor_helpers.rb +17 -18
- data/manual/basic_concepts/view.rb +48 -0
- data/manual/bounding_box/bounding_box.rb +31 -29
- data/manual/bounding_box/bounds.rb +17 -18
- data/manual/bounding_box/canvas.rb +8 -9
- data/manual/bounding_box/creation.rb +8 -9
- data/manual/bounding_box/indentation.rb +22 -23
- data/manual/bounding_box/nesting.rb +32 -25
- data/manual/bounding_box/russian_boxes.rb +19 -19
- data/manual/bounding_box/stretchy.rb +18 -20
- data/manual/contents.rb +35 -0
- data/manual/cover.rb +43 -0
- data/manual/document_and_page_options/background.rb +16 -14
- data/manual/document_and_page_options/document_and_page_options.rb +26 -23
- data/manual/document_and_page_options/metadata.rb +21 -19
- data/manual/document_and_page_options/page_margins.rb +20 -22
- data/manual/document_and_page_options/page_size.rb +15 -15
- data/manual/document_and_page_options/print_scaling.rb +23 -0
- data/manual/example_helper.rb +5 -408
- data/manual/graphics/blend_mode.rb +52 -0
- data/manual/graphics/circle_and_ellipse.rb +8 -9
- data/manual/graphics/color.rb +11 -13
- data/manual/graphics/common_lines.rb +13 -12
- data/manual/graphics/fill_and_stroke.rb +10 -11
- data/manual/graphics/fill_rules.rb +13 -12
- data/manual/graphics/gradients.rb +28 -22
- data/manual/graphics/graphics.rb +52 -46
- data/manual/graphics/helper.rb +20 -10
- data/manual/graphics/line_width.rb +13 -12
- data/manual/graphics/lines_and_curves.rb +13 -14
- data/manual/graphics/polygon.rb +10 -12
- data/manual/graphics/rectangle.rb +7 -8
- data/manual/graphics/rotate.rb +9 -12
- data/manual/graphics/scale.rb +19 -18
- data/manual/graphics/soft_masks.rb +5 -7
- data/manual/graphics/stroke_cap.rb +10 -11
- data/manual/graphics/stroke_dash.rb +16 -17
- data/manual/graphics/stroke_join.rb +10 -11
- data/manual/graphics/translate.rb +13 -13
- data/manual/graphics/transparency.rb +11 -13
- data/manual/{manual/how_to_read_this_manual.rb → how_to_read_this_manual.rb} +23 -25
- data/manual/images/absolute_position.rb +9 -10
- data/manual/images/fit.rb +9 -10
- data/manual/images/horizontal.rb +13 -14
- data/manual/images/images.rb +31 -30
- data/manual/images/plain_image.rb +6 -7
- data/manual/images/scale.rb +12 -13
- data/manual/images/vertical.rb +19 -17
- data/manual/images/width_and_height.rb +13 -14
- data/manual/layout/boxes.rb +14 -15
- data/manual/layout/content.rb +12 -13
- data/manual/layout/layout.rb +19 -20
- data/manual/layout/simple_grid.rb +8 -9
- data/manual/outline/add_subsection_to.rb +26 -27
- data/manual/outline/insert_section_after.rb +19 -20
- data/manual/outline/outline.rb +23 -22
- data/manual/outline/sections_and_pages.rb +24 -25
- data/manual/repeatable_content/alternate_page_numbering.rb +36 -0
- data/manual/repeatable_content/page_numbering.rb +20 -19
- data/manual/repeatable_content/repeatable_content.rb +26 -22
- data/manual/repeatable_content/repeater.rb +18 -19
- data/manual/repeatable_content/stamp.rb +18 -19
- data/manual/security/encryption.rb +8 -11
- data/manual/security/permissions.rb +20 -15
- data/manual/security/security.rb +20 -20
- data/manual/table.rb +16 -0
- data/manual/text/alignment.rb +17 -18
- data/manual/text/color.rb +13 -13
- data/manual/text/column_box.rb +10 -12
- data/manual/text/fallback_fonts.rb +29 -25
- data/manual/text/font.rb +17 -18
- data/manual/text/font_size.rb +21 -22
- data/manual/text/font_style.rb +12 -10
- data/manual/text/formatted_callbacks.rb +36 -26
- data/manual/text/formatted_text.rb +41 -34
- data/manual/text/free_flowing_text.rb +28 -29
- data/manual/text/inline.rb +23 -26
- data/manual/text/kerning_and_character_spacing.rb +20 -21
- data/manual/text/leading.rb +10 -11
- data/manual/text/line_wrapping.rb +40 -21
- data/manual/text/paragraph_indentation.rb +17 -12
- data/manual/text/positioned_text.rb +19 -20
- data/manual/text/registering_families.rb +33 -30
- data/manual/text/rendering_and_color.rb +11 -12
- data/manual/text/right_to_left_text.rb +31 -20
- data/manual/text/rotation.rb +36 -27
- data/manual/text/single_usage.rb +13 -14
- data/manual/text/text.rb +62 -62
- data/manual/text/text_box_excess.rb +22 -19
- data/manual/text/text_box_extensions.rb +21 -18
- data/manual/text/text_box_overflow.rb +28 -21
- data/manual/text/utf8.rb +16 -17
- data/manual/text/win_ansi_charset.rb +29 -26
- data/prawn.gemspec +45 -43
- data/spec/extensions/encoding_helpers.rb +4 -3
- data/spec/prawn/document/bounding_box_spec.rb +550 -0
- data/spec/prawn/document/column_box_spec.rb +75 -0
- data/spec/prawn/document/security_spec.rb +176 -0
- data/spec/prawn/document_annotations_spec.rb +76 -0
- data/spec/prawn/document_destinations_spec.rb +15 -0
- data/spec/prawn/document_grid_spec.rb +99 -0
- data/spec/prawn/document_reference_spec.rb +27 -0
- data/spec/prawn/document_span_spec.rb +44 -0
- data/spec/prawn/document_spec.rb +805 -0
- data/spec/prawn/font_metric_cache_spec.rb +54 -0
- data/spec/prawn/font_spec.rb +544 -0
- data/spec/prawn/graphics/blend_mode_spec.rb +63 -0
- data/spec/prawn/graphics/transparency_spec.rb +81 -0
- data/spec/prawn/graphics_spec.rb +872 -0
- data/spec/prawn/graphics_stroke_styles_spec.rb +229 -0
- data/spec/prawn/image_handler_spec.rb +53 -0
- data/spec/prawn/images/jpg_spec.rb +20 -0
- data/spec/prawn/images/png_spec.rb +283 -0
- data/spec/prawn/images_spec.rb +229 -0
- data/spec/prawn/measurements_extensions_spec.rb +24 -0
- data/spec/prawn/outline_spec.rb +512 -0
- data/spec/prawn/repeater_spec.rb +166 -0
- data/spec/prawn/soft_mask_spec.rb +74 -0
- data/spec/prawn/stamp_spec.rb +173 -0
- data/spec/prawn/text/box_spec.rb +1110 -0
- data/spec/prawn/text/formatted/arranger_spec.rb +466 -0
- data/spec/prawn/text/formatted/box_spec.rb +849 -0
- data/spec/prawn/text/formatted/fragment_spec.rb +343 -0
- data/spec/prawn/text/formatted/line_wrap_spec.rb +495 -0
- data/spec/prawn/text/formatted/parser_spec.rb +697 -0
- data/spec/prawn/text_draw_text_spec.rb +150 -0
- data/spec/prawn/text_rendering_mode_spec.rb +48 -0
- data/spec/prawn/text_spacing_spec.rb +95 -0
- data/spec/prawn/text_spec.rb +603 -0
- data/spec/prawn/text_with_inline_formatting_spec.rb +35 -0
- data/spec/prawn/transformation_stack_spec.rb +66 -0
- data/spec/prawn/view_spec.rb +63 -0
- data/spec/prawn_manual_spec.rb +35 -0
- data/spec/spec_helper.rb +22 -21
- data.tar.gz.sig +0 -0
- metadata +168 -307
- metadata.gz.sig +0 -0
- data/README.md +0 -109
- data/data/encodings/win_ansi.txt +0 -29
- data/data/images/16bit.alpha +0 -0
- data/data/images/16bit.dat +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/barcode_issue.png +0 -0
- data/data/images/dice.alpha +0 -0
- data/data/images/dice.dat +0 -0
- data/data/images/dice.png +0 -0
- data/data/images/dice_interlaced.png +0 -0
- data/data/images/indexed_color.dat +0 -0
- data/data/images/indexed_color.png +0 -0
- data/data/images/letterhead.jpg +0 -0
- data/data/images/page_white_text.alpha +0 -0
- data/data/images/page_white_text.dat +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/lib/pdf/core/annotations.rb +0 -60
- data/lib/pdf/core/byte_string.rb +0 -9
- data/lib/pdf/core/destinations.rb +0 -90
- data/lib/pdf/core/document_state.rb +0 -78
- data/lib/pdf/core/filter_list.rb +0 -51
- data/lib/pdf/core/filters.rb +0 -36
- data/lib/pdf/core/graphics_state.rb +0 -68
- data/lib/pdf/core/literal_string.rb +0 -16
- data/lib/pdf/core/name_tree.rb +0 -177
- data/lib/pdf/core/object_store.rb +0 -320
- data/lib/pdf/core/outline.rb +0 -315
- data/lib/pdf/core/page.rb +0 -212
- data/lib/pdf/core/page_geometry.rb +0 -126
- data/lib/pdf/core/pdf_object.rb +0 -124
- data/lib/pdf/core/reference.rb +0 -103
- data/lib/pdf/core/stream.rb +0 -98
- data/lib/pdf/core/text.rb +0 -275
- data/lib/pdf/core.rb +0 -35
- data/lib/prawn/compatibility.rb +0 -91
- data/lib/prawn/document/graphics_state.rb +0 -73
- data/lib/prawn/document/snapshot.rb +0 -89
- data/lib/prawn/font/afm.rb +0 -203
- data/lib/prawn/layout.rb +0 -20
- data/lib/prawn/table/cell/image.rb +0 -70
- data/lib/prawn/table/cell/in_table.rb +0 -27
- data/lib/prawn/table/cell/span_dummy.rb +0 -92
- data/lib/prawn/table/cell/subtable.rb +0 -65
- data/lib/prawn/table/cell/text.rb +0 -153
- data/lib/prawn/table/cell.rb +0 -770
- data/lib/prawn/table/cells.rb +0 -295
- data/lib/prawn/table.rb +0 -643
- data/manual/example_file.rb +0 -116
- data/manual/example_package.rb +0 -53
- data/manual/example_section.rb +0 -46
- data/manual/manual/cover.rb +0 -35
- data/manual/manual/foreword.rb +0 -85
- data/manual/manual/manual.rb +0 -35
- data/manual/syntax_highlight.rb +0 -52
- data/manual/table/basic_block.rb +0 -53
- data/manual/table/before_rendering_page.rb +0 -26
- data/manual/table/cell_border_lines.rb +0 -24
- data/manual/table/cell_borders_and_bg.rb +0 -31
- data/manual/table/cell_dimensions.rb +0 -30
- data/manual/table/cell_text.rb +0 -38
- data/manual/table/column_widths.rb +0 -30
- data/manual/table/content_and_subtables.rb +0 -39
- data/manual/table/creation.rb +0 -27
- data/manual/table/filtering.rb +0 -36
- data/manual/table/flow_and_header.rb +0 -17
- data/manual/table/image_cells.rb +0 -33
- data/manual/table/position.rb +0 -29
- data/manual/table/row_colors.rb +0 -20
- data/manual/table/span.rb +0 -30
- data/manual/table/style.rb +0 -22
- data/manual/table/table.rb +0 -52
- data/manual/table/width.rb +0 -27
- data/manual/templates/full_template.rb +0 -25
- data/manual/templates/page_template.rb +0 -48
- data/manual/templates/templates.rb +0 -27
- data/manual/text/group.rb +0 -29
- data/spec/acceptance/png.rb +0 -23
- data/spec/annotations_spec.rb +0 -74
- data/spec/bounding_box_spec.rb +0 -493
- data/spec/cell_spec.rb +0 -628
- data/spec/column_box_spec.rb +0 -33
- data/spec/destinations_spec.rb +0 -15
- data/spec/document_spec.rb +0 -761
- data/spec/extensions/mocha.rb +0 -44
- data/spec/filters_spec.rb +0 -34
- data/spec/font_metric_cache_spec.rb +0 -52
- data/spec/font_spec.rb +0 -464
- data/spec/formatted_text_arranger_spec.rb +0 -421
- data/spec/formatted_text_box_spec.rb +0 -650
- data/spec/formatted_text_fragment_spec.rb +0 -298
- data/spec/graphics_spec.rb +0 -651
- data/spec/grid_spec.rb +0 -85
- data/spec/image_handler_spec.rb +0 -42
- data/spec/images_spec.rb +0 -157
- data/spec/inline_formatted_text_parser_spec.rb +0 -564
- data/spec/jpg_spec.rb +0 -25
- data/spec/line_wrap_spec.rb +0 -333
- data/spec/measurement_units_spec.rb +0 -23
- data/spec/name_tree_spec.rb +0 -112
- data/spec/object_store_spec.rb +0 -170
- data/spec/outline_spec.rb +0 -448
- data/spec/pdf_object_spec.rb +0 -172
- data/spec/png_spec.rb +0 -240
- data/spec/reference_spec.rb +0 -82
- data/spec/repeater_spec.rb +0 -158
- data/spec/security_spec.rb +0 -158
- data/spec/snapshot_spec.rb +0 -186
- data/spec/soft_mask_spec.rb +0 -117
- data/spec/span_spec.rb +0 -44
- data/spec/stamp_spec.rb +0 -158
- data/spec/stream_spec.rb +0 -58
- data/spec/stroke_styles_spec.rb +0 -211
- data/spec/table/span_dummy_spec.rb +0 -17
- data/spec/table_spec.rb +0 -1355
- data/spec/template_spec.rb +0 -351
- data/spec/text_at_spec.rb +0 -130
- data/spec/text_box_spec.rb +0 -1030
- data/spec/text_rendering_mode_spec.rb +0 -45
- data/spec/text_spacing_spec.rb +0 -93
- data/spec/text_spec.rb +0 -425
- data/spec/text_with_inline_formatting_spec.rb +0 -35
- data/spec/transparency_spec.rb +0 -89
data/lib/prawn/document.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# document.rb : Implements PDF document generation for Prawn
|
4
4
|
#
|
@@ -6,23 +6,21 @@
|
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
|
9
|
-
require
|
10
|
-
require "prawn/document/bounding_box"
|
11
|
-
require "prawn/document/column_box"
|
12
|
-
require "prawn/document/internals"
|
13
|
-
require "prawn/document/span"
|
14
|
-
require "prawn/document/snapshot"
|
15
|
-
require "prawn/document/graphics_state"
|
9
|
+
require 'stringio'
|
16
10
|
|
17
|
-
|
11
|
+
require_relative 'document/bounding_box'
|
12
|
+
require_relative 'document/column_box'
|
13
|
+
require_relative 'document/internals'
|
14
|
+
require_relative 'document/span'
|
18
15
|
|
16
|
+
module Prawn
|
19
17
|
# The Prawn::Document class is how you start creating a PDF document.
|
20
18
|
#
|
21
19
|
# There are three basic ways you can instantiate PDF Documents in Prawn, they
|
22
|
-
# are through assignment, implicit block or explicit block. Below is an
|
23
|
-
# of each type, each example does exactly the same thing, makes a PDF
|
24
|
-
# with all the defaults and puts in the default font "Hello There"
|
25
|
-
# saves it to the current directory as "example.pdf"
|
20
|
+
# are through assignment, implicit block or explicit block. Below is an
|
21
|
+
# example of each type, each example does exactly the same thing, makes a PDF
|
22
|
+
# document with all the defaults and puts in the default font "Hello There"
|
23
|
+
# and then saves it to the current directory as "example.pdf"
|
26
24
|
#
|
27
25
|
# For example, assignment can be like this:
|
28
26
|
#
|
@@ -44,8 +42,8 @@ module Prawn
|
|
44
42
|
# pdf.text words
|
45
43
|
# end
|
46
44
|
#
|
47
|
-
# Usually, the block forms are used when you are simply creating a PDF
|
48
|
-
# that you want to immediately save or render out.
|
45
|
+
# Usually, the block forms are used when you are simply creating a PDF
|
46
|
+
# document that you want to immediately save or render out.
|
49
47
|
#
|
50
48
|
# See the new and generate methods for further details on the above.
|
51
49
|
#
|
@@ -53,14 +51,25 @@ module Prawn
|
|
53
51
|
include Prawn::Document::Internals
|
54
52
|
include PDF::Core::Annotations
|
55
53
|
include PDF::Core::Destinations
|
56
|
-
include Prawn::Document::Snapshot
|
57
|
-
include Prawn::Document::GraphicsState
|
58
54
|
include Prawn::Document::Security
|
59
55
|
include Prawn::Text
|
60
56
|
include Prawn::Graphics
|
61
57
|
include Prawn::Images
|
62
58
|
include Prawn::Stamp
|
63
59
|
include Prawn::SoftMask
|
60
|
+
include Prawn::TransformationStack
|
61
|
+
|
62
|
+
# @group Extension API
|
63
|
+
|
64
|
+
# NOTE: We probably need to rethink the options validation system, but this
|
65
|
+
# constant temporarily allows for extensions to modify the list.
|
66
|
+
|
67
|
+
VALID_OPTIONS = %i[
|
68
|
+
page_size page_layout margin left_margin
|
69
|
+
right_margin top_margin bottom_margin skip_page_creation
|
70
|
+
compress background info
|
71
|
+
text_formatter print_scaling
|
72
|
+
].freeze
|
64
73
|
|
65
74
|
# Any module added to this array will be included into instances of
|
66
75
|
# Prawn::Document at the per-object level. These will also be inherited by
|
@@ -82,14 +91,29 @@ module Prawn
|
|
82
91
|
# party!
|
83
92
|
# end
|
84
93
|
#
|
94
|
+
#
|
85
95
|
def self.extensions
|
86
96
|
@extensions ||= []
|
87
97
|
end
|
88
98
|
|
89
|
-
|
99
|
+
# @private
|
100
|
+
def self.inherited(base)
|
101
|
+
super
|
90
102
|
extensions.each { |e| base.extensions << e }
|
91
103
|
end
|
92
104
|
|
105
|
+
# @group Stable Attributes
|
106
|
+
|
107
|
+
attr_accessor :margin_box
|
108
|
+
attr_reader :margins, :y
|
109
|
+
attr_accessor :page_number
|
110
|
+
|
111
|
+
# @group Extension Attributes
|
112
|
+
|
113
|
+
attr_accessor :text_formatter
|
114
|
+
|
115
|
+
# @group Stable API
|
116
|
+
|
93
117
|
# Creates and renders a PDF document.
|
94
118
|
#
|
95
119
|
# When using the implicit block form, Prawn will evaluate the block
|
@@ -117,32 +141,37 @@ module Prawn
|
|
117
141
|
# pdf.draw_text content, :at => [200,720], :size => 32
|
118
142
|
# end
|
119
143
|
#
|
120
|
-
def self.generate(filename,options={}
|
121
|
-
pdf = new(options
|
144
|
+
def self.generate(filename, options = {}, &block)
|
145
|
+
pdf = new(options, &block)
|
122
146
|
pdf.render_file(filename)
|
123
147
|
end
|
124
148
|
|
125
149
|
# Creates a new PDF Document. The following options are available (with
|
126
150
|
# the default values marked in [])
|
127
151
|
#
|
128
|
-
# <tt>:page_size</tt>:: One of the
|
152
|
+
# <tt>:page_size</tt>:: One of the PDF::Core::PageGeometry sizes [LETTER]
|
129
153
|
# <tt>:page_layout</tt>:: Either <tt>:portrait</tt> or <tt>:landscape</tt>
|
130
154
|
# <tt>:margin</tt>:: Sets the margin on all sides in points [0.5 inch]
|
131
155
|
# <tt>:left_margin</tt>:: Sets the left margin in points [0.5 inch]
|
132
156
|
# <tt>:right_margin</tt>:: Sets the right margin in points [0.5 inch]
|
133
157
|
# <tt>:top_margin</tt>:: Sets the top margin in points [0.5 inch]
|
134
158
|
# <tt>:bottom_margin</tt>:: Sets the bottom margin in points [0.5 inch]
|
135
|
-
# <tt>:skip_page_creation</tt>:: Creates a document without starting the
|
136
|
-
#
|
137
|
-
# <tt>:
|
138
|
-
#
|
159
|
+
# <tt>:skip_page_creation</tt>:: Creates a document without starting the
|
160
|
+
# first page [false]
|
161
|
+
# <tt>:compress</tt>:: Compresses content streams before rendering them
|
162
|
+
# [false]
|
163
|
+
# <tt>:background</tt>:: An image path to be used as background on all pages
|
164
|
+
# [nil]
|
139
165
|
# <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
|
140
|
-
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties
|
141
|
-
#
|
142
|
-
# <tt>:text_formatter</tt>: The text formatter to use for
|
166
|
+
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties
|
167
|
+
# [nil]
|
168
|
+
# <tt>:text_formatter</tt>: The text formatter to use for
|
169
|
+
# <tt>:inline_format</tt>ted text
|
170
|
+
# [Prawn::Text::Formatted::Parser]
|
143
171
|
#
|
144
|
-
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
145
|
-
# of 100 points on every side except for the left, where
|
172
|
+
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will
|
173
|
+
# result in margins of 100 points on every side except for the left, where
|
174
|
+
# it will be 50.
|
146
175
|
#
|
147
176
|
# The :margin can also be an array much like CSS shorthand:
|
148
177
|
#
|
@@ -153,8 +182,8 @@ module Prawn
|
|
153
182
|
# # Top is 10, right is 20, bottom is 30, left is 40.
|
154
183
|
# :margin => [10, 20, 30, 40]
|
155
184
|
#
|
156
|
-
# Additionally, :page_size can be specified as a simple two value array
|
157
|
-
# the width and height of the document you need in PDF Points.
|
185
|
+
# Additionally, :page_size can be specified as a simple two value array
|
186
|
+
# giving the width and height of the document you need in PDF Points.
|
158
187
|
#
|
159
188
|
# Usage:
|
160
189
|
#
|
@@ -162,54 +191,47 @@ module Prawn
|
|
162
191
|
# pdf = Prawn::Document.new
|
163
192
|
#
|
164
193
|
# # New document, A4 paper, landscaped
|
165
|
-
# pdf = Prawn::Document.new(:
|
194
|
+
# pdf = Prawn::Document.new(page_size: "A4", page_layout: :landscape)
|
166
195
|
#
|
167
196
|
# # New document, Custom size
|
168
|
-
# pdf = Prawn::Document.new(:
|
197
|
+
# pdf = Prawn::Document.new(page_size: [200, 300])
|
169
198
|
#
|
170
199
|
# # New document, with background
|
171
|
-
# pdf = Prawn::Document.new(
|
200
|
+
# pdf = Prawn::Document.new(
|
201
|
+
# background: "#{Prawn::DATADIR}/images/pigs.jpg"
|
202
|
+
# )
|
172
203
|
#
|
173
|
-
def initialize(options={}
|
204
|
+
def initialize(options = {}, &block)
|
174
205
|
options = options.dup
|
175
206
|
|
176
|
-
Prawn.verify_options
|
177
|
-
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
|
178
|
-
:compress, :skip_encoding, :background, :info,
|
179
|
-
:optimize_objects, :template, :text_formatter], options
|
207
|
+
Prawn.verify_options VALID_OPTIONS, options
|
180
208
|
|
181
209
|
# need to fix, as the refactoring breaks this
|
182
210
|
# raise NotImplementedError if options[:skip_page_creation]
|
183
211
|
|
184
212
|
self.class.extensions.reverse_each { |e| extend e }
|
185
|
-
|
186
|
-
|
187
|
-
min_version(state.store.min_version) if state.store.min_version
|
213
|
+
self.state = PDF::Core::DocumentState.new(options)
|
214
|
+
state.populate_pages_from_store(self)
|
215
|
+
renderer.min_version(state.store.min_version) if state.store.min_version
|
216
|
+
|
217
|
+
renderer.min_version(1.6) if options[:print_scaling] == :none
|
188
218
|
|
189
219
|
@background = options[:background]
|
190
220
|
@background_scale = options[:background_scale] || 1
|
191
|
-
@font_size
|
221
|
+
@font_size = 12
|
192
222
|
|
193
|
-
@bounding_box
|
194
|
-
@margin_box
|
223
|
+
@bounding_box = nil
|
224
|
+
@margin_box = nil
|
195
225
|
|
196
226
|
@page_number = 0
|
197
227
|
|
198
|
-
@text_formatter = options.delete(:text_formatter) ||
|
228
|
+
@text_formatter = options.delete(:text_formatter) ||
|
229
|
+
Text::Formatted::Parser
|
199
230
|
|
200
231
|
options[:size] = options.delete(:page_size)
|
201
232
|
options[:layout] = options.delete(:page_layout)
|
202
233
|
|
203
|
-
|
204
|
-
fresh_content_streams(options)
|
205
|
-
go_to_page(1)
|
206
|
-
else
|
207
|
-
if options[:skip_page_creation] || options[:template]
|
208
|
-
start_new_page(options.merge(:orphan => true))
|
209
|
-
else
|
210
|
-
start_new_page(options)
|
211
|
-
end
|
212
|
-
end
|
234
|
+
initialize_first_page(options)
|
213
235
|
|
214
236
|
@bounding_box = @margin_box
|
215
237
|
|
@@ -218,19 +240,7 @@ module Prawn
|
|
218
240
|
end
|
219
241
|
end
|
220
242
|
|
221
|
-
|
222
|
-
attr_reader :margins, :y
|
223
|
-
attr_writer :font_size
|
224
|
-
attr_accessor :page_number
|
225
|
-
attr_accessor :text_formatter
|
226
|
-
|
227
|
-
def state
|
228
|
-
@internal_state
|
229
|
-
end
|
230
|
-
|
231
|
-
def page
|
232
|
-
state.page
|
233
|
-
end
|
243
|
+
# @group Stable API
|
234
244
|
|
235
245
|
# Creates and advances to a new page in the document.
|
236
246
|
#
|
@@ -242,31 +252,30 @@ module Prawn
|
|
242
252
|
# pdf.start_new_page(:left_margin => 50, :right_margin => 50)
|
243
253
|
# pdf.start_new_page(:margin => 100)
|
244
254
|
#
|
245
|
-
# A template for a page can be specified by pointing to the path of and existing pdf.
|
246
|
-
# One can also specify which page of the template which defaults otherwise to 1.
|
247
|
-
#
|
248
|
-
# pdf.start_new_page(:template => multipage_template.pdf, :template_page => 2)
|
249
|
-
#
|
250
|
-
# Note: templates get indexed by either the object_id of the filename or stream
|
251
|
-
# entered so that if you reuse the same template multiple times be sure to use the
|
252
|
-
# same instance for more efficient use of resources and smaller rendered pdfs.
|
253
255
|
def start_new_page(options = {})
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
256
|
+
last_page = state.page
|
257
|
+
if last_page
|
258
|
+
last_page_size = last_page.size
|
259
|
+
last_page_layout = last_page.layout
|
260
|
+
last_page_margins = last_page.margins.dup
|
258
261
|
end
|
259
262
|
|
260
|
-
page_options = {
|
261
|
-
|
262
|
-
|
263
|
+
page_options = {
|
264
|
+
size: options[:size] || last_page_size,
|
265
|
+
layout: options[:layout] || last_page_layout,
|
266
|
+
margins: last_page_margins
|
267
|
+
}
|
263
268
|
if last_page
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
269
|
+
if last_page.graphic_state
|
270
|
+
new_graphic_state = last_page.graphic_state.dup
|
271
|
+
end
|
272
|
+
|
273
|
+
# erase the color space so that it gets reset on new page for fussy
|
274
|
+
# pdf-readers
|
275
|
+
new_graphic_state&.color_space = {}
|
276
|
+
|
277
|
+
page_options[:graphic_state] = new_graphic_state
|
268
278
|
end
|
269
|
-
merge_template_options(page_options, options) if options[:template]
|
270
279
|
|
271
280
|
state.page = PDF::Core::Page.new(self, page_options)
|
272
281
|
|
@@ -279,15 +288,17 @@ module Prawn
|
|
279
288
|
@bounding_box = @margin_box
|
280
289
|
end
|
281
290
|
|
282
|
-
|
283
|
-
use_graphic_settings(options[:template])
|
284
|
-
forget_text_rendering_mode! if options[:template]
|
291
|
+
use_graphic_settings
|
285
292
|
|
286
293
|
unless options[:orphan]
|
287
294
|
state.insert_page(state.page, @page_number)
|
288
295
|
@page_number += 1
|
289
296
|
|
290
|
-
|
297
|
+
if @background
|
298
|
+
canvas do
|
299
|
+
image(@background, scale: @background_scale, at: bounds.top_left)
|
300
|
+
end
|
301
|
+
end
|
291
302
|
@y = @bounding_box.absolute_top
|
292
303
|
|
293
304
|
float do
|
@@ -296,6 +307,26 @@ module Prawn
|
|
296
307
|
end
|
297
308
|
end
|
298
309
|
|
310
|
+
# Remove page of the document by index
|
311
|
+
#
|
312
|
+
# pdf = Prawn::Document.new
|
313
|
+
# pdf.page_count #=> 1
|
314
|
+
# 3.times { pdf.start_new_page }
|
315
|
+
# pdf.page_count #=> 4
|
316
|
+
# pdf.delete_page(-1)
|
317
|
+
# pdf.page_count #=> 3
|
318
|
+
#
|
319
|
+
def delete_page(index)
|
320
|
+
return false if index.abs > (state.pages.count - 1)
|
321
|
+
|
322
|
+
state.pages.delete_at(index)
|
323
|
+
|
324
|
+
state.store.pages.data[:Kids].delete_at(index)
|
325
|
+
state.store.pages.data[:Count] -= 1
|
326
|
+
@page_number -= 1
|
327
|
+
true
|
328
|
+
end
|
329
|
+
|
299
330
|
# Returns the number of pages in the document
|
300
331
|
#
|
301
332
|
# pdf = Prawn::Document.new
|
@@ -312,9 +343,9 @@ module Prawn
|
|
312
343
|
#
|
313
344
|
# See Prawn::Document#number_pages for a sample usage of this capability.
|
314
345
|
#
|
315
|
-
def go_to_page(
|
316
|
-
@page_number =
|
317
|
-
state.page = state.pages[
|
346
|
+
def go_to_page(page_number)
|
347
|
+
@page_number = page_number
|
348
|
+
state.page = state.pages[page_number - 1]
|
318
349
|
generate_margin_box
|
319
350
|
@y = @bounding_box.absolute_top
|
320
351
|
end
|
@@ -361,20 +392,13 @@ module Prawn
|
|
361
392
|
# Renders the PDF document to string.
|
362
393
|
# Pass an open file descriptor to render to file.
|
363
394
|
#
|
364
|
-
def render(
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
render_body(output)
|
369
|
-
render_xref(output)
|
370
|
-
render_trailer(output)
|
371
|
-
if output.instance_of?(StringIO)
|
372
|
-
str = output.string
|
373
|
-
str.force_encoding("ASCII-8BIT") if str.respond_to?(:force_encoding)
|
374
|
-
return str
|
375
|
-
else
|
376
|
-
return nil
|
395
|
+
def render(*arguments, &block)
|
396
|
+
(1..page_count).each do |i|
|
397
|
+
go_to_page i
|
398
|
+
repeaters.each { |r| r.run(i) }
|
377
399
|
end
|
400
|
+
|
401
|
+
renderer.render(*arguments, &block)
|
378
402
|
end
|
379
403
|
|
380
404
|
# Renders the PDF document to file.
|
@@ -382,8 +406,7 @@ module Prawn
|
|
382
406
|
# pdf.render_file "foo.pdf"
|
383
407
|
#
|
384
408
|
def render_file(filename)
|
385
|
-
|
386
|
-
File.open(filename,mode) { |f| render(f) }
|
409
|
+
File.open(filename, 'wb') { |f| render(f) }
|
387
410
|
end
|
388
411
|
|
389
412
|
# The bounds method returns the current bounding box you are currently in,
|
@@ -392,14 +415,15 @@ module Prawn
|
|
392
415
|
# block, the box defined by that call will be returned instead of the
|
393
416
|
# document margin box.
|
394
417
|
#
|
395
|
-
# Another important point about bounding boxes is that all x and
|
396
|
-
# within a bounding box code block are relative to the bottom
|
397
|
-
# bounding box.
|
418
|
+
# Another important point about bounding boxes is that all x and
|
419
|
+
# y measurements within a bounding box code block are relative to the bottom
|
420
|
+
# left corner of the bounding box.
|
398
421
|
#
|
399
422
|
# For example:
|
400
423
|
#
|
401
424
|
# Prawn::Document.new do
|
402
|
-
# # In the default "margin box" of a Prawn document of 0.5in along each
|
425
|
+
# # In the default "margin box" of a Prawn document of 0.5in along each
|
426
|
+
# # edge
|
403
427
|
#
|
404
428
|
# # Draw a border around the page (the manual way)
|
405
429
|
# stroke do
|
@@ -419,14 +443,15 @@ module Prawn
|
|
419
443
|
|
420
444
|
# Returns the innermost non-stretchy bounding box.
|
421
445
|
#
|
446
|
+
# @private
|
422
447
|
def reference_bounds
|
423
448
|
@bounding_box.reference_bounds
|
424
449
|
end
|
425
450
|
|
426
451
|
# Sets Document#bounds to the BoundingBox provided. See above for a brief
|
427
452
|
# description of what a bounding box is. This function is useful if you
|
428
|
-
# really need to change the bounding box manually, but usually, just
|
429
|
-
# and exiting bounding box code blocks is good enough.
|
453
|
+
# really need to change the bounding box manually, but usually, just
|
454
|
+
# entering and exiting bounding box code blocks is good enough.
|
430
455
|
#
|
431
456
|
def bounds=(bounding_box)
|
432
457
|
@bounding_box = bounding_box
|
@@ -435,15 +460,15 @@ module Prawn
|
|
435
460
|
# Moves up the document by n points relative to the current position inside
|
436
461
|
# the current bounding box.
|
437
462
|
#
|
438
|
-
def move_up(
|
439
|
-
self.y +=
|
463
|
+
def move_up(amount)
|
464
|
+
self.y += amount
|
440
465
|
end
|
441
466
|
|
442
|
-
# Moves down the document by n points relative to the current position
|
443
|
-
# the current bounding box.
|
467
|
+
# Moves down the document by n points relative to the current position
|
468
|
+
# inside the current bounding box.
|
444
469
|
#
|
445
|
-
def move_down(
|
446
|
-
self.y -=
|
470
|
+
def move_down(amount)
|
471
|
+
self.y -= amount
|
447
472
|
end
|
448
473
|
|
449
474
|
# Moves down the document and then executes a block.
|
@@ -487,7 +512,6 @@ module Prawn
|
|
487
512
|
move_down(y)
|
488
513
|
end
|
489
514
|
|
490
|
-
|
491
515
|
# Indents the specified number of PDF points for the duration of the block
|
492
516
|
#
|
493
517
|
# pdf.text "some text"
|
@@ -504,119 +528,117 @@ module Prawn
|
|
504
528
|
bounds.indent(left, right, &block)
|
505
529
|
end
|
506
530
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
yield
|
515
|
-
fields.each { |f| send("#{f}=", stored[f]) }
|
516
|
-
end
|
517
|
-
|
518
|
-
# Attempts to group the given block vertically within the current context.
|
519
|
-
# First attempts to render it in the current position on the current page.
|
520
|
-
# If that attempt overflows, it is tried anew after starting a new context
|
521
|
-
# (page or column). Returns a logically true value if the content fits in
|
522
|
-
# one page/column, false if a new page or column was needed.
|
523
|
-
#
|
524
|
-
# Raises CannotGroup if the provided content is too large to fit alone in
|
525
|
-
# the current page or column.
|
526
|
-
#
|
527
|
-
def group(second_attempt=false)
|
528
|
-
old_bounding_box = @bounding_box
|
529
|
-
@bounding_box = SimpleDelegator.new(@bounding_box)
|
530
|
-
|
531
|
-
def @bounding_box.move_past_bottom
|
532
|
-
raise RollbackTransaction
|
533
|
-
end
|
534
|
-
|
535
|
-
success = transaction { yield }
|
536
|
-
|
537
|
-
@bounding_box = old_bounding_box
|
538
|
-
|
539
|
-
unless success
|
540
|
-
raise Prawn::Errors::CannotGroup if second_attempt
|
541
|
-
old_bounding_box.move_past_bottom
|
542
|
-
group(second_attempt=true) { yield }
|
543
|
-
end
|
544
|
-
|
545
|
-
success
|
546
|
-
end
|
547
|
-
|
548
|
-
# Places a text box on specified pages for page numbering. This should be called
|
549
|
-
# towards the end of document creation, after all your content is already in
|
550
|
-
# place. In your template string, <page> refers to the current page, and
|
551
|
-
# <total> refers to the total amount of pages in the document. Page numbering should
|
552
|
-
# occur at the end of your Prawn::Document.generate block because the method iterates
|
553
|
-
# through existing pages after they are created.
|
531
|
+
# Places a text box on specified pages for page numbering. This should be
|
532
|
+
# called towards the end of document creation, after all your content is
|
533
|
+
# already in place. In your template string, <page> refers to the current
|
534
|
+
# page, and <total> refers to the total amount of pages in the document.
|
535
|
+
# Page numbering should occur at the end of your Prawn::Document.generate
|
536
|
+
# block because the method iterates through existing pages after they are
|
537
|
+
# created.
|
554
538
|
#
|
555
539
|
# Parameters are:
|
556
540
|
#
|
557
541
|
# <tt>string</tt>:: Template string for page number wording.
|
558
542
|
# Should include '<page>' and, optionally, '<total>'.
|
559
543
|
# <tt>options</tt>:: A hash for page numbering and text box options.
|
560
|
-
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
561
|
-
# Refer to the method 'page_match?'
|
544
|
+
# <tt>:page_filter</tt>:: A filter to specify which pages to place page
|
545
|
+
# numbers on. Refer to the method 'page_match?'
|
562
546
|
# <tt>:start_count_at</tt>:: The starting count to increment pages from.
|
563
|
-
# <tt>:total_pages</tt>:: If provided, will replace <total> with the
|
564
|
-
# Useful to override the total
|
565
|
-
# the start_count_at
|
547
|
+
# <tt>:total_pages</tt>:: If provided, will replace <total> with the
|
548
|
+
# value given. Useful to override the total
|
549
|
+
# number of pages when using the start_count_at
|
550
|
+
# option.
|
566
551
|
# <tt>:color</tt>:: Text fill color.
|
567
552
|
#
|
568
|
-
# Please refer to Prawn::Text::text_box for additional options
|
569
|
-
# formatting and placement.
|
570
|
-
#
|
571
|
-
# Example: Print page numbers on every page except for the first. Start counting from
|
572
|
-
# five.
|
553
|
+
# Please refer to Prawn::Text::text_box for additional options
|
554
|
+
# concerning text formatting and placement.
|
573
555
|
#
|
574
|
-
#
|
575
|
-
#
|
576
|
-
#
|
577
|
-
#
|
578
|
-
#
|
579
|
-
#
|
580
|
-
#
|
581
|
-
#
|
556
|
+
# Example:
|
557
|
+
# Print page numbers on every page except for the first. Start counting
|
558
|
+
# from five.
|
559
|
+
#
|
560
|
+
# Prawn::Document.generate("page_with_numbering.pdf") do
|
561
|
+
# number_pages "<page> in a total of <total>", {
|
562
|
+
# start_count_at: 5,
|
563
|
+
# page_filter: lambda { |pg| pg != 1 },
|
564
|
+
# at: [bounds.right - 50, 0],
|
565
|
+
# align: :right,
|
566
|
+
# size: 14
|
567
|
+
# }
|
568
|
+
# end
|
582
569
|
#
|
583
|
-
def number_pages(string, options={})
|
570
|
+
def number_pages(string, options = {})
|
584
571
|
opts = options.dup
|
585
572
|
start_count_at = opts.delete(:start_count_at).to_i
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
573
|
+
|
574
|
+
page_filter =
|
575
|
+
if opts.key?(:page_filter)
|
576
|
+
opts.delete(:page_filter)
|
577
|
+
else
|
578
|
+
:all
|
579
|
+
end
|
580
|
+
|
591
581
|
total_pages = opts.delete(:total_pages)
|
592
582
|
txtcolor = opts.delete(:color)
|
593
583
|
# An explicit height so that we can draw page numbers in the margins
|
594
|
-
opts[:height] = 50 unless opts.
|
584
|
+
opts[:height] = 50 unless opts.key?(:height)
|
595
585
|
|
596
586
|
start_count = false
|
597
587
|
pseudopage = 0
|
598
588
|
(1..page_count).each do |p|
|
599
589
|
unless start_count
|
600
|
-
pseudopage =
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
590
|
+
pseudopage =
|
591
|
+
case start_count_at
|
592
|
+
when 0
|
593
|
+
1
|
594
|
+
else
|
595
|
+
start_count_at.to_i
|
596
|
+
end
|
606
597
|
end
|
607
598
|
if page_match?(page_filter, p)
|
608
599
|
go_to_page(p)
|
609
|
-
# have to use fill_color here otherwise text reverts back to default
|
600
|
+
# have to use fill_color here otherwise text reverts back to default
|
601
|
+
# fill color
|
610
602
|
fill_color txtcolor unless txtcolor.nil?
|
611
603
|
total_pages = total_pages.nil? ? page_count : total_pages
|
612
|
-
str = string.gsub(
|
604
|
+
str = string.gsub('<page>', pseudopage.to_s)
|
605
|
+
.gsub('<total>', total_pages.to_s)
|
613
606
|
text_box str, opts
|
614
|
-
start_count = true
|
607
|
+
start_count = true # increment page count as soon as first match found
|
615
608
|
end
|
616
609
|
pseudopage += 1 if start_count
|
617
610
|
end
|
618
611
|
end
|
619
612
|
|
613
|
+
# @group Experimental API
|
614
|
+
|
615
|
+
# Attempts to group the given block vertically within the current context.
|
616
|
+
# First attempts to render it in the current position on the current page.
|
617
|
+
# If that attempt overflows, it is tried anew after starting a new context
|
618
|
+
# (page or column). Returns a logically true value if the content fits in
|
619
|
+
# one page/column, false if a new page or column was needed.
|
620
|
+
#
|
621
|
+
# Raises CannotGroup if the provided content is too large to fit alone in
|
622
|
+
# the current page or column.
|
623
|
+
#
|
624
|
+
# @private
|
625
|
+
def group(*_arguments)
|
626
|
+
raise NotImplementedError,
|
627
|
+
'Document#group has been disabled because its implementation ' \
|
628
|
+
'lead to corrupted documents whenever a page boundary was ' \
|
629
|
+
'crossed. We will try to work on reimplementing it in a ' \
|
630
|
+
'future release'
|
631
|
+
end
|
632
|
+
|
633
|
+
# @private
|
634
|
+
def transaction
|
635
|
+
raise NotImplementedError,
|
636
|
+
'Document#transaction has been disabled because its implementation ' \
|
637
|
+
'lead to corrupted documents whenever a page boundary was ' \
|
638
|
+
'crossed. We will try to work on reimplementing it in a ' \
|
639
|
+
'future release'
|
640
|
+
end
|
641
|
+
|
620
642
|
# Provides a way to execute a block of code repeatedly based on a
|
621
643
|
# page_filter.
|
622
644
|
#
|
@@ -632,9 +654,9 @@ module Prawn
|
|
632
654
|
when :all
|
633
655
|
true
|
634
656
|
when :odd
|
635
|
-
page_number
|
657
|
+
page_number.odd?
|
636
658
|
when :even
|
637
|
-
page_number
|
659
|
+
page_number.even?
|
638
660
|
when Range, Array
|
639
661
|
page_filter.include?(page_number)
|
640
662
|
when Proc
|
@@ -642,26 +664,45 @@ module Prawn
|
|
642
664
|
end
|
643
665
|
end
|
644
666
|
|
667
|
+
# @private
|
645
668
|
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
669
|
+
def mask(*fields)
|
670
|
+
# Stores the current state of the named attributes, executes the block,
|
671
|
+
# and then restores the original values after the block has executed.
|
672
|
+
# -- I will remove the nodoc if/when this feature is a little less hacky
|
673
|
+
stored = {}
|
674
|
+
fields.each { |f| stored[f] = public_send(f) }
|
675
|
+
yield
|
676
|
+
fields.each { |f| public_send("#{f}=", stored[f]) }
|
651
677
|
end
|
652
678
|
|
653
|
-
|
679
|
+
# @group Extension API
|
680
|
+
|
681
|
+
def initialize_first_page(options)
|
682
|
+
if options[:skip_page_creation]
|
683
|
+
start_new_page(options.merge(orphan: true))
|
684
|
+
else
|
685
|
+
start_new_page(options)
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
## Internals. Don't depend on them!
|
690
|
+
|
691
|
+
# @private
|
692
|
+
attr_accessor :state
|
654
693
|
|
655
|
-
|
656
|
-
|
657
|
-
|
694
|
+
# @private
|
695
|
+
def page
|
696
|
+
state.page
|
658
697
|
end
|
659
698
|
|
660
|
-
|
661
|
-
|
699
|
+
private
|
700
|
+
|
701
|
+
# setting override_settings to true ensures that a new graphic state does
|
702
|
+
# not end up using previous settings.
|
662
703
|
def use_graphic_settings(override_settings = false)
|
663
|
-
set_fill_color if current_fill_color !=
|
664
|
-
set_stroke_color if current_stroke_color !=
|
704
|
+
set_fill_color if current_fill_color != '000000' || override_settings
|
705
|
+
set_stroke_color if current_stroke_color != '000000' || override_settings
|
665
706
|
write_line_width if line_width != 1 || override_settings
|
666
707
|
write_stroke_cap_style if cap_style != :butt || override_settings
|
667
708
|
write_stroke_join_style if join_style != :miter || override_settings
|
@@ -670,14 +711,16 @@ module Prawn
|
|
670
711
|
|
671
712
|
def generate_margin_box
|
672
713
|
old_margin_box = @margin_box
|
673
|
-
page
|
714
|
+
page = state.page
|
674
715
|
|
675
716
|
@margin_box = BoundingBox.new(
|
676
717
|
self,
|
677
|
-
nil,
|
678
|
-
[
|
679
|
-
:
|
680
|
-
|
718
|
+
nil, # margin box has no parent
|
719
|
+
[page.margins[:left], page.dimensions[-1] - page.margins[:top]],
|
720
|
+
width: page.dimensions[-2] -
|
721
|
+
(page.margins[:left] + page.margins[:right]),
|
722
|
+
height: page.dimensions[-1] -
|
723
|
+
(page.margins[:top] + page.margins[:bottom])
|
681
724
|
)
|
682
725
|
|
683
726
|
# This check maintains indentation settings across page breaks
|
@@ -688,32 +731,30 @@ module Prawn
|
|
688
731
|
|
689
732
|
# we must update bounding box if not flowing from the previous page
|
690
733
|
#
|
691
|
-
|
692
|
-
# when the bounding box exits.
|
693
|
-
@bounding_box = @margin_box if old_margin_box == @bounding_box
|
734
|
+
@bounding_box = @margin_box unless @bounding_box&.parent
|
694
735
|
end
|
695
736
|
|
696
737
|
def apply_margin_options(options)
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
[
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
738
|
+
sides = %i[top right bottom left]
|
739
|
+
margin = Array(options[:margin])
|
740
|
+
|
741
|
+
# Treat :margin as CSS shorthand with 1-4 values.
|
742
|
+
positions = {
|
743
|
+
4 => [0, 1, 2, 3],
|
744
|
+
3 => [0, 1, 2, 1],
|
745
|
+
2 => [0, 1, 0, 1],
|
746
|
+
1 => [0, 0, 0, 0],
|
747
|
+
0 => []
|
748
|
+
}[margin.length]
|
749
|
+
|
750
|
+
sides.zip(positions).each do |side, pos|
|
751
|
+
new_margin = options[:"#{side}_margin"] || (margin[pos] if pos)
|
752
|
+
state.page.margins[side] = new_margin if new_margin
|
712
753
|
end
|
713
754
|
end
|
714
755
|
|
715
756
|
def font_metric_cache #:nodoc:
|
716
|
-
@font_metric_cache ||= FontMetricCache.new(
|
757
|
+
@font_metric_cache ||= FontMetricCache.new(self)
|
717
758
|
end
|
718
759
|
end
|
719
760
|
end
|