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/font.rb
CHANGED
@@ -1,19 +1,17 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# font.rb : The Prawn font class
|
4
4
|
#
|
5
5
|
# Copyright May 2008, Gregory Brown / James Healy. All Rights Reserved.
|
6
6
|
#
|
7
7
|
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
8
|
#
|
9
|
-
|
10
|
-
require "prawn/font/ttf"
|
11
|
-
require "prawn/font/dfont"
|
12
|
-
require "prawn/font_metric_cache"
|
9
|
+
require_relative 'font_metric_cache'
|
13
10
|
|
14
11
|
module Prawn
|
15
|
-
|
16
12
|
class Document
|
13
|
+
# @group Stable API
|
14
|
+
|
17
15
|
# Without arguments, this returns the currently selected font. Otherwise,
|
18
16
|
# it sets the current font. When a block is used, the font is applied
|
19
17
|
# transactionally and is rolled back when the block exits.
|
@@ -24,8 +22,8 @@ module Prawn
|
|
24
22
|
# font "Times-Roman"
|
25
23
|
# text "Now using Times-Roman"
|
26
24
|
#
|
27
|
-
# font("
|
28
|
-
# text "Using TTF font from file
|
25
|
+
# font("DejaVuSans.ttf") do
|
26
|
+
# text "Using TTF font from file DejaVuSans.ttf"
|
29
27
|
# font "Courier", :style => :bold
|
30
28
|
# text "You see this in bold Courier"
|
31
29
|
# end
|
@@ -34,8 +32,8 @@ module Prawn
|
|
34
32
|
# end
|
35
33
|
#
|
36
34
|
# The :name parameter must be a string. It can be one of the 14 built-in
|
37
|
-
# fonts supported by PDF, or the location of a TTF file. The
|
38
|
-
# array specifies the valid built in font values.
|
35
|
+
# fonts supported by PDF, or the location of a TTF file. The
|
36
|
+
# Fonts::AFM::BUILT_INS array specifies the valid built in font values.
|
39
37
|
#
|
40
38
|
# If a ttf font is specified, the glyphs necessary to render your document
|
41
39
|
# will be embedded in the rendered PDF. This should be your preferred option
|
@@ -43,11 +41,12 @@ module Prawn
|
|
43
41
|
# make it more portable.
|
44
42
|
#
|
45
43
|
# The options parameter is an optional hash providing size and style. To use
|
46
|
-
# the :style option you need to map those font styles to their respective
|
44
|
+
# the :style option you need to map those font styles to their respective
|
45
|
+
# font files.
|
47
46
|
# See font_families for more information.
|
48
47
|
#
|
49
|
-
def font(name=nil, options={})
|
50
|
-
return((defined?(@font) && @font) || font(
|
48
|
+
def font(name = nil, options = {})
|
49
|
+
return((defined?(@font) && @font) || font('Helvetica')) if name.nil?
|
51
50
|
|
52
51
|
if state.pages.empty? && !state.page.in_stamp_stream?
|
53
52
|
raise Prawn::Errors::NotOnPage
|
@@ -67,7 +66,10 @@ module Prawn
|
|
67
66
|
@font
|
68
67
|
end
|
69
68
|
|
69
|
+
# @method font_size(points=nil)
|
70
|
+
#
|
70
71
|
# When called with no argument, returns the current font size.
|
72
|
+
#
|
71
73
|
# When called with a single argument but no block, sets the current font
|
72
74
|
# size. When a block is used, the font size is applied transactionally and
|
73
75
|
# is rolled back when the block exits. You may still change the font size
|
@@ -90,18 +92,113 @@ module Prawn
|
|
90
92
|
# When called without an argument, this method returns the current font
|
91
93
|
# size.
|
92
94
|
#
|
93
|
-
def font_size(points=nil)
|
95
|
+
def font_size(points = nil)
|
94
96
|
return @font_size unless points
|
97
|
+
|
95
98
|
size_before_yield = @font_size
|
96
99
|
@font_size = points
|
97
100
|
block_given? ? yield : return
|
98
101
|
@font_size = size_before_yield
|
99
102
|
end
|
100
103
|
|
104
|
+
# Sets the font size
|
105
|
+
def font_size=(size)
|
106
|
+
font_size(size)
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns the width of the given string using the given font. If :size is
|
110
|
+
# not specified as one of the options, the string is measured using the
|
111
|
+
# current font size. You can also pass :kerning as an option to indicate
|
112
|
+
# whether kerning should be used when measuring the width (defaults to
|
113
|
+
# +false+).
|
114
|
+
#
|
115
|
+
# Note that the string _must_ be encoded properly for the font being used.
|
116
|
+
# For AFM fonts, this is WinAnsi. For TTF, make sure the font is encoded as
|
117
|
+
# UTF-8. You can use the Font#normalize_encoding method to make sure strings
|
118
|
+
# are in an encoding appropriate for the current font.
|
119
|
+
#--
|
120
|
+
# For the record, this method used to be a method of Font (and still
|
121
|
+
# delegates to width computations on Font). However, having the primary
|
122
|
+
# interface for calculating string widths exist on Font made it tricky to
|
123
|
+
# write extensions for Prawn in which widths are computed differently (e.g.,
|
124
|
+
# taking formatting tags into account, or the like).
|
125
|
+
#
|
126
|
+
# By putting width_of here, on Document itself, extensions may easily
|
127
|
+
# override it and redefine the width calculation behavior.
|
128
|
+
#++
|
129
|
+
def width_of(string, options = {})
|
130
|
+
if options.key? :inline_format
|
131
|
+
p = options[:inline_format]
|
132
|
+
p = [] unless p.is_a?(Array)
|
133
|
+
|
134
|
+
# Build up an Arranger with the entire string on one line, finalize it,
|
135
|
+
# and find its width.
|
136
|
+
arranger = Prawn::Text::Formatted::Arranger.new(self, options)
|
137
|
+
arranger.consumed = text_formatter.format(string, *p)
|
138
|
+
arranger.finalize_line
|
139
|
+
|
140
|
+
arranger.line_width
|
141
|
+
else
|
142
|
+
width_of_string(string, options)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# Hash that maps font family names to their styled individual font names.
|
147
|
+
#
|
148
|
+
# To add support for another font family, append to this hash, e.g:
|
149
|
+
#
|
150
|
+
# pdf.font_families.update(
|
151
|
+
# "MyTrueTypeFamily" => { :bold => "foo-bold.ttf",
|
152
|
+
# :italic => "foo-italic.ttf",
|
153
|
+
# :bold_italic => "foo-bold-italic.ttf",
|
154
|
+
# :normal => "foo.ttf" })
|
155
|
+
#
|
156
|
+
# This will then allow you to use the fonts like so:
|
157
|
+
#
|
158
|
+
# pdf.font("MyTrueTypeFamily", :style => :bold)
|
159
|
+
# pdf.text "Some bold text"
|
160
|
+
# pdf.font("MyTrueTypeFamily")
|
161
|
+
# pdf.text "Some normal text"
|
162
|
+
#
|
163
|
+
# This assumes that you have appropriate TTF fonts for each style you
|
164
|
+
# wish to support.
|
165
|
+
#
|
166
|
+
# By default the styles :bold, :italic, :bold_italic, and :normal are
|
167
|
+
# defined for fonts "Courier", "Times-Roman" and "Helvetica". When
|
168
|
+
# defining your own font families, you can map any or all of these
|
169
|
+
# styles to whatever font files you'd like.
|
170
|
+
#
|
171
|
+
def font_families
|
172
|
+
@font_families ||= {}.merge!(
|
173
|
+
'Courier' => {
|
174
|
+
bold: 'Courier-Bold',
|
175
|
+
italic: 'Courier-Oblique',
|
176
|
+
bold_italic: 'Courier-BoldOblique',
|
177
|
+
normal: 'Courier'
|
178
|
+
},
|
179
|
+
|
180
|
+
'Times-Roman' => {
|
181
|
+
bold: 'Times-Bold',
|
182
|
+
italic: 'Times-Italic',
|
183
|
+
bold_italic: 'Times-BoldItalic',
|
184
|
+
normal: 'Times-Roman'
|
185
|
+
},
|
186
|
+
|
187
|
+
'Helvetica' => {
|
188
|
+
bold: 'Helvetica-Bold',
|
189
|
+
italic: 'Helvetica-Oblique',
|
190
|
+
bold_italic: 'Helvetica-BoldOblique',
|
191
|
+
normal: 'Helvetica'
|
192
|
+
}
|
193
|
+
)
|
194
|
+
end
|
195
|
+
|
196
|
+
# @group Experimental API
|
197
|
+
|
101
198
|
# Sets the font directly, given an actual Font object
|
102
199
|
# and size.
|
103
200
|
#
|
104
|
-
def set_font(font, size=nil) # :nodoc:
|
201
|
+
def set_font(font, size = nil) # :nodoc:
|
105
202
|
@font = font
|
106
203
|
@font_size = size if size
|
107
204
|
end
|
@@ -110,7 +207,7 @@ module Prawn
|
|
110
207
|
# finishes, the original font is restored.
|
111
208
|
#
|
112
209
|
def save_font
|
113
|
-
@font ||= find_font(
|
210
|
+
@font ||= find_font('Helvetica')
|
114
211
|
original_font = @font
|
115
212
|
original_size = @font_size
|
116
213
|
|
@@ -120,31 +217,40 @@ module Prawn
|
|
120
217
|
end
|
121
218
|
|
122
219
|
# Looks up the given font using the given criteria. Once a font has been
|
123
|
-
# found by that matches the criteria, it will be cached to subsequent
|
124
|
-
# for that font will return the same object.
|
125
|
-
|
220
|
+
# found by that matches the criteria, it will be cached to subsequent
|
221
|
+
# lookups for that font will return the same object.
|
222
|
+
# --
|
126
223
|
# Challenges involved: the name alone is not sufficient to uniquely identify
|
127
224
|
# a font (think dfont suitcases that can hold multiple different fonts in a
|
128
225
|
# single file). Thus, the :name key is included in the cache key.
|
129
226
|
#
|
130
227
|
# It is further complicated, however, since fonts in some formats (like the
|
131
228
|
# dfont suitcases) can be identified either by numeric index, OR by their
|
132
|
-
# name within the suitcase, and both should hash to the same font object
|
133
|
-
#
|
134
|
-
# which means if someone selects a font both by name, and by
|
135
|
-
# font will be embedded twice. Since we do font subsetting, this
|
136
|
-
# embedding won't be catastrophic, just annoying.
|
229
|
+
# name within the suitcase, and both should hash to the same font object (to
|
230
|
+
# avoid the font being embedded multiple times). This is not yet
|
231
|
+
# implemented, which means if someone selects a font both by name, and by
|
232
|
+
# index, the font will be embedded twice. Since we do font subsetting, this
|
233
|
+
# double embedding won't be catastrophic, just annoying.
|
137
234
|
# ++
|
138
|
-
|
235
|
+
#
|
236
|
+
# @private
|
237
|
+
def find_font(name, options = {}) #:nodoc:
|
139
238
|
if font_families.key?(name)
|
140
|
-
family
|
239
|
+
family = name
|
240
|
+
name = font_families[name][options[:style] || :normal]
|
141
241
|
if name.is_a?(::Hash)
|
142
242
|
options = options.merge(name)
|
143
243
|
name = options[:file]
|
144
244
|
end
|
145
245
|
end
|
146
246
|
key = "#{name}:#{options[:font] || 0}"
|
147
|
-
|
247
|
+
|
248
|
+
if name.is_a? Prawn::Font
|
249
|
+
font_registry[key] = name
|
250
|
+
else
|
251
|
+
font_registry[key] ||=
|
252
|
+
Font.load(self, name, options.merge(family: family))
|
253
|
+
end
|
148
254
|
end
|
149
255
|
|
150
256
|
# Hash of Font objects keyed by names
|
@@ -153,89 +259,9 @@ module Prawn
|
|
153
259
|
@font_registry ||= {}
|
154
260
|
end
|
155
261
|
|
156
|
-
# Hash that maps font family names to their styled individual font names.
|
157
|
-
#
|
158
|
-
# To add support for another font family, append to this hash, e.g:
|
159
|
-
#
|
160
|
-
# pdf.font_families.update(
|
161
|
-
# "MyTrueTypeFamily" => { :bold => "foo-bold.ttf",
|
162
|
-
# :italic => "foo-italic.ttf",
|
163
|
-
# :bold_italic => "foo-bold-italic.ttf",
|
164
|
-
# :normal => "foo.ttf" })
|
165
|
-
#
|
166
|
-
# This will then allow you to use the fonts like so:
|
167
|
-
#
|
168
|
-
# pdf.font("MyTrueTypeFamily", :style => :bold)
|
169
|
-
# pdf.text "Some bold text"
|
170
|
-
# pdf.font("MyTrueTypeFamily")
|
171
|
-
# pdf.text "Some normal text"
|
172
|
-
#
|
173
|
-
# This assumes that you have appropriate TTF fonts for each style you
|
174
|
-
# wish to support.
|
175
|
-
#
|
176
|
-
# By default the styles :bold, :italic, :bold_italic, and :normal are
|
177
|
-
# defined for fonts "Courier", "Times-Roman" and "Helvetica".
|
178
|
-
#
|
179
|
-
# You probably want to provide those four styles, but are free to define
|
180
|
-
# custom ones, like :thin, and use them in font calls.
|
181
|
-
#
|
182
|
-
def font_families
|
183
|
-
@font_families ||= {}.merge!(
|
184
|
-
{ "Courier" => { :bold => "Courier-Bold",
|
185
|
-
:italic => "Courier-Oblique",
|
186
|
-
:bold_italic => "Courier-BoldOblique",
|
187
|
-
:normal => "Courier" },
|
188
|
-
|
189
|
-
"Times-Roman" => { :bold => "Times-Bold",
|
190
|
-
:italic => "Times-Italic",
|
191
|
-
:bold_italic => "Times-BoldItalic",
|
192
|
-
:normal => "Times-Roman" },
|
193
|
-
|
194
|
-
"Helvetica" => { :bold => "Helvetica-Bold",
|
195
|
-
:italic => "Helvetica-Oblique",
|
196
|
-
:bold_italic => "Helvetica-BoldOblique",
|
197
|
-
:normal => "Helvetica" }
|
198
|
-
})
|
199
|
-
end
|
200
|
-
|
201
|
-
# Returns the width of the given string using the given font. If :size is not
|
202
|
-
# specified as one of the options, the string is measured using the current
|
203
|
-
# font size. You can also pass :kerning as an option to indicate whether
|
204
|
-
# kerning should be used when measuring the width (defaults to +false+).
|
205
|
-
#
|
206
|
-
# Note that the string _must_ be encoded properly for the font being used.
|
207
|
-
# For AFM fonts, this is WinAnsi. For TTF, make sure the font is encoded as
|
208
|
-
# UTF-8. You can use the Font#normalize_encoding method to make sure strings
|
209
|
-
# are in an encoding appropriate for the current font.
|
210
|
-
#--
|
211
|
-
# For the record, this method used to be a method of Font (and still delegates
|
212
|
-
# to width computations on Font). However, having the primary interface for
|
213
|
-
# calculating string widths exist on Font made it tricky to write extensions
|
214
|
-
# for Prawn in which widths are computed differently (e.g., taking formatting
|
215
|
-
# tags into account, or the like).
|
216
|
-
#
|
217
|
-
# By putting width_of here, on Document itself, extensions may easily override
|
218
|
-
# it and redefine the width calculation behavior.
|
219
|
-
#++
|
220
|
-
def width_of(string, options={})
|
221
|
-
if p = options[:inline_format]
|
222
|
-
p = [] unless p.is_a?(Array)
|
223
|
-
|
224
|
-
# Build up an Arranger with the entire string on one line, finalize it,
|
225
|
-
# and find its width.
|
226
|
-
arranger = Prawn::Text::Formatted::Arranger.new(self, options)
|
227
|
-
arranger.consumed = self.text_formatter.format(string, *p)
|
228
|
-
arranger.finalize_line
|
229
|
-
|
230
|
-
arranger.line_width
|
231
|
-
else
|
232
|
-
width_of_string(string, options)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
262
|
private
|
237
263
|
|
238
|
-
def width_of_inline_formatted_string(string, options={})
|
264
|
+
def width_of_inline_formatted_string(string, options = {})
|
239
265
|
# Build up an Arranger with the entire string on one line, finalize it,
|
240
266
|
# and find its width.
|
241
267
|
arranger = Prawn::Text::Formatted::Arranger.new(self, options)
|
@@ -245,14 +271,25 @@ module Prawn
|
|
245
271
|
arranger.line_width
|
246
272
|
end
|
247
273
|
|
248
|
-
def width_of_string(string, options={})
|
249
|
-
font_metric_cache.width_of(
|
274
|
+
def width_of_string(string, options = {})
|
275
|
+
font_metric_cache.width_of(string, options)
|
250
276
|
end
|
251
277
|
end
|
252
278
|
|
253
279
|
# Provides font information and helper functions.
|
254
280
|
#
|
255
281
|
class Font
|
282
|
+
require_relative 'fonts/afm'
|
283
|
+
require_relative 'fonts/ttf'
|
284
|
+
require_relative 'fonts/dfont'
|
285
|
+
require_relative 'fonts/otf'
|
286
|
+
require_relative 'fonts/ttc'
|
287
|
+
|
288
|
+
# @deprecated
|
289
|
+
AFM = Fonts::AFM
|
290
|
+
TTF = Fonts::TTF
|
291
|
+
DFont = Fonts::DFont
|
292
|
+
TTC = Fonts::TTC
|
256
293
|
|
257
294
|
# The current font name
|
258
295
|
attr_reader :name
|
@@ -264,24 +301,37 @@ module Prawn
|
|
264
301
|
attr_reader :options
|
265
302
|
|
266
303
|
# Shortcut interface for constructing a font object. Filenames of the form
|
267
|
-
# *.ttf will call
|
268
|
-
# will be passed through to
|
269
|
-
#
|
270
|
-
def self.load(document,
|
271
|
-
case
|
272
|
-
when
|
273
|
-
when
|
274
|
-
when
|
275
|
-
|
304
|
+
# *.ttf will call Fonts::TTF.new, *.dfont Fonts::DFont.new, *.ttc goes to
|
305
|
+
# Fonts::TTC.new, and anything else will be passed through to
|
306
|
+
# Fonts::AFM.new()
|
307
|
+
def self.load(document, src, options = {})
|
308
|
+
case font_format(src, options)
|
309
|
+
when 'ttf' then TTF.new(document, src, options)
|
310
|
+
when 'otf' then Fonts::OTF.new(document, src, options)
|
311
|
+
when 'dfont' then DFont.new(document, src, options)
|
312
|
+
when 'ttc' then TTC.new(document, src, options)
|
313
|
+
else AFM.new(document, src, options)
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
def self.font_format(src, options)
|
318
|
+
return options.fetch(:format, 'ttf') if src.respond_to? :read
|
319
|
+
|
320
|
+
case src.to_s
|
321
|
+
when /\.ttf$/i then 'ttf'
|
322
|
+
when /\.otf$/i then 'otf'
|
323
|
+
when /\.dfont$/i then 'dfont'
|
324
|
+
when /\.ttc$/i then 'ttc'
|
325
|
+
else 'afm'
|
276
326
|
end
|
277
327
|
end
|
278
328
|
|
279
|
-
def initialize(document,name,options={}) #:nodoc:
|
280
|
-
@document
|
281
|
-
@name
|
282
|
-
@options
|
329
|
+
def initialize(document, name, options = {}) #:nodoc:
|
330
|
+
@document = document
|
331
|
+
@name = name
|
332
|
+
@options = options
|
283
333
|
|
284
|
-
@family
|
334
|
+
@family = options[:family]
|
285
335
|
|
286
336
|
@identifier = generate_unique_id
|
287
337
|
|
@@ -310,15 +360,19 @@ module Prawn
|
|
310
360
|
# font. The string is expected to be UTF-8 going in. It will be re-encoded
|
311
361
|
# and the new string will be returned. For an in-place (destructive)
|
312
362
|
# version, see normalize_encoding!.
|
313
|
-
def normalize_encoding(
|
314
|
-
raise NotImplementedError,
|
363
|
+
def normalize_encoding(_string)
|
364
|
+
raise NotImplementedError,
|
365
|
+
'subclasses of Prawn::Font must implement #normalize_encoding'
|
315
366
|
end
|
316
367
|
|
317
368
|
# Destructive version of normalize_encoding; normalizes the encoding of a
|
318
369
|
# string in place.
|
319
370
|
#
|
371
|
+
# @deprecated
|
320
372
|
def normalize_encoding!(str)
|
321
|
-
|
373
|
+
warn 'Font#normalize_encoding! is deprecated. ' \
|
374
|
+
'Please use non-mutating version Font#normalize_encoding instead.'
|
375
|
+
str.dup.replace(normalize_encoding(str))
|
322
376
|
end
|
323
377
|
|
324
378
|
# Gets height of current font in PDF points at the given font size
|
@@ -340,11 +394,13 @@ module Prawn
|
|
340
394
|
#
|
341
395
|
def add_to_current_page(subset)
|
342
396
|
@references[subset] ||= register(subset)
|
343
|
-
@document.state.page.fonts.merge!(
|
397
|
+
@document.state.page.fonts.merge!(
|
398
|
+
identifier_for(subset) => @references[subset]
|
399
|
+
)
|
344
400
|
end
|
345
401
|
|
346
402
|
def identifier_for(subset) #:nodoc:
|
347
|
-
"#{@identifier}.#{subset}"
|
403
|
+
"#{@identifier}.#{subset}".to_sym
|
348
404
|
end
|
349
405
|
|
350
406
|
def inspect #:nodoc:
|
@@ -357,49 +413,42 @@ module Prawn
|
|
357
413
|
# Prawn::Table::Text#styled_with_of_single_character)
|
358
414
|
#
|
359
415
|
def hash #:nodoc:
|
360
|
-
[
|
416
|
+
[self.class, name, family, size].hash
|
361
417
|
end
|
362
418
|
|
363
419
|
# Compliments the #hash implementation above
|
364
420
|
#
|
365
|
-
def eql?(
|
366
|
-
self.class == other.class &&
|
367
|
-
|
421
|
+
def eql?(other) #:nodoc:
|
422
|
+
self.class == other.class && name == other.name &&
|
423
|
+
family == other.family && size == other.size
|
368
424
|
end
|
369
425
|
|
370
426
|
private
|
371
427
|
|
372
|
-
# generate a font identifier that hasn't been used on the
|
428
|
+
# generate a font identifier that hasn't been used on the current page yet
|
373
429
|
#
|
374
430
|
def generate_unique_id
|
375
|
-
|
431
|
+
key = nil
|
432
|
+
font_count = @document.font_registry.size + 1
|
433
|
+
loop do
|
434
|
+
key = :"F#{font_count}"
|
435
|
+
break if key_is_unique?(key)
|
376
436
|
|
377
|
-
|
378
|
-
offset += 1
|
379
|
-
id = :"F#{@document.font_registry.size + offset}"
|
437
|
+
font_count += 1
|
380
438
|
end
|
381
|
-
|
382
|
-
id
|
439
|
+
key
|
383
440
|
end
|
384
441
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
# page_contains_font_id?("F1")
|
390
|
-
# => true
|
391
|
-
#
|
392
|
-
def page_contains_font_id?(id)
|
393
|
-
id = id.to_s
|
394
|
-
@document.state.page.fonts.keys.any? { |exist_id|
|
395
|
-
exist_id.to_s[0,id.size] == id
|
396
|
-
}
|
442
|
+
def key_is_unique?(test_key)
|
443
|
+
@document.state.page.fonts.keys.none? do |key|
|
444
|
+
key.to_s.start_with?("#{test_key}.")
|
445
|
+
end
|
397
446
|
end
|
398
447
|
|
448
|
+
protected
|
449
|
+
|
399
450
|
def size
|
400
451
|
@document.font_size
|
401
452
|
end
|
402
|
-
|
403
453
|
end
|
404
|
-
|
405
454
|
end
|
@@ -1,5 +1,5 @@
|
|
1
|
-
#
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
3
|
# font_metric_cache.rb : The Prawn font class
|
4
4
|
#
|
5
5
|
# Copyright Dec 2012, Kenneth Kalmer. All Rights Reserved.
|
@@ -8,38 +8,42 @@
|
|
8
8
|
#
|
9
9
|
|
10
10
|
module Prawn
|
11
|
-
|
12
11
|
# Cache used internally by Prawn::Document instances to calculate the width
|
13
12
|
# of various strings for layout purposes.
|
13
|
+
#
|
14
|
+
# @private
|
14
15
|
class FontMetricCache
|
16
|
+
CacheEntry = Struct.new(:font, :options, :string)
|
15
17
|
|
16
|
-
|
17
|
-
|
18
|
-
def initialize( document )
|
18
|
+
def initialize(document)
|
19
19
|
@document = document
|
20
20
|
|
21
21
|
@cache = {}
|
22
22
|
end
|
23
23
|
|
24
|
-
def width_of(
|
25
|
-
f =
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
24
|
+
def width_of(string, options)
|
25
|
+
f =
|
26
|
+
if options[:style]
|
27
|
+
# override style with :style => :bold
|
28
|
+
@document.find_font(@document.font.family, style: options[:style])
|
29
|
+
else
|
30
|
+
@document.font
|
31
|
+
end
|
32
|
+
|
33
|
+
encoded_string = f.normalize_encoding(string)
|
32
34
|
|
33
|
-
key = CacheEntry.new(
|
35
|
+
key = CacheEntry.new(f, options, encoded_string)
|
34
36
|
|
35
|
-
|
36
|
-
|
37
|
+
@cache[key] ||= f.compute_width_of(encoded_string, options)
|
38
|
+
|
39
|
+
length = @cache[key]
|
40
|
+
|
41
|
+
character_count = @document.font.character_count(encoded_string)
|
42
|
+
if character_count.positive?
|
43
|
+
length += @document.character_spacing * (character_count - 1)
|
37
44
|
end
|
38
45
|
|
39
|
-
length
|
40
|
-
(@document.character_spacing * @document.font.character_count(string))
|
46
|
+
length
|
41
47
|
end
|
42
|
-
|
43
48
|
end
|
44
|
-
|
45
49
|
end
|