hexapdf 0.11.9 → 0.12.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 +82 -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 +18 -9
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/form.rb +240 -0
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +1 -1
- data/lib/hexapdf/cli/merge.rb +1 -1
- 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 +66 -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 +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/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 +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document.rb +14 -5
- 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/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 +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/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 +1 -1
- 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 +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/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 +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_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 +67 -51
- 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 +1 -1
- 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 +1 -1
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.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/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +2 -2
- data/lib/hexapdf/parser.rb +4 -3
- data/lib/hexapdf/pdf_array.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/serializer.rb +1 -1
- 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 +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- 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 +401 -0
- data/lib/hexapdf/type/acro_form/button_field.rb +300 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
- data/lib/hexapdf/type/acro_form/field.rb +220 -17
- data/lib/hexapdf/type/acro_form/form.rb +157 -7
- data/lib/hexapdf/type/acro_form/text_field.rb +186 -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 +1 -1
- 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 +239 -2
- data/lib/hexapdf/type/catalog.rb +21 -1
- 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 +1 -1
- data/lib/hexapdf/type/font.rb +18 -1
- data/lib/hexapdf/type/font_descriptor.rb +2 -2
- 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 +16 -1
- data/lib/hexapdf/type/font_type3.rb +1 -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 +3 -1
- 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 +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +8 -11
- data/lib/hexapdf/type/resources.rb +16 -3
- data/lib/hexapdf/type/trailer.rb +2 -3
- 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 +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/test/hexapdf/content/common.rb +2 -2
- 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/font/test_true_type_wrapper.rb +10 -7
- data/test/hexapdf/font/test_type1_wrapper.rb +32 -8
- data/test/hexapdf/test_document.rb +12 -0
- data/test/hexapdf/test_parser.rb +10 -0
- data/test/hexapdf/test_rectangle.rb +14 -0
- data/test/hexapdf/test_revision.rb +3 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +515 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +276 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
- data/test/hexapdf/type/acro_form/test_field.rb +124 -6
- data/test/hexapdf/type/acro_form/test_form.rb +189 -22
- data/test/hexapdf/type/acro_form/test_text_field.rb +119 -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_type1.rb +8 -0
- data/test/hexapdf/type/test_image.rb +7 -0
- data/test/hexapdf/type/test_page_tree_node.rb +20 -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 +13 -1
- data/test/test_helper.rb +1 -1
- metadata +37 -18
- data/lib/hexapdf/filter/dct_decode.rb +0 -60
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-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/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-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
|
|
@@ -46,6 +46,54 @@ module HexaPDF
|
|
|
46
46
|
# See: PDF1.7 s12.5
|
|
47
47
|
class Annotation < Dictionary
|
|
48
48
|
|
|
49
|
+
# The appearance dictionary references appearance streams for various use cases.
|
|
50
|
+
#
|
|
51
|
+
# Each appearance can either be an XObject or a dictionary mapping names to XObjects. The
|
|
52
|
+
# latter is used when the appearance depends on the state of the annotation, e.g. a check box
|
|
53
|
+
# widget that can be checked or unchecked.
|
|
54
|
+
#
|
|
55
|
+
# See: PDF1.7 s12.5.5
|
|
56
|
+
class AppearanceDictionary < Dictionary
|
|
57
|
+
|
|
58
|
+
define_type :XXAppearanceDictionary
|
|
59
|
+
|
|
60
|
+
define_field :N, type: [Dictionary, Stream], required: true
|
|
61
|
+
define_field :R, type: [Dictionary, Stream]
|
|
62
|
+
define_field :D, type: [Dictionary, Stream]
|
|
63
|
+
|
|
64
|
+
# The annotation's normal appearance.
|
|
65
|
+
def normal_appearance
|
|
66
|
+
self[:N]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# The rollover appearance which should be used when the cursor is moved into the active area
|
|
70
|
+
# of the annotation without pressing a button.
|
|
71
|
+
def rollover_appearance
|
|
72
|
+
self[:R] || self[:N]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# The down appearance which should be used when the mouse button is pressed or held down
|
|
76
|
+
# inside the active area of the annotation.
|
|
77
|
+
def down_appearance
|
|
78
|
+
self[:D] || self[:N]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Border style dictionary used by various annotation types.
|
|
84
|
+
#
|
|
85
|
+
# See: PDF1.7 s12.5.4
|
|
86
|
+
class Border < Dictionary
|
|
87
|
+
|
|
88
|
+
define_type :Border
|
|
89
|
+
|
|
90
|
+
define_field :Type, type: Symbol, default: type
|
|
91
|
+
define_field :W, type: [Integer, Float], default: 1
|
|
92
|
+
define_field :S, type: Symbol, default: :S, allowed_values: [:S, :D, :B, :I, :U]
|
|
93
|
+
define_field :D, type: PDFArray, default: [3]
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
|
|
49
97
|
extend Utils::BitField
|
|
50
98
|
|
|
51
99
|
define_type :Annot
|
|
@@ -58,7 +106,7 @@ module HexaPDF
|
|
|
58
106
|
define_field :NM, type: String, version: '1.4'
|
|
59
107
|
define_field :M, type: PDFDate, version: '1.1'
|
|
60
108
|
define_field :F, type: Integer, default: 0, version: '1.1'
|
|
61
|
-
define_field :AP, type:
|
|
109
|
+
define_field :AP, type: :XXAppearanceDictionary, version: '1.2'
|
|
62
110
|
define_field :AS, type: Symbol, version: '1.2'
|
|
63
111
|
define_field :Border, type: PDFArray, default: [0, 0, 1]
|
|
64
112
|
define_field :C, type: PDFArray, version: '1.1'
|
|
@@ -68,7 +116,29 @@ module HexaPDF
|
|
|
68
116
|
bit_field(:raw_flags, {invisible: 0, hidden: 1, print: 2, no_zoom: 3, no_rotate: 4,
|
|
69
117
|
no_view: 5, read_only: 6, locked: 7, toggle_no_view: 8,
|
|
70
118
|
locked_contents: 9},
|
|
71
|
-
lister: "flags", getter: "flagged?", setter: "flag")
|
|
119
|
+
lister: "flags", getter: "flagged?", setter: "flag", unsetter: "unflag")
|
|
120
|
+
|
|
121
|
+
# Returns +true+ because annotation objects must always be indirect objects.
|
|
122
|
+
def must_be_indirect?
|
|
123
|
+
true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# Returns the AppearanceDictionary instance associated with the annotation or +nil+ if none is
|
|
127
|
+
# set.
|
|
128
|
+
def appearance
|
|
129
|
+
self[:AP]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Returns +true+ if the widget's normal appearance exists.
|
|
133
|
+
#
|
|
134
|
+
# Note that this checks only if the appearance exists but not if the structure of the
|
|
135
|
+
# appearance dictionary conforms to the expectations of the annotation.
|
|
136
|
+
def appearance?
|
|
137
|
+
return false unless (normal_appearance = appearance&.normal_appearance)
|
|
138
|
+
normal_appearance.kind_of?(HexaPDF::Stream) ||
|
|
139
|
+
(!normal_appearance.empty? &&
|
|
140
|
+
normal_appearance.each.all? {|_k, v| v.kind_of?(HexaPDF::Stream) })
|
|
141
|
+
end
|
|
72
142
|
|
|
73
143
|
private
|
|
74
144
|
|
|
@@ -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
|
|
@@ -53,7 +53,7 @@ module HexaPDF
|
|
|
53
53
|
version: '1.2'
|
|
54
54
|
define_field :PA, type: Dictionary, version: '1.3'
|
|
55
55
|
define_field :QuadPoints, type: PDFArray, version: '1.6'
|
|
56
|
-
define_field :BS, type:
|
|
56
|
+
define_field :BS, type: :Border, version: '1.6'
|
|
57
57
|
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -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
|
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
#++
|
|
36
36
|
|
|
37
37
|
require 'hexapdf/type/annotation'
|
|
38
|
+
require 'hexapdf/content'
|
|
39
|
+
require 'hexapdf/serializer'
|
|
38
40
|
|
|
39
41
|
module HexaPDF
|
|
40
42
|
module Type
|
|
@@ -80,9 +82,244 @@ module HexaPDF
|
|
|
80
82
|
define_field :MK, type: :XXAppearanceCharacteristics
|
|
81
83
|
define_field :A, type: Dictionary, version: '1.1'
|
|
82
84
|
define_field :AA, type: Dictionary, version: '1.2'
|
|
83
|
-
define_field :BS, type:
|
|
85
|
+
define_field :BS, type: :Border, version: '1.2'
|
|
84
86
|
define_field :Parent, type: Dictionary
|
|
85
87
|
|
|
88
|
+
# Returs the AcroForm field object to which this widget annotation belongs.
|
|
89
|
+
#
|
|
90
|
+
# Since a widget and a field can share the same dictionary object, the returned object is
|
|
91
|
+
# often just the widget re-wrapped in the correct field class.
|
|
92
|
+
def form_field
|
|
93
|
+
field = if key?(:Parent) &&
|
|
94
|
+
(tmp = document.wrap(self[:Parent], type: :XXAcroFormField)).terminal_field?
|
|
95
|
+
tmp
|
|
96
|
+
else
|
|
97
|
+
document.wrap(self, type: :XXAcroFormField)
|
|
98
|
+
end
|
|
99
|
+
document.wrap(field, type: :XXAcroFormField, subtype: field[:FT])
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# :call-seq:
|
|
103
|
+
# widget.background_color => background_color or nil
|
|
104
|
+
# widget.background_color(*color) => widget
|
|
105
|
+
#
|
|
106
|
+
# Returns the current background color as device color object, or +nil+ if no background
|
|
107
|
+
# color is set, when no argument is given. Otherwise sets the background color using the
|
|
108
|
+
# +color+ argument and returns self.
|
|
109
|
+
#
|
|
110
|
+
# See HexaPDF::Content::ColorSpace.device_color_from_specification for information on the
|
|
111
|
+
# allowed arguments.
|
|
112
|
+
def background_color(*color)
|
|
113
|
+
if color.empty?
|
|
114
|
+
components = self[:MK]&.[](:BG)
|
|
115
|
+
components.nil? ? nil : Content::ColorSpace.prenormalized_device_color(components)
|
|
116
|
+
else
|
|
117
|
+
color = Content::ColorSpace.device_color_from_specification(color)
|
|
118
|
+
(self[:MK] ||= {})[:BG] = color.components
|
|
119
|
+
self
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Describes the border of an annotation.
|
|
124
|
+
#
|
|
125
|
+
# The +color+ property is either +nil+ if the border is transparent or else a device color
|
|
126
|
+
# object - see HexaPDF::Content::ColorSpace.
|
|
127
|
+
#
|
|
128
|
+
# The +style+ property can be one of the following:
|
|
129
|
+
#
|
|
130
|
+
# :solid:: Solid line.
|
|
131
|
+
# :beveled:: Embossed rectangle seemingly raised above the surface of the page.
|
|
132
|
+
# :inset:: Engraved rectangle receeding into the page.
|
|
133
|
+
# :underlined:: Underlined, i.e. only the bottom border is draw.
|
|
134
|
+
# Array: Dash array describing how to dash the line.
|
|
135
|
+
BorderStyle = Struct.new(:width, :color, :style, :horizontal_corner_radius,
|
|
136
|
+
:vertical_corner_radius)
|
|
137
|
+
|
|
138
|
+
# :call-seq:
|
|
139
|
+
# widget.border_style => border_style
|
|
140
|
+
# widget.border_style(color: 0, width: 1, style: :solid) => widget
|
|
141
|
+
#
|
|
142
|
+
# Returns a BorderStyle instance representing the border style of the widget when no
|
|
143
|
+
# argument is given. Otherwise sets the border style of the widget and returns self.
|
|
144
|
+
#
|
|
145
|
+
# When setting a border style, arguments that are not provided will use the default: a
|
|
146
|
+
# border with a solid, black, 1pt wide line. This also means that multiple invocations will
|
|
147
|
+
# reset *all* prior values.
|
|
148
|
+
#
|
|
149
|
+
# +color+:: The color of the border. See
|
|
150
|
+
# HexaPDF::Content::ColorSpace.device_color_from_specification for information on
|
|
151
|
+
# the allowed arguments.
|
|
152
|
+
#
|
|
153
|
+
# If the special value +:transparent+ is used when setting the color, a
|
|
154
|
+
# transparent is used. A transparent border will return a +nil+ value when getting
|
|
155
|
+
# the border color.
|
|
156
|
+
#
|
|
157
|
+
# +width+:: The width of the border. If set to 0, no border is shown.
|
|
158
|
+
#
|
|
159
|
+
# +style+:: Defines how the border is drawn. can be one of the following:
|
|
160
|
+
#
|
|
161
|
+
# +:solid+:: Draws a solid border.
|
|
162
|
+
# +:beveled+:: Draws a beveled border.
|
|
163
|
+
# +:inset+:: Draws an inset border.
|
|
164
|
+
# +:underlined+:: Draws only the bottom border.
|
|
165
|
+
# Array:: An array specifying a line dash pattern (see
|
|
166
|
+
# HexaPDF::Content::LineDashPattern)
|
|
167
|
+
def border_style(color: nil, width: nil, style: nil)
|
|
168
|
+
if color || width || style
|
|
169
|
+
color = if color == :transparent
|
|
170
|
+
[]
|
|
171
|
+
else
|
|
172
|
+
Content::ColorSpace.device_color_from_specification(color || 0).components
|
|
173
|
+
end
|
|
174
|
+
width ||= 1
|
|
175
|
+
style ||= :solid
|
|
176
|
+
|
|
177
|
+
(self[:MK] ||= {})[:BC] = color
|
|
178
|
+
bs = self[:BS] = {W: width}
|
|
179
|
+
case style
|
|
180
|
+
when :solid then bs[:S] = :S
|
|
181
|
+
when :beveled then bs[:S] = :B
|
|
182
|
+
when :inset then bs[:S] = :I
|
|
183
|
+
when :underlined then bs[:S] = :U
|
|
184
|
+
when Array
|
|
185
|
+
bs[:S] = :D
|
|
186
|
+
bs[:D] = style
|
|
187
|
+
else
|
|
188
|
+
raise ArgumentError, "Unknown value #{style} for style argument"
|
|
189
|
+
end
|
|
190
|
+
self
|
|
191
|
+
else
|
|
192
|
+
result = BorderStyle.new(1, nil, :solid, 0, 0)
|
|
193
|
+
if (ac = self[:MK]) && (bc = ac[:BC]) && !bc.empty?
|
|
194
|
+
result.color = Content::ColorSpace.prenormalized_device_color(bc.value)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
if (bs = self[:BS])
|
|
198
|
+
result.width = bs[:W] if bs.key?(:W)
|
|
199
|
+
result.style = case bs[:S]
|
|
200
|
+
when :S then :solid
|
|
201
|
+
when :B then :beveled
|
|
202
|
+
when :I then :inset
|
|
203
|
+
when :U then :underlined
|
|
204
|
+
when :D then bs[:D].value
|
|
205
|
+
else :solid
|
|
206
|
+
end
|
|
207
|
+
elsif key?(:Border)
|
|
208
|
+
border = self[:Border]
|
|
209
|
+
result.horizontal_corner_radius = border[0]
|
|
210
|
+
result.vertical_corner_radius = border[1]
|
|
211
|
+
result.width = border[2]
|
|
212
|
+
result.style = border[3] if border[3]
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
result
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Describes the marker style of a check box or radio button widget.
|
|
220
|
+
class MarkerStyle
|
|
221
|
+
|
|
222
|
+
# The kind of marker that is shown inside the widget. Can either be one of the symbols
|
|
223
|
+
# +:check+, +:circle+, +:cross+, +:diamond+, +:square+ or +:star+, or a one character
|
|
224
|
+
# string. The latter is interpreted using the ZapfDingbats font.
|
|
225
|
+
attr_reader :style
|
|
226
|
+
|
|
227
|
+
# The size of the marker in PDF points that is shown inside the widget. The special value
|
|
228
|
+
# 0 means that the marker should be auto-sized based on the widget's rectangle.
|
|
229
|
+
attr_reader :size
|
|
230
|
+
|
|
231
|
+
# A device color object representing the color of the marker - see
|
|
232
|
+
# HexaPDF::Content::ColorSpace.
|
|
233
|
+
attr_reader :color
|
|
234
|
+
|
|
235
|
+
# Creates a new instance with the given values.
|
|
236
|
+
def initialize(style, size, color)
|
|
237
|
+
@style = style
|
|
238
|
+
@size = size
|
|
239
|
+
@color = color
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
# :call-seq:
|
|
245
|
+
# widget.marker_style => marker_style
|
|
246
|
+
# widget.marker_style(style: nil, size: nil, color: nil) => widget
|
|
247
|
+
#
|
|
248
|
+
# Returns a MarkerStyle instance representing the marker style of the widget when no
|
|
249
|
+
# argument is given. Otherwise sets the button marker style of the widget and returns self.
|
|
250
|
+
#
|
|
251
|
+
# This method returns valid information only for check boxes and radio buttons!
|
|
252
|
+
#
|
|
253
|
+
# When setting a marker style, arguments that are not provided will use the default: a black
|
|
254
|
+
# auto-sized checkmark (i.e. :check for for check boxes) or circle (:circle for radio
|
|
255
|
+
# buttons). This also means that multiple invocations will reset *all* prior values.
|
|
256
|
+
#
|
|
257
|
+
# Note: The marker is called "normal caption" in the PDF 1.7 spec and the /CA entry of the
|
|
258
|
+
# associated appearance characteristics dictionary. The marker size and color are set using
|
|
259
|
+
# the /DA key on the widget (although /DA is not defined for widget, this is how Acrobat
|
|
260
|
+
# does it).
|
|
261
|
+
#
|
|
262
|
+
# See: PDF1.7 s12.5.6.19 and s17.7.3.3
|
|
263
|
+
def marker_style(style: nil, size: nil, color: nil)
|
|
264
|
+
field = form_field
|
|
265
|
+
if style || size || color
|
|
266
|
+
style ||= (field.check_box? ? :check : :cicrle)
|
|
267
|
+
size ||= 0
|
|
268
|
+
color = Content::ColorSpace.device_color_from_specification(color || 0)
|
|
269
|
+
|
|
270
|
+
self[:MK] ||= {}
|
|
271
|
+
self[:MK][:CA] = case style
|
|
272
|
+
when :check then '4'
|
|
273
|
+
when :circle then 'l'
|
|
274
|
+
when :cross then '8'
|
|
275
|
+
when :diamond then 'u'
|
|
276
|
+
when :square then 'n'
|
|
277
|
+
when :star then 'H'
|
|
278
|
+
when String then style
|
|
279
|
+
else
|
|
280
|
+
raise ArgumentError, "Unknown value #{style} for argument 'style'"
|
|
281
|
+
end
|
|
282
|
+
operator = case color.color_space.family
|
|
283
|
+
when :DeviceRGB then :rg
|
|
284
|
+
when :DeviceGray then :g
|
|
285
|
+
when :DeviceCMYK then :k
|
|
286
|
+
end
|
|
287
|
+
serialized_color = Content::Operator::DEFAULT_OPERATORS[operator].
|
|
288
|
+
serialize(HexaPDF::Serializer.new, *color.components)
|
|
289
|
+
self[:DA] = "/ZaDb #{size} Tf #{serialized_color}".strip
|
|
290
|
+
else
|
|
291
|
+
style = case self[:MK]&.[](:CA)
|
|
292
|
+
when '4' then :check
|
|
293
|
+
when 'l' then :circle
|
|
294
|
+
when '8' then :cross
|
|
295
|
+
when 'u' then :diamond
|
|
296
|
+
when 'n' then :square
|
|
297
|
+
when 'H' then :star
|
|
298
|
+
when String then self[:MK][:CA]
|
|
299
|
+
else
|
|
300
|
+
if field.check_box?
|
|
301
|
+
:check
|
|
302
|
+
else
|
|
303
|
+
:circle
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
size = 0
|
|
307
|
+
color = [0]
|
|
308
|
+
if (da = self[:DA] || field[:DA])
|
|
309
|
+
HexaPDF::Content::Parser.parse(da) do |obj, params|
|
|
310
|
+
if obj == :rg || obj == :g || obj == :k
|
|
311
|
+
color = params.dup
|
|
312
|
+
elsif obj == :Tf
|
|
313
|
+
size = params[1]
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
color = HexaPDF::Content::ColorSpace.prenormalized_device_color(color)
|
|
318
|
+
|
|
319
|
+
MarkerStyle.new(style, size, color)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
86
323
|
end
|
|
87
324
|
|
|
88
325
|
end
|