hexapdf 0.11.9 → 0.13.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 +4 -4
- data/CHANGELOG.md +157 -0
- data/LICENSE +1 -1
- data/examples/001-hello_world.rb +1 -1
- data/examples/002-graphics.rb +1 -1
- data/examples/003-arcs.rb +1 -1
- data/examples/004-optimizing.rb +1 -1
- data/examples/005-merging.rb +1 -1
- data/examples/006-standard_pdf_fonts.rb +1 -1
- data/examples/007-truetype.rb +1 -1
- data/examples/008-show_char_bboxes.rb +1 -1
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +1 -1
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +1 -1
- data/examples/016-frame_automatic_box_placement.rb +1 -1
- data/examples/017-frame_text_flow.rb +1 -1
- data/examples/018-composer.rb +1 -1
- data/examples/019-acro_form.rb +51 -0
- data/lib/hexapdf.rb +1 -1
- data/lib/hexapdf/cli.rb +3 -1
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +22 -11
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/form.rb +240 -0
- data/lib/hexapdf/cli/image2pdf.rb +3 -2
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +52 -3
- data/lib/hexapdf/cli/inspect.rb +31 -9
- data/lib/hexapdf/cli/merge.rb +2 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +81 -11
- data/lib/hexapdf/content.rb +3 -1
- data/lib/hexapdf/content/canvas.rb +5 -18
- data/lib/hexapdf/content/color_space.rb +111 -32
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +4 -4
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +9 -9
- data/lib/hexapdf/content/parser.rb +18 -5
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +5 -5
- data/lib/hexapdf/dictionary_fields.rb +2 -10
- data/lib/hexapdf/document.rb +45 -17
- data/lib/hexapdf/document/files.rb +1 -2
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/pages.rb +3 -14
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +2 -2
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +2 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter.rb +3 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/{jpx_decode.rb → pass_through.rb} +5 -5
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +2 -5
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +9 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +7 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +3 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +54 -51
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +68 -52
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +4 -3
- data/lib/hexapdf/importer.rb +2 -4
- data/lib/hexapdf/layout.rb +1 -1
- data/lib/hexapdf/layout/box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +2 -2
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +24 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +1 -1
- data/lib/hexapdf/layout/text_shaper.rb +4 -3
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +32 -27
- data/lib/hexapdf/parser.rb +69 -6
- data/lib/hexapdf/pdf_array.rb +10 -3
- data/lib/hexapdf/rectangle.rb +31 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +2 -1
- data/lib/hexapdf/revisions.rb +30 -22
- data/lib/hexapdf/serializer.rb +2 -2
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +7 -5
- data/lib/hexapdf/tokenizer.rb +5 -4
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +7 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +405 -0
- data/lib/hexapdf/type/acro_form/button_field.rb +305 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
- data/lib/hexapdf/type/acro_form/field.rb +250 -17
- data/lib/hexapdf/type/acro_form/form.rb +159 -7
- data/lib/hexapdf/type/acro_form/text_field.rb +187 -0
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +122 -0
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +4 -3
- data/lib/hexapdf/type/annotation.rb +73 -3
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +238 -2
- data/lib/hexapdf/type/catalog.rb +23 -3
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font.rb +18 -1
- data/lib/hexapdf/type/font_descriptor.rb +2 -2
- data/lib/hexapdf/type/font_simple.rb +4 -2
- data/lib/hexapdf/type/font_true_type.rb +7 -3
- data/lib/hexapdf/type/font_type0.rb +2 -2
- data/lib/hexapdf/type/font_type1.rb +16 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +12 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +5 -3
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +36 -12
- data/lib/hexapdf/type/page_tree_node.rb +37 -16
- data/lib/hexapdf/type/resources.rb +17 -3
- data/lib/hexapdf/type/trailer.rb +4 -6
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +38 -24
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +19 -16
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +6 -1
- data/test/hexapdf/content/common.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_arc.rb +4 -4
- data/test/hexapdf/content/test_canvas.rb +3 -3
- data/test/hexapdf/content/test_color_space.rb +71 -8
- data/test/hexapdf/content/test_operator.rb +22 -22
- data/test/hexapdf/content/test_parser.rb +14 -0
- data/test/hexapdf/document/test_fonts.rb +1 -1
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/encryption/test_aes.rb +4 -4
- data/test/hexapdf/encryption/test_standard_security_handler.rb +11 -11
- data/test/hexapdf/filter/test_ascii85_decode.rb +1 -1
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +1 -1
- data/test/hexapdf/font/encoding/test_base.rb +10 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +8 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +10 -7
- data/test/hexapdf/font/test_type1_wrapper.rb +33 -8
- data/test/hexapdf/layout/test_style.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +3 -4
- data/test/hexapdf/test_configuration.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +3 -1
- data/test/hexapdf/test_dictionary_fields.rb +2 -2
- data/test/hexapdf/test_document.rb +16 -4
- data/test/hexapdf/test_object.rb +44 -26
- data/test/hexapdf/test_parser.rb +125 -55
- data/test/hexapdf/test_pdf_array.rb +7 -0
- data/test/hexapdf/test_rectangle.rb +14 -0
- data/test/hexapdf/test_revision.rb +3 -0
- data/test/hexapdf/test_revisions.rb +35 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +521 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +281 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
- data/test/hexapdf/type/acro_form/test_field.rb +163 -6
- data/test/hexapdf/type/acro_form/test_form.rb +189 -22
- data/test/hexapdf/type/acro_form/test_text_field.rb +121 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +77 -0
- data/test/hexapdf/type/annotations/test_text.rb +1 -1
- data/test/hexapdf/type/annotations/test_widget.rb +199 -0
- data/test/hexapdf/type/test_annotation.rb +45 -0
- data/test/hexapdf/type/test_catalog.rb +18 -0
- data/test/hexapdf/type/test_font.rb +5 -0
- data/test/hexapdf/type/test_font_simple.rb +2 -1
- data/test/hexapdf/type/test_font_true_type.rb +6 -0
- data/test/hexapdf/type/test_font_type1.rb +8 -0
- data/test/hexapdf/type/test_form.rb +19 -1
- data/test/hexapdf/type/test_image.rb +7 -0
- data/test/hexapdf/type/test_page.rb +45 -7
- data/test/hexapdf/type/test_page_tree_node.rb +62 -12
- data/test/hexapdf/type/test_resources.rb +20 -0
- data/test/hexapdf/type/test_trailer.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +15 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -9
- data/test/test_helper.rb +1 -1
- metadata +34 -21
- data/lib/hexapdf/filter/dct_decode.rb +0 -60
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -104,23 +104,33 @@ module HexaPDF
|
|
|
104
104
|
# Returns the wrapped Type1 font object.
|
|
105
105
|
attr_reader :wrapped_font
|
|
106
106
|
|
|
107
|
-
#
|
|
108
|
-
attr_reader :
|
|
107
|
+
# Returns the PDF object associated with the wrapper.
|
|
108
|
+
attr_reader :pdf_object
|
|
109
109
|
|
|
110
|
-
# Creates a new object wrapping the Type1 font
|
|
110
|
+
# Creates a new Type1Wrapper object wrapping the Type1 font.
|
|
111
111
|
#
|
|
112
|
-
# The optional argument +
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
112
|
+
# The optional argument +pdf_object+ can be used to set the PDF font object that this wrapper
|
|
113
|
+
# should be associated with. If no object is set, a suitable one is automatically created.
|
|
114
|
+
#
|
|
115
|
+
# If +pdf_object+ is provided, the PDF object's encoding is used. Otherwise, the
|
|
116
|
+
# WinAnsiEncoding or, for 'Special' fonts, the font's internal encoding is used. The optional
|
|
117
|
+
# argument +custom_encoding+ can be set to +true+ so that a custom encoding is used (only
|
|
118
|
+
# respected if +pdf_object+ is not provided).
|
|
119
|
+
def initialize(document, font, pdf_object: nil, custom_encoding: false)
|
|
116
120
|
@wrapped_font = font
|
|
121
|
+
@pdf_object = pdf_object || create_pdf_object(document)
|
|
122
|
+
@missing_glyph_callable = document.config['font.on_missing_glyph']
|
|
117
123
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
124
|
+
if pdf_object
|
|
125
|
+
@encoding = pdf_object.encoding
|
|
126
|
+
@max_code = 255 # Encoding is not modified
|
|
127
|
+
elsif custom_encoding
|
|
121
128
|
@encoding = Encoding::Base.new
|
|
122
129
|
@encoding.code_to_name[32] = :space
|
|
123
130
|
@max_code = 32 # 32 = space
|
|
131
|
+
elsif @wrapped_font.metrics.character_set == 'Special'
|
|
132
|
+
@encoding = @wrapped_font.encoding
|
|
133
|
+
@max_code = 255 # Encoding is not modified
|
|
124
134
|
else
|
|
125
135
|
@encoding = Encoding.for_name(:WinAnsiEncoding)
|
|
126
136
|
@max_code = 255 # Encoding is not modified
|
|
@@ -150,17 +160,25 @@ module HexaPDF
|
|
|
150
160
|
if @wrapped_font.metrics.character_metrics.key?(name)
|
|
151
161
|
Glyph.new(@wrapped_font, name, str)
|
|
152
162
|
else
|
|
153
|
-
@
|
|
163
|
+
@missing_glyph_callable.call(str, font_type, @wrapped_font)
|
|
154
164
|
end
|
|
155
165
|
end
|
|
156
166
|
end
|
|
157
167
|
|
|
158
168
|
# Returns an array of glyph objects representing the characters in the UTF-8 encoded string.
|
|
169
|
+
#
|
|
170
|
+
# If a Unicode codepoint is not available as glyph object, it is tried to map the codepoint
|
|
171
|
+
# using the font's internal encoding. This is useful, for example, for the ZapfDingbats font
|
|
172
|
+
# to use ASCII characters for accessing the glyphs.
|
|
159
173
|
def decode_utf8(str)
|
|
160
174
|
str.codepoints.map! do |c|
|
|
161
175
|
@codepoint_to_glyph[c] ||=
|
|
162
176
|
begin
|
|
163
177
|
name = Encoding::GlyphList.unicode_to_name(+'' << c, **@zapf_dingbats_opt)
|
|
178
|
+
if @wrapped_font.metrics.character_set == 'Special' &&
|
|
179
|
+
(name == :'.notdef' || !@wrapped_font.metrics.character_metrics.key?(name))
|
|
180
|
+
name = @encoding.name(c)
|
|
181
|
+
end
|
|
164
182
|
name = +"u" << c.to_s(16).rjust(6, '0') if name == :'.notdef'
|
|
165
183
|
glyph(name)
|
|
166
184
|
end
|
|
@@ -174,7 +192,7 @@ module HexaPDF
|
|
|
174
192
|
if glyph.name == @wrapped_font.missing_glyph_id
|
|
175
193
|
raise HexaPDF::Error, "Glyph for #{glyph.str.inspect} missing"
|
|
176
194
|
end
|
|
177
|
-
code = @encoding.
|
|
195
|
+
code = @encoding.code(glyph.name)
|
|
178
196
|
if code
|
|
179
197
|
code.chr.freeze
|
|
180
198
|
elsif @max_code < 255
|
|
@@ -189,49 +207,47 @@ module HexaPDF
|
|
|
189
207
|
|
|
190
208
|
private
|
|
191
209
|
|
|
192
|
-
# Builds a generic Type1 font dictionary for the wrapped font.
|
|
193
|
-
#
|
|
194
|
-
# Generic in the sense that no information regarding the encoding or widths is included.
|
|
195
|
-
def build_font_dict
|
|
196
|
-
unless defined?(@fd)
|
|
197
|
-
@fd = @document.wrap({Type: :FontDescriptor,
|
|
198
|
-
FontName: @wrapped_font.font_name.intern,
|
|
199
|
-
FontWeight: @wrapped_font.weight_class,
|
|
200
|
-
FontBBox: @wrapped_font.bounding_box,
|
|
201
|
-
ItalicAngle: @wrapped_font.italic_angle || 0,
|
|
202
|
-
Ascent: @wrapped_font.ascender || 0,
|
|
203
|
-
Descent: @wrapped_font.descender || 0,
|
|
204
|
-
CapHeight: @wrapped_font.cap_height,
|
|
205
|
-
XHeight: @wrapped_font.x_height,
|
|
206
|
-
StemH: @wrapped_font.dominant_horizontal_stem_width,
|
|
207
|
-
StemV: @wrapped_font.dominant_vertical_stem_width || 0})
|
|
208
|
-
@fd.flag(:fixed_pitch) if @wrapped_font.metrics.is_fixed_pitch
|
|
209
|
-
@fd.flag(@wrapped_font.metrics.character_set == 'Special' ? :symbolic : :nonsymbolic)
|
|
210
|
-
@fd.must_be_indirect = true
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
@document.wrap({Type: :Font, Subtype: :Type1,
|
|
214
|
-
BaseFont: @wrapped_font.font_name.intern, Encoding: :WinAnsiEncoding,
|
|
215
|
-
FontDescriptor: @fd})
|
|
216
|
-
end
|
|
217
|
-
|
|
218
210
|
# Array of valid encoding names in PDF
|
|
219
211
|
VALID_ENCODING_NAMES = [:WinAnsiEncoding, :MacRomanEncoding, :MacExpertEncoding].freeze
|
|
220
212
|
|
|
221
|
-
#
|
|
222
|
-
def
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
213
|
+
# Creates a PDF object representing the wrapped font for the given PDF document.
|
|
214
|
+
def create_pdf_object(document)
|
|
215
|
+
fd = document.wrap({Type: :FontDescriptor,
|
|
216
|
+
FontName: @wrapped_font.font_name.intern,
|
|
217
|
+
FontWeight: @wrapped_font.weight_class,
|
|
218
|
+
FontBBox: @wrapped_font.bounding_box,
|
|
219
|
+
ItalicAngle: @wrapped_font.italic_angle || 0,
|
|
220
|
+
Ascent: @wrapped_font.ascender || 0,
|
|
221
|
+
Descent: @wrapped_font.descender || 0,
|
|
222
|
+
CapHeight: @wrapped_font.cap_height,
|
|
223
|
+
XHeight: @wrapped_font.x_height,
|
|
224
|
+
StemH: @wrapped_font.dominant_horizontal_stem_width,
|
|
225
|
+
StemV: @wrapped_font.dominant_vertical_stem_width || 0})
|
|
226
|
+
fd.flag(:fixed_pitch) if @wrapped_font.metrics.is_fixed_pitch
|
|
227
|
+
fd.flag(@wrapped_font.metrics.character_set == 'Special' ? :symbolic : :nonsymbolic)
|
|
228
|
+
fd.must_be_indirect = true
|
|
229
|
+
|
|
230
|
+
dict = document.wrap({Type: :Font, Subtype: :Type1,
|
|
231
|
+
BaseFont: @wrapped_font.font_name.intern,
|
|
232
|
+
FontDescriptor: fd})
|
|
233
|
+
dict.font_wrapper = self
|
|
234
|
+
|
|
235
|
+
document.register_listener(:complete_objects) do
|
|
236
|
+
min, max = @encoding.code_to_name.keys.minmax
|
|
237
|
+
dict[:FirstChar] = min
|
|
238
|
+
dict[:LastChar] = max
|
|
239
|
+
dict[:Widths] = (min..max).map {|code| glyph(@encoding.name(code)).width }
|
|
240
|
+
|
|
241
|
+
if VALID_ENCODING_NAMES.include?(@encoding.encoding_name)
|
|
242
|
+
dict[:Encoding] = @encoding.encoding_name
|
|
243
|
+
elsif @encoding != @wrapped_font.encoding
|
|
244
|
+
differences = [min]
|
|
245
|
+
(min..max).each {|code| differences << @encoding.name(code) }
|
|
246
|
+
dict[:Encoding] = {Differences: differences}
|
|
247
|
+
end
|
|
234
248
|
end
|
|
249
|
+
|
|
250
|
+
dict
|
|
235
251
|
end
|
|
236
252
|
|
|
237
253
|
end
|
data/lib/hexapdf/font_loader.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/image_loader.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -162,9 +162,10 @@ module HexaPDF
|
|
|
162
162
|
io.seek(length, IO::SEEK_CUR)
|
|
163
163
|
end
|
|
164
164
|
when 'tRNS' # PNG s11.3.2
|
|
165
|
-
|
|
165
|
+
case @color_type
|
|
166
|
+
when INDEXED
|
|
166
167
|
trns = io.read(length).unpack('C*')
|
|
167
|
-
|
|
168
|
+
when TRUECOLOR, GREYSCALE
|
|
168
169
|
dict[:Mask] = io.read(length).unpack('n*').map {|val| [val, val] }.flatten
|
|
169
170
|
else
|
|
170
171
|
io.seek(length, IO::SEEK_CUR)
|
data/lib/hexapdf/importer.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -109,9 +109,7 @@ module HexaPDF
|
|
|
109
109
|
def duplicate(object)
|
|
110
110
|
case object
|
|
111
111
|
when Hash
|
|
112
|
-
object.
|
|
113
|
-
obj[k] = duplicate(v)
|
|
114
|
-
end
|
|
112
|
+
object.transform_values {|v| duplicate(v) }
|
|
115
113
|
when Array
|
|
116
114
|
object.map {|v| duplicate(v) }
|
|
117
115
|
when HexaPDF::Reference
|
data/lib/hexapdf/layout.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/layout/box.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/layout/frame.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/layout/line.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -198,7 +198,7 @@ module HexaPDF
|
|
|
198
198
|
# Note: The cache is not cleared!
|
|
199
199
|
def add(item)
|
|
200
200
|
last = @items.last
|
|
201
|
-
if last.
|
|
201
|
+
if last.instance_of?(item.class) && item.kind_of?(TextFragment) && last.style == item.style
|
|
202
202
|
if last.items.frozen?
|
|
203
203
|
@items[-1] = last = last.dup
|
|
204
204
|
last.items = last.items.dup
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/layout/style.rb
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -524,7 +524,7 @@ module HexaPDF
|
|
|
524
524
|
# Style.new(font_size: 15, align: :center, valign: center)
|
|
525
525
|
def initialize(**properties)
|
|
526
526
|
update(**properties)
|
|
527
|
-
@scaled_item_widths = {}
|
|
527
|
+
@scaled_item_widths = {}.compare_by_identity
|
|
528
528
|
end
|
|
529
529
|
|
|
530
530
|
# Duplicates the complex properties that can be modified, as well as the cache.
|
|
@@ -883,41 +883,41 @@ module HexaPDF
|
|
|
883
883
|
[:text_rise, 0],
|
|
884
884
|
[:font_features, {}],
|
|
885
885
|
[:text_rendering_mode, "Content::TextRenderingMode::FILL",
|
|
886
|
-
setter: "Content::TextRenderingMode.normalize(value)"],
|
|
886
|
+
{setter: "Content::TextRenderingMode.normalize(value)"}],
|
|
887
887
|
[:subscript, false,
|
|
888
|
-
setter: "value; superscript(false) if superscript",
|
|
889
|
-
|
|
888
|
+
{setter: "value; superscript(false) if superscript",
|
|
889
|
+
valid_values: [true, false]}],
|
|
890
890
|
[:superscript, false,
|
|
891
|
-
setter: "value; subscript(false) if subscript",
|
|
892
|
-
|
|
893
|
-
[:underline, false, valid_values: [true, false]],
|
|
894
|
-
[:strikeout, false, valid_values: [true, false]],
|
|
891
|
+
{setter: "value; subscript(false) if subscript",
|
|
892
|
+
valid_values: [true, false]}],
|
|
893
|
+
[:underline, false, {valid_values: [true, false]}],
|
|
894
|
+
[:strikeout, false, {valid_values: [true, false]}],
|
|
895
895
|
[:fill_color, "default_color"],
|
|
896
896
|
[:fill_alpha, 1],
|
|
897
897
|
[:stroke_color, "default_color"],
|
|
898
898
|
[:stroke_alpha, 1],
|
|
899
899
|
[:stroke_width, 1],
|
|
900
900
|
[:stroke_cap_style, "Content::LineCapStyle::BUTT_CAP",
|
|
901
|
-
setter: "Content::LineCapStyle.normalize(value)"],
|
|
901
|
+
{setter: "Content::LineCapStyle.normalize(value)"}],
|
|
902
902
|
[:stroke_join_style, "Content::LineJoinStyle::MITER_JOIN",
|
|
903
|
-
setter: "Content::LineJoinStyle.normalize(value)"],
|
|
903
|
+
{setter: "Content::LineJoinStyle.normalize(value)"}],
|
|
904
904
|
[:stroke_miter_limit, 10.0],
|
|
905
905
|
[:stroke_dash_pattern, "Content::LineDashPattern.new",
|
|
906
|
-
setter: "Content::LineDashPattern.normalize(value, phase)", extra_args: ", phase = 0"],
|
|
907
|
-
[:align, :left, valid_values: [:left, :center, :right, :justify]],
|
|
908
|
-
[:valign, :top, valid_values: [:top, :center, :bottom]],
|
|
906
|
+
{setter: "Content::LineDashPattern.normalize(value, phase)", extra_args: ", phase = 0"}],
|
|
907
|
+
[:align, :left, {valid_values: [:left, :center, :right, :justify]}],
|
|
908
|
+
[:valign, :top, {valid_values: [:top, :center, :bottom]}],
|
|
909
909
|
[:text_indent, 0],
|
|
910
910
|
[:line_spacing, "LineSpacing.new(type: :single)",
|
|
911
|
-
setter: "LineSpacing.new(**(value.kind_of?(Symbol) ? {type: value, value: extra_arg} : value))",
|
|
912
|
-
|
|
913
|
-
[:last_line_gap, false, valid_values: [true, false]],
|
|
911
|
+
{setter: "LineSpacing.new(**(value.kind_of?(Symbol) ? {type: value, value: extra_arg} : value))",
|
|
912
|
+
extra_args: ", extra_arg = nil"}],
|
|
913
|
+
[:last_line_gap, false, {valid_values: [true, false]}],
|
|
914
914
|
[:background_color, nil],
|
|
915
|
-
[:padding, "Quad.new(0)", setter: "Quad.new(value)"],
|
|
916
|
-
[:margin, "Quad.new(0)", setter: "Quad.new(value)"],
|
|
917
|
-
[:border, "Border.new", setter: "Border.new(**value)"],
|
|
918
|
-
[:overlays, "Layers.new", setter: "Layers.new(value)"],
|
|
919
|
-
[:underlays, "Layers.new", setter: "Layers.new(value)"],
|
|
920
|
-
[:position, :default, valid_values: [:default, :float, :flow, :absolute]],
|
|
915
|
+
[:padding, "Quad.new(0)", {setter: "Quad.new(value)"}],
|
|
916
|
+
[:margin, "Quad.new(0)", {setter: "Quad.new(value)"}],
|
|
917
|
+
[:border, "Border.new", {setter: "Border.new(**value)"}],
|
|
918
|
+
[:overlays, "Layers.new", {setter: "Layers.new(value)"}],
|
|
919
|
+
[:underlays, "Layers.new", {setter: "Layers.new(value)"}],
|
|
920
|
+
[:position, :default, {valid_values: [:default, :float, :flow, :absolute]}],
|
|
921
921
|
[:position_hint, nil],
|
|
922
922
|
].each do |name, default, options = {}|
|
|
923
923
|
default = default.inspect unless default.kind_of?(String)
|
|
@@ -1075,7 +1075,7 @@ module HexaPDF
|
|
|
1075
1075
|
# The item may be a (singleton) glyph object or an integer/float, i.e. items that can appear
|
|
1076
1076
|
# inside a TextFragment.
|
|
1077
1077
|
def scaled_item_width(item)
|
|
1078
|
-
@scaled_item_widths[item
|
|
1078
|
+
@scaled_item_widths[item] ||=
|
|
1079
1079
|
begin
|
|
1080
1080
|
if item.kind_of?(Numeric)
|
|
1081
1081
|
-item * scaled_font_size
|