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
@@ -0,0 +1,292 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Implements AFM font support for Prawn
|
4
|
+
#
|
5
|
+
# Copyright May 2008, Gregory Brown / James Healy. All Rights Reserved.
|
6
|
+
#
|
7
|
+
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
+
|
9
|
+
require_relative '../encoding'
|
10
|
+
|
11
|
+
module Prawn
|
12
|
+
module Fonts
|
13
|
+
# @private
|
14
|
+
|
15
|
+
class AFM < Font
|
16
|
+
class << self
|
17
|
+
attr_accessor :hide_m17n_warning
|
18
|
+
end
|
19
|
+
|
20
|
+
self.hide_m17n_warning = false
|
21
|
+
|
22
|
+
BUILT_INS = %w[
|
23
|
+
Courier Helvetica Times-Roman Symbol ZapfDingbats
|
24
|
+
Courier-Bold Courier-Oblique Courier-BoldOblique
|
25
|
+
Times-Bold Times-Italic Times-BoldItalic
|
26
|
+
Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
|
27
|
+
].freeze
|
28
|
+
|
29
|
+
def unicode?
|
30
|
+
false
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.metrics_path
|
34
|
+
@metrics_path ||=
|
35
|
+
if ENV['METRICS']
|
36
|
+
ENV['METRICS'].split(':')
|
37
|
+
else
|
38
|
+
[
|
39
|
+
'.', '/usr/lib/afm',
|
40
|
+
'/usr/local/lib/afm',
|
41
|
+
'/usr/openwin/lib/fonts/afm',
|
42
|
+
"#{Prawn::DATADIR}/fonts"
|
43
|
+
]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :attributes #:nodoc:
|
48
|
+
|
49
|
+
# parse each ATM font file once only
|
50
|
+
def self.font_data
|
51
|
+
@font_data ||= SynchronizedCache.new
|
52
|
+
end
|
53
|
+
|
54
|
+
def initialize(document, name, options = {}) #:nodoc:
|
55
|
+
name ||= options[:family]
|
56
|
+
unless BUILT_INS.include?(name)
|
57
|
+
raise Prawn::Errors::UnknownFont,
|
58
|
+
"#{name} (#{options[:style] || 'normal'}) is not a known font."
|
59
|
+
end
|
60
|
+
|
61
|
+
super
|
62
|
+
|
63
|
+
file_name = @name.dup
|
64
|
+
file_name << '.afm' unless /\.afm$/.match?(file_name)
|
65
|
+
file_name = file_name[0] == '/' ? file_name : find_font(file_name)
|
66
|
+
|
67
|
+
font_data = self.class.font_data[file_name] ||= parse_afm(file_name)
|
68
|
+
@glyph_widths = font_data[:glyph_widths]
|
69
|
+
@glyph_table = font_data[:glyph_table]
|
70
|
+
@bounding_boxes = font_data[:bounding_boxes]
|
71
|
+
@kern_pairs = font_data[:kern_pairs]
|
72
|
+
@kern_pair_table = font_data[:kern_pair_table]
|
73
|
+
@attributes = font_data[:attributes]
|
74
|
+
|
75
|
+
@ascender = @attributes['ascender'].to_i
|
76
|
+
@descender = @attributes['descender'].to_i
|
77
|
+
@line_gap = Float(bbox[3] - bbox[1]) - (@ascender - @descender)
|
78
|
+
end
|
79
|
+
|
80
|
+
# The font bbox, as an array of integers
|
81
|
+
#
|
82
|
+
def bbox
|
83
|
+
@bbox ||= @attributes['fontbbox'].split(/\s+/).map { |e| Integer(e) }
|
84
|
+
end
|
85
|
+
|
86
|
+
# NOTE: String *must* be encoded as WinAnsi
|
87
|
+
def compute_width_of(string, options = {}) #:nodoc:
|
88
|
+
scale = (options[:size] || size) / 1000.0
|
89
|
+
|
90
|
+
if options[:kerning]
|
91
|
+
strings, numbers = kern(string).partition { |e| e.is_a?(String) }
|
92
|
+
total_kerning_offset = numbers.sum
|
93
|
+
(unscaled_width_of(strings.join) - total_kerning_offset) * scale
|
94
|
+
else
|
95
|
+
unscaled_width_of(string) * scale
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Returns true if the font has kerning data, false otherwise
|
100
|
+
#
|
101
|
+
# rubocop: disable Naming/PredicateName
|
102
|
+
def has_kerning_data?
|
103
|
+
@kern_pairs.any?
|
104
|
+
end
|
105
|
+
# rubocop: enable Naming/PredicateName
|
106
|
+
|
107
|
+
# built-in fonts only work with winansi encoding, so translate the
|
108
|
+
# string. Changes the encoding in-place, so the argument itself
|
109
|
+
# is replaced with a string in WinAnsi encoding.
|
110
|
+
#
|
111
|
+
def normalize_encoding(text)
|
112
|
+
text.encode('windows-1252')
|
113
|
+
rescue ::Encoding::InvalidByteSequenceError,
|
114
|
+
::Encoding::UndefinedConversionError
|
115
|
+
|
116
|
+
raise Prawn::Errors::IncompatibleStringEncoding,
|
117
|
+
"Your document includes text that's not compatible with the " \
|
118
|
+
"Windows-1252 character set.\n" \
|
119
|
+
'If you need full UTF-8 support, use external fonts instead of ' \
|
120
|
+
"PDF's built-in fonts.\n"
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_utf8(text)
|
124
|
+
text.encode('UTF-8')
|
125
|
+
end
|
126
|
+
|
127
|
+
# Returns the number of characters in +str+ (a WinAnsi-encoded string).
|
128
|
+
#
|
129
|
+
def character_count(str)
|
130
|
+
str.length
|
131
|
+
end
|
132
|
+
|
133
|
+
# Perform any changes to the string that need to happen
|
134
|
+
# before it is rendered to the canvas. Returns an array of
|
135
|
+
# subset "chunks", where each chunk is an array of two elements.
|
136
|
+
# The first element is the font subset number, and the second
|
137
|
+
# is either a string or an array (for kerned text).
|
138
|
+
#
|
139
|
+
# For Adobe fonts, there is only ever a single subset, so
|
140
|
+
# the first element of the array is "0", and the second is
|
141
|
+
# the string itself (or an array, if kerning is performed).
|
142
|
+
#
|
143
|
+
# The +text+ parameter must be in WinAnsi encoding (cp1252).
|
144
|
+
#
|
145
|
+
def encode_text(text, options = {})
|
146
|
+
[[0, options[:kerning] ? kern(text) : text]]
|
147
|
+
end
|
148
|
+
|
149
|
+
def glyph_present?(char)
|
150
|
+
!normalize_encoding(char).nil?
|
151
|
+
rescue Prawn::Errors::IncompatibleStringEncoding
|
152
|
+
false
|
153
|
+
end
|
154
|
+
|
155
|
+
private
|
156
|
+
|
157
|
+
def register(_subset)
|
158
|
+
font_dict = {
|
159
|
+
Type: :Font,
|
160
|
+
Subtype: :Type1,
|
161
|
+
BaseFont: name.to_sym
|
162
|
+
}
|
163
|
+
|
164
|
+
# Symbolic AFM fonts (Symbol, ZapfDingbats) have their own encodings
|
165
|
+
font_dict[:Encoding] = :WinAnsiEncoding unless symbolic?
|
166
|
+
|
167
|
+
@document.ref!(font_dict)
|
168
|
+
end
|
169
|
+
|
170
|
+
def symbolic?
|
171
|
+
attributes['characterset'] == 'Special'
|
172
|
+
end
|
173
|
+
|
174
|
+
def find_font(file)
|
175
|
+
self.class.metrics_path.find { |f| File.exist? "#{f}/#{file}" } +
|
176
|
+
"/#{file}"
|
177
|
+
rescue NoMethodError
|
178
|
+
raise Prawn::Errors::UnknownFont,
|
179
|
+
"Couldn't find the font: #{file} in any of:\n" +
|
180
|
+
self.class.metrics_path.join("\n")
|
181
|
+
end
|
182
|
+
|
183
|
+
def parse_afm(file_name)
|
184
|
+
data = {
|
185
|
+
glyph_widths: {},
|
186
|
+
bounding_boxes: {},
|
187
|
+
kern_pairs: {},
|
188
|
+
attributes: {}
|
189
|
+
}
|
190
|
+
section = []
|
191
|
+
|
192
|
+
File.foreach(file_name) do |line|
|
193
|
+
case line
|
194
|
+
when /^Start(\w+)/
|
195
|
+
section.push Regexp.last_match(1)
|
196
|
+
next
|
197
|
+
when /^End(\w+)/
|
198
|
+
section.pop
|
199
|
+
next
|
200
|
+
end
|
201
|
+
|
202
|
+
case section
|
203
|
+
when %w[FontMetrics CharMetrics]
|
204
|
+
next unless /^CH?\s/.match?(line)
|
205
|
+
|
206
|
+
name = line[/\bN\s+(\.?\w+)\s*;/, 1]
|
207
|
+
data[:glyph_widths][name] = line[/\bWX\s+(\d+)\s*;/, 1].to_i
|
208
|
+
data[:bounding_boxes][name] = line[/\bB\s+([^;]+);/, 1].to_s.rstrip
|
209
|
+
when %w[FontMetrics KernData KernPairs]
|
210
|
+
next unless line =~ /^KPX\s+(\.?\w+)\s+(\.?\w+)\s+(-?\d+)/
|
211
|
+
|
212
|
+
data[:kern_pairs][[Regexp.last_match(1), Regexp.last_match(2)]] =
|
213
|
+
Regexp.last_match(3).to_i
|
214
|
+
when %w[FontMetrics KernData TrackKern],
|
215
|
+
%w[FontMetrics Composites]
|
216
|
+
next
|
217
|
+
else
|
218
|
+
parse_generic_afm_attribute(line, data)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# process data parsed from AFM file to build tables which
|
223
|
+
# will be used when measuring and kerning text
|
224
|
+
data[:glyph_table] =
|
225
|
+
(0..255).map do |i|
|
226
|
+
data[:glyph_widths][Encoding::WinAnsi::CHARACTERS[i]].to_i
|
227
|
+
end
|
228
|
+
|
229
|
+
character_hash = Hash[
|
230
|
+
Encoding::WinAnsi::CHARACTERS.zip(
|
231
|
+
(0..Encoding::WinAnsi::CHARACTERS.size).to_a
|
232
|
+
)
|
233
|
+
]
|
234
|
+
data[:kern_pair_table] =
|
235
|
+
data[:kern_pairs].each_with_object({}) do |p, h|
|
236
|
+
h[p[0].map { |n| character_hash[n] }] = p[1]
|
237
|
+
end
|
238
|
+
|
239
|
+
data.each_value(&:freeze)
|
240
|
+
data.freeze
|
241
|
+
end
|
242
|
+
|
243
|
+
def parse_generic_afm_attribute(line, hash)
|
244
|
+
line =~ /(^\w+)\s+(.*)/
|
245
|
+
key = Regexp.last_match(1).to_s.downcase
|
246
|
+
value = Regexp.last_match(2)
|
247
|
+
|
248
|
+
hash[:attributes][key] =
|
249
|
+
if hash[:attributes][key]
|
250
|
+
Array(hash[:attributes][key]) << value
|
251
|
+
else
|
252
|
+
value
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
# converts a string into an array with spacing offsets
|
257
|
+
# bewteen characters that need to be kerned
|
258
|
+
#
|
259
|
+
# String *must* be encoded as WinAnsi
|
260
|
+
#
|
261
|
+
def kern(string)
|
262
|
+
kerned = [[]]
|
263
|
+
last_byte = nil
|
264
|
+
|
265
|
+
string.each_byte do |byte|
|
266
|
+
k = last_byte && @kern_pair_table[[last_byte, byte]]
|
267
|
+
if k
|
268
|
+
kerned << -k << [byte]
|
269
|
+
else
|
270
|
+
kerned.last << byte
|
271
|
+
end
|
272
|
+
last_byte = byte
|
273
|
+
end
|
274
|
+
|
275
|
+
kerned.map do |e|
|
276
|
+
e = e.is_a?(Array) ? e.pack('C*') : e
|
277
|
+
if e.respond_to?(:force_encoding)
|
278
|
+
e.force_encoding(::Encoding::Windows_1252)
|
279
|
+
else
|
280
|
+
e
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def unscaled_width_of(string)
|
286
|
+
string.bytes.reduce(0) do |s, r|
|
287
|
+
s + @glyph_table[r]
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
@@ -1,17 +1,11 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
# Copyright November 2008, Jamis Buck. All Rights Reserved.
|
6
|
-
#
|
7
|
-
# This is free software. Please see the LICENSE and COPYING files for details.
|
8
|
-
#
|
9
|
-
require 'prawn/font/ttf'
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'ttf'
|
10
4
|
|
11
5
|
module Prawn
|
12
|
-
|
6
|
+
module Fonts
|
7
|
+
# @private
|
13
8
|
class DFont < TTF
|
14
|
-
|
15
9
|
# Returns a list of the names of all named fonts in the given dfont file.
|
16
10
|
# Note that fonts are not required to be named in a dfont file, so the
|
17
11
|
# list may be empty even if the file does contain fonts. Also, note that
|
@@ -20,7 +14,7 @@ module Prawn
|
|
20
14
|
#
|
21
15
|
def self.named_fonts(file)
|
22
16
|
TTFunk::ResourceFile.open(file) do |f|
|
23
|
-
return f.resources_for(
|
17
|
+
return f.resources_for('sfnt')
|
24
18
|
end
|
25
19
|
end
|
26
20
|
|
@@ -28,7 +22,7 @@ module Prawn
|
|
28
22
|
#
|
29
23
|
def self.font_count(file)
|
30
24
|
TTFunk::ResourceFile.open(file) do |f|
|
31
|
-
return f.map[
|
25
|
+
return f.map['sfnt'][:list].length
|
32
26
|
end
|
33
27
|
end
|
34
28
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'ttf'
|
4
|
+
|
5
|
+
module Prawn
|
6
|
+
module Fonts
|
7
|
+
# @private
|
8
|
+
class TTC < TTF
|
9
|
+
# Returns a list of the names of all named fonts in the given ttc file.
|
10
|
+
# They are returned in order of their appearance in the file.
|
11
|
+
#
|
12
|
+
def self.font_names(file)
|
13
|
+
TTFunk::Collection.open(file) do |ttc|
|
14
|
+
ttc.map { |font| font.name.font_name.first }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def read_ttf_file
|
21
|
+
TTFunk::File.from_ttc(
|
22
|
+
@name,
|
23
|
+
font_option_to_index(@name, @options[:font])
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
def font_option_to_index(file, option)
|
28
|
+
if option.is_a?(Numeric)
|
29
|
+
option
|
30
|
+
else
|
31
|
+
self.class.font_names(file).index { |n| n == option } || 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|