hexapdf 0.32.1 → 0.33.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -1
- data/README.md +9 -0
- data/examples/002-graphics.rb +15 -17
- data/examples/003-arcs.rb +9 -9
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +2 -2
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +7 -7
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +8 -7
- data/examples/016-frame_automatic_box_placement.rb +2 -2
- data/examples/017-frame_text_flow.rb +2 -1
- data/examples/018-composer.rb +1 -1
- data/examples/020-column_box.rb +2 -1
- data/examples/025-table_box.rb +46 -0
- data/lib/hexapdf/cli/command.rb +5 -2
- data/lib/hexapdf/cli/form.rb +5 -5
- data/lib/hexapdf/cli/inspect.rb +3 -3
- data/lib/hexapdf/cli.rb +4 -0
- data/lib/hexapdf/composer.rb +104 -52
- data/lib/hexapdf/configuration.rb +44 -39
- data/lib/hexapdf/content/canvas.rb +393 -267
- data/lib/hexapdf/content/color_space.rb +72 -25
- data/lib/hexapdf/content/graphic_object/arc.rb +57 -24
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +66 -23
- data/lib/hexapdf/content/graphic_object/geom2d.rb +47 -6
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +58 -36
- data/lib/hexapdf/content/graphic_object.rb +6 -7
- data/lib/hexapdf/content/graphics_state.rb +54 -45
- data/lib/hexapdf/content/operator.rb +52 -54
- data/lib/hexapdf/content/parser.rb +2 -2
- data/lib/hexapdf/content/processor.rb +15 -15
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/content.rb +5 -0
- data/lib/hexapdf/dictionary.rb +6 -5
- data/lib/hexapdf/dictionary_fields.rb +42 -14
- data/lib/hexapdf/digital_signature/cms_handler.rb +2 -2
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +2 -3
- data/lib/hexapdf/digital_signature/signature.rb +6 -6
- data/lib/hexapdf/digital_signature/signatures.rb +13 -12
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +14 -5
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +2 -4
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +4 -4
- data/lib/hexapdf/digital_signature/signing.rb +4 -0
- data/lib/hexapdf/digital_signature/verification_result.rb +2 -2
- data/lib/hexapdf/digital_signature.rb +7 -2
- data/lib/hexapdf/document/destinations.rb +12 -11
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/layout.rb +167 -39
- data/lib/hexapdf/document/pages.rb +3 -2
- data/lib/hexapdf/document.rb +89 -55
- data/lib/hexapdf/encryption/aes.rb +5 -5
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +2 -2
- 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 +31 -24
- data/lib/hexapdf/encryption/standard_security_handler.rb +45 -36
- data/lib/hexapdf/encryption.rb +7 -2
- data/lib/hexapdf/error.rb +18 -0
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.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 +55 -6
- data/lib/hexapdf/font/cmap/parser.rb +2 -2
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +2 -2
- 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 +3 -3
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +3 -0
- data/lib/hexapdf/font/true_type_wrapper.rb +17 -4
- data/lib/hexapdf/font/type1_wrapper.rb +19 -4
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -2
- data/lib/hexapdf/font_loader/from_file.rb +5 -5
- data/lib/hexapdf/font_loader/standard14.rb +3 -3
- data/lib/hexapdf/font_loader.rb +3 -0
- data/lib/hexapdf/image_loader/jpeg.rb +2 -2
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +2 -2
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +13 -0
- data/lib/hexapdf/layout/box.rb +9 -2
- data/lib/hexapdf/layout/box_fitter.rb +2 -2
- data/lib/hexapdf/layout/column_box.rb +18 -4
- data/lib/hexapdf/layout/frame.rb +30 -12
- data/lib/hexapdf/layout/image_box.rb +5 -0
- data/lib/hexapdf/layout/inline_box.rb +1 -0
- data/lib/hexapdf/layout/list_box.rb +17 -1
- data/lib/hexapdf/layout/page_style.rb +4 -4
- data/lib/hexapdf/layout/style.rb +18 -3
- data/lib/hexapdf/layout/table_box.rb +682 -0
- data/lib/hexapdf/layout/text_box.rb +5 -3
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +12 -4
- data/lib/hexapdf/layout.rb +1 -0
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +18 -7
- data/lib/hexapdf/parser.rb +8 -8
- 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 +3 -3
- data/lib/hexapdf/serializer.rb +15 -15
- data/lib/hexapdf/stream.rb +4 -2
- data/lib/hexapdf/tokenizer.rb +14 -14
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +22 -22
- 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 +2 -2
- data/lib/hexapdf/type/acro_form/form.rb +1 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +4 -4
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
- 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/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +3 -3
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- 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 +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +1 -1
- data/lib/hexapdf/type/cid_font.rb +3 -3
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +2 -2
- data/lib/hexapdf/type/font_type0.rb +3 -3
- 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 +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/names.rb +2 -2
- data/lib/hexapdf/type/object_stream.rb +7 -3
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +19 -10
- 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/trailer.rb +2 -2
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +4 -4
- data/lib/hexapdf/xref_section.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +11 -1
- data/test/hexapdf/content/graphic_object/test_geom2d.rb +7 -0
- data/test/hexapdf/content/test_canvas.rb +0 -1
- data/test/hexapdf/digital_signature/test_signatures.rb +22 -0
- data/test/hexapdf/document/test_files.rb +2 -2
- data/test/hexapdf/document/test_layout.rb +98 -0
- data/test/hexapdf/encryption/test_security_handler.rb +12 -11
- data/test/hexapdf/encryption/test_standard_security_handler.rb +35 -23
- data/test/hexapdf/font/test_true_type_wrapper.rb +18 -1
- data/test/hexapdf/font/test_type1_wrapper.rb +15 -1
- data/test/hexapdf/layout/test_box.rb +1 -1
- data/test/hexapdf/layout/test_column_box.rb +65 -21
- data/test/hexapdf/layout/test_frame.rb +14 -14
- data/test/hexapdf/layout/test_image_box.rb +4 -0
- data/test/hexapdf/layout/test_inline_box.rb +5 -0
- data/test/hexapdf/layout/test_list_box.rb +40 -6
- data/test/hexapdf/layout/test_page_style.rb +3 -2
- data/test/hexapdf/layout/test_style.rb +50 -0
- data/test/hexapdf/layout/test_table_box.rb +722 -0
- data/test/hexapdf/layout/test_text_box.rb +18 -0
- data/test/hexapdf/layout/test_text_layouter.rb +4 -0
- data/test/hexapdf/test_dictionary_fields.rb +4 -1
- data/test/hexapdf/test_document.rb +1 -0
- data/test/hexapdf/test_filter.rb +8 -0
- data/test/hexapdf/test_importer.rb +9 -0
- data/test/hexapdf/test_object.rb +16 -5
- data/test/hexapdf/test_parser.rb +1 -1
- data/test/hexapdf/test_stream.rb +7 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +13 -5
- data/test/hexapdf/type/acro_form/test_form.rb +4 -3
- data/test/hexapdf/type/test_object_stream.rb +9 -3
- data/test/hexapdf/type/test_page.rb +18 -4
- metadata +17 -8
@@ -86,7 +86,7 @@ module HexaPDF
|
|
86
86
|
# to combination of the superclass value of the constant and the mapping of flag names to bit
|
87
87
|
# indices.
|
88
88
|
#
|
89
|
-
# See:
|
89
|
+
# See: PDF2.0 s12.7.4.1
|
90
90
|
class Field < Dictionary
|
91
91
|
|
92
92
|
# Provides a #value method for hash that returns self so that a Hash can be used
|
@@ -367,7 +367,7 @@ module HexaPDF
|
|
367
367
|
document.pages.each do |page|
|
368
368
|
if page.key?(:Annots) && (index = page[:Annots].index(self))
|
369
369
|
page[:Annots][index] = widget
|
370
|
-
break # Each annotation dictionary may only appear on one page, see
|
370
|
+
break # Each annotation dictionary may only appear on one page, see PDF2.0 12.5.2
|
371
371
|
end
|
372
372
|
end
|
373
373
|
widget
|
@@ -68,7 +68,7 @@ module HexaPDF
|
|
68
68
|
# HexaPDF uses the configuration option +acro_form.create_appearance_streams+ to determine
|
69
69
|
# whether appearances should automatically be generated.
|
70
70
|
#
|
71
|
-
# See:
|
71
|
+
# See: PDF2.0 s12.7.3, Field, HexaPDF::Type::Annotations::Widget
|
72
72
|
class Form < Dictionary
|
73
73
|
|
74
74
|
extend Utils::BitField
|
@@ -49,13 +49,13 @@ module HexaPDF
|
|
49
49
|
# If the signature should not be visible, the associated widget annotation should have zero
|
50
50
|
# width and height; and/or the 'hidden' or 'no_view' flags of the annotation should be set.
|
51
51
|
#
|
52
|
-
# See:
|
52
|
+
# See: PDF2.0 s12.7.5.5
|
53
53
|
class SignatureField < Field
|
54
54
|
|
55
55
|
# A signature field lock dictionary specifies a set of form fields that should be locked
|
56
56
|
# once the associated signature field is signed.
|
57
57
|
#
|
58
|
-
# See:
|
58
|
+
# See: PDF2.0 s12.7.5.5
|
59
59
|
class LockDictionary < Dictionary
|
60
60
|
|
61
61
|
define_type :SigFieldLock
|
@@ -86,7 +86,7 @@ module HexaPDF
|
|
86
86
|
# The available flags are: filter, sub_filter, v, reasons, legal_attestation, add_rev_info
|
87
87
|
# and digest_method.
|
88
88
|
#
|
89
|
-
# See:
|
89
|
+
# See: PDF2.0 s12.7.5.5
|
90
90
|
class SeedValueDictionary < Dictionary
|
91
91
|
|
92
92
|
extend Utils::BitField
|
@@ -145,7 +145,7 @@ module HexaPDF
|
|
145
145
|
#
|
146
146
|
# The available flags are: subject, issuer, oid, subject_dn, reserved, key_usage and url.
|
147
147
|
#
|
148
|
-
# See:
|
148
|
+
# See: PDF2.0 s12.7.5.5
|
149
149
|
class CertificateSeedValueDictionary < Dictionary
|
150
150
|
|
151
151
|
extend Utils::BitField
|
data/lib/hexapdf/type/action.rb
CHANGED
@@ -44,7 +44,7 @@ module HexaPDF
|
|
44
44
|
# Action dictionaries are used, for example, by annotations or outline items to specify the
|
45
45
|
# action that should be performed. Each action class should be defined under the Actions module.
|
46
46
|
#
|
47
|
-
# See:
|
47
|
+
# See: PDF2.0 s12.6
|
48
48
|
class Action < Dictionary
|
49
49
|
|
50
50
|
define_type :Action
|
@@ -42,7 +42,7 @@ module HexaPDF
|
|
42
42
|
|
43
43
|
# A Launch action dictionary launches an application, opens a document or prints a document.
|
44
44
|
#
|
45
|
-
# See:
|
45
|
+
# See: PDF2.0 s12.6.4.6
|
46
46
|
class Launch < Action
|
47
47
|
|
48
48
|
# The type used for the /Win field of a Launch action dictionary.
|
data/lib/hexapdf/type/actions.rb
CHANGED
@@ -43,7 +43,7 @@ module HexaPDF
|
|
43
43
|
# Annotations are used to associate objects like notes, sounds or movies with a location on a
|
44
44
|
# PDF page or allow the user to interact with a PDF document using a keyboard or mouse.
|
45
45
|
#
|
46
|
-
# See:
|
46
|
+
# See: PDF2.0 s12.5
|
47
47
|
class Annotation < Dictionary
|
48
48
|
|
49
49
|
# The appearance dictionary references appearance streams for various use cases.
|
@@ -52,7 +52,7 @@ module HexaPDF
|
|
52
52
|
# latter is used when the appearance depends on the state of the annotation, e.g. a check box
|
53
53
|
# widget that can be checked or unchecked.
|
54
54
|
#
|
55
|
-
# See:
|
55
|
+
# See: PDF2.0 s12.5.5
|
56
56
|
class AppearanceDictionary < Dictionary
|
57
57
|
|
58
58
|
define_type :XXAppearanceDictionary
|
@@ -101,7 +101,7 @@ module HexaPDF
|
|
101
101
|
|
102
102
|
# Border style dictionary used by various annotation types.
|
103
103
|
#
|
104
|
-
# See:
|
104
|
+
# See: PDF2.0 s12.5.4
|
105
105
|
class Border < Dictionary
|
106
106
|
|
107
107
|
define_type :Border
|
@@ -43,7 +43,7 @@ module HexaPDF
|
|
43
43
|
# Link annotations represent a link to a destination elsewhere in the PDF document or an
|
44
44
|
# action to be performed.
|
45
45
|
#
|
46
|
-
# See:
|
46
|
+
# See: PDF2.0 s12.5.6.5, HexaPDF::Type::Annotation
|
47
47
|
class Link < Annotation
|
48
48
|
|
49
49
|
define_field :Subtype, type: Symbol, required: true, default: :Link
|
@@ -43,7 +43,7 @@ module HexaPDF
|
|
43
43
|
# Markup annotations are used to "mark up" a PDF document, most of the available PDF
|
44
44
|
# annotations are actually markup annotations.
|
45
45
|
#
|
46
|
-
# See:
|
46
|
+
# See: PDF2.0 s12.5.6.2, HexaPDF::Type::Annotation
|
47
47
|
class MarkupAnnotation < Annotation
|
48
48
|
|
49
49
|
define_field :T, type: String, version: '1.1'
|
@@ -43,7 +43,7 @@ module HexaPDF
|
|
43
43
|
# Text annotations are "sticky notes" attached to a point in a PDF document. They act as if
|
44
44
|
# the NoZoom and NoRotate flags were always set.
|
45
45
|
#
|
46
|
-
# See:
|
46
|
+
# See: PDF2.0 s12.5.6.4, HexaPDF::Type::MarkupAnnotation
|
47
47
|
class Text < MarkupAnnotation
|
48
48
|
|
49
49
|
define_field :Subtype, type: Symbol, required: true, default: :Text
|
@@ -45,7 +45,7 @@ module HexaPDF
|
|
45
45
|
# Widget annotations are used by interactive forms to represent the appearance of fields and
|
46
46
|
# to manage user interactions.
|
47
47
|
#
|
48
|
-
# See:
|
48
|
+
# See: PDF2.0 s12.5.6.19, HexaPDF::Type::Annotation
|
49
49
|
class Widget < Annotation
|
50
50
|
|
51
51
|
# The dictionary used by the /MK key of the widget annotation.
|
@@ -264,7 +264,7 @@ module HexaPDF
|
|
264
264
|
# the /DA key on the widget (although /DA is not defined for widget, this is how Acrobat
|
265
265
|
# does it).
|
266
266
|
#
|
267
|
-
# See:
|
267
|
+
# See: PDF2.0 s12.5.6.19 and s12.7.4.3
|
268
268
|
def marker_style(style: nil, size: nil, color: nil)
|
269
269
|
field = form_field
|
270
270
|
if style || size || color
|
@@ -41,7 +41,7 @@ module HexaPDF
|
|
41
41
|
|
42
42
|
# Namespace module for all PDF annotation dictionary types.
|
43
43
|
#
|
44
|
-
# See:
|
44
|
+
# See: PDF2.0 s12.5.6, Annotation
|
45
45
|
module Annotations
|
46
46
|
|
47
47
|
autoload(:MarkupAnnotation, 'hexapdf/type/annotations/markup_annotation')
|
data/lib/hexapdf/type/catalog.rb
CHANGED
@@ -42,7 +42,7 @@ module HexaPDF
|
|
42
42
|
# Represents a generic CIDFont which can only be used as a descendant font of a composite PDF
|
43
43
|
# font.
|
44
44
|
#
|
45
|
-
# See:
|
45
|
+
# See: PDF2.0 s9.7.4
|
46
46
|
class CIDFont < Font
|
47
47
|
|
48
48
|
DEFAULT_WIDTH = 1000 # :nodoc:
|
@@ -66,7 +66,7 @@ module HexaPDF
|
|
66
66
|
# Sets the /W and /DW keys using the given array of [CID, width] pairs and an optional default
|
67
67
|
# width.
|
68
68
|
#
|
69
|
-
# See:
|
69
|
+
# See: PDF2.0 s9.7.4.3
|
70
70
|
def set_widths(widths, default_width: DEFAULT_WIDTH)
|
71
71
|
if widths.empty?
|
72
72
|
(default_width == DEFAULT_WIDTH ? delete(:DW) : self[:DW] = default_width)
|
@@ -93,7 +93,7 @@ module HexaPDF
|
|
93
93
|
#
|
94
94
|
# Note that the hash is cached internally when accessed the first time.
|
95
95
|
#
|
96
|
-
# See:
|
96
|
+
# See: PDF2.0 s9.7.4.3
|
97
97
|
def widths
|
98
98
|
cache(:widths) do
|
99
99
|
result = {}
|
@@ -46,7 +46,7 @@ module HexaPDF
|
|
46
46
|
# Type::FileSpecification dictionary or with the document as a whole through the /EmbeddedFiles
|
47
47
|
# entry in the document catalog's /Names dictionary.
|
48
48
|
#
|
49
|
-
# See:
|
49
|
+
# See: PDF2.0 s7.11.4, FileSpecification
|
50
50
|
class EmbeddedFile < Stream
|
51
51
|
|
52
52
|
# The type used for the /Mac field of an EmbeddedFile::Parameters dictionary.
|
@@ -60,7 +60,7 @@ module HexaPDF
|
|
60
60
|
# is useful to provide embedding/unembedding operations in this class, see #embed and
|
61
61
|
# #unembed.
|
62
62
|
#
|
63
|
-
# See:
|
63
|
+
# See: PDF2.0 s7.11
|
64
64
|
class FileSpecification < Dictionary
|
65
65
|
|
66
66
|
# The type used for the /EF field of a FileSpecification
|
@@ -107,7 +107,7 @@ module HexaPDF
|
|
107
107
|
# /Unix, /Mac and /DOS).
|
108
108
|
def path
|
109
109
|
tmp = (self[:UF] || self[:F] || self[:Unix] || self[:Mac] || self[:DOS] || '').dup
|
110
|
-
tmp.gsub!(/\\\//, "/") #
|
110
|
+
tmp.gsub!(/\\\//, "/") # PDF2.0 s7.11.2.1 but / in filename is interpreted as separator!
|
111
111
|
tmp.tr!("\\", "/") # always use slashes instead of back-slashes!
|
112
112
|
tmp
|
113
113
|
end
|
@@ -44,7 +44,7 @@ module HexaPDF
|
|
44
44
|
#
|
45
45
|
# A simple font has only single-byte character codes and only supports horizontal metrics.
|
46
46
|
#
|
47
|
-
# See:
|
47
|
+
# See: PDF2.0 s9.6
|
48
48
|
class FontSimple < Font
|
49
49
|
|
50
50
|
define_field :FirstChar, type: Integer
|
@@ -129,7 +129,7 @@ module HexaPDF
|
|
129
129
|
#
|
130
130
|
# Always returns +true+ for simple fonts.
|
131
131
|
#
|
132
|
-
# See:
|
132
|
+
# See: PDF2.0 s9.3.3
|
133
133
|
def word_spacing_applicable?
|
134
134
|
true
|
135
135
|
end
|
@@ -48,7 +48,7 @@ module HexaPDF
|
|
48
48
|
# Composite fonts also allow for vertical writing mode and support TrueType as well as OpenType
|
49
49
|
# fonts.
|
50
50
|
#
|
51
|
-
# See:
|
51
|
+
# See: PDF2.0 s9.7
|
52
52
|
class FontType0 < Font
|
53
53
|
|
54
54
|
define_field :Subtype, type: Symbol, required: true, default: :Type0
|
@@ -110,7 +110,7 @@ module HexaPDF
|
|
110
110
|
#
|
111
111
|
# Note that the return value is cached when accessed the first time.
|
112
112
|
#
|
113
|
-
# See:
|
113
|
+
# See: PDF2.0 s9.3.3
|
114
114
|
def word_spacing_applicable?
|
115
115
|
@word_spacing_applicable ||= ((cmap.read_codes("\x20") && true) rescue false)
|
116
116
|
end
|
@@ -138,7 +138,7 @@ module HexaPDF
|
|
138
138
|
#
|
139
139
|
# Note that the CMap is cached internally when accessed the first time.
|
140
140
|
#
|
141
|
-
# See:
|
141
|
+
# See: PDF2.0 s9.10.2
|
142
142
|
def ucs2_cmap
|
143
143
|
cache(:ucs2_cmap) do
|
144
144
|
encoding = self[:Encoding]
|
@@ -45,7 +45,7 @@ module HexaPDF
|
|
45
45
|
# If it is of a different form, things won't work correctly. This will be handled once such a
|
46
46
|
# case is found.
|
47
47
|
#
|
48
|
-
# See:
|
48
|
+
# See: PDF2.0 s9.6.4
|
49
49
|
class FontType3 < FontSimple
|
50
50
|
|
51
51
|
define_field :Subtype, type: Symbol, required: true, default: :Type3
|
data/lib/hexapdf/type/form.rb
CHANGED
data/lib/hexapdf/type/image.rb
CHANGED
data/lib/hexapdf/type/info.rb
CHANGED
@@ -42,7 +42,7 @@ module HexaPDF
|
|
42
42
|
# Represents the mark information dictionary which provides some general information related to
|
43
43
|
# structured PDF documents.
|
44
44
|
#
|
45
|
-
# See:
|
45
|
+
# See: PDF2.0 s14.7.1
|
46
46
|
class MarkInformation < Dictionary
|
47
47
|
|
48
48
|
define_type :XXMarkInformation
|
data/lib/hexapdf/type/names.rb
CHANGED
@@ -47,7 +47,7 @@ module HexaPDF
|
|
47
47
|
#
|
48
48
|
# This dictionary is linked via the /Names entry from the HexaPDF::Catalog.
|
49
49
|
#
|
50
|
-
# See:
|
50
|
+
# See: PDF2.0 s7.7.4, HexaPDF::Catalog, HexaPDF::NameTreeNode
|
51
51
|
class Names < Dictionary
|
52
52
|
|
53
53
|
define_type :XXNames
|
@@ -71,7 +71,7 @@ module HexaPDF
|
|
71
71
|
# provides a much easier to work with convenience interface for working with destination
|
72
72
|
# objects.
|
73
73
|
#
|
74
|
-
# See:
|
74
|
+
# See: PDF2.0 s12.3.2
|
75
75
|
def destinations
|
76
76
|
self[:Dests] ||= document.add({}, type: NameTreeNode)
|
77
77
|
end
|
@@ -70,7 +70,7 @@ module HexaPDF
|
|
70
70
|
# However, only objects that can be written to the object stream are actually written. The
|
71
71
|
# other objects are deleted from the object stream (#delete_object) and written normally.
|
72
72
|
#
|
73
|
-
# See
|
73
|
+
# See PDF2.0 s7.5.7
|
74
74
|
class ObjectStream < HexaPDF::Stream
|
75
75
|
|
76
76
|
# Holds all necessary information to load objects for an object stream.
|
@@ -114,6 +114,7 @@ module HexaPDF
|
|
114
114
|
return @stream_data if defined?(@stream_data)
|
115
115
|
data = stream
|
116
116
|
oids, offsets = parse_oids_and_offsets(data)
|
117
|
+
@objects ||= {}
|
117
118
|
oids.each {|oid| add_object(Reference.new(oid, 0)) }
|
118
119
|
@stream_data = Data.new(data, oids, offsets)
|
119
120
|
end
|
@@ -172,13 +173,16 @@ module HexaPDF
|
|
172
173
|
serializer = Serializer.new
|
173
174
|
obj_to_stm = {}
|
174
175
|
|
175
|
-
|
176
|
+
is_encrypt_dict = document.revisions.each.with_object({}) do |rev, hash|
|
177
|
+
hash[rev.trailer[:Encrypt]] = true
|
178
|
+
end
|
176
179
|
while index < objects.size / 2
|
177
180
|
obj = revision.object(objects[index])
|
178
181
|
|
179
182
|
# Due to a bug in Adobe Acrobat, the Catalog may not be in an object stream if the
|
180
183
|
# document is encrypted
|
181
|
-
if obj.nil? || obj.null? || obj.gen != 0 || obj.kind_of?(Stream) ||
|
184
|
+
if obj.nil? || obj.null? || obj.gen != 0 || obj.kind_of?(Stream) ||
|
185
|
+
is_encrypt_dict[obj] ||
|
182
186
|
obj.type == :Catalog ||
|
183
187
|
obj.type == :Sig || obj.type == :DocTimeStamp ||
|
184
188
|
(obj.respond_to?(:key?) && obj.key?(:ByteRange) && obj.key?(:Contents))
|
data/lib/hexapdf/type/outline.rb
CHANGED
@@ -60,7 +60,7 @@ module HexaPDF
|
|
60
60
|
# Since many dictionary keys need to be kept up-to-date when manipulating the outline item tree,
|
61
61
|
# it is not recommended to manually do this but to rely on the provided convenience methods.
|
62
62
|
#
|
63
|
-
# See:
|
63
|
+
# See: PDF2.0 s12.3.3
|
64
64
|
class OutlineItem < Dictionary
|
65
65
|
|
66
66
|
extend Utils::BitField
|
data/lib/hexapdf/type/page.rb
CHANGED
@@ -54,7 +54,7 @@ module HexaPDF
|
|
54
54
|
# Field inheritance means that if a field is not set on the page object itself, the value is
|
55
55
|
# taken from the nearest page tree ancestor that has this value set.
|
56
56
|
#
|
57
|
-
# See:
|
57
|
+
# See: PDF2.0 s7.7.3.3, s7.7.3.4, Pages
|
58
58
|
class Page < Dictionary
|
59
59
|
|
60
60
|
# The predefined paper sizes in points (1/72 inch):
|
@@ -223,7 +223,7 @@ module HexaPDF
|
|
223
223
|
# The art box defines the region of the page's meaningful content as intended by the
|
224
224
|
# author. The default is the crop box.
|
225
225
|
#
|
226
|
-
# See:
|
226
|
+
# See: PDF2.0 s14.11.2
|
227
227
|
def box(type = :crop, rectangle = nil)
|
228
228
|
if rectangle
|
229
229
|
case type
|
@@ -522,8 +522,8 @@ module HexaPDF
|
|
522
522
|
# Yields each annotation of this page.
|
523
523
|
def each_annotation
|
524
524
|
return to_enum(__method__) unless block_given?
|
525
|
-
self[:Annots]
|
526
|
-
next unless annotation
|
525
|
+
Array(self[:Annots]).each do |annotation|
|
526
|
+
next unless annotation&.key?(:Subtype) && annotation&.key?(:Rect)
|
527
527
|
yield(document.wrap(annotation, type: :Annot))
|
528
528
|
end
|
529
529
|
self
|
@@ -539,10 +539,14 @@ module HexaPDF
|
|
539
539
|
# If an annotation is a form field widget, only the widget will be deleted but not the form
|
540
540
|
# field itself.
|
541
541
|
def flatten_annotations(annotations = self[:Annots])
|
542
|
-
not_flattened = (annotations || []
|
542
|
+
not_flattened = Array(annotations) || []
|
543
543
|
return not_flattened unless key?(:Annots)
|
544
544
|
|
545
|
-
annotations =
|
545
|
+
annotations = if annotations == self[:Annots]
|
546
|
+
not_flattened
|
547
|
+
else
|
548
|
+
not_flattened & Array(self[:Annots])
|
549
|
+
end
|
546
550
|
return not_flattened if annotations.empty?
|
547
551
|
|
548
552
|
canvas = self.canvas(type: :overlay)
|
@@ -554,6 +558,11 @@ module HexaPDF
|
|
554
558
|
to_delete = []
|
555
559
|
not_flattened -= annotations
|
556
560
|
annotations.each do |annotation|
|
561
|
+
unless annotation&.key?(:Subtype) && annotation&.key?(:Rect)
|
562
|
+
to_delete << annotation if annotation
|
563
|
+
next
|
564
|
+
end
|
565
|
+
|
557
566
|
annotation = document.wrap(annotation, type: :Annot)
|
558
567
|
appearance = annotation.appearance
|
559
568
|
if annotation.flagged?(:hidden) || annotation.flagged?(:invisible)
|
@@ -567,8 +576,8 @@ module HexaPDF
|
|
567
576
|
rect = annotation[:Rect]
|
568
577
|
box = appearance.box
|
569
578
|
|
570
|
-
#
|
571
|
-
# Step
|
579
|
+
# PDF2.0 12.5.5 algorithm
|
580
|
+
# Step 1) Calculate smallest rectangle containing transformed bounding box
|
572
581
|
matrix = HexaPDF::Content::TransformationMatrix.new(*appearance[:Matrix].value)
|
573
582
|
llx, lly = matrix.evaluate(box.left, box.bottom)
|
574
583
|
ulx, uly = matrix.evaluate(box.left, box.top)
|
@@ -582,12 +591,12 @@ module HexaPDF
|
|
582
591
|
next
|
583
592
|
end
|
584
593
|
|
585
|
-
# Step
|
594
|
+
# Step 2) Fit calculated rectangle to annotation rectangle by translating/scaling
|
586
595
|
a = HexaPDF::Content::TransformationMatrix.new
|
587
596
|
a.translate(rect.left - left, rect.bottom - bottom)
|
588
597
|
a.scale(rect.width.fdiv(right - left), rect.height.fdiv(top - bottom))
|
589
598
|
|
590
|
-
# Step
|
599
|
+
# Step 3) Premultiply form matrix - done implicitly when drawing the XObject
|
591
600
|
|
592
601
|
canvas.transform(*a) do
|
593
602
|
# Use [box.left, box.bottom] to counter default translation in #xobject since that
|
@@ -70,7 +70,7 @@ module HexaPDF
|
|
70
70
|
#
|
71
71
|
# "", "", "", ... (i.e. always the empty string)
|
72
72
|
#
|
73
|
-
# See:
|
73
|
+
# See: PDF2.0 s12.4.2, HexaPDF::Document::Pages, HexaPDF::Type::Catalog
|
74
74
|
class PageLabel < Dictionary
|
75
75
|
|
76
76
|
define_type :PageLabel
|