hexapdf 1.6.0 → 1.8.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 +50 -0
- data/LICENSE +1 -1
- data/examples/005-merging.rb +2 -1
- data/examples/032-acro_form_list_and_fill.rb +47 -0
- data/examples/033-text_extraction.rb +34 -0
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/debug_info.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +6 -4
- data/lib/hexapdf/cli/form.rb +1 -1
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +17 -17
- data/lib/hexapdf/cli/info.rb +3 -1
- data/lib/hexapdf/cli/inspect.rb +1 -1
- data/lib/hexapdf/cli/merge.rb +14 -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/usage.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +1 -1
- data/lib/hexapdf/configuration.rb +10 -1
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/canvas_composer.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- 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/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/smart_text_extractor.rb +311 -0
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +3 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/digital_signature/cms_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signature.rb +1 -1
- data/lib/hexapdf/digital_signature/signatures.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +2 -16
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +22 -9
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing.rb +1 -1
- data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
- data/lib/hexapdf/digital_signature.rb +1 -1
- data/lib/hexapdf/document/annotations.rb +1 -1
- data/lib/hexapdf/document/destinations.rb +1 -1
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +1 -1
- data/lib/hexapdf/document/metadata.rb +1 -1
- data/lib/hexapdf/document/pages.rb +1 -1
- data/lib/hexapdf/document.rb +8 -4
- 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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/brotli_decode.rb +88 -0
- data/lib/hexapdf/filter/crypt.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/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +2 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -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/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +2 -2
- data/lib/hexapdf/font/true_type/font.rb +14 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +11 -6
- 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 +6 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -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 +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +2 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +3 -3
- 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.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +5 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader/variant_from_name.rb +1 -1
- data/lib/hexapdf/font_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 +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +1 -1
- data/lib/hexapdf/layout/box_fitter.rb +1 -1
- data/lib/hexapdf/layout/column_box.rb +1 -1
- data/lib/hexapdf/layout/container_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 +1 -1
- data/lib/hexapdf/layout/list_box.rb +1 -1
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/page_style.rb +1 -1
- data/lib/hexapdf/layout/style.rb +7 -3
- data/lib/hexapdf/layout/table_box.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/layout.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 +1 -1
- data/lib/hexapdf/parser.rb +1 -1
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +1 -1
- data/lib/hexapdf/revisions.rb +1 -1
- data/lib/hexapdf/serializer.rb +3 -3
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/import_pages.rb +185 -0
- data/lib/hexapdf/task/merge_acro_form.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +1 -1
- data/lib/hexapdf/task/pdfa.rb +109 -2
- data/lib/hexapdf/task.rb +2 -1
- data/lib/hexapdf/test_utils.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +1 -1
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/field.rb +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +5 -1
- data/lib/hexapdf/type/acro_form/java_script_actions.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +5 -3
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.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/set_ocg_state.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/appearance_generator.rb +1 -1
- data/lib/hexapdf/type/annotations/border_effect.rb +1 -1
- data/lib/hexapdf/type/annotations/border_styling.rb +1 -1
- data/lib/hexapdf/type/annotations/circle.rb +1 -1
- data/lib/hexapdf/type/annotations/interior_color.rb +1 -1
- data/lib/hexapdf/type/annotations/line.rb +1 -1
- data/lib/hexapdf/type/annotations/line_ending_styling.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/polygon.rb +1 -1
- data/lib/hexapdf/type/annotations/polygon_polyline.rb +1 -1
- data/lib/hexapdf/type/annotations/polyline.rb +1 -1
- data/lib/hexapdf/type/annotations/square.rb +1 -1
- data/lib/hexapdf/type/annotations/square_circle.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +10 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +1 -1
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/cmap.rb +1 -1
- data/lib/hexapdf/type/document_security_store.rb +80 -0
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +4 -4
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type1.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +6 -1
- data/lib/hexapdf/type/form.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/marked_content_reference.rb +1 -1
- data/lib/hexapdf/type/measure.rb +1 -1
- data/lib/hexapdf/type/metadata.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/namespace.rb +1 -1
- data/lib/hexapdf/type/object_reference.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/optional_content_configuration.rb +1 -1
- data/lib/hexapdf/type/optional_content_group.rb +1 -1
- data/lib/hexapdf/type/optional_content_membership.rb +1 -1
- data/lib/hexapdf/type/optional_content_properties.rb +1 -1
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/output_intent.rb +1 -1
- data/lib/hexapdf/type/page.rb +12 -1
- data/lib/hexapdf/type/page_label.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/struct_elem.rb +1 -1
- data/lib/hexapdf/type/struct_tree_root.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +1 -1
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/type.rb +2 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/utils.rb +1 -1
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/data/pdfa/mismatching_glyph_widths_cidfont_type2.pdf +0 -0
- data/test/hexapdf/content/test_smart_text_extractor.rb +129 -0
- data/test/hexapdf/digital_signature/common.rb +19 -5
- data/test/hexapdf/digital_signature/signing/test_signed_data_creator.rb +29 -4
- data/test/hexapdf/digital_signature/test_signatures.rb +3 -3
- data/test/hexapdf/filter/test_brotli_decode.rb +34 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_directory.rb +5 -3
- data/test/hexapdf/font/true_type/test_builder.rb +9 -0
- data/test/hexapdf/font/true_type/test_font.rb +17 -3
- data/test/hexapdf/font/true_type/test_subsetter.rb +11 -9
- data/test/hexapdf/font_loader/test_from_file.rb +7 -0
- data/test/hexapdf/task/test_import_pages.rb +126 -0
- data/test/hexapdf/task/test_pdfa.rb +72 -0
- data/test/hexapdf/test_document.rb +13 -0
- data/test/hexapdf/test_serializer.rb +1 -1
- data/test/hexapdf/type/acro_form/test_form.rb +6 -0
- data/test/hexapdf/type/acro_form/test_text_field.rb +7 -1
- data/test/hexapdf/type/annotations/test_widget.rb +11 -0
- data/test/hexapdf/type/test_font_type3.rb +4 -0
- data/test/hexapdf/type/test_page.rb +8 -0
- metadata +25 -1
data/lib/hexapdf/revision.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-2026 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/revisions.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-2026 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/serializer.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-2026 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
|
|
@@ -270,7 +270,7 @@ module HexaPDF
|
|
|
270
270
|
str << ">>"
|
|
271
271
|
end
|
|
272
272
|
|
|
273
|
-
STRING_ESCAPE_MAP = {"(" => "\\(", ")" => "\\)", "\\" => "\\\\", "\r" => "\\r"}.freeze # :nodoc:
|
|
273
|
+
STRING_ESCAPE_MAP = {"(" => "\\(", ")" => "\\)", "\\" => "\\\\", "\r" => "\\r", "\n" => "\\n"}.freeze # :nodoc:
|
|
274
274
|
|
|
275
275
|
# Serializes a String object.
|
|
276
276
|
#
|
|
@@ -287,7 +287,7 @@ module HexaPDF
|
|
|
287
287
|
else
|
|
288
288
|
obj.b
|
|
289
289
|
end
|
|
290
|
-
obj.gsub!(/[()\\\r]/n, STRING_ESCAPE_MAP)
|
|
290
|
+
obj.gsub!(/[()\\\r\n]/n, STRING_ESCAPE_MAP)
|
|
291
291
|
"(#{obj})"
|
|
292
292
|
end
|
|
293
293
|
|
data/lib/hexapdf/stream.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-2026 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-2026 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
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
|
2
|
+
#
|
|
3
|
+
#--
|
|
4
|
+
# This file is part of HexaPDF.
|
|
5
|
+
#
|
|
6
|
+
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
+
# Copyright (C) 2014-2026 Thomas Leitner
|
|
8
|
+
#
|
|
9
|
+
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
|
+
# under the terms of the GNU Affero General Public License version 3 as
|
|
11
|
+
# published by the Free Software Foundation with the addition of the
|
|
12
|
+
# following permission added to Section 15 as permitted in Section 7(a):
|
|
13
|
+
# FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
|
14
|
+
# THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
|
|
15
|
+
# INFRINGEMENT OF THIRD PARTY RIGHTS.
|
|
16
|
+
#
|
|
17
|
+
# HexaPDF is distributed in the hope that it will be useful, but WITHOUT
|
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
|
20
|
+
# License for more details.
|
|
21
|
+
#
|
|
22
|
+
# You should have received a copy of the GNU Affero General Public License
|
|
23
|
+
# along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
|
|
24
|
+
#
|
|
25
|
+
# The interactive user interfaces in modified source and object code
|
|
26
|
+
# versions of HexaPDF must display Appropriate Legal Notices, as required
|
|
27
|
+
# under Section 5 of the GNU Affero General Public License version 3.
|
|
28
|
+
#
|
|
29
|
+
# In accordance with Section 7(b) of the GNU Affero General Public
|
|
30
|
+
# License, a covered work must retain the producer line in every PDF that
|
|
31
|
+
# is created or manipulated using HexaPDF.
|
|
32
|
+
#
|
|
33
|
+
# If the GNU Affero General Public License doesn't fit your need,
|
|
34
|
+
# commercial licenses are available at <https://gettalong.at/hexapdf/>.
|
|
35
|
+
#++
|
|
36
|
+
|
|
37
|
+
require 'hexapdf/serializer'
|
|
38
|
+
require 'set'
|
|
39
|
+
|
|
40
|
+
module HexaPDF
|
|
41
|
+
module Task
|
|
42
|
+
|
|
43
|
+
# Task for importing pages from another document that preserves the visual appearance.
|
|
44
|
+
#
|
|
45
|
+
# It takes care of
|
|
46
|
+
#
|
|
47
|
+
# * importing the specified pages with all associated objects,
|
|
48
|
+
# * handling optional content groups and their default state,
|
|
49
|
+
# * and merging form fields.
|
|
50
|
+
#
|
|
51
|
+
# Note that the /Order, /AS and /Locked fields of the default optional content configuration
|
|
52
|
+
# dictionary are not preserved.
|
|
53
|
+
#
|
|
54
|
+
# Example:
|
|
55
|
+
#
|
|
56
|
+
# doc.task(:import_pages, source: source_doc, pages: [1..-2])
|
|
57
|
+
module ImportPages
|
|
58
|
+
|
|
59
|
+
# Performs the necessary steps to import the pages from the +source+ docment into the target
|
|
60
|
+
# document +doc+. Returns the imported pages.
|
|
61
|
+
#
|
|
62
|
+
# +source+::
|
|
63
|
+
# Specifies the source PDF document from which the pages should be imported.
|
|
64
|
+
#
|
|
65
|
+
# +pages+::
|
|
66
|
+
# Specifies the pages that should be imported. The argument has to be one of the
|
|
67
|
+
# following:
|
|
68
|
+
#
|
|
69
|
+
# +:all+:: Imports all pages from the +source+ document.
|
|
70
|
+
# Integer value:: Imports the page with the given zero-based index.
|
|
71
|
+
# Range value:: Imports the pages from the zero-based range.
|
|
72
|
+
# Array of Integer or Range values:: Imports all specified pages or page ranges.
|
|
73
|
+
# Array of source page objects:: Imports the given pages.
|
|
74
|
+
#
|
|
75
|
+
# +:append+::
|
|
76
|
+
# Specifies whether the imported pages should be appended to the target document's page
|
|
77
|
+
# tree.
|
|
78
|
+
#
|
|
79
|
+
# +ocgs+::
|
|
80
|
+
# Specifies the handling of optional content groups:
|
|
81
|
+
#
|
|
82
|
+
# +:preserve+:: Preserve the on/off state for all used OCGs.
|
|
83
|
+
# +:ignore+:: Ignore the on/off state.
|
|
84
|
+
#
|
|
85
|
+
# +:acro_form+::
|
|
86
|
+
# Specifies whether AcroForm fields should be merged into the target document.
|
|
87
|
+
#
|
|
88
|
+
# +:merge+:: Merge AcroForm fields using the MergeAcroForm task.
|
|
89
|
+
# +:ignore+:: Ignore AcroForm fields.
|
|
90
|
+
def self.call(doc, source:, pages: :all, append: true, ocgs: :preserve, acro_form: :merge)
|
|
91
|
+
# Retrieve all specified source pages
|
|
92
|
+
pages = if pages == :all
|
|
93
|
+
source.pages.each.to_a
|
|
94
|
+
elsif pages.kind_of?(Integer)
|
|
95
|
+
[source.pages[pages]]
|
|
96
|
+
elsif pages.kind_of?(Array) && pages[0].kind_of?(HexaPDF::Type::Page)
|
|
97
|
+
pages
|
|
98
|
+
else
|
|
99
|
+
result = Set.new
|
|
100
|
+
all_pages = source.pages.each.to_a
|
|
101
|
+
pages = [pages] unless pages.kind_of?(Array)
|
|
102
|
+
pages.each {|selector| result.merge(Array(all_pages[selector])) }
|
|
103
|
+
result
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Import the source pages and optionally append them to the target page tree
|
|
107
|
+
pages = pages.map do |page|
|
|
108
|
+
imported_page = doc.import(page)
|
|
109
|
+
doc.pages << imported_page if append
|
|
110
|
+
imported_page
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
doc.task(:merge_acro_form, source: source, pages: pages) if acro_form == :merge
|
|
114
|
+
preserve_ocgs(doc, source, pages) if ocgs == :preserve
|
|
115
|
+
|
|
116
|
+
pages
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Preserves the state of the OCGs found on +pages+ so that the visual appearance in the target
|
|
120
|
+
# document +doc+ is the same as in the +source+ document.
|
|
121
|
+
def self.preserve_ocgs(doc, source, pages)
|
|
122
|
+
# Find all OCGs used on all pages
|
|
123
|
+
ocgs = Set.new
|
|
124
|
+
process_ocg_or_ocmd = lambda do |obj|
|
|
125
|
+
if obj.type == :OCG
|
|
126
|
+
ocgs << obj
|
|
127
|
+
elsif obj.type == :OCMD
|
|
128
|
+
ocgs.merge(obj[:OCGs].to_ary)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
seen_resources = {}
|
|
132
|
+
pages.each do |page|
|
|
133
|
+
unless seen_resources[page.resources] # handle case when pages share the resources dict
|
|
134
|
+
page.resources[:Properties]&.each do |name, obj|
|
|
135
|
+
next unless obj
|
|
136
|
+
process_ocg_or_ocmd.call(obj)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
page.resources[:XObject]&.each do |name, obj|
|
|
140
|
+
process_ocg_or_ocmd.call(obj[:OC]) if obj.key?(:OC)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
page.each_annotation do |annot|
|
|
145
|
+
process_ocg_or_ocmd.call(annot[:OC]) if annot.key?(:OC)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
seen_resources[page.resources] = true
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
return if ocgs.empty?
|
|
152
|
+
|
|
153
|
+
# Add all found OCGs to the optional content properties dictionary
|
|
154
|
+
ocp = doc.optional_content
|
|
155
|
+
ocgs.each {|ocg| ocp.add_ocg(ocg) }
|
|
156
|
+
|
|
157
|
+
# Create a mapping from source OCGs to target OCGs and vice-versa
|
|
158
|
+
source_ocg = {}
|
|
159
|
+
target_ocg = {}
|
|
160
|
+
source.optional_content.ocgs.each do |ocg|
|
|
161
|
+
imported_ocg = doc.import(ocg)
|
|
162
|
+
next unless ocgs.include?(imported_ocg)
|
|
163
|
+
source_ocg[imported_ocg] = ocg
|
|
164
|
+
target_ocg[ocg] = imported_ocg
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# Ensure the initial state of the OCGs is correct
|
|
168
|
+
source_config = source.optional_content.default_configuration
|
|
169
|
+
target_config = ocp.default_configuration
|
|
170
|
+
ocgs.each do |ocg|
|
|
171
|
+
target_config.ocg_state(ocg, source_config.ocg_state(source_ocg[ocg]))
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Copy radio button groups from the source document, removing unknown OCGs from them
|
|
175
|
+
source_config[:RBGroups]&.each do |array|
|
|
176
|
+
result = array.map {|ocg| target_ocg[ocg] }.compact
|
|
177
|
+
next if result.empty?
|
|
178
|
+
(target_config[:RBGroups] ||= []) << result
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -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-2026 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-2026 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/task/pdfa.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-2026 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
|
|
@@ -40,6 +40,7 @@ require 'hexapdf/content/parser'
|
|
|
40
40
|
require 'hexapdf/content/operator'
|
|
41
41
|
require 'hexapdf/type/xref_stream'
|
|
42
42
|
require 'hexapdf/type/object_stream'
|
|
43
|
+
require 'hexapdf/font/true_type'
|
|
43
44
|
|
|
44
45
|
module HexaPDF
|
|
45
46
|
module Task
|
|
@@ -51,6 +52,13 @@ module HexaPDF
|
|
|
51
52
|
# * prevents the Standard 14 PDF fonts to be used.
|
|
52
53
|
# * adds an appropriate output intent if none is set.
|
|
53
54
|
# * adds the necessary PDF/A metadata properties.
|
|
55
|
+
#
|
|
56
|
+
# Additionally, it applies fixes to the document so that the structures and content of
|
|
57
|
+
# non-conforming PDFs are corrected. See ::call for more information on the available fixes.
|
|
58
|
+
#
|
|
59
|
+
# Note that you should use a PDF/A validation tool like veraPDF (https://verapdf.org/) to ensure
|
|
60
|
+
# that the resulting files confirm to the PDF/A specification because not all documents can be
|
|
61
|
+
# fixed at the moment.
|
|
54
62
|
module PDFA
|
|
55
63
|
|
|
56
64
|
# Performs the necessary tasks to make the document PDF/A compatible.
|
|
@@ -58,7 +66,22 @@ module HexaPDF
|
|
|
58
66
|
# +level+::
|
|
59
67
|
# Specifies the PDF/A conformance level that should be used. Can be one of the following
|
|
60
68
|
# strings: 2b, 2u, 3b, 3u.
|
|
61
|
-
|
|
69
|
+
#
|
|
70
|
+
# +fixes+::
|
|
71
|
+
# Specifies the fixes that should be applied when converting a non-conforming PDF. If a
|
|
72
|
+
# document is created with HexaPDF but also includes parts of loaded documents, this
|
|
73
|
+
# argument hast to be set to +:all+.
|
|
74
|
+
#
|
|
75
|
+
# Can be +:default+ (which is also the default value), +:all+ or an array with one or more
|
|
76
|
+
# fix names.
|
|
77
|
+
#
|
|
78
|
+
# +:default+:: Applies all fixes if the document was loaded from a file. Otherwise applies
|
|
79
|
+
# only those fixes necessary for files created with HexaPDF.
|
|
80
|
+
#
|
|
81
|
+
# +:all+: Applies all available fixes.
|
|
82
|
+
#
|
|
83
|
+
# +:glyph_widths+:: Corrects mismatching width information in fonts.
|
|
84
|
+
def self.call(doc, level: '3u', fixes: :default)
|
|
62
85
|
unless level.match?(/\A[23][bu]\z/)
|
|
63
86
|
raise ArgumentError, "The given PDF/A conformance level '#{level}' is not supported"
|
|
64
87
|
end
|
|
@@ -68,6 +91,15 @@ module HexaPDF
|
|
|
68
91
|
doc.metadata.property('pdfaid', 'part', part)
|
|
69
92
|
doc.metadata.property('pdfaid', 'conformance', conformance.upcase)
|
|
70
93
|
add_srgb_icc_output_intent(doc) unless doc.catalog.key?(:OutputIntents)
|
|
94
|
+
|
|
95
|
+
fixes = if fixes == :all || (fixes == :default && doc.revisions.parser)
|
|
96
|
+
ALL_FIXES
|
|
97
|
+
elsif fixes == :default
|
|
98
|
+
ALL_FIXES - FIXES_FOR_LOADED_DOCUMENTS
|
|
99
|
+
else
|
|
100
|
+
fixes
|
|
101
|
+
end
|
|
102
|
+
fixes.each {|fix| send(fix, doc) }
|
|
71
103
|
end
|
|
72
104
|
end
|
|
73
105
|
|
|
@@ -81,6 +113,81 @@ module HexaPDF
|
|
|
81
113
|
]
|
|
82
114
|
end
|
|
83
115
|
|
|
116
|
+
ALL_FIXES = [:fix_glyph_widths] # :nodoc:
|
|
117
|
+
|
|
118
|
+
FIXES_FOR_LOADED_DOCUMENTS = [:fix_glyph_widths] # :nodoc:
|
|
119
|
+
|
|
120
|
+
# Makes the glyph widths stored in the embedded fonts the same as the ones specified in the
|
|
121
|
+
# PDF font data structures.
|
|
122
|
+
#
|
|
123
|
+
# Note: Currently only handles Type 2 CIDFonts.
|
|
124
|
+
def self.fix_glyph_widths(doc) # :nodoc:
|
|
125
|
+
# Step 1: Collect all CIDs together with their respective fonts
|
|
126
|
+
processor = CIDCollector.new
|
|
127
|
+
doc.pages.each do |page|
|
|
128
|
+
page.process_contents(processor)
|
|
129
|
+
page.each_annotation do |annotation|
|
|
130
|
+
next unless (appearance = annotation.appearance)
|
|
131
|
+
appearance.process_contents(processor, original_resources: page.resources)
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Step 2: Process all found fonts
|
|
136
|
+
processor.map.each do |font_object, all_cids|
|
|
137
|
+
next if all_cids.empty?
|
|
138
|
+
font = HexaPDF::Font::TrueType::Font.new(StringIO.new(font_object.font_file.stream))
|
|
139
|
+
cid_to_gid = cid_to_gid_mapping(font_object)
|
|
140
|
+
|
|
141
|
+
# Process all found CIDs by comparing their width with the ones defined in the font and
|
|
142
|
+
# correcting the font if necessary.
|
|
143
|
+
raw_hmtx = font[:hmtx].raw_data
|
|
144
|
+
width_conversion_factor = 1000.0 / font[:head].units_per_em
|
|
145
|
+
all_cids.each do |cid|
|
|
146
|
+
cid_width = font_object.width(cid)
|
|
147
|
+
gid = cid_to_gid[cid]
|
|
148
|
+
gid_width = font[:hmtx][gid].advance_width * width_conversion_factor
|
|
149
|
+
next if (cid_width - gid_width).abs.round <= 1
|
|
150
|
+
raw_hmtx[4 * gid, 2] = [(cid_width / width_conversion_factor).round].pack('n')
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
font_object.font_file.stream = font.build('hmtx' => raw_hmtx)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Processes the contents of a stream and collects the CIDs for each composite font.
|
|
158
|
+
class CIDCollector < HexaPDF::Content::Processor
|
|
159
|
+
|
|
160
|
+
# The mapping from the composite font's descendant font to the set of used CIDs.
|
|
161
|
+
attr_reader :map
|
|
162
|
+
|
|
163
|
+
def initialize(*) # :nodoc:
|
|
164
|
+
super
|
|
165
|
+
@map = Hash.new {|h, k| h[k] = Set.new }
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def show_text(data) # :nodoc:
|
|
169
|
+
font = graphics_state.font
|
|
170
|
+
return unless font[:Subtype] == :Type0 && font.descendant_font[:Subtype] == :CIDFontType2
|
|
171
|
+
|
|
172
|
+
Array(data).each do |item|
|
|
173
|
+
next if item.kind_of?(Numeric)
|
|
174
|
+
@map[font.descendant_font].merge(font.decode(item))
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
alias show_text_with_positioning show_text
|
|
178
|
+
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
# Returns an object responding to #[] that maps CIDs to GIDs for Type 2 CIDFonts.
|
|
182
|
+
def self.cid_to_gid_mapping(font)
|
|
183
|
+
if font[:CIDToGIDMap] == :Identity
|
|
184
|
+
proc {|cid| cid }
|
|
185
|
+
else
|
|
186
|
+
font[:CIDToGIDMap].stream.unpack('n*')
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
private_class_method :cid_to_gid_mapping
|
|
190
|
+
|
|
84
191
|
end
|
|
85
192
|
|
|
86
193
|
end
|
data/lib/hexapdf/task.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-2026 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
|
|
@@ -66,6 +66,7 @@ module HexaPDF
|
|
|
66
66
|
autoload(:Dereference, 'hexapdf/task/dereference')
|
|
67
67
|
autoload(:PDFA, 'hexapdf/task/pdfa')
|
|
68
68
|
autoload(:MergeAcroForm, 'hexapdf/task/merge_acro_form')
|
|
69
|
+
autoload(:ImportPages, 'hexapdf/task/import_pages')
|
|
69
70
|
|
|
70
71
|
end
|
|
71
72
|
|
data/lib/hexapdf/test_utils.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-2026 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/tokenizer.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-2026 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-2026 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-2026 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-2026 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-2026 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-2026 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
|
|
@@ -412,6 +412,8 @@ module HexaPDF
|
|
|
412
412
|
#
|
|
413
413
|
# * For radio buttons the value needs to be a String or a Symbol representing the name of
|
|
414
414
|
# the radio button widget to select.
|
|
415
|
+
#
|
|
416
|
+
# * Values for password fields are ignored as they should not be stored in the PDF.
|
|
415
417
|
def fill(data)
|
|
416
418
|
data.each do |field_name, value|
|
|
417
419
|
field = field_by_name(field_name)
|
|
@@ -427,6 +429,8 @@ module HexaPDF
|
|
|
427
429
|
when /\A(?:n(o)?|f(alse)?)\z/ then false
|
|
428
430
|
else value
|
|
429
431
|
end
|
|
432
|
+
when :password_field
|
|
433
|
+
# Ignore the value
|
|
430
434
|
else
|
|
431
435
|
raise HexaPDF::Error, "AcroForm field type #{field.concrete_field_type} not yet supported"
|
|
432
436
|
end
|
|
@@ -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-2026 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-2026 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-2026 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
|
|
@@ -344,8 +344,10 @@ module HexaPDF
|
|
|
344
344
|
super
|
|
345
345
|
|
|
346
346
|
if self[:V] && !(self[:V].kind_of?(String) || self[:V].kind_of?(HexaPDF::Stream))
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
correctable = self[:V].kind_of?(Symbol)
|
|
348
|
+
yield("Text field doesn't contain text but an object of type #{self[:V].class}", correctable)
|
|
349
|
+
return unless correctable
|
|
350
|
+
self[:V] = self[:V].to_s
|
|
349
351
|
end
|
|
350
352
|
if (max_len = self[:MaxLen]) && field_value && field_value.length > max_len
|
|
351
353
|
correctable = true
|
|
@@ -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-2026 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-2026 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/type/action.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-2026 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-2026 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-2026 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-2026 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-2026 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-2026 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/type/actions.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-2026 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
|