prawn 0.11.1 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.yardopts +10 -0
- data/COPYING +2 -2
- data/GPLv2 +340 -0
- data/GPLv3 +674 -0
- data/Gemfile +11 -0
- data/LICENSE +1 -1
- data/Rakefile +29 -38
- 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/page_white_text.alpha +0 -0
- data/data/images/page_white_text.color +0 -0
- data/data/pdfs/nested_pages.pdf +13 -13
- data/lib/prawn/document/bounding_box.rb +87 -12
- data/lib/prawn/document/column_box.rb +57 -28
- data/lib/prawn/document/graphics_state.rb +11 -74
- data/lib/prawn/document/internals.rb +25 -23
- data/lib/prawn/document/snapshot.rb +11 -8
- data/lib/prawn/document/span.rb +12 -10
- data/lib/prawn/document.rb +250 -194
- data/lib/prawn/encoding.rb +9 -10
- data/lib/prawn/errors.rb +18 -29
- data/lib/prawn/font/afm.rb +52 -41
- data/lib/prawn/font/dfont.rb +4 -3
- data/lib/prawn/font/ttf.rb +44 -48
- data/lib/prawn/font.rb +138 -88
- data/lib/prawn/font_metric_cache.rb +47 -0
- data/lib/prawn/graphics/cap_style.rb +4 -3
- data/lib/prawn/graphics/color.rb +13 -5
- data/lib/prawn/graphics/dash.rb +53 -31
- data/lib/prawn/graphics/join_style.rb +9 -7
- data/lib/prawn/graphics/patterns.rb +138 -0
- data/lib/prawn/graphics/transformation.rb +10 -9
- data/lib/prawn/graphics/transparency.rb +3 -1
- data/lib/prawn/graphics.rb +316 -61
- data/lib/prawn/image_handler.rb +36 -0
- data/lib/prawn/images/image.rb +49 -0
- data/lib/prawn/images/jpg.rb +21 -15
- data/lib/prawn/images/png.rb +62 -119
- data/lib/prawn/images.rb +89 -108
- data/lib/prawn/layout/grid.rb +66 -54
- data/lib/prawn/layout.rb +10 -15
- data/lib/prawn/measurement_extensions.rb +10 -6
- data/lib/prawn/measurements.rb +27 -21
- data/lib/prawn/outline.rb +6 -308
- data/lib/prawn/repeater.rb +11 -9
- data/lib/prawn/security/arcfour.rb +1 -0
- data/lib/prawn/security.rb +55 -33
- data/lib/prawn/soft_mask.rb +96 -0
- data/lib/prawn/stamp.rb +5 -3
- data/lib/prawn/table/cell/image.rb +69 -0
- data/lib/prawn/table/cell/in_table.rb +4 -2
- data/lib/prawn/table/cell/span_dummy.rb +93 -0
- data/lib/prawn/table/cell/subtable.rb +2 -2
- data/lib/prawn/table/cell/text.rb +44 -26
- data/lib/prawn/table/cell.rb +302 -50
- data/lib/prawn/table/cells.rb +147 -49
- data/lib/prawn/table/column_width_calculator.rb +61 -0
- data/lib/prawn/table.rb +297 -118
- data/lib/prawn/text/box.rb +21 -5
- data/lib/prawn/text/formatted/arranger.rb +290 -0
- data/lib/prawn/text/formatted/box.rb +103 -59
- data/lib/prawn/text/formatted/fragment.rb +34 -23
- data/lib/prawn/text/formatted/line_wrap.rb +266 -0
- data/lib/prawn/text/formatted/parser.rb +15 -5
- data/lib/prawn/text/formatted/wrap.rb +150 -0
- data/lib/prawn/text/formatted.rb +5 -4
- data/lib/prawn/text.rb +38 -24
- data/lib/prawn/utilities.rb +46 -0
- data/lib/prawn.rb +85 -20
- data/manual/basic_concepts/adding_pages.rb +27 -0
- data/manual/basic_concepts/basic_concepts.rb +34 -0
- data/manual/basic_concepts/creation.rb +39 -0
- data/manual/basic_concepts/cursor.rb +33 -0
- data/manual/basic_concepts/measurement.rb +25 -0
- data/manual/basic_concepts/origin.rb +38 -0
- data/manual/basic_concepts/other_cursor_helpers.rb +40 -0
- data/manual/bounding_box/bounding_box.rb +39 -0
- data/manual/bounding_box/bounds.rb +49 -0
- data/manual/bounding_box/canvas.rb +24 -0
- data/manual/bounding_box/creation.rb +23 -0
- data/manual/bounding_box/indentation.rb +46 -0
- data/manual/bounding_box/nesting.rb +45 -0
- data/manual/bounding_box/russian_boxes.rb +40 -0
- data/manual/bounding_box/stretchy.rb +31 -0
- data/manual/document_and_page_options/background.rb +27 -0
- data/manual/document_and_page_options/document_and_page_options.rb +32 -0
- data/manual/document_and_page_options/metadata.rb +23 -0
- data/manual/document_and_page_options/page_margins.rb +38 -0
- data/manual/document_and_page_options/page_size.rb +34 -0
- data/manual/document_and_page_options/print_scaling.rb +20 -0
- data/manual/example_file.rb +111 -0
- data/manual/example_helper.rb +411 -0
- data/manual/example_package.rb +53 -0
- data/manual/example_section.rb +46 -0
- data/manual/graphics/circle_and_ellipse.rb +22 -0
- data/manual/graphics/color.rb +24 -0
- data/manual/graphics/common_lines.rb +30 -0
- data/manual/graphics/fill_and_stroke.rb +42 -0
- data/manual/graphics/fill_rules.rb +37 -0
- data/manual/graphics/gradients.rb +37 -0
- data/manual/graphics/graphics.rb +58 -0
- data/manual/graphics/helper.rb +24 -0
- data/manual/graphics/line_width.rb +35 -0
- data/manual/graphics/lines_and_curves.rb +41 -0
- data/manual/graphics/polygon.rb +29 -0
- data/manual/graphics/rectangle.rb +21 -0
- data/manual/graphics/rotate.rb +28 -0
- data/manual/graphics/scale.rb +41 -0
- data/manual/graphics/soft_masks.rb +46 -0
- data/manual/graphics/stroke_cap.rb +31 -0
- data/manual/graphics/stroke_dash.rb +48 -0
- data/manual/graphics/stroke_join.rb +30 -0
- data/manual/graphics/translate.rb +29 -0
- data/manual/graphics/transparency.rb +35 -0
- data/manual/images/absolute_position.rb +23 -0
- data/manual/images/fit.rb +21 -0
- data/manual/images/horizontal.rb +25 -0
- data/manual/images/images.rb +40 -0
- data/manual/images/plain_image.rb +18 -0
- data/manual/images/scale.rb +22 -0
- data/manual/images/vertical.rb +28 -0
- data/manual/images/width_and_height.rb +25 -0
- data/manual/layout/boxes.rb +27 -0
- data/manual/layout/content.rb +25 -0
- data/manual/layout/layout.rb +28 -0
- data/manual/layout/simple_grid.rb +23 -0
- data/manual/manual/cover.rb +36 -0
- data/manual/manual/foreword.rb +85 -0
- data/manual/manual/how_to_read_this_manual.rb +41 -0
- data/manual/manual/manual.rb +34 -0
- data/manual/outline/add_subsection_to.rb +61 -0
- data/manual/outline/insert_section_after.rb +47 -0
- data/manual/outline/outline.rb +32 -0
- data/manual/outline/sections_and_pages.rb +67 -0
- data/manual/repeatable_content/page_numbering.rb +54 -0
- data/manual/repeatable_content/repeatable_content.rb +31 -0
- data/manual/repeatable_content/repeater.rb +55 -0
- data/manual/repeatable_content/stamp.rb +41 -0
- data/manual/security/encryption.rb +31 -0
- data/manual/security/permissions.rb +38 -0
- data/manual/security/security.rb +28 -0
- data/manual/syntax_highlight.rb +52 -0
- data/manual/table/basic_block.rb +53 -0
- data/manual/table/before_rendering_page.rb +26 -0
- data/manual/table/cell_border_lines.rb +24 -0
- data/manual/table/cell_borders_and_bg.rb +31 -0
- data/manual/table/cell_dimensions.rb +30 -0
- data/manual/table/cell_text.rb +38 -0
- data/manual/table/column_widths.rb +30 -0
- data/manual/table/content_and_subtables.rb +39 -0
- data/manual/table/creation.rb +27 -0
- data/manual/table/filtering.rb +36 -0
- data/manual/table/flow_and_header.rb +17 -0
- data/manual/table/image_cells.rb +33 -0
- data/manual/table/position.rb +29 -0
- data/manual/table/row_colors.rb +20 -0
- data/manual/table/span.rb +30 -0
- data/manual/table/style.rb +22 -0
- data/manual/table/table.rb +52 -0
- data/manual/table/width.rb +27 -0
- data/manual/text/alignment.rb +44 -0
- data/manual/text/color.rb +24 -0
- data/manual/text/column_box.rb +32 -0
- data/manual/text/fallback_fonts.rb +37 -0
- data/manual/text/font.rb +41 -0
- data/manual/text/font_size.rb +45 -0
- data/manual/text/font_style.rb +23 -0
- data/manual/text/formatted_callbacks.rb +60 -0
- data/manual/text/formatted_text.rb +54 -0
- data/manual/text/free_flowing_text.rb +51 -0
- data/manual/text/group.rb +31 -0
- data/manual/text/inline.rb +43 -0
- data/manual/text/kerning_and_character_spacing.rb +39 -0
- data/manual/text/leading.rb +25 -0
- data/manual/text/line_wrapping.rb +41 -0
- data/manual/text/paragraph_indentation.rb +26 -0
- data/manual/text/positioned_text.rb +38 -0
- data/manual/text/registering_families.rb +48 -0
- data/manual/text/rendering_and_color.rb +37 -0
- data/manual/text/right_to_left_text.rb +43 -0
- data/manual/text/rotation.rb +43 -0
- data/manual/text/single_usage.rb +37 -0
- data/manual/text/text.rb +75 -0
- data/manual/text/text_box_excess.rb +32 -0
- data/manual/text/text_box_extensions.rb +45 -0
- data/manual/text/text_box_overflow.rb +44 -0
- data/manual/text/utf8.rb +28 -0
- data/{examples/m17n → manual/text}/win_ansi_charset.rb +14 -10
- data/prawn.gemspec +27 -17
- data/spec/acceptance/png.rb +23 -0
- data/spec/annotations_spec.rb +16 -32
- data/spec/bounding_box_spec.rb +284 -2
- data/spec/cell_spec.rb +169 -38
- data/spec/column_box_spec.rb +65 -0
- data/spec/data/curves.pdf +66 -0
- data/spec/destinations_spec.rb +5 -5
- data/spec/document_spec.rb +212 -113
- data/spec/extensions/encoding_helpers.rb +9 -0
- data/spec/extensions/mocha.rb +2 -3
- data/spec/font_metric_cache_spec.rb +52 -0
- data/spec/font_spec.rb +205 -95
- data/spec/formatted_text_arranger_spec.rb +43 -43
- data/spec/formatted_text_box_spec.rb +63 -24
- data/spec/formatted_text_fragment_spec.rb +8 -8
- data/spec/graphics_spec.rb +175 -68
- data/spec/grid_spec.rb +26 -15
- data/spec/image_handler_spec.rb +54 -0
- data/spec/images_spec.rb +58 -30
- data/spec/inline_formatted_text_parser_spec.rb +73 -19
- data/spec/jpg_spec.rb +4 -4
- data/spec/line_wrap_spec.rb +28 -28
- data/spec/measurement_units_spec.rb +6 -6
- data/spec/object_store_spec.rb +17 -106
- data/spec/outline_spec.rb +103 -63
- data/spec/png_spec.rb +25 -25
- data/spec/reference_spec.rb +8 -65
- data/spec/repeater_spec.rb +25 -11
- data/spec/security_spec.rb +44 -12
- data/spec/snapshot_spec.rb +38 -6
- data/spec/soft_mask_spec.rb +117 -0
- data/spec/span_spec.rb +10 -15
- data/spec/spec_helper.rb +32 -8
- data/spec/stamp_spec.rb +29 -30
- data/spec/stroke_styles_spec.rb +36 -18
- data/spec/table/span_dummy_spec.rb +17 -0
- data/spec/table_spec.rb +850 -104
- data/spec/text_at_spec.rb +19 -33
- data/spec/text_box_spec.rb +117 -64
- data/spec/text_rendering_mode_spec.rb +5 -5
- data/spec/text_spacing_spec.rb +20 -2
- data/spec/text_spec.rb +111 -59
- data/spec/transparency_spec.rb +5 -5
- metadata +477 -328
- data/HACKING +0 -50
- data/README +0 -141
- 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/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/examples/bounding_box/bounding_boxes.rb +0 -44
- data/examples/bounding_box/indentation.rb +0 -35
- data/examples/bounding_box/russian_boxes.rb +0 -37
- data/examples/bounding_box/stretched_nesting.rb +0 -68
- data/examples/example_helper.rb +0 -8
- data/examples/general/background.rb +0 -24
- data/examples/general/canvas.rb +0 -16
- data/examples/general/context_sensitive_headers.rb +0 -38
- data/examples/general/float.rb +0 -12
- data/examples/general/margin.rb +0 -37
- data/examples/general/measurement_units.rb +0 -52
- data/examples/general/metadata-info.rb +0 -17
- data/examples/general/multi_page_layout.rb +0 -19
- data/examples/general/outlines.rb +0 -67
- data/examples/general/page_geometry.rb +0 -32
- data/examples/general/page_numbering.rb +0 -40
- data/examples/general/page_templates.rb +0 -20
- data/examples/general/repeaters.rb +0 -48
- data/examples/general/stamp.rb +0 -42
- data/examples/general/templates.rb +0 -14
- data/examples/graphics/basic_images.rb +0 -24
- data/examples/graphics/cmyk.rb +0 -13
- data/examples/graphics/curves.rb +0 -12
- data/examples/graphics/gradient.rb +0 -23
- data/examples/graphics/hexagon.rb +0 -14
- data/examples/graphics/image_fit.rb +0 -16
- data/examples/graphics/image_flow.rb +0 -38
- data/examples/graphics/image_position.rb +0 -18
- data/examples/graphics/line.rb +0 -33
- data/examples/graphics/png_types.rb +0 -23
- data/examples/graphics/polygons.rb +0 -17
- data/examples/graphics/remote_images.rb +0 -13
- data/examples/graphics/rounded_polygons.rb +0 -20
- data/examples/graphics/rounded_rectangle.rb +0 -21
- data/examples/graphics/ruport_style_helpers.rb +0 -20
- data/examples/graphics/stroke_bounds.rb +0 -21
- data/examples/graphics/stroke_cap_and_join.rb +0 -46
- data/examples/graphics/stroke_dash.rb +0 -43
- data/examples/graphics/transformations.rb +0 -53
- data/examples/graphics/transparency.rb +0 -27
- data/examples/grid/bounding_boxes.rb +0 -22
- data/examples/grid/column_gutter_grid.rb +0 -21
- data/examples/grid/multi_boxes.rb +0 -52
- data/examples/grid/show_grid.rb +0 -14
- data/examples/grid/simple_grid.rb +0 -21
- data/examples/m17n/chinese_text_wrapping.rb +0 -18
- data/examples/m17n/euro.rb +0 -16
- data/examples/m17n/full_win_ansi_character_list.rb +0 -20
- data/examples/m17n/sjis.rb +0 -29
- data/examples/m17n/utf8.rb +0 -14
- data/examples/security/hello_foo.rb +0 -9
- data/examples/table/bill.rb +0 -54
- data/examples/table/borders.rb +0 -25
- data/examples/table/cell.rb +0 -13
- data/examples/table/checkerboard.rb +0 -23
- data/examples/table/header.rb +0 -15
- data/examples/table/inline_format_table.rb +0 -13
- data/examples/table/multi_page_table.rb +0 -10
- data/examples/table/simple_table.rb +0 -25
- data/examples/table/subtable.rb +0 -13
- data/examples/table/widths.rb +0 -21
- data/examples/text/alignment.rb +0 -19
- data/examples/text/character_spacing.rb +0 -13
- data/examples/text/dfont.rb +0 -49
- data/examples/text/family_based_styling.rb +0 -25
- data/examples/text/font_calculations.rb +0 -92
- data/examples/text/font_size.rb +0 -34
- data/examples/text/hyphenation.rb +0 -45
- data/examples/text/indent_paragraphs.rb +0 -24
- data/examples/text/inline_format.rb +0 -104
- data/examples/text/kerning.rb +0 -31
- data/examples/text/rendering_mode.rb +0 -21
- data/examples/text/rotated.rb +0 -99
- data/examples/text/shaped_text_box.rb +0 -32
- data/examples/text/simple_text.rb +0 -18
- data/examples/text/simple_text_ttf.rb +0 -18
- data/examples/text/span.rb +0 -30
- data/examples/text/text_box.rb +0 -90
- data/examples/text/text_box_returning_excess.rb +0 -52
- data/examples/text/text_flow.rb +0 -68
- data/lib/prawn/compatibility.rb +0 -51
- 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 -78
- data/lib/prawn/core/literal_string.rb +0 -16
- data/lib/prawn/core/name_tree.rb +0 -165
- data/lib/prawn/core/object_store.rb +0 -264
- data/lib/prawn/core/page.rb +0 -213
- data/lib/prawn/core/pdf_object.rb +0 -108
- data/lib/prawn/core/reference.rb +0 -112
- data/lib/prawn/core/text/formatted/arranger.rb +0 -293
- data/lib/prawn/core/text/formatted/line_wrap.rb +0 -272
- data/lib/prawn/core/text/formatted/wrap.rb +0 -149
- data/lib/prawn/core/text.rb +0 -268
- data/lib/prawn/core.rb +0 -85
- data/lib/prawn/document/page_geometry.rb +0 -136
- data/lib/prawn/graphics/gradient.rb +0 -84
- data/spec/name_tree_spec.rb +0 -112
- data/spec/pdf_object_spec.rb +0 -170
- data/spec/template_spec.rb +0 -291
data/lib/prawn/document.rb
CHANGED
@@ -7,13 +7,13 @@
|
|
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
|
-
|
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/snapshot"
|
16
|
+
require_relative "document/graphics_state"
|
17
17
|
|
18
18
|
module Prawn
|
19
19
|
|
@@ -52,8 +52,8 @@ module Prawn
|
|
52
52
|
#
|
53
53
|
class Document
|
54
54
|
include Prawn::Document::Internals
|
55
|
-
include
|
56
|
-
include
|
55
|
+
include PDF::Core::Annotations
|
56
|
+
include PDF::Core::Destinations
|
57
57
|
include Prawn::Document::Snapshot
|
58
58
|
include Prawn::Document::GraphicsState
|
59
59
|
include Prawn::Document::Security
|
@@ -61,6 +61,17 @@ module Prawn
|
|
61
61
|
include Prawn::Graphics
|
62
62
|
include Prawn::Images
|
63
63
|
include Prawn::Stamp
|
64
|
+
include Prawn::SoftMask
|
65
|
+
|
66
|
+
# @group Extension API
|
67
|
+
|
68
|
+
# NOTE: We probably need to rethink the options validation system, but this
|
69
|
+
# constant temporarily allows for extensions to modify the list.
|
70
|
+
|
71
|
+
VALID_OPTIONS = [:page_size, :page_layout, :margin, :left_margin,
|
72
|
+
:right_margin, :top_margin, :bottom_margin, :skip_page_creation,
|
73
|
+
:compress, :skip_encoding, :background, :info,
|
74
|
+
:optimize_objects, :text_formatter, :print_scaling]
|
64
75
|
|
65
76
|
# Any module added to this array will be included into instances of
|
66
77
|
# Prawn::Document at the per-object level. These will also be inherited by
|
@@ -82,14 +93,28 @@ module Prawn
|
|
82
93
|
# party!
|
83
94
|
# end
|
84
95
|
#
|
96
|
+
#
|
85
97
|
def self.extensions
|
86
98
|
@extensions ||= []
|
87
99
|
end
|
88
100
|
|
89
|
-
|
101
|
+
# @private
|
102
|
+
def self.inherited(base)
|
90
103
|
extensions.each { |e| base.extensions << e }
|
91
104
|
end
|
92
105
|
|
106
|
+
# @group Stable Attributes
|
107
|
+
|
108
|
+
attr_accessor :margin_box
|
109
|
+
attr_reader :margins, :y
|
110
|
+
attr_accessor :page_number
|
111
|
+
|
112
|
+
# @group Extension Attributes
|
113
|
+
|
114
|
+
attr_accessor :text_formatter
|
115
|
+
|
116
|
+
# @group Stable API
|
117
|
+
|
93
118
|
# Creates and renders a PDF document.
|
94
119
|
#
|
95
120
|
# When using the implicit block form, Prawn will evaluate the block
|
@@ -136,8 +161,9 @@ module Prawn
|
|
136
161
|
# <tt>:compress</tt>:: Compresses content streams before rendering them [false]
|
137
162
|
# <tt>:optimize_objects</tt>:: Reduce number of PDF objects in output, at expense of render time [false]
|
138
163
|
# <tt>:background</tt>:: An image path to be used as background on all pages [nil]
|
164
|
+
# <tt>:background_scale</tt>:: Backgound image scale [1] [nil]
|
139
165
|
# <tt>:info</tt>:: Generic hash allowing for custom metadata properties [nil]
|
140
|
-
# <tt>:
|
166
|
+
# <tt>:text_formatter</tt>: The text formatter to use for <tt>:inline_format</tt>ted text [Prawn::Text::Formatted::Parser]
|
141
167
|
#
|
142
168
|
# Setting e.g. the :margin to 100 points and the :left_margin to 50 will result in margins
|
143
169
|
# of 100 points on every side except for the left, where it will be 50.
|
@@ -166,116 +192,100 @@ module Prawn
|
|
166
192
|
# pdf = Prawn::Document.new(:page_size => [200, 300])
|
167
193
|
#
|
168
194
|
# # New document, with background
|
169
|
-
# pdf = Prawn::Document.new(:background => "#{Prawn::
|
195
|
+
# pdf = Prawn::Document.new(:background => "#{Prawn::DATADIR}/images/pigs.jpg")
|
170
196
|
#
|
171
197
|
def initialize(options={},&block)
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
:layout => options[:layout] || last_page_layout,
|
251
|
-
:margins => last_page_margins}
|
252
|
-
if last_page
|
253
|
-
new_graphic_state = last_page.graphic_state.dup
|
254
|
-
#erase the color space so that it gets reset on new page for fussy pdf-readers
|
255
|
-
new_graphic_state.color_space = {}
|
256
|
-
page_options.merge!(:graphic_state => new_graphic_state)
|
257
|
-
end
|
258
|
-
merge_template_options(page_options, options) if options[:template]
|
259
|
-
|
260
|
-
state.page = Prawn::Core::Page.new(self, page_options)
|
261
|
-
|
262
|
-
apply_margin_options(options)
|
263
|
-
state.page.new_content_stream if options[:template]
|
264
|
-
use_graphic_settings(options[:template])
|
265
|
-
|
266
|
-
unless options[:orphan]
|
267
|
-
state.insert_page(state.page, @page_number)
|
268
|
-
@page_number += 1
|
269
|
-
|
270
|
-
canvas { image(@background, :at => bounds.top_left) } if @background
|
271
|
-
@y = @bounding_box.absolute_top
|
272
|
-
|
273
|
-
float do
|
274
|
-
state.on_page_create_action(self)
|
275
|
-
end
|
276
|
-
end
|
198
|
+
options = options.dup
|
199
|
+
|
200
|
+
Prawn.verify_options VALID_OPTIONS, options
|
201
|
+
|
202
|
+
# need to fix, as the refactoring breaks this
|
203
|
+
# raise NotImplementedError if options[:skip_page_creation]
|
204
|
+
|
205
|
+
self.class.extensions.reverse_each { |e| extend e }
|
206
|
+
@internal_state = PDF::Core::DocumentState.new(options)
|
207
|
+
@internal_state.populate_pages_from_store(self)
|
208
|
+
min_version(state.store.min_version) if state.store.min_version
|
209
|
+
|
210
|
+
min_version(1.6) if options[:print_scaling] == :none
|
211
|
+
|
212
|
+
@background = options[:background]
|
213
|
+
@background_scale = options[:background_scale] || 1
|
214
|
+
@font_size = 12
|
215
|
+
|
216
|
+
@bounding_box = nil
|
217
|
+
@margin_box = nil
|
218
|
+
|
219
|
+
@page_number = 0
|
220
|
+
|
221
|
+
@text_formatter = options.delete(:text_formatter) || Text::Formatted::Parser
|
222
|
+
|
223
|
+
options[:size] = options.delete(:page_size)
|
224
|
+
options[:layout] = options.delete(:page_layout)
|
225
|
+
|
226
|
+
initialize_first_page(options)
|
227
|
+
|
228
|
+
@bounding_box = @margin_box
|
229
|
+
|
230
|
+
if block
|
231
|
+
block.arity < 1 ? instance_eval(&block) : block[self]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
# @group Stable API
|
236
|
+
|
237
|
+
# Creates and advances to a new page in the document.
|
238
|
+
#
|
239
|
+
# Page size, margins, and layout can also be set when generating a
|
240
|
+
# new page. These values will become the new defaults for page creation
|
241
|
+
#
|
242
|
+
# pdf.start_new_page #=> Starts new page keeping current values
|
243
|
+
# pdf.start_new_page(:size => "LEGAL", :layout => :landscape)
|
244
|
+
# pdf.start_new_page(:left_margin => 50, :right_margin => 50)
|
245
|
+
# pdf.start_new_page(:margin => 100)
|
246
|
+
#
|
247
|
+
def start_new_page(options = {})
|
248
|
+
if last_page = state.page
|
249
|
+
last_page_size = last_page.size
|
250
|
+
last_page_layout = last_page.layout
|
251
|
+
last_page_margins = last_page.margins
|
252
|
+
end
|
253
|
+
|
254
|
+
page_options = {:size => options[:size] || last_page_size,
|
255
|
+
:layout => options[:layout] || last_page_layout,
|
256
|
+
:margins => last_page_margins}
|
257
|
+
if last_page
|
258
|
+
new_graphic_state = last_page.graphic_state.dup if last_page.graphic_state
|
259
|
+
#erase the color space so that it gets reset on new page for fussy pdf-readers
|
260
|
+
new_graphic_state.color_space = {} if new_graphic_state
|
261
|
+
page_options.merge!(:graphic_state => new_graphic_state)
|
262
|
+
end
|
263
|
+
|
264
|
+
state.page = PDF::Core::Page.new(self, page_options)
|
265
|
+
|
266
|
+
apply_margin_options(options)
|
267
|
+
generate_margin_box
|
268
|
+
|
269
|
+
# Reset the bounding box if the new page has different size or layout
|
270
|
+
if last_page && (last_page.size != state.page.size ||
|
271
|
+
last_page.layout != state.page.layout)
|
272
|
+
@bounding_box = @margin_box
|
273
|
+
end
|
274
|
+
|
275
|
+
use_graphic_settings
|
277
276
|
|
278
|
-
|
277
|
+
unless options[:orphan]
|
278
|
+
state.insert_page(state.page, @page_number)
|
279
|
+
@page_number += 1
|
280
|
+
|
281
|
+
canvas { image(@background, :scale => @background_scale, :at => bounds.top_left) } if @background
|
282
|
+
@y = @bounding_box.absolute_top
|
283
|
+
|
284
|
+
float do
|
285
|
+
state.on_page_create_action(self)
|
286
|
+
end
|
287
|
+
end
|
288
|
+
end
|
279
289
|
|
280
290
|
# Returns the number of pages in the document
|
281
291
|
#
|
@@ -318,7 +328,9 @@ module Prawn
|
|
318
328
|
self.y = new_y + bounds.absolute_bottom
|
319
329
|
end
|
320
330
|
|
321
|
-
# Executes a block and then restores the original y position
|
331
|
+
# Executes a block and then restores the original y position. If new pages
|
332
|
+
# were created during this block, it will teleport back to the original
|
333
|
+
# page when done.
|
322
334
|
#
|
323
335
|
# pdf.text "A"
|
324
336
|
#
|
@@ -330,22 +342,33 @@ module Prawn
|
|
330
342
|
# pdf.text "B"
|
331
343
|
#
|
332
344
|
def float
|
333
|
-
|
345
|
+
original_page = page_number
|
346
|
+
original_y = y
|
347
|
+
yield
|
348
|
+
go_to_page(original_page) unless page_number == original_page
|
349
|
+
self.y = original_y
|
334
350
|
end
|
335
351
|
|
336
|
-
# Renders the PDF document to string
|
352
|
+
# Renders the PDF document to string.
|
353
|
+
# Pass an open file descriptor to render to file.
|
337
354
|
#
|
338
|
-
def render
|
339
|
-
output
|
355
|
+
def render(output = StringIO.new)
|
356
|
+
if output.instance_of?(StringIO)
|
357
|
+
output.set_encoding(::Encoding::ASCII_8BIT)
|
358
|
+
end
|
340
359
|
finalize_all_page_contents
|
341
360
|
|
342
361
|
render_header(output)
|
343
362
|
render_body(output)
|
344
363
|
render_xref(output)
|
345
364
|
render_trailer(output)
|
346
|
-
|
347
|
-
|
348
|
-
|
365
|
+
if output.instance_of?(StringIO)
|
366
|
+
str = output.string
|
367
|
+
str.force_encoding(::Encoding::ASCII_8BIT)
|
368
|
+
return str
|
369
|
+
else
|
370
|
+
return nil
|
371
|
+
end
|
349
372
|
end
|
350
373
|
|
351
374
|
# Renders the PDF document to file.
|
@@ -353,8 +376,7 @@ module Prawn
|
|
353
376
|
# pdf.render_file "foo.pdf"
|
354
377
|
#
|
355
378
|
def render_file(filename)
|
356
|
-
|
357
|
-
File.open(filename,mode) { |f| f << render }
|
379
|
+
File.open(filename, "wb") { |f| render(f) }
|
358
380
|
end
|
359
381
|
|
360
382
|
# The bounds method returns the current bounding box you are currently in,
|
@@ -388,6 +410,13 @@ module Prawn
|
|
388
410
|
@bounding_box
|
389
411
|
end
|
390
412
|
|
413
|
+
# Returns the innermost non-stretchy bounding box.
|
414
|
+
#
|
415
|
+
# @private
|
416
|
+
def reference_bounds
|
417
|
+
@bounding_box.reference_bounds
|
418
|
+
end
|
419
|
+
|
391
420
|
# Sets Document#bounds to the BoundingBox provided. See above for a brief
|
392
421
|
# description of what a bounding box is. This function is useful if you
|
393
422
|
# really need to change the bounding box manually, but usually, just entering
|
@@ -469,47 +498,6 @@ module Prawn
|
|
469
498
|
bounds.indent(left, right, &block)
|
470
499
|
end
|
471
500
|
|
472
|
-
|
473
|
-
def mask(*fields) # :nodoc:
|
474
|
-
# Stores the current state of the named attributes, executes the block, and
|
475
|
-
# then restores the original values after the block has executed.
|
476
|
-
# -- I will remove the nodoc if/when this feature is a little less hacky
|
477
|
-
stored = {}
|
478
|
-
fields.each { |f| stored[f] = send(f) }
|
479
|
-
yield
|
480
|
-
fields.each { |f| send("#{f}=", stored[f]) }
|
481
|
-
end
|
482
|
-
|
483
|
-
# Attempts to group the given block vertically within the current context.
|
484
|
-
# First attempts to render it in the current position on the current page.
|
485
|
-
# If that attempt overflows, it is tried anew after starting a new context
|
486
|
-
# (page or column). Returns a logically true value if the content fits in
|
487
|
-
# one page/column, false if a new page or column was needed.
|
488
|
-
#
|
489
|
-
# Raises CannotGroup if the provided content is too large to fit alone in
|
490
|
-
# the current page or column.
|
491
|
-
#
|
492
|
-
def group(second_attempt=false)
|
493
|
-
old_bounding_box = @bounding_box
|
494
|
-
@bounding_box = SimpleDelegator.new(@bounding_box)
|
495
|
-
|
496
|
-
def @bounding_box.move_past_bottom
|
497
|
-
raise RollbackTransaction
|
498
|
-
end
|
499
|
-
|
500
|
-
success = transaction { yield }
|
501
|
-
|
502
|
-
@bounding_box = old_bounding_box
|
503
|
-
|
504
|
-
unless success
|
505
|
-
raise Prawn::Errors::CannotGroup if second_attempt
|
506
|
-
old_bounding_box.move_past_bottom
|
507
|
-
group(second_attempt=true) { yield }
|
508
|
-
end
|
509
|
-
|
510
|
-
success
|
511
|
-
end
|
512
|
-
|
513
501
|
# Places a text box on specified pages for page numbering. This should be called
|
514
502
|
# towards the end of document creation, after all your content is already in
|
515
503
|
# place. In your template string, <page> refers to the current page, and
|
@@ -518,15 +506,15 @@ module Prawn
|
|
518
506
|
# through existing pages after they are created.
|
519
507
|
#
|
520
508
|
# Parameters are:
|
521
|
-
#
|
522
|
-
# <tt>string</tt>:: Template string for page number wording.
|
509
|
+
#
|
510
|
+
# <tt>string</tt>:: Template string for page number wording.
|
523
511
|
# Should include '<page>' and, optionally, '<total>'.
|
524
512
|
# <tt>options</tt>:: A hash for page numbering and text box options.
|
525
|
-
# <tt>:page_filter</tt>:: A filter to specify which pages to place page numbers on.
|
513
|
+
# <tt>:page_filter</tt>:: A filter to specify which pages to place page numbers on.
|
526
514
|
# Refer to the method 'page_match?'
|
527
515
|
# <tt>:start_count_at</tt>:: The starting count to increment pages from.
|
528
516
|
# <tt>:total_pages</tt>:: If provided, will replace <total> with the value given.
|
529
|
-
# Useful to override the total number of pages when using
|
517
|
+
# Useful to override the total number of pages when using
|
530
518
|
# the start_count_at option.
|
531
519
|
# <tt>:color</tt>:: Text fill color.
|
532
520
|
#
|
@@ -537,7 +525,7 @@ module Prawn
|
|
537
525
|
# five.
|
538
526
|
#
|
539
527
|
# Prawn::Document.generate("page_with_numbering.pdf") do
|
540
|
-
# number_pages "<page> in a total of <total>",
|
528
|
+
# number_pages "<page> in a total of <total>",
|
541
529
|
# {:start_count_at => 5,
|
542
530
|
# :page_filter => lambda{ |pg| pg != 1 },
|
543
531
|
# :at => [bounds.right - 50, 0],
|
@@ -548,12 +536,16 @@ module Prawn
|
|
548
536
|
def number_pages(string, options={})
|
549
537
|
opts = options.dup
|
550
538
|
start_count_at = opts.delete(:start_count_at).to_i
|
551
|
-
page_filter = opts.
|
539
|
+
page_filter = if opts.has_key?(:page_filter)
|
540
|
+
opts.delete(:page_filter)
|
541
|
+
else
|
542
|
+
:all
|
543
|
+
end
|
552
544
|
total_pages = opts.delete(:total_pages)
|
553
545
|
txtcolor = opts.delete(:color)
|
554
546
|
# An explicit height so that we can draw page numbers in the margins
|
555
|
-
opts[:height] = 50
|
556
|
-
|
547
|
+
opts[:height] = 50 unless opts.has_key?(:height)
|
548
|
+
|
557
549
|
start_count = false
|
558
550
|
pseudopage = 0
|
559
551
|
(1..page_count).each do |p|
|
@@ -564,7 +556,7 @@ module Prawn
|
|
564
556
|
else
|
565
557
|
start_count_at.to_i
|
566
558
|
end
|
567
|
-
end
|
559
|
+
end
|
568
560
|
if page_match?(page_filter, p)
|
569
561
|
go_to_page(p)
|
570
562
|
# have to use fill_color here otherwise text reverts back to default fill color
|
@@ -573,13 +565,53 @@ module Prawn
|
|
573
565
|
str = string.gsub("<page>","#{pseudopage}").gsub("<total>","#{total_pages}")
|
574
566
|
text_box str, opts
|
575
567
|
start_count = true # increment page count as soon as first match found
|
576
|
-
end
|
568
|
+
end
|
577
569
|
pseudopage += 1 if start_count
|
578
570
|
end
|
579
571
|
end
|
580
572
|
|
573
|
+
# Returns true if content streams will be compressed before rendering,
|
574
|
+
# false otherwise
|
575
|
+
#
|
576
|
+
def compression_enabled?
|
577
|
+
!!state.compress
|
578
|
+
end
|
579
|
+
|
580
|
+
# @group Experimental API
|
581
|
+
|
582
|
+
# Attempts to group the given block vertically within the current context.
|
583
|
+
# First attempts to render it in the current position on the current page.
|
584
|
+
# If that attempt overflows, it is tried anew after starting a new context
|
585
|
+
# (page or column). Returns a logically true value if the content fits in
|
586
|
+
# one page/column, false if a new page or column was needed.
|
587
|
+
#
|
588
|
+
# Raises CannotGroup if the provided content is too large to fit alone in
|
589
|
+
# the current page or column.
|
590
|
+
#
|
591
|
+
def group(second_attempt=false)
|
592
|
+
old_bounding_box = @bounding_box
|
593
|
+
@bounding_box = SimpleDelegator.new(@bounding_box)
|
594
|
+
|
595
|
+
# @private
|
596
|
+
def @bounding_box.move_past_bottom
|
597
|
+
raise RollbackTransaction
|
598
|
+
end
|
599
|
+
|
600
|
+
success = transaction { yield }
|
601
|
+
|
602
|
+
@bounding_box = old_bounding_box
|
603
|
+
|
604
|
+
unless success
|
605
|
+
raise Prawn::Errors::CannotGroup if second_attempt
|
606
|
+
old_bounding_box.move_past_bottom
|
607
|
+
group(second_attempt=true) { yield }
|
608
|
+
end
|
609
|
+
|
610
|
+
success
|
611
|
+
end
|
612
|
+
|
581
613
|
# Provides a way to execute a block of code repeatedly based on a
|
582
|
-
# page_filter.
|
614
|
+
# page_filter.
|
583
615
|
#
|
584
616
|
# Available page filters are:
|
585
617
|
# :all repeats on every page
|
@@ -587,7 +619,7 @@ module Prawn
|
|
587
619
|
# :even repeats on even pages
|
588
620
|
# some_array repeats on every page listed in the array
|
589
621
|
# some_range repeats on every page included in the range
|
590
|
-
# some_lambda yields page number and repeats for true return values
|
622
|
+
# some_lambda yields page number and repeats for true return values
|
591
623
|
def page_match?(page_filter, page_number)
|
592
624
|
case page_filter
|
593
625
|
when :all
|
@@ -601,25 +633,47 @@ module Prawn
|
|
601
633
|
when Proc
|
602
634
|
page_filter.call(page_number)
|
603
635
|
end
|
604
|
-
end
|
636
|
+
end
|
605
637
|
|
638
|
+
# @private
|
639
|
+
|
640
|
+
def mask(*fields)
|
641
|
+
# Stores the current state of the named attributes, executes the block, and
|
642
|
+
# then restores the original values after the block has executed.
|
643
|
+
# -- I will remove the nodoc if/when this feature is a little less hacky
|
644
|
+
stored = {}
|
645
|
+
fields.each { |f| stored[f] = send(f) }
|
646
|
+
yield
|
647
|
+
fields.each { |f| send("#{f}=", stored[f]) }
|
648
|
+
end
|
606
649
|
|
607
|
-
#
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
650
|
+
# @group Extension API
|
651
|
+
|
652
|
+
def initialize_first_page(options)
|
653
|
+
if options[:skip_page_creation]
|
654
|
+
start_new_page(options.merge(:orphan => true))
|
655
|
+
else
|
656
|
+
start_new_page(options)
|
657
|
+
end
|
612
658
|
end
|
613
659
|
|
614
|
-
|
660
|
+
## Internals. Don't depend on them!
|
615
661
|
|
616
|
-
|
617
|
-
|
618
|
-
|
662
|
+
# @private
|
663
|
+
def state
|
664
|
+
@internal_state
|
619
665
|
end
|
620
666
|
|
667
|
+
# @private
|
668
|
+
def page
|
669
|
+
state.page
|
670
|
+
end
|
671
|
+
|
672
|
+
private
|
673
|
+
|
674
|
+
|
621
675
|
# setting override_settings to true ensures that a new graphic state does not end up using
|
622
|
-
# previous settings
|
676
|
+
# previous settings.
|
623
677
|
def use_graphic_settings(override_settings = false)
|
624
678
|
set_fill_color if current_fill_color != "000000" || override_settings
|
625
679
|
set_stroke_color if current_stroke_color != "000000" || override_settings
|
@@ -642,7 +696,7 @@ module Prawn
|
|
642
696
|
)
|
643
697
|
|
644
698
|
# This check maintains indentation settings across page breaks
|
645
|
-
if
|
699
|
+
if old_margin_box
|
646
700
|
@margin_box.add_left_padding(old_margin_box.total_left_padding)
|
647
701
|
@margin_box.add_right_padding(old_margin_box.total_right_padding)
|
648
702
|
end
|
@@ -671,8 +725,10 @@ module Prawn
|
|
671
725
|
state.page.margins[side] = margin
|
672
726
|
end
|
673
727
|
end
|
728
|
+
end
|
674
729
|
|
675
|
-
|
730
|
+
def font_metric_cache #:nodoc:
|
731
|
+
@font_metric_cache ||= FontMetricCache.new( self )
|
676
732
|
end
|
677
733
|
end
|
678
734
|
end
|
data/lib/prawn/encoding.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
6
6
|
#
|
7
7
|
module Prawn
|
8
|
-
module Encoding
|
8
|
+
module Encoding # @private
|
9
9
|
# Map between unicode and WinAnsiEnoding
|
10
10
|
#
|
11
11
|
class WinAnsi #:nodoc:
|
@@ -18,7 +18,7 @@ module Prawn
|
|
18
18
|
.notdef .notdef .notdef .notdef
|
19
19
|
.notdef .notdef .notdef .notdef
|
20
20
|
.notdef .notdef .notdef .notdef
|
21
|
-
|
21
|
+
|
22
22
|
space exclam quotedbl numbersign
|
23
23
|
dollar percent ampersand quotesingle
|
24
24
|
parenleft parenright asterisk plus
|
@@ -54,7 +54,7 @@ module Prawn
|
|
54
54
|
quotedblright bullet endash emdash
|
55
55
|
tilde trademark scaron guilsinglright
|
56
56
|
oe .notdef zcaron ydieresis
|
57
|
-
|
57
|
+
|
58
58
|
space exclamdown cent sterling
|
59
59
|
currency yen brokenbar section
|
60
60
|
dieresis copyright ordfeminine guillemotleft
|
@@ -81,10 +81,10 @@ module Prawn
|
|
81
81
|
ocircumflex otilde odieresis divide
|
82
82
|
oslash ugrave uacute ucircumflex
|
83
83
|
udieresis yacute thorn ydieresis
|
84
|
-
]
|
85
|
-
|
84
|
+
]
|
85
|
+
|
86
86
|
def initialize
|
87
|
-
@mapping_file = "#{Prawn::
|
87
|
+
@mapping_file = "#{Prawn::DATADIR}/encodings/win_ansi.txt"
|
88
88
|
load_mapping if self.class.mapping.empty?
|
89
89
|
end
|
90
90
|
|
@@ -100,7 +100,7 @@ module Prawn
|
|
100
100
|
# Replace anything else with an underscore
|
101
101
|
self.class.mapping[codepoint] || 95
|
102
102
|
end
|
103
|
-
|
103
|
+
|
104
104
|
def self.mapping
|
105
105
|
@mapping ||= {}
|
106
106
|
end
|
@@ -108,10 +108,9 @@ module Prawn
|
|
108
108
|
private
|
109
109
|
|
110
110
|
def load_mapping
|
111
|
-
|
112
|
-
File.open(@mapping_file, mode) do |f|
|
111
|
+
File.open(@mapping_file, "r:BINARY") do |f|
|
113
112
|
f.each do |l|
|
114
|
-
|
113
|
+
_, single_byte, unicode = *l.match(/([0-9A-Za-z]+);([0-9A-F]{4})/)
|
115
114
|
self.class.mapping["0x#{unicode}".hex] = "0x#{single_byte}".hex if single_byte
|
116
115
|
end
|
117
116
|
end
|