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/text.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# text.rb : Implements PDF text primitives
|
4
4
|
#
|
@@ -6,24 +6,24 @@
|
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
|
9
|
-
require
|
9
|
+
require 'zlib'
|
10
10
|
|
11
|
-
require_relative
|
12
|
-
require_relative
|
13
|
-
require_relative "text/box"
|
11
|
+
require_relative 'text/formatted'
|
12
|
+
require_relative 'text/box'
|
14
13
|
|
15
14
|
module Prawn
|
16
15
|
module Text
|
17
|
-
|
18
16
|
include PDF::Core::Text
|
19
17
|
include Prawn::Text::Formatted
|
20
18
|
|
21
19
|
# No-Break Space
|
22
|
-
|
20
|
+
NBSP = "\u00A0"
|
23
21
|
# Zero Width Space (indicate word boundaries without a space)
|
24
|
-
|
22
|
+
ZWSP = "\u200B"
|
25
23
|
# Soft Hyphen (invisible, except when causing a line break)
|
26
|
-
|
24
|
+
SHY = "\u00AD"
|
25
|
+
|
26
|
+
# @group Stable API
|
27
27
|
|
28
28
|
# If you want text to flow onto a new page or between columns, this is the
|
29
29
|
# method to use. If, instead, if you want to place bounded text outside of
|
@@ -97,11 +97,6 @@ module Prawn
|
|
97
97
|
# <tt>\<link></link></tt>::
|
98
98
|
# with the following attributes
|
99
99
|
# <tt>href="http://example.com"</tt>:: an external link
|
100
|
-
# <tt>anchor="ToC"</tt>::
|
101
|
-
# where the value of the anchor attribute is the name of a
|
102
|
-
# destination that has already been or will be registered
|
103
|
-
# using PDF::Core::Destinations#add_dest. A clickable link
|
104
|
-
# will be created to that destination.
|
105
100
|
# Note that you must explicitly underline and color using the
|
106
101
|
# appropriate tags if you which to draw attention to the link
|
107
102
|
#
|
@@ -118,7 +113,7 @@ module Prawn
|
|
118
113
|
# the current font familly. [current style]
|
119
114
|
# <tt>:indent_paragraphs</tt>:: <tt>number</tt>. The amount to indent the
|
120
115
|
# first line of each paragraph. Omit this
|
121
|
-
# option if you do not want indenting
|
116
|
+
# option if you do not want indenting.
|
122
117
|
# <tt>:direction</tt>::
|
123
118
|
# <tt>:ltr</tt>, <tt>:rtl</tt>, Direction of the text (left-to-right
|
124
119
|
# or right-to-left) [value of document.text_direction]
|
@@ -142,9 +137,9 @@ module Prawn
|
|
142
137
|
# each line is included below the last line;
|
143
138
|
# otherwise, document.y is placed just below the
|
144
139
|
# descender of the last line printed [true]
|
145
|
-
# <tt>:mode</tt>:: The text rendering mode to use. Use this to specify if
|
146
|
-
# text should render with the fill color, stroke color
|
147
|
-
# both. See the comments to text_rendering_mode() to see
|
140
|
+
# <tt>:mode</tt>:: The text rendering mode to use. Use this to specify if
|
141
|
+
# the text should render with the fill color, stroke color
|
142
|
+
# or both. See the comments to text_rendering_mode() to see
|
148
143
|
# a list of valid options. [0]
|
149
144
|
#
|
150
145
|
# == Exceptions
|
@@ -154,23 +149,24 @@ module Prawn
|
|
154
149
|
# Raises <tt>Prawn::Errrors::CannotFit</tt> if not wide enough to print
|
155
150
|
# any text
|
156
151
|
#
|
157
|
-
def text(string, options={})
|
152
|
+
def text(string, options = {})
|
158
153
|
return false if string.nil?
|
154
|
+
|
159
155
|
# we modify the options. don't change the user's hash
|
160
156
|
options = options.dup
|
161
157
|
|
162
|
-
|
158
|
+
p = options[:inline_format]
|
159
|
+
if p
|
163
160
|
p = [] unless p.is_a?(Array)
|
164
161
|
options.delete(:inline_format)
|
165
|
-
array =
|
162
|
+
array = text_formatter.format(string, *p)
|
166
163
|
else
|
167
|
-
array = [{ :
|
164
|
+
array = [{ text: string }]
|
168
165
|
end
|
169
166
|
|
170
167
|
formatted_text(array, options)
|
171
168
|
end
|
172
169
|
|
173
|
-
|
174
170
|
# Draws formatted text to the page.
|
175
171
|
# Formatted text is comprised of an array of hashes, where each hash defines
|
176
172
|
# text and format information. See Text::Formatted#formatted_text_box for
|
@@ -191,37 +187,33 @@ module Prawn
|
|
191
187
|
#
|
192
188
|
# Same as for #text
|
193
189
|
#
|
194
|
-
def formatted_text(array, options={})
|
190
|
+
def formatted_text(array, options = {})
|
195
191
|
options = inspect_options_for_text(options.dup)
|
196
192
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
193
|
+
color = options.delete(:color)
|
194
|
+
if color
|
195
|
+
array =
|
196
|
+
array.map do |fragment|
|
197
|
+
fragment[:color] ? fragment : fragment.merge(color: color)
|
198
|
+
end
|
201
199
|
end
|
202
200
|
|
203
201
|
if @indent_paragraphs
|
204
|
-
|
205
|
-
options[:skip_encoding] = false
|
202
|
+
text_formatter.array_paragraphs(array).each do |paragraph|
|
206
203
|
remaining_text = draw_indented_formatted_line(paragraph, options)
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
unless @all_text_printed
|
212
|
-
@bounding_box.move_past_bottom
|
213
|
-
options[:skip_encoding] = false
|
214
|
-
remaining_text = draw_indented_formatted_line(paragraph, options)
|
215
|
-
options[:skip_encoding] = true
|
216
|
-
end
|
204
|
+
|
205
|
+
if @no_text_printed && !@all_text_printed
|
206
|
+
@bounding_box.move_past_bottom
|
207
|
+
remaining_text = draw_indented_formatted_line(paragraph, options)
|
217
208
|
end
|
218
209
|
|
219
|
-
|
220
|
-
|
210
|
+
unless @all_text_printed
|
211
|
+
remaining_text = fill_formatted_text_box(remaining_text, options)
|
212
|
+
draw_remaining_formatted_text_on_new_pages(remaining_text, options)
|
213
|
+
end
|
221
214
|
end
|
222
215
|
else
|
223
216
|
remaining_text = fill_formatted_text_box(array, options)
|
224
|
-
options[:skip_encoding] = true
|
225
217
|
draw_remaining_formatted_text_on_new_pages(remaining_text, options)
|
226
218
|
end
|
227
219
|
end
|
@@ -245,7 +237,8 @@ module Prawn
|
|
245
237
|
# == Rotation
|
246
238
|
#
|
247
239
|
# Text can be rotated before it is placed on the canvas by specifying the
|
248
|
-
# <tt>:rotate</tt> option with a given angle. Rotation occurs
|
240
|
+
# <tt>:rotate</tt> option with a given angle. Rotation occurs
|
241
|
+
# counter-clockwise.
|
249
242
|
#
|
250
243
|
# == Encoding
|
251
244
|
#
|
@@ -262,7 +255,8 @@ module Prawn
|
|
262
255
|
#
|
263
256
|
# == Options (default values marked in [])
|
264
257
|
#
|
265
|
-
# <tt>:at</tt>:: <tt>[x, y]</tt>(required). The position at which to start
|
258
|
+
# <tt>:at</tt>:: <tt>[x, y]</tt>(required). The position at which to start
|
259
|
+
# the text
|
266
260
|
# <tt>:kerning</tt>:: <tt>boolean</tt>. Whether or not to use kerning (if it
|
267
261
|
# is available with the current font)
|
268
262
|
# [value of default_kerning?]
|
@@ -286,11 +280,29 @@ module Prawn
|
|
286
280
|
text = text.to_s.dup
|
287
281
|
save_font do
|
288
282
|
process_text_options(options)
|
289
|
-
font.normalize_encoding
|
283
|
+
text = font.normalize_encoding(text)
|
290
284
|
font_size(options[:size]) { draw_text!(text, options) }
|
291
285
|
end
|
292
286
|
end
|
293
287
|
|
288
|
+
# Low level text placement method. All font and size alterations
|
289
|
+
# should already be set
|
290
|
+
#
|
291
|
+
def draw_text!(text, options)
|
292
|
+
unless font.unicode? || font.class.hide_m17n_warning || text.ascii_only?
|
293
|
+
warn "PDF's built-in fonts have very limited support for " \
|
294
|
+
"internationalized text.\nIf you need full UTF-8 support, " \
|
295
|
+
"consider using an external font instead.\n\nTo disable this " \
|
296
|
+
"warning, add the following line to your code:\n" \
|
297
|
+
"Prawn::Fonts::AFM.hide_m17n_warning = true\n"
|
298
|
+
|
299
|
+
font.class.hide_m17n_warning = true
|
300
|
+
end
|
301
|
+
|
302
|
+
x, y = map_to_absolute(options[:at])
|
303
|
+
add_text_content(text, x, y, options)
|
304
|
+
end
|
305
|
+
|
294
306
|
# Gets height of text in PDF points.
|
295
307
|
# Same options as #text, except as noted.
|
296
308
|
# Not compatible with :indent_paragraphs option
|
@@ -307,8 +319,8 @@ module Prawn
|
|
307
319
|
# Raises <tt>Prawn::Errrors::CannotFit</tt> if not wide enough to print
|
308
320
|
# any text
|
309
321
|
#
|
310
|
-
def height_of(string, options={})
|
311
|
-
height_of_formatted([{ :
|
322
|
+
def height_of(string, options = {})
|
323
|
+
height_of_formatted([{ text: string }], options)
|
312
324
|
end
|
313
325
|
|
314
326
|
# Gets height of formatted text in PDF points.
|
@@ -321,16 +333,17 @@ module Prawn
|
|
321
333
|
# :size => 24,
|
322
334
|
# :styles => [:bold, :italic] }])
|
323
335
|
#
|
324
|
-
def height_of_formatted(array, options={})
|
336
|
+
def height_of_formatted(array, options = {})
|
325
337
|
if options[:indent_paragraphs]
|
326
|
-
raise NotImplementedError,
|
327
|
-
|
338
|
+
raise NotImplementedError,
|
339
|
+
':indent_paragraphs option not available with height_of'
|
328
340
|
end
|
329
341
|
process_final_gap_option(options)
|
330
|
-
box = Text::Formatted::Box.new(
|
331
|
-
|
332
|
-
|
333
|
-
|
342
|
+
box = Text::Formatted::Box.new(
|
343
|
+
array,
|
344
|
+
options.merge(height: 100_000_000, document: self)
|
345
|
+
)
|
346
|
+
box.render(dry_run: true)
|
334
347
|
|
335
348
|
height = box.height
|
336
349
|
height += box.line_gap + box.leading if @final_gap
|
@@ -340,7 +353,7 @@ module Prawn
|
|
340
353
|
private
|
341
354
|
|
342
355
|
def draw_remaining_formatted_text_on_new_pages(remaining_text, options)
|
343
|
-
|
356
|
+
until remaining_text.empty?
|
344
357
|
@bounding_box.move_past_bottom
|
345
358
|
previous_remaining_text = remaining_text
|
346
359
|
remaining_text = fill_formatted_text_box(remaining_text, options)
|
@@ -349,8 +362,15 @@ module Prawn
|
|
349
362
|
end
|
350
363
|
|
351
364
|
def draw_indented_formatted_line(string, options)
|
352
|
-
|
353
|
-
|
365
|
+
gap =
|
366
|
+
if options.fetch(:direction, text_direction) == :ltr
|
367
|
+
[@indent_paragraphs, 0]
|
368
|
+
else
|
369
|
+
[0, @indent_paragraphs]
|
370
|
+
end
|
371
|
+
|
372
|
+
indent(*gap) do
|
373
|
+
fill_formatted_text_box(string, options.dup.merge(single_line: true))
|
354
374
|
end
|
355
375
|
end
|
356
376
|
|
@@ -368,33 +388,41 @@ module Prawn
|
|
368
388
|
end
|
369
389
|
|
370
390
|
def merge_text_box_positioning_options(options)
|
371
|
-
bottom =
|
372
|
-
|
391
|
+
bottom =
|
392
|
+
if @bounding_box.stretchy?
|
393
|
+
@margin_box.absolute_bottom
|
394
|
+
else
|
395
|
+
@bounding_box.absolute_bottom
|
396
|
+
end
|
373
397
|
|
374
398
|
options[:height] = y - bottom
|
375
399
|
options[:width] = bounds.width
|
376
|
-
options[:at] = [
|
377
|
-
|
400
|
+
options[:at] = [
|
401
|
+
@bounding_box.left_side - @bounding_box.absolute_left,
|
402
|
+
y - @bounding_box.absolute_bottom
|
403
|
+
]
|
378
404
|
end
|
379
405
|
|
380
406
|
def inspect_options_for_draw_text(options)
|
381
407
|
if options[:at].nil?
|
382
|
-
raise ArgumentError,
|
408
|
+
raise ArgumentError, 'The :at option is required for draw_text'
|
383
409
|
elsif options[:align]
|
384
|
-
raise ArgumentError,
|
410
|
+
raise ArgumentError, 'The :align option does not work with draw_text'
|
385
411
|
end
|
386
|
-
|
412
|
+
|
413
|
+
if options[:kerning].nil?
|
387
414
|
options[:kerning] = default_kerning?
|
388
415
|
end
|
389
|
-
valid_options = PDF::Core::Text::VALID_OPTIONS + [
|
416
|
+
valid_options = PDF::Core::Text::VALID_OPTIONS + %i[at rotate]
|
390
417
|
Prawn.verify_options(valid_options, options)
|
391
418
|
options
|
392
419
|
end
|
393
420
|
|
394
421
|
def inspect_options_for_text(options)
|
395
422
|
if options[:at]
|
396
|
-
raise ArgumentError,
|
397
|
-
|
423
|
+
raise ArgumentError,
|
424
|
+
':at is no longer a valid option with text.' \
|
425
|
+
'use draw_text or text_box instead'
|
398
426
|
end
|
399
427
|
process_final_gap_option(options)
|
400
428
|
process_indent_paragraphs_option(options)
|
@@ -412,13 +440,17 @@ module Prawn
|
|
412
440
|
options.delete(:indent_paragraphs)
|
413
441
|
end
|
414
442
|
|
415
|
-
def move_text_position(
|
416
|
-
bottom =
|
417
|
-
|
443
|
+
def move_text_position(amount)
|
444
|
+
bottom =
|
445
|
+
if @bounding_box.stretchy?
|
446
|
+
@margin_box.absolute_bottom
|
447
|
+
else
|
448
|
+
@bounding_box.absolute_bottom
|
449
|
+
end
|
418
450
|
|
419
|
-
@bounding_box.move_past_bottom if (y -
|
451
|
+
@bounding_box.move_past_bottom if (y - amount) < bottom
|
420
452
|
|
421
|
-
self.y -=
|
453
|
+
self.y -= amount
|
422
454
|
end
|
423
455
|
end
|
424
456
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# transformation_stack.rb : Stores the transformations that have been applied to
|
4
|
+
# the document
|
5
|
+
#
|
6
|
+
# Copyright 2015, Roger Nesbitt. All Rights Reserved.
|
7
|
+
#
|
8
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
9
|
+
|
10
|
+
require 'matrix'
|
11
|
+
|
12
|
+
# rubocop: disable Metrics/ParameterLists, Naming/MethodParameterName
|
13
|
+
module Prawn
|
14
|
+
module TransformationStack
|
15
|
+
def add_to_transformation_stack(a, b, c, d, e, f)
|
16
|
+
@transformation_stack ||= [[]]
|
17
|
+
@transformation_stack.last.push([a, b, c, d, e, f].map(&:to_f))
|
18
|
+
end
|
19
|
+
|
20
|
+
def save_transformation_stack
|
21
|
+
@transformation_stack ||= [[]]
|
22
|
+
@transformation_stack.push(@transformation_stack.last.dup)
|
23
|
+
end
|
24
|
+
|
25
|
+
def restore_transformation_stack
|
26
|
+
@transformation_stack&.pop
|
27
|
+
end
|
28
|
+
|
29
|
+
def current_transformation_matrix_with_translation(x = 0, y = 0)
|
30
|
+
transformations = (@transformation_stack || [[]]).last
|
31
|
+
|
32
|
+
matrix = Matrix.identity(3)
|
33
|
+
|
34
|
+
transformations.each do |a, b, c, d, e, f|
|
35
|
+
matrix *= Matrix[[a, c, e], [b, d, f], [0, 0, 1]]
|
36
|
+
end
|
37
|
+
|
38
|
+
matrix *= Matrix[[1, 0, x], [0, 1, y], [0, 0, 1]]
|
39
|
+
|
40
|
+
matrix.to_a[0..1].transpose.flatten
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
# rubocop: enable Metrics/ParameterLists, Naming/MethodParameterName
|
data/lib/prawn/utilities.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# utilities.rb : General-purpose utility classes which don't fit anywhere else
|
4
4
|
#
|
@@ -6,39 +6,29 @@
|
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
|
9
|
-
require 'thread'
|
10
|
-
|
11
9
|
module Prawn
|
12
|
-
|
13
|
-
#
|
14
|
-
# In some cases, caching and reusing results can not only save CPU cycles but
|
15
|
-
#
|
10
|
+
# Throughout the Prawn codebase, repeated calculations which can benefit from
|
11
|
+
# caching are made.
|
12
|
+
# In some cases, caching and reusing results can not only save CPU cycles but
|
13
|
+
# also greatly reduce memory requirements
|
16
14
|
# But at the same time, we don't want to throw away thread safety
|
17
15
|
# We have two interchangeable thread-safe cache implementations:
|
18
16
|
|
17
|
+
# @private
|
19
18
|
class SynchronizedCache
|
20
|
-
# As an optimization, this could access the hash directly on VMs with
|
19
|
+
# As an optimization, this could access the hash directly on VMs with
|
20
|
+
# a global interpreter lock (like MRI)
|
21
21
|
def initialize
|
22
22
|
@cache = {}
|
23
23
|
@mutex = Mutex.new
|
24
24
|
end
|
25
|
+
|
25
26
|
def [](key)
|
26
27
|
@mutex.synchronize { @cache[key] }
|
27
28
|
end
|
28
|
-
def []=(key,value)
|
29
|
-
@mutex.synchronize { @cache[key] = value }
|
30
|
-
end
|
31
|
-
end
|
32
29
|
|
33
|
-
|
34
|
-
|
35
|
-
@cache_id = "cache_#{self.object_id}".to_sym
|
36
|
-
end
|
37
|
-
def [](key)
|
38
|
-
(Thread.current[@cache_id] ||= {})[key]
|
39
|
-
end
|
40
|
-
def []=(key,value)
|
41
|
-
(Thread.current[@cache_id] ||= {})[key] = value
|
30
|
+
def []=(key, value)
|
31
|
+
@mutex.synchronize { @cache[key] = value }
|
42
32
|
end
|
43
33
|
end
|
44
34
|
end
|
data/lib/prawn/view.rb
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# prawn/view.rb : Implements a mixin for Prawn's DSL
|
4
|
+
#
|
5
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
6
|
+
|
7
|
+
module Prawn
|
8
|
+
# This mixin allows you to create modular Prawn code without the
|
9
|
+
# need to create subclasses of Prawn::Document.
|
10
|
+
#
|
11
|
+
# class Greeter
|
12
|
+
# include Prawn::View
|
13
|
+
#
|
14
|
+
# # Optional override: allows you to set document options or even use
|
15
|
+
# # a custom document class
|
16
|
+
# def document
|
17
|
+
# @document ||= Prawn::Document.new(page_size: 'A4')
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# def initialize(name)
|
21
|
+
# @name = name
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# def say_hello
|
25
|
+
# text "Hello, #{@name}!"
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# def say_goodbye
|
29
|
+
# font("Courier") do
|
30
|
+
# text "Goodbye, #{@name}!"
|
31
|
+
# end
|
32
|
+
# end
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
# greeter = Greeter.new("Gregory")
|
36
|
+
#
|
37
|
+
# greeter.say_hello
|
38
|
+
# greeter.say_goodbye
|
39
|
+
#
|
40
|
+
# greeter.save_as("greetings.pdf")
|
41
|
+
#
|
42
|
+
# The short story about why you should use this mixin rather than
|
43
|
+
# creating subclasses of +Prawn::Document+ is that it helps
|
44
|
+
# prevent accidental conflicts between your code and Prawn's
|
45
|
+
# code.
|
46
|
+
#
|
47
|
+
# Here's the slightly longer story...
|
48
|
+
#
|
49
|
+
# By using composition rather than inheritance under the hood, this
|
50
|
+
# mixin allows you to keep your state separate from +Prawn::Document+'s
|
51
|
+
# state, and also will prevent unexpected method name collisions due
|
52
|
+
# to late binding effects.
|
53
|
+
#
|
54
|
+
# This mixin is mostly meant for extending Prawn's functionality
|
55
|
+
# with your own additions, but you can also use it to replace or
|
56
|
+
# wrap existing Prawn methods. Calling +super+ will still work
|
57
|
+
# as expected, and alternatively you can explictly call
|
58
|
+
# +document.some_method+ to delegate to Prawn where needed.
|
59
|
+
module View
|
60
|
+
# @group Experimental API
|
61
|
+
|
62
|
+
# Lazily instantiates a +Prawn::Document+ object.
|
63
|
+
#
|
64
|
+
# You can also redefine this method in your own classes to use
|
65
|
+
# a custom document class.
|
66
|
+
def document
|
67
|
+
@document ||= Prawn::Document.new
|
68
|
+
end
|
69
|
+
|
70
|
+
# Delegates all unhandled calls to object returned by +document+ method.
|
71
|
+
# (which is an instance of Prawn::Document by default)
|
72
|
+
def method_missing(method_name, *arguments, &block)
|
73
|
+
return super unless document.respond_to?(method_name)
|
74
|
+
|
75
|
+
document.public_send(method_name, *arguments, &block)
|
76
|
+
end
|
77
|
+
|
78
|
+
def respond_to_missing?(method_name, _include_all = false)
|
79
|
+
document.respond_to?(method_name) || super
|
80
|
+
end
|
81
|
+
|
82
|
+
# Syntactic sugar that uses +instance_eval+ under the hood to provide
|
83
|
+
# a block-based DSL.
|
84
|
+
#
|
85
|
+
# greeter.update do
|
86
|
+
# say_hello
|
87
|
+
# say_goodbye
|
88
|
+
# end
|
89
|
+
#
|
90
|
+
def update(&block)
|
91
|
+
instance_eval(&block)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Syntatic sugar that calls +document.render_file+ under the hood.
|
95
|
+
#
|
96
|
+
# greeter.save_as("greetings.pdf")
|
97
|
+
def save_as(filename)
|
98
|
+
document.render_file(filename)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|