hexapdf 0.11.9 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +157 -0
- data/LICENSE +1 -1
- data/examples/001-hello_world.rb +1 -1
- data/examples/002-graphics.rb +1 -1
- data/examples/003-arcs.rb +1 -1
- data/examples/004-optimizing.rb +1 -1
- data/examples/005-merging.rb +1 -1
- data/examples/006-standard_pdf_fonts.rb +1 -1
- data/examples/007-truetype.rb +1 -1
- data/examples/008-show_char_bboxes.rb +1 -1
- data/examples/009-text_layouter_alignment.rb +1 -1
- data/examples/010-text_layouter_inline_boxes.rb +1 -1
- data/examples/011-text_layouter_line_wrapping.rb +1 -1
- data/examples/012-text_layouter_styling.rb +1 -1
- data/examples/013-text_layouter_shapes.rb +1 -1
- data/examples/014-text_in_polygon.rb +1 -1
- data/examples/015-boxes.rb +1 -1
- data/examples/016-frame_automatic_box_placement.rb +1 -1
- data/examples/017-frame_text_flow.rb +1 -1
- data/examples/018-composer.rb +1 -1
- data/examples/019-acro_form.rb +51 -0
- data/lib/hexapdf.rb +1 -1
- data/lib/hexapdf/cli.rb +3 -1
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +22 -11
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/form.rb +240 -0
- data/lib/hexapdf/cli/image2pdf.rb +3 -2
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +52 -3
- data/lib/hexapdf/cli/inspect.rb +31 -9
- data/lib/hexapdf/cli/merge.rb +2 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +81 -11
- data/lib/hexapdf/content.rb +3 -1
- data/lib/hexapdf/content/canvas.rb +5 -18
- data/lib/hexapdf/content/color_space.rb +111 -32
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +4 -4
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +9 -9
- data/lib/hexapdf/content/parser.rb +18 -5
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/content/transformation_matrix.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +5 -5
- data/lib/hexapdf/dictionary_fields.rb +2 -10
- data/lib/hexapdf/document.rb +45 -17
- data/lib/hexapdf/document/files.rb +1 -2
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/pages.rb +3 -14
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +2 -2
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +2 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter.rb +3 -3
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/{jpx_decode.rb → pass_through.rb} +5 -5
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +2 -5
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +9 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +7 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +1 -1
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +3 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +54 -51
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +1 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +68 -52
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +4 -3
- data/lib/hexapdf/importer.rb +2 -4
- data/lib/hexapdf/layout.rb +1 -1
- data/lib/hexapdf/layout/box.rb +1 -1
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +2 -2
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/style.rb +24 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +1 -1
- data/lib/hexapdf/layout/text_shaper.rb +4 -3
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +32 -27
- data/lib/hexapdf/parser.rb +69 -6
- data/lib/hexapdf/pdf_array.rb +10 -3
- data/lib/hexapdf/rectangle.rb +31 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +2 -1
- data/lib/hexapdf/revisions.rb +30 -22
- data/lib/hexapdf/serializer.rb +2 -2
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +7 -5
- data/lib/hexapdf/tokenizer.rb +5 -4
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/type/acro_form.rb +7 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +405 -0
- data/lib/hexapdf/type/acro_form/button_field.rb +305 -0
- data/lib/hexapdf/type/acro_form/choice_field.rb +220 -0
- data/lib/hexapdf/type/acro_form/field.rb +250 -17
- data/lib/hexapdf/type/acro_form/form.rb +159 -7
- data/lib/hexapdf/type/acro_form/text_field.rb +187 -0
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +122 -0
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +4 -3
- data/lib/hexapdf/type/annotation.rb +73 -3
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/annotations/link.rb +2 -2
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +238 -2
- data/lib/hexapdf/type/catalog.rb +23 -3
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font.rb +18 -1
- data/lib/hexapdf/type/font_descriptor.rb +2 -2
- data/lib/hexapdf/type/font_simple.rb +4 -2
- data/lib/hexapdf/type/font_true_type.rb +7 -3
- data/lib/hexapdf/type/font_type0.rb +2 -2
- data/lib/hexapdf/type/font_type1.rb +16 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +12 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +5 -3
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/page.rb +36 -12
- data/lib/hexapdf/type/page_tree_node.rb +37 -16
- data/lib/hexapdf/type/resources.rb +17 -3
- data/lib/hexapdf/type/trailer.rb +4 -6
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +38 -24
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +19 -16
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +6 -1
- data/test/hexapdf/content/common.rb +2 -2
- data/test/hexapdf/content/graphic_object/test_arc.rb +4 -4
- data/test/hexapdf/content/test_canvas.rb +3 -3
- data/test/hexapdf/content/test_color_space.rb +71 -8
- data/test/hexapdf/content/test_operator.rb +22 -22
- data/test/hexapdf/content/test_parser.rb +14 -0
- data/test/hexapdf/document/test_fonts.rb +1 -1
- data/test/hexapdf/document/test_pages.rb +6 -6
- data/test/hexapdf/encryption/test_aes.rb +4 -4
- data/test/hexapdf/encryption/test_standard_security_handler.rb +11 -11
- data/test/hexapdf/filter/test_ascii85_decode.rb +1 -1
- data/test/hexapdf/filter/test_ascii_hex_decode.rb +1 -1
- data/test/hexapdf/font/encoding/test_base.rb +10 -0
- data/test/hexapdf/font/encoding/test_difference_encoding.rb +8 -0
- data/test/hexapdf/font/test_true_type_wrapper.rb +10 -7
- data/test/hexapdf/font/test_type1_wrapper.rb +33 -8
- data/test/hexapdf/layout/test_style.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +3 -4
- data/test/hexapdf/test_configuration.rb +2 -2
- data/test/hexapdf/test_dictionary.rb +3 -1
- data/test/hexapdf/test_dictionary_fields.rb +2 -2
- data/test/hexapdf/test_document.rb +16 -4
- data/test/hexapdf/test_object.rb +44 -26
- data/test/hexapdf/test_parser.rb +125 -55
- data/test/hexapdf/test_pdf_array.rb +7 -0
- data/test/hexapdf/test_rectangle.rb +14 -0
- data/test/hexapdf/test_revision.rb +3 -0
- data/test/hexapdf/test_revisions.rb +35 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_appearance_generator.rb +521 -0
- data/test/hexapdf/type/acro_form/test_button_field.rb +281 -0
- data/test/hexapdf/type/acro_form/test_choice_field.rb +137 -0
- data/test/hexapdf/type/acro_form/test_field.rb +163 -6
- data/test/hexapdf/type/acro_form/test_form.rb +189 -22
- data/test/hexapdf/type/acro_form/test_text_field.rb +121 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +77 -0
- data/test/hexapdf/type/annotations/test_text.rb +1 -1
- data/test/hexapdf/type/annotations/test_widget.rb +199 -0
- data/test/hexapdf/type/test_annotation.rb +45 -0
- data/test/hexapdf/type/test_catalog.rb +18 -0
- data/test/hexapdf/type/test_font.rb +5 -0
- data/test/hexapdf/type/test_font_simple.rb +2 -1
- data/test/hexapdf/type/test_font_true_type.rb +6 -0
- data/test/hexapdf/type/test_font_type1.rb +8 -0
- data/test/hexapdf/type/test_form.rb +19 -1
- data/test/hexapdf/type/test_image.rb +7 -0
- data/test/hexapdf/type/test_page.rb +45 -7
- data/test/hexapdf/type/test_page_tree_node.rb +62 -12
- data/test/hexapdf/type/test_resources.rb +20 -0
- data/test/hexapdf/type/test_trailer.rb +4 -0
- data/test/hexapdf/utils/test_bit_field.rb +15 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +10 -9
- data/test/test_helper.rb +1 -1
- metadata +34 -21
- data/lib/hexapdf/filter/dct_decode.rb +0 -60
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -48,8 +48,12 @@ module HexaPDF
|
|
|
48
48
|
private
|
|
49
49
|
|
|
50
50
|
def perform_validation
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
std_font = FontType1::StandardFonts.standard_font?(self[:BaseFont])
|
|
52
|
+
super(ignore_missing_font_fields: std_font)
|
|
53
|
+
|
|
54
|
+
if self[:FontDescriptor].nil? && !std_font
|
|
55
|
+
yield("Required field FontDescriptor is not set", false)
|
|
56
|
+
end
|
|
53
57
|
end
|
|
54
58
|
|
|
55
59
|
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-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
|
|
@@ -59,7 +59,7 @@ module HexaPDF
|
|
|
59
59
|
# Returns the CID font of this type 0 font.
|
|
60
60
|
def descendant_font
|
|
61
61
|
document.cache(@data, :descendant_font) do
|
|
62
|
-
document.wrap(
|
|
62
|
+
document.wrap(self[:DescendantFonts][0])
|
|
63
63
|
end
|
|
64
64
|
end
|
|
65
65
|
|
|
@@ -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
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
require 'hexapdf/data_dir'
|
|
38
38
|
require 'hexapdf/type/font_simple'
|
|
39
39
|
require 'hexapdf/font/type1'
|
|
40
|
+
require 'hexapdf/font/type1_wrapper'
|
|
40
41
|
|
|
41
42
|
module HexaPDF
|
|
42
43
|
module Type
|
|
@@ -105,6 +106,20 @@ module HexaPDF
|
|
|
105
106
|
define_field :Subtype, type: Symbol, required: true, default: :Type1
|
|
106
107
|
define_field :BaseFont, type: Symbol, required: true
|
|
107
108
|
|
|
109
|
+
# Overrides the default to provide a font wrapper in case none is set and the font is one of
|
|
110
|
+
# the standard fonts.
|
|
111
|
+
#
|
|
112
|
+
# See: Font#font_wrapper
|
|
113
|
+
def font_wrapper
|
|
114
|
+
if (tmp = super)
|
|
115
|
+
tmp
|
|
116
|
+
elsif StandardFonts.standard_font?(self[:BaseFont])
|
|
117
|
+
self.font_wrapper = HexaPDF::Font::Type1Wrapper.new(document,
|
|
118
|
+
StandardFonts.font(self[:BaseFont]),
|
|
119
|
+
pdf_object: self)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
108
123
|
# Returns the unscaled width of the given code point in glyph units, or 0 if the width for the
|
|
109
124
|
# code point is missing.
|
|
110
125
|
def width(code)
|
|
@@ -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/form.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
|
|
@@ -101,7 +101,8 @@ module HexaPDF
|
|
|
101
101
|
|
|
102
102
|
# Returns the resource dictionary which is automatically created if it doesn't exist.
|
|
103
103
|
def resources
|
|
104
|
-
self[:Resources] ||= document.wrap({
|
|
104
|
+
self[:Resources] ||= document.wrap({ProcSet: [:PDF, :Text, :ImageB, :ImageC, :ImageI]},
|
|
105
|
+
type: :XXResources)
|
|
105
106
|
end
|
|
106
107
|
|
|
107
108
|
# Processes the content stream of the form XObject with the given processor object.
|
|
@@ -126,13 +127,22 @@ module HexaPDF
|
|
|
126
127
|
# The canvas object is cached once it is created so that its graphics state is correctly
|
|
127
128
|
# retained without the need for parsing its contents.
|
|
128
129
|
#
|
|
130
|
+
# If the bounding box of the form XObject doesn't have its origin at (0, 0), the canvas origin
|
|
131
|
+
# is translated into the bottom left corner so that this detail doesn't matter when using the
|
|
132
|
+
# canvas. This means that the canvas' origin is always at the bottom left corner of the
|
|
133
|
+
# bounding box.
|
|
134
|
+
#
|
|
129
135
|
# *Note* that a canvas can only be retrieved for initially empty form XObjects!
|
|
130
136
|
def canvas
|
|
131
137
|
document.cache(@data, :canvas) do
|
|
132
138
|
unless stream.empty?
|
|
133
139
|
raise HexaPDF::Error, "Cannot create a canvas for a form XObjects with contents"
|
|
134
140
|
end
|
|
141
|
+
|
|
135
142
|
canvas = Content::Canvas.new(self)
|
|
143
|
+
if box.left != 0 || box.bottom != 0
|
|
144
|
+
canvas.save_graphics_state.translate(box.left, box.bottom)
|
|
145
|
+
end
|
|
136
146
|
self.stream = canvas.stream_data
|
|
137
147
|
set_filter(:FlateDecode)
|
|
138
148
|
canvas
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# This file is part of HexaPDF.
|
|
5
5
|
#
|
|
6
6
|
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
|
7
|
-
# Copyright (C) 2014-
|
|
7
|
+
# Copyright (C) 2014-2020 Thomas Leitner
|
|
8
8
|
#
|
|
9
9
|
# HexaPDF is free software: you can redistribute it and/or modify it
|
|
10
10
|
# under the terms of the GNU Affero General Public License version 3 as
|
data/lib/hexapdf/type/image.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
|
|
@@ -150,7 +150,7 @@ module HexaPDF
|
|
|
150
150
|
color_space, = *self[:ColorSpace]
|
|
151
151
|
if color_space == :Indexed
|
|
152
152
|
result.indexed = true
|
|
153
|
-
color_space, = *
|
|
153
|
+
color_space, = *self[:ColorSpace][1]
|
|
154
154
|
end
|
|
155
155
|
case color_space
|
|
156
156
|
when :DeviceRGB, :CalRGB
|
|
@@ -169,6 +169,8 @@ module HexaPDF
|
|
|
169
169
|
result.writable = false if result.type == :png
|
|
170
170
|
end
|
|
171
171
|
|
|
172
|
+
result.writable = false if self[:SMask]
|
|
173
|
+
|
|
172
174
|
result
|
|
173
175
|
end
|
|
174
176
|
|
|
@@ -238,7 +240,7 @@ module HexaPDF
|
|
|
238
240
|
end
|
|
239
241
|
|
|
240
242
|
if color_type == ImageLoader::PNG::INDEXED
|
|
241
|
-
palette_data =
|
|
243
|
+
palette_data = self[:ColorSpace][3]
|
|
242
244
|
palette_data = palette_data.stream unless palette_data.kind_of?(String)
|
|
243
245
|
palette = ''.b
|
|
244
246
|
if info.color_space == :rgb
|
data/lib/hexapdf/type/info.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/names.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
|
data/lib/hexapdf/type/page.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
|
|
@@ -304,7 +304,7 @@ module HexaPDF
|
|
|
304
304
|
def contents
|
|
305
305
|
Array(self[:Contents]).each_with_object("".b) do |content_stream, content|
|
|
306
306
|
content << " " unless content.empty?
|
|
307
|
-
content <<
|
|
307
|
+
content << content_stream.stream
|
|
308
308
|
end
|
|
309
309
|
end
|
|
310
310
|
|
|
@@ -323,10 +323,11 @@ module HexaPDF
|
|
|
323
323
|
end
|
|
324
324
|
end
|
|
325
325
|
|
|
326
|
-
# Returns the possibly inherited resource dictionary which is automatically created if it
|
|
326
|
+
# Returns the, possibly inherited, resource dictionary which is automatically created if it
|
|
327
327
|
# doesn't exist.
|
|
328
328
|
def resources
|
|
329
|
-
self[:Resources] ||= document.wrap({
|
|
329
|
+
self[:Resources] ||= document.wrap({ProcSet: [:PDF, :Text, :ImageB, :ImageC, :ImageI]},
|
|
330
|
+
type: :XXResources)
|
|
330
331
|
end
|
|
331
332
|
|
|
332
333
|
# Processes the content streams associated with the page with the given processor object.
|
|
@@ -344,8 +345,7 @@ module HexaPDF
|
|
|
344
345
|
node = self
|
|
345
346
|
while (parent_node = node[:Parent])
|
|
346
347
|
parent_node[:Kids].each do |kid|
|
|
347
|
-
kid
|
|
348
|
-
break if kid.data == node.data
|
|
348
|
+
break if kid == node
|
|
349
349
|
idx += (kid.type == :Page ? 1 : kid[:Count])
|
|
350
350
|
end
|
|
351
351
|
node = parent_node
|
|
@@ -353,11 +353,26 @@ module HexaPDF
|
|
|
353
353
|
idx
|
|
354
354
|
end
|
|
355
355
|
|
|
356
|
+
# Returns all parent nodes of the page up to the root of the page tree.
|
|
357
|
+
#
|
|
358
|
+
# The direct parent is the first node in the array and the root node the last.
|
|
359
|
+
def ancestor_nodes
|
|
360
|
+
parent = self[:Parent]
|
|
361
|
+
result = [parent]
|
|
362
|
+
result << parent while (parent = parent[:Parent])
|
|
363
|
+
result
|
|
364
|
+
end
|
|
365
|
+
|
|
356
366
|
# Returns the requested type of canvas for the page.
|
|
357
367
|
#
|
|
358
368
|
# The canvas object is cached once it is created so that its graphics state is correctly
|
|
359
369
|
# retained without the need for parsing its contents.
|
|
360
370
|
#
|
|
371
|
+
# If the media box of the page doesn't have its origin at (0, 0), the canvas origin is
|
|
372
|
+
# translated into the bottom left corner so that this detail doesn't matter when using the
|
|
373
|
+
# canvas. This means that the canvas' origin is always at the bottom left corner of the media
|
|
374
|
+
# box.
|
|
375
|
+
#
|
|
361
376
|
# type::
|
|
362
377
|
# Can either be
|
|
363
378
|
# * :page for getting the canvas for the page itself (only valid for initially empty pages)
|
|
@@ -374,16 +389,25 @@ module HexaPDF
|
|
|
374
389
|
raise HexaPDF::Error, "Cannot get the canvas for a page with contents"
|
|
375
390
|
end
|
|
376
391
|
|
|
392
|
+
create_canvas = lambda do
|
|
393
|
+
Content::Canvas.new(self).tap do |canvas|
|
|
394
|
+
media_box = box(:media)
|
|
395
|
+
if media_box.left != 0 || media_box.bottom != 0
|
|
396
|
+
canvas.translate(media_box.left, media_box.bottom)
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
end
|
|
400
|
+
|
|
377
401
|
contents = self[:Contents]
|
|
378
402
|
if contents.nil?
|
|
379
|
-
page_canvas = document.cache(@data, :page_canvas,
|
|
403
|
+
page_canvas = document.cache(@data, :page_canvas, create_canvas.call)
|
|
380
404
|
self[:Contents] = document.add({Filter: :FlateDecode},
|
|
381
405
|
stream: page_canvas.stream_data)
|
|
382
406
|
end
|
|
383
407
|
|
|
384
408
|
if type == :overlay || type == :underlay
|
|
385
|
-
underlay_canvas = document.cache(@data, :underlay_canvas,
|
|
386
|
-
overlay_canvas = document.cache(@data, :overlay_canvas,
|
|
409
|
+
underlay_canvas = document.cache(@data, :underlay_canvas, create_canvas.call)
|
|
410
|
+
overlay_canvas = document.cache(@data, :overlay_canvas, create_canvas.call)
|
|
387
411
|
|
|
388
412
|
stream = HexaPDF::StreamData.new do
|
|
389
413
|
Fiber.yield(" q ")
|
|
@@ -396,11 +420,12 @@ module HexaPDF
|
|
|
396
420
|
underlay = document.add({Filter: :FlateDecode}, stream: stream)
|
|
397
421
|
|
|
398
422
|
stream = HexaPDF::StreamData.new do
|
|
399
|
-
Fiber.yield(" Q ")
|
|
423
|
+
Fiber.yield(" Q q ")
|
|
400
424
|
fiber = overlay_canvas.stream_data.fiber
|
|
401
425
|
while fiber.alive? && (data = fiber.resume)
|
|
402
426
|
Fiber.yield(data)
|
|
403
427
|
end
|
|
428
|
+
" Q "
|
|
404
429
|
end
|
|
405
430
|
overlay = document.add({Filter: :FlateDecode}, stream: stream)
|
|
406
431
|
|
|
@@ -448,8 +473,7 @@ module HexaPDF
|
|
|
448
473
|
REQUIRED_INHERITABLE_FIELDS.each do |name|
|
|
449
474
|
next if self[name]
|
|
450
475
|
yield("Inheritable page field #{name} not set", name == :Resources)
|
|
451
|
-
|
|
452
|
-
self[:Resources].validate(&block)
|
|
476
|
+
resources.validate(&block) if name == :Ressources
|
|
453
477
|
end
|
|
454
478
|
end
|
|
455
479
|
|
|
@@ -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,7 @@
|
|
|
35
35
|
#++
|
|
36
36
|
|
|
37
37
|
require 'hexapdf/dictionary'
|
|
38
|
+
require 'hexapdf/error'
|
|
38
39
|
|
|
39
40
|
module HexaPDF
|
|
40
41
|
module Type
|
|
@@ -159,38 +160,58 @@ module HexaPDF
|
|
|
159
160
|
end
|
|
160
161
|
|
|
161
162
|
# :call-seq:
|
|
162
|
-
# pages.delete_page(page)
|
|
163
|
-
# pages.delete_page(index)
|
|
163
|
+
# pages.delete_page(page)
|
|
164
|
+
# pages.delete_page(index)
|
|
164
165
|
#
|
|
165
166
|
# Deletes the given page or the page at the position specified by the zero-based index from
|
|
166
|
-
# the page tree and
|
|
167
|
-
# returned.
|
|
168
|
-
#
|
|
169
|
-
# Note that the page is *not* deleted from the document itself, only from the page tree! This
|
|
170
|
-
# also means that the /Parent entry of the page is set to +nil+ if deleted.
|
|
167
|
+
# the page tree and the document.
|
|
171
168
|
#
|
|
172
169
|
# Negative indices count backwards from the end, i.e. -1 is the last page.
|
|
173
170
|
def delete_page(page)
|
|
174
171
|
page = self.page(page) if page.kind_of?(Integer)
|
|
175
|
-
return
|
|
172
|
+
return unless page && !page.null? && page[:Parent]
|
|
176
173
|
|
|
177
174
|
parent = page[:Parent]
|
|
178
|
-
index = parent[:Kids].index
|
|
175
|
+
index = parent[:Kids].index(page)
|
|
179
176
|
|
|
180
177
|
if index
|
|
181
|
-
ancestors =
|
|
182
|
-
ancestors << parent while (parent = parent[:Parent])
|
|
178
|
+
ancestors = page.ancestor_nodes
|
|
183
179
|
return nil unless ancestors.include?(self)
|
|
184
180
|
|
|
185
181
|
page[:Parent][:Kids].delete_at(index)
|
|
186
182
|
page.delete(:Parent)
|
|
183
|
+
document.delete(page)
|
|
187
184
|
ancestors.each {|node| node[:Count] -= 1 }
|
|
188
|
-
page
|
|
189
185
|
else
|
|
190
|
-
|
|
186
|
+
raise HexaPDF::Error, "Given page not found in page tree"
|
|
191
187
|
end
|
|
192
188
|
end
|
|
193
189
|
|
|
190
|
+
# :call-seq:
|
|
191
|
+
# pages.move_page(page, to_index)
|
|
192
|
+
# pages.move_page(index, to_index)
|
|
193
|
+
#
|
|
194
|
+
# Moves the given page or the page at the position specified by the zero-based index to the
|
|
195
|
+
# +to_index+ position.
|
|
196
|
+
#
|
|
197
|
+
# If the page that should be moved, doesn't exist or is invalid, an error is raised.
|
|
198
|
+
#
|
|
199
|
+
# Negative indices count backwards from the end, i.e. -1 is the last page. When using a
|
|
200
|
+
# negative index, the page will be moved after that element. So using an index of -1 will
|
|
201
|
+
# move the page after the last page.
|
|
202
|
+
def move_page(page, to_index)
|
|
203
|
+
page = self.page(page) if page.kind_of?(Integer)
|
|
204
|
+
if page.nil? || page.null? || !page[:Parent] ||
|
|
205
|
+
!(ancestors = page.ancestor_nodes).include?(self)
|
|
206
|
+
raise HexaPDF::Error, "The page to be moved doesn't exist in this page tree"
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
parent = page[:Parent]
|
|
210
|
+
insert_page(to_index, page)
|
|
211
|
+
ancestors.each {|node| node[:Count] -= 1 }
|
|
212
|
+
parent[:Kids].delete(page)
|
|
213
|
+
end
|
|
214
|
+
|
|
194
215
|
# :call-seq:
|
|
195
216
|
# pages.each_page {|page| block } -> pages
|
|
196
217
|
# pages.each_page -> Enumerator
|
|
@@ -225,7 +246,7 @@ module HexaPDF
|
|
|
225
246
|
# Ensures that the /Count and /Parent fields of the whole page tree are set up correctly and
|
|
226
247
|
# that there is at least one page node. This is therefore only done for the root node of the
|
|
227
248
|
# page tree!
|
|
228
|
-
def perform_validation
|
|
249
|
+
def perform_validation(&block)
|
|
229
250
|
super
|
|
230
251
|
return if key?(:Parent)
|
|
231
252
|
|
|
@@ -258,7 +279,7 @@ module HexaPDF
|
|
|
258
279
|
|
|
259
280
|
if self[:Count] == 0
|
|
260
281
|
yield("A PDF document needs at least one page", true)
|
|
261
|
-
add_page.validate
|
|
282
|
+
add_page.validate(&block)
|
|
262
283
|
end
|
|
263
284
|
end
|
|
264
285
|
|
|
@@ -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
|
|
@@ -69,11 +69,10 @@ module HexaPDF
|
|
|
69
69
|
when :DeviceRGB, :DeviceGray, :DeviceCMYK
|
|
70
70
|
GlobalConfiguration.constantize('color_space.map', name).new
|
|
71
71
|
else
|
|
72
|
-
space_definition =
|
|
72
|
+
space_definition = (name == :Pattern ? name : self[:ColorSpace]&.[](name))
|
|
73
73
|
if space_definition.nil?
|
|
74
74
|
raise HexaPDF::Error, "Color space '#{name}' not found in the resources"
|
|
75
75
|
elsif space_definition.kind_of?(Array)
|
|
76
|
-
space_definition.map! {|item| document.deref(item) }
|
|
77
76
|
space_family = space_definition[0]
|
|
78
77
|
else
|
|
79
78
|
space_family = space_definition
|
|
@@ -168,6 +167,20 @@ module HexaPDF
|
|
|
168
167
|
object_setter(:Properties, 'P', dict)
|
|
169
168
|
end
|
|
170
169
|
|
|
170
|
+
# Returns the pattern dictionary stored under the given name.
|
|
171
|
+
#
|
|
172
|
+
# If the dictionary is not found, an error is raised.
|
|
173
|
+
def pattern(name)
|
|
174
|
+
object_getter(:Pattern, name)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Adds the pattern dictionary to the resources and returns the name under which it is stored.
|
|
178
|
+
#
|
|
179
|
+
# If there already exists a name for the given dictionary, it is just returned.
|
|
180
|
+
def add_pattern(object)
|
|
181
|
+
object_setter(:Pattern, 'P', object)
|
|
182
|
+
end
|
|
183
|
+
|
|
171
184
|
private
|
|
172
185
|
|
|
173
186
|
# Helper method for returning an entry of a subdictionary.
|
|
@@ -206,6 +219,7 @@ module HexaPDF
|
|
|
206
219
|
super
|
|
207
220
|
val = self[:ProcSet]
|
|
208
221
|
if !val
|
|
222
|
+
yield("No procedure set specified", true)
|
|
209
223
|
self[:ProcSet] = [:PDF, :Text, :ImageB, :ImageC, :ImageI]
|
|
210
224
|
else
|
|
211
225
|
val.reject! do |name|
|