hexapdf 0.10.0 → 0.11.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 +33 -0
- data/CONTRIBUTERS +1 -1
- data/Rakefile +35 -50
- data/VERSION +1 -1
- data/lib/hexapdf/cli.rb +4 -0
- data/lib/hexapdf/cli/command.rb +6 -2
- data/lib/hexapdf/cli/image2pdf.rb +141 -0
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +32 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +130 -0
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +7 -1
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/dictionary.rb +11 -3
- data/lib/hexapdf/dictionary_fields.rb +32 -3
- data/lib/hexapdf/document.rb +7 -3
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +21 -1
- data/lib/hexapdf/document/pages.rb +2 -2
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -2
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -2
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -4
- data/lib/hexapdf/font/true_type_wrapper.rb +16 -16
- data/lib/hexapdf/font/type1_wrapper.rb +16 -16
- data/lib/hexapdf/font_loader.rb +2 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -0
- data/lib/hexapdf/font_loader/standard14.rb +5 -0
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/layout/box.rb +2 -2
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/style.rb +50 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +2 -2
- data/lib/hexapdf/layout/text_layouter.rb +14 -10
- data/lib/hexapdf/name_tree_node.rb +3 -3
- data/lib/hexapdf/number_tree_node.rb +3 -3
- data/lib/hexapdf/pdf_array.rb +207 -0
- data/lib/hexapdf/rectangle.rb +12 -12
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +6 -4
- data/lib/hexapdf/task/optimize.rb +3 -3
- data/lib/hexapdf/type.rb +2 -0
- data/lib/hexapdf/type/acro_form.rb +51 -0
- data/lib/hexapdf/type/acro_form/field.rb +129 -0
- data/lib/hexapdf/type/acro_form/form.rb +124 -0
- 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/annotation.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -0
- data/lib/hexapdf/type/annotations/link.rb +4 -15
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -1
- data/lib/hexapdf/type/annotations/text.rb +3 -6
- data/lib/hexapdf/type/annotations/widget.rb +90 -0
- data/lib/hexapdf/type/catalog.rb +12 -9
- data/lib/hexapdf/type/cid_font.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +5 -2
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +2 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +11 -6
- data/lib/hexapdf/type/icon_fit.rb +58 -0
- data/lib/hexapdf/type/image.rb +14 -8
- data/lib/hexapdf/type/info.rb +2 -1
- data/lib/hexapdf/type/page.rb +4 -4
- data/lib/hexapdf/type/page_tree_node.rb +3 -7
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +4 -4
- data/lib/hexapdf/type/viewer_preferences.rb +7 -4
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/man/man1/hexapdf.1 +77 -8
- data/test/hexapdf/content/test_canvas.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +3 -3
- data/test/hexapdf/document/test_files.rb +4 -4
- data/test/hexapdf/document/test_fonts.rb +13 -1
- data/test/hexapdf/document/test_images.rb +6 -6
- data/test/hexapdf/document/test_pages.rb +8 -8
- data/test/hexapdf/encryption/test_security_handler.rb +7 -7
- data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -5
- data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
- data/test/hexapdf/font_loader/test_from_configuration.rb +4 -0
- data/test/hexapdf/font_loader/test_standard14.rb +10 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_box.rb +2 -2
- data/test/hexapdf/layout/test_frame.rb +1 -1
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_style.rb +18 -13
- data/test/hexapdf/layout/test_text_box.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +11 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +11 -11
- data/test/hexapdf/test_composer.rb +1 -1
- data/test/hexapdf/test_dictionary.rb +10 -2
- data/test/hexapdf/test_dictionary_fields.rb +27 -3
- data/test/hexapdf/test_document.rb +16 -15
- data/test/hexapdf/test_importer.rb +4 -4
- data/test/hexapdf/test_object.rb +1 -1
- data/test/hexapdf/test_pdf_array.rb +162 -0
- data/test/hexapdf/test_rectangle.rb +3 -5
- data/test/hexapdf/test_serializer.rb +1 -1
- data/test/hexapdf/test_stream.rb +1 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_field.rb +85 -0
- data/test/hexapdf/type/acro_form/test_form.rb +69 -0
- data/test/hexapdf/type/annotations/test_text.rb +2 -6
- data/test/hexapdf/type/annotations/test_widget.rb +24 -0
- data/test/hexapdf/type/test_annotation.rb +1 -1
- data/test/hexapdf/type/test_catalog.rb +1 -1
- data/test/hexapdf/type/test_cid_font.rb +3 -3
- data/test/hexapdf/type/test_font.rb +2 -2
- data/test/hexapdf/type/test_font_descriptor.rb +2 -1
- data/test/hexapdf/type/test_font_simple.rb +3 -3
- data/test/hexapdf/type/test_font_true_type.rb +6 -6
- data/test/hexapdf/type/test_font_type0.rb +5 -5
- data/test/hexapdf/type/test_font_type1.rb +8 -8
- data/test/hexapdf/type/test_font_type3.rb +4 -4
- data/test/hexapdf/type/test_image.rb +16 -12
- data/test/hexapdf/type/test_page.rb +11 -11
- data/test/hexapdf/type/test_page_tree_node.rb +20 -20
- data/test/hexapdf/type/test_resources.rb +6 -6
- data/test/hexapdf/type/test_trailer.rb +5 -2
- data/test/hexapdf/type/test_xref_stream.rb +1 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +35 -35
- metadata +23 -7
- data/test/hexapdf/type/annotations/test_link.rb +0 -19
@@ -54,7 +54,7 @@ module HexaPDF
|
|
54
54
|
define_field :Subtype, type: Symbol, required: true, default: :Type0
|
55
55
|
define_field :BaseFont, type: Symbol, required: true
|
56
56
|
define_field :Encoding, type: [Stream, Symbol], required: true
|
57
|
-
define_field :DescendantFonts, type:
|
57
|
+
define_field :DescendantFonts, type: PDFArray, required: true
|
58
58
|
|
59
59
|
# Returns the CID font of this type 0 font.
|
60
60
|
def descendant_font
|
@@ -47,7 +47,7 @@ module HexaPDF
|
|
47
47
|
define_field :Subtype, type: Symbol, required: true, default: :Type3
|
48
48
|
define_field :Name, type: Symbol
|
49
49
|
define_field :FontBBox, type: Rectangle, required: true
|
50
|
-
define_field :FontMatrix, type:
|
50
|
+
define_field :FontMatrix, type: PDFArray, required: true
|
51
51
|
define_field :CharProcs, type: Dictionary, required: true
|
52
52
|
define_field :Resources, type: Dictionary, version: '1.2'
|
53
53
|
|
data/lib/hexapdf/type/form.rb
CHANGED
@@ -49,9 +49,9 @@ module HexaPDF
|
|
49
49
|
|
50
50
|
define_field :Type, type: Symbol, default: type
|
51
51
|
define_field :Subtype, type: Symbol, required: true, default: :Form
|
52
|
-
define_field :FormType, type: Integer, default: 1
|
52
|
+
define_field :FormType, type: Integer, default: 1, allowed_values: 1
|
53
53
|
define_field :BBox, type: Rectangle, required: true
|
54
|
-
define_field :Matrix, type:
|
54
|
+
define_field :Matrix, type: PDFArray, default: [1, 0, 0, 1, 0, 0]
|
55
55
|
define_field :Resources, type: :XXResources, version: '1.2'
|
56
56
|
define_field :Group, type: Dictionary, version: '1.4'
|
57
57
|
define_field :Ref, type: Dictionary, version: '1.4'
|
@@ -35,6 +35,7 @@
|
|
35
35
|
#++
|
36
36
|
|
37
37
|
require 'hexapdf/dictionary'
|
38
|
+
require 'hexapdf/content/graphics_state'
|
38
39
|
|
39
40
|
module HexaPDF
|
40
41
|
module Type
|
@@ -55,23 +56,27 @@ module HexaPDF
|
|
55
56
|
define_field :LC, type: Integer, version: "1.3"
|
56
57
|
define_field :LJ, type: Integer, version: "1.3"
|
57
58
|
define_field :ML, type: Numeric, version: "1.3"
|
58
|
-
define_field :D, type:
|
59
|
-
define_field :RI, type: Symbol, version: "1.3"
|
59
|
+
define_field :D, type: PDFArray, version: "1.3"
|
60
|
+
define_field :RI, type: Symbol, version: "1.3",
|
61
|
+
allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
|
62
|
+
HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
|
63
|
+
HexaPDF::Content::RenderingIntent::SATURATION,
|
64
|
+
HexaPDF::Content::RenderingIntent::PERCEPTUAL]
|
60
65
|
define_field :OP, type: Boolean
|
61
66
|
define_field :op, type: Boolean, version: "1.3"
|
62
67
|
define_field :OPM, type: Integer, version: "1.3"
|
63
|
-
define_field :Font, type:
|
68
|
+
define_field :Font, type: PDFArray, version: "1.3"
|
64
69
|
define_field :BG, type: [Dictionary, Stream]
|
65
70
|
define_field :BG2, type: [Dictionary, Stream, Symbol], version: "1.3"
|
66
71
|
define_field :UCR, type: [Dictionary, Stream]
|
67
72
|
define_field :UCR2, type: [Dictionary, Stream, Symbol], version: "1.3"
|
68
|
-
define_field :TR, type: [Dictionary, Stream,
|
69
|
-
define_field :TR2, type: [Dictionary, Stream,
|
73
|
+
define_field :TR, type: [Dictionary, Stream, PDFArray, Symbol]
|
74
|
+
define_field :TR2, type: [Dictionary, Stream, PDFArray, Symbol], version: "1.3"
|
70
75
|
define_field :HT, type: [Dictionary, Stream, Symbol]
|
71
76
|
define_field :FL, type: Numeric, version: "1.3"
|
72
77
|
define_field :SM, type: Numeric, version: "1.3"
|
73
78
|
define_field :SA, type: Boolean
|
74
|
-
define_field :BM, type: [Symbol,
|
79
|
+
define_field :BM, type: [Symbol, PDFArray], version: "1.4"
|
75
80
|
define_field :SMask, type: [Dictionary, Symbol], version: "1.4"
|
76
81
|
define_field :CA, type: Numeric, version: "1.4"
|
77
82
|
define_field :ca, type: Numeric, version: "1.4"
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# -*- encoding: utf-8; frozen_string_literal: true -*-
|
2
|
+
#
|
3
|
+
#--
|
4
|
+
# This file is part of HexaPDF.
|
5
|
+
#
|
6
|
+
# HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
|
7
|
+
# Copyright (C) 2014-2019 Thomas Leitner
|
8
|
+
#
|
9
|
+
# HexaPDF is free software: you can redistribute it and/or modify it
|
10
|
+
# under the terms of the GNU Affero General Public License version 3 as
|
11
|
+
# published by the Free Software Foundation with the addition of the
|
12
|
+
# following permission added to Section 15 as permitted in Section 7(a):
|
13
|
+
# FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
|
14
|
+
# THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
|
15
|
+
# INFRINGEMENT OF THIRD PARTY RIGHTS.
|
16
|
+
#
|
17
|
+
# HexaPDF is distributed in the hope that it will be useful, but WITHOUT
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
|
20
|
+
# License for more details.
|
21
|
+
#
|
22
|
+
# You should have received a copy of the GNU Affero General Public License
|
23
|
+
# along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
|
24
|
+
#
|
25
|
+
# The interactive user interfaces in modified source and object code
|
26
|
+
# versions of HexaPDF must display Appropriate Legal Notices, as required
|
27
|
+
# under Section 5 of the GNU Affero General Public License version 3.
|
28
|
+
#
|
29
|
+
# In accordance with Section 7(b) of the GNU Affero General Public
|
30
|
+
# License, a covered work must retain the producer line in every PDF that
|
31
|
+
# is created or manipulated using HexaPDF.
|
32
|
+
#
|
33
|
+
# If the GNU Affero General Public License doesn't fit your need,
|
34
|
+
# commercial licenses are available at <https://gettalong.at/hexapdf/>.
|
35
|
+
#++
|
36
|
+
|
37
|
+
require 'hexapdf/type/annotation'
|
38
|
+
|
39
|
+
module HexaPDF
|
40
|
+
module Type
|
41
|
+
|
42
|
+
# An IconFit dictionary specifies how an icon should be displayed inside an annotation
|
43
|
+
# rectangle.
|
44
|
+
#
|
45
|
+
# See: PDF1.7 s12.7.7.3.2
|
46
|
+
class IconFit < Annotation
|
47
|
+
|
48
|
+
define_type :XXIconFit
|
49
|
+
|
50
|
+
define_field :SW, type: Symbol, default: :A, allowed_values: [:A, :B, :S, :N]
|
51
|
+
define_field :S, type: Symbol, default: :P, allowed_values: [:A, :P]
|
52
|
+
define_field :A, type: PDFArray, default: [0.5, 0.5]
|
53
|
+
define_field :FB, type: Boolean, default: false, version: '1.5'
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
data/lib/hexapdf/type/image.rb
CHANGED
@@ -38,6 +38,7 @@ require 'zlib'
|
|
38
38
|
require 'hexapdf/error'
|
39
39
|
require 'hexapdf/stream'
|
40
40
|
require 'hexapdf/image_loader'
|
41
|
+
require 'hexapdf/content/graphics_state'
|
41
42
|
|
42
43
|
module HexaPDF
|
43
44
|
module Type
|
@@ -57,16 +58,20 @@ module HexaPDF
|
|
57
58
|
define_field :Subtype, type: Symbol, required: true, default: :Image
|
58
59
|
define_field :Width, type: Integer, required: true
|
59
60
|
define_field :Height, type: Integer, required: true
|
60
|
-
define_field :ColorSpace, type: [Symbol,
|
61
|
+
define_field :ColorSpace, type: [Symbol, PDFArray]
|
61
62
|
define_field :BitsPerComponent, type: Integer
|
62
|
-
define_field :Intent, type: Symbol, version: '1.1'
|
63
|
+
define_field :Intent, type: Symbol, version: '1.1',
|
64
|
+
allowed_values: [HexaPDF::Content::RenderingIntent::ABSOLUTE_COLORIMETRIC,
|
65
|
+
HexaPDF::Content::RenderingIntent::RELATIVE_COLORIMETRIC,
|
66
|
+
HexaPDF::Content::RenderingIntent::SATURATION,
|
67
|
+
HexaPDF::Content::RenderingIntent::PERCEPTUAL]
|
63
68
|
define_field :ImageMask, type: Boolean, default: false
|
64
|
-
define_field :Mask, type: [Stream,
|
65
|
-
define_field :Decode, type:
|
69
|
+
define_field :Mask, type: [Stream, PDFArray], version: '1.3'
|
70
|
+
define_field :Decode, type: PDFArray
|
66
71
|
define_field :Interpolate, type: Boolean, default: false
|
67
|
-
define_field :Alternates, type:
|
72
|
+
define_field :Alternates, type: PDFArray, version: '1.3'
|
68
73
|
define_field :SMask, type: Stream, version: '1.4'
|
69
|
-
define_field :SMaskInData, type: Integer, version: '1.5'
|
74
|
+
define_field :SMaskInData, type: Integer, version: '1.5', allowed_values: [0, 1, 2]
|
70
75
|
define_field :StructParent, type: Integer, version: '1.3'
|
71
76
|
define_field :ID, type: PDFByteString, version: '1.3'
|
72
77
|
define_field :OPI, type: Dictionary, version: '1.2'
|
@@ -244,13 +249,14 @@ module HexaPDF
|
|
244
249
|
io << png_chunk('PLTE', palette)
|
245
250
|
end
|
246
251
|
|
247
|
-
if self[:Mask].kind_of?(
|
252
|
+
if self[:Mask].kind_of?(PDFArray) && self[:Mask].each_slice(2).all? {|a, b| a == b } &&
|
248
253
|
(color_type == ImageLoader::PNG::TRUECOLOR || color_type == ImageLoader::PNG::GREYSCALE)
|
249
254
|
io << png_chunk('tRNS', self[:Mask].each_slice(2).map {|a, _| a }.pack('n*'))
|
250
255
|
end
|
251
256
|
|
252
257
|
filter, = *self[:Filter]
|
253
|
-
|
258
|
+
decode_parms, = *self[:DecodeParms]
|
259
|
+
if filter == :FlateDecode && decode_parms && decode_parms[:Predictor].to_i >= 10
|
254
260
|
data = stream_source
|
255
261
|
else
|
256
262
|
colors = (color_type == ImageLoader::PNG::INDEXED ? 1 : info.components)
|
data/lib/hexapdf/type/info.rb
CHANGED
@@ -57,7 +57,8 @@ module HexaPDF
|
|
57
57
|
define_field :Producer, type: String
|
58
58
|
define_field :CreationDate, type: PDFDate
|
59
59
|
define_field :ModDate, type: PDFDate
|
60
|
-
define_field :Trapped, type: Symbol, version: '1.3'
|
60
|
+
define_field :Trapped, type: Symbol, version: '1.3',
|
61
|
+
allowed_values: [:True, :False, :Unknown]
|
61
62
|
|
62
63
|
# Info dictionaries must always be indirect.
|
63
64
|
def must_be_indirect?
|
data/lib/hexapdf/type/page.rb
CHANGED
@@ -133,14 +133,14 @@ module HexaPDF
|
|
133
133
|
define_field :TrimBox, type: Rectangle, version: '1.3'
|
134
134
|
define_field :ArtBox, type: Rectangle, version: '1.3'
|
135
135
|
define_field :BoxColorInfo, type: Dictionary, version: '1.4'
|
136
|
-
define_field :Contents, type: [Stream,
|
136
|
+
define_field :Contents, type: [Stream, PDFArray]
|
137
137
|
define_field :Rotate, type: Integer, default: 0
|
138
138
|
define_field :Group, type: Dictionary, version: '1.4'
|
139
139
|
define_field :Thumb, type: Stream
|
140
|
-
define_field :B, type:
|
140
|
+
define_field :B, type: PDFArray, version: '1.1'
|
141
141
|
define_field :Dur, type: Numeric, version: '1.1'
|
142
142
|
define_field :Trans, type: Dictionary, version: '1.1'
|
143
|
-
define_field :Annots, type:
|
143
|
+
define_field :Annots, type: PDFArray
|
144
144
|
define_field :AA, type: Dictionary, version: '1.2'
|
145
145
|
define_field :Metadata, type: Stream, version: '1.4'
|
146
146
|
define_field :PieceInfo, type: Dictionary, version: '1.3'
|
@@ -152,7 +152,7 @@ module HexaPDF
|
|
152
152
|
define_field :TemplateInstantiated, type: Symbol, version: '1.5'
|
153
153
|
define_field :PresSteps, type: Dictionary, version: '1.5'
|
154
154
|
define_field :UserUnit, type: Numeric, version: '1.6'
|
155
|
-
define_field :VP, type:
|
155
|
+
define_field :VP, type: PDFArray, version: '1.6'
|
156
156
|
|
157
157
|
# Returns +true+ since page objects must always be indirect.
|
158
158
|
def must_be_indirect?
|
@@ -66,7 +66,7 @@ module HexaPDF
|
|
66
66
|
|
67
67
|
define_field :Type, type: Symbol, required: true, default: type
|
68
68
|
define_field :Parent, type: Dictionary, indirect: true
|
69
|
-
define_field :Kids, type:
|
69
|
+
define_field :Kids, type: PDFArray, required: true, default: []
|
70
70
|
define_field :Count, type: Integer, required: true, default: 0
|
71
71
|
|
72
72
|
# Inheritable page fields
|
@@ -96,7 +96,6 @@ module HexaPDF
|
|
96
96
|
return nil if index < 0 || index >= self[:Count]
|
97
97
|
|
98
98
|
self[:Kids].each do |kid|
|
99
|
-
kid = document.deref(kid)
|
100
99
|
if kid.type == :Page
|
101
100
|
if index == 0
|
102
101
|
return kid
|
@@ -132,7 +131,6 @@ module HexaPDF
|
|
132
131
|
page[:Resources] ||= {}
|
133
132
|
else
|
134
133
|
self[:Kids].each_with_index do |kid, kid_index|
|
135
|
-
kid = document.deref(kid)
|
136
134
|
if index == 0
|
137
135
|
self[:Kids].insert(kid_index, page)
|
138
136
|
page[:Parent] = self
|
@@ -177,7 +175,7 @@ module HexaPDF
|
|
177
175
|
return nil unless page && page[:Parent]
|
178
176
|
|
179
177
|
parent = page[:Parent]
|
180
|
-
index = parent[:Kids].index {|kid|
|
178
|
+
index = parent[:Kids].index {|kid| kid.data == page.data }
|
181
179
|
|
182
180
|
if index
|
183
181
|
ancestors = [parent]
|
@@ -203,7 +201,6 @@ module HexaPDF
|
|
203
201
|
return to_enum(__method__) unless block_given?
|
204
202
|
|
205
203
|
self[:Kids].each do |kid|
|
206
|
-
kid = document.deref(kid)
|
207
204
|
if kid.type == :Page
|
208
205
|
yield(kid)
|
209
206
|
else
|
@@ -222,7 +219,7 @@ module HexaPDF
|
|
222
219
|
if box.kind_of?(Symbol)
|
223
220
|
box = Page.media_box(box, orientation: config['page.default_media_orientation'])
|
224
221
|
end
|
225
|
-
document.add(Type: :Page, MediaBox: box)
|
222
|
+
document.add({Type: :Page, MediaBox: box})
|
226
223
|
end
|
227
224
|
|
228
225
|
# Ensures that the /Count and /Parent fields of the whole page tree are set up correctly and
|
@@ -235,7 +232,6 @@ module HexaPDF
|
|
235
232
|
validate_node = lambda do |node|
|
236
233
|
count = 0
|
237
234
|
node[:Kids].reject! do |kid|
|
238
|
-
kid = document.deref(kid)
|
239
235
|
if !kid.kind_of?(HexaPDF::Object) || kid.null? ||
|
240
236
|
(kid.type != :Page && kid.type != :Pages)
|
241
237
|
yield("Invalid object in page tree node", true)
|
@@ -55,7 +55,7 @@ module HexaPDF
|
|
55
55
|
define_field :Shading, type: Dictionary, version: '1.3'
|
56
56
|
define_field :XObject, type: Dictionary
|
57
57
|
define_field :Font, type: Dictionary
|
58
|
-
define_field :ProcSet, type:
|
58
|
+
define_field :ProcSet, type: PDFArray
|
59
59
|
define_field :Properties, type: Dictionary, version: '1.2'
|
60
60
|
|
61
61
|
# Returns the color space stored under the given name.
|
data/lib/hexapdf/type/trailer.rb
CHANGED
@@ -65,12 +65,12 @@ module HexaPDF
|
|
65
65
|
define_field :Root, type: :Catalog, indirect: true
|
66
66
|
define_field :Encrypt, type: Dictionary
|
67
67
|
define_field :Info, type: :XXInfo, indirect: true
|
68
|
-
define_field :ID, type:
|
68
|
+
define_field :ID, type: PDFArray
|
69
69
|
define_field :XRefStm, type: Integer, version: '1.5'
|
70
70
|
|
71
71
|
# Returns the document's Catalog (see Type::Catalog), creating it if needed.
|
72
72
|
def catalog
|
73
|
-
self[:Root] ||= document.add(Type: :Catalog)
|
73
|
+
self[:Root] ||= document.add({Type: :Catalog})
|
74
74
|
end
|
75
75
|
|
76
76
|
# Returns the document's information dictionary (see Type::Info), creating it if needed.
|
@@ -88,7 +88,7 @@ module HexaPDF
|
|
88
88
|
# Updates the second part of the /ID field (the first part should always be the same for a
|
89
89
|
# PDF file, the second part should change with each write).
|
90
90
|
def update_id
|
91
|
-
if !
|
91
|
+
if !self[:ID].kind_of?(PDFArray)
|
92
92
|
set_random_id
|
93
93
|
else
|
94
94
|
value[:ID][1] = Digest::MD5.digest(rand.to_s)
|
@@ -112,7 +112,7 @@ module HexaPDF
|
|
112
112
|
|
113
113
|
unless value[:Root]
|
114
114
|
yield("A PDF document must have a Catalog dictionary", true)
|
115
|
-
value[:Root] = document.add(Type: :Catalog)
|
115
|
+
value[:Root] = document.add({Type: :Catalog})
|
116
116
|
value[:Root].validate {|message, correctable| yield(message, correctable) }
|
117
117
|
end
|
118
118
|
|
@@ -55,16 +55,19 @@ module HexaPDF
|
|
55
55
|
define_field :FitWindow, type: Boolean, default: false
|
56
56
|
define_field :CenterWindow, type: Boolean, default: false
|
57
57
|
define_field :DisplayDocTitle, type: Boolean, default: false, version: '1.4'
|
58
|
-
define_field :NonFullScreenPageMode, type: Symbol, default: :UseNone
|
59
|
-
|
58
|
+
define_field :NonFullScreenPageMode, type: Symbol, default: :UseNone,
|
59
|
+
allowed_values: [:UseNone, :UseOutlines, :UseThumbs, :UseOC]
|
60
|
+
define_field :Direction, type: Symbol, default: :L2R, version: '1.3',
|
61
|
+
allowed_values: [:L2R, :R2L]
|
60
62
|
define_field :ViewArea, type: Symbol, default: :CropBox, version: '1.4'
|
61
63
|
define_field :ViewClip, type: Symbol, default: :CropBox, version: '1.4'
|
62
64
|
define_field :PrintArea, type: Symbol, default: :CropBox, version: '1.4'
|
63
65
|
define_field :PrintClip, type: Symbol, default: :CropBox, version: '1.4'
|
64
66
|
define_field :PrintScaling, type: Symbol, default: :AppDefault, version: '1.6'
|
65
|
-
define_field :Duplex, type: Symbol, version: '1.7'
|
67
|
+
define_field :Duplex, type: Symbol, version: '1.7',
|
68
|
+
allowed_values: [:Simplex, :DuplexFlipShortEdge, :DuplexFlipLongEdge]
|
66
69
|
define_field :PickTrayByPDFSize, type: Boolean, version: '1.7'
|
67
|
-
define_field :PrintPageRange, type:
|
70
|
+
define_field :PrintPageRange, type: PDFArray, version: '1.7'
|
68
71
|
define_field :NumCopies, type: Integer, version: '1.7'
|
69
72
|
|
70
73
|
end
|
@@ -74,10 +74,10 @@ module HexaPDF
|
|
74
74
|
version: '1.5'
|
75
75
|
# Size is not required because it will be auto-filled before the object is written
|
76
76
|
define_field :Size, type: Integer, indirect: false
|
77
|
-
define_field :Index, type:
|
77
|
+
define_field :Index, type: PDFArray, indirect: false
|
78
78
|
define_field :Prev, type: Integer, indirect: false
|
79
79
|
# W is not required because it will be auto-filled on #update_with_xref_section_and_trailer
|
80
|
-
define_field :W, type:
|
80
|
+
define_field :W, type: PDFArray, indirect: false
|
81
81
|
|
82
82
|
# Returns an XRefSection that represents the content of this cross-reference stream.
|
83
83
|
#
|
data/lib/hexapdf/version.rb
CHANGED
data/man/man1/hexapdf.1
CHANGED
@@ -15,23 +15,27 @@ Using the hexapdf application the following tasks can be performed with PDF file
|
|
15
15
|
.sp
|
16
16
|
.PD 0
|
17
17
|
.IP \(bu 4
|
18
|
-
|
18
|
+
Modifying an existing PDF file (see the \fBmodify\fP command)
|
19
19
|
.IP \(bu 4
|
20
|
-
|
20
|
+
Merging multiple PDF files into one (see the \fBmerge\fP command)
|
21
21
|
.IP \(bu 4
|
22
|
-
|
22
|
+
Splitting a PDF file into individual pages (see the \fBsplit\fP command)
|
23
23
|
.IP \(bu 4
|
24
|
-
|
24
|
+
Optimizing the file size of a PDF file (see the \fBoptimize\fP command)
|
25
25
|
.IP \(bu 4
|
26
|
-
|
26
|
+
Watermarking/Stamping a PDF onto another one (see the \fBwatermark\fP command)
|
27
27
|
.IP \(bu 4
|
28
|
-
|
28
|
+
Extracting embedded files (see the \fBfiles\fP command)
|
29
29
|
.IP \(bu 4
|
30
|
-
|
30
|
+
Extracting images (see the \fBimages\fP command)
|
31
31
|
.IP \(bu 4
|
32
|
-
|
32
|
+
Converting images to PDF (see the \fBimage2pdf\fP command)
|
33
|
+
.IP \(bu 4
|
34
|
+
Showing general information of a PDF file (see the \fBinfo\fP command)
|
33
35
|
.IP \(bu 4
|
34
36
|
Batch execution of a command on multiple PDF files (see the \fBbatch\fP command)
|
37
|
+
.IP \(bu 4
|
38
|
+
Inspecting the internal structure of a PDF file (see the \fBinspect\fP command)
|
35
39
|
.PD
|
36
40
|
.P
|
37
41
|
The application contains a built\-in \fBhelp\fP command that can be used to provide a quick reminder of a command\[u2019]s purpose and its options\.
|
@@ -247,6 +251,34 @@ The image type\. Either jpg (JPEG), jp2 (JPEG2000), ccitt (CCITT Group 3 or 4 Fa
|
|
247
251
|
\fBwritable\fP
|
248
252
|
Either true or false depending on whether hexapdf supports the image format\.
|
249
253
|
.RE
|
254
|
+
.SS "image2pdf"
|
255
|
+
Synopsis: \fBiamge2pdf\fP [\fBOPTIONS\fP] \fIOUTPUT\fP [\fIIMAGES\fP\.\.\.]
|
256
|
+
.P
|
257
|
+
This command converts one or more images into a single PDF file, one image per page\. The various options allow setting a page size, scaling the images and defining margins\. Images are always centered on the pages\.
|
258
|
+
.P
|
259
|
+
Supported image formats are JPEG, PNG and PDF\. Images in PNG format may take longer to process due to the way they are stored inside a PDF\.
|
260
|
+
.TP
|
261
|
+
\fB\-p\fP \fIPAGE_SIZE\fP, \fB\-\-page\-size\fP \fIPAGE_SIZE\fP
|
262
|
+
The PDF page size\. The default value of \fIauto\fP chooses the page size based on the image dimensions\. Either \fIauto\fP which chooses a size based on the image size or a valid page size like \fIA4\fP, \fIA4\-landscape\fP or \fI595x842\fP\&\. The \fI\-landscape\fP suffix can be added to any predefined page size\.
|
263
|
+
.RS
|
264
|
+
.P
|
265
|
+
Common page sizes are \fIA4\fP, \fIA5\fP, \fIA3\fP, \fILetter\fP and \fILegal\fP\&\.
|
266
|
+
.RE
|
267
|
+
.TP
|
268
|
+
\fB\-\-[no\-]auto\-rotate\fP
|
269
|
+
If enabled (the default) pages are automatically rotated so that the pages and images always have the same orientation\. I\.e\. landscape\-oriented images go on landscape page, portrait\-oriented images on portrait pages\.
|
270
|
+
.RS
|
271
|
+
.P
|
272
|
+
Note that pages won\[u2019]t be rotated if scaling is used and the image would fit into the requested page size\.
|
273
|
+
.RE
|
274
|
+
.TP
|
275
|
+
\fB\-s\fP \fISCALE\fP, \fB\-\-scale\fP \fISCALE\fP
|
276
|
+
Defines how the images should be scaled\. The default value of \fIfit\fP scales the images so that they optimally fit the pages\. Otherwise \fISCALE\fP is interpreted as the minimum number of pixels per inch (PPI) that the images should have\.
|
277
|
+
.TP
|
278
|
+
\fB\-m\fP \fIMARGINS\fP, \fB\-\-margins\fP \fIMARGINS\fP
|
279
|
+
Defines the margins around the images\. The argument \fIMARGINS\fP can either be a single number specifying the margin on all four sides, or four numbers separated by commas (like \fB10,20,30,40\fP) specifying the top, right, bottom and left margins\. Default: \fI0\fP\&\.
|
280
|
+
.P
|
281
|
+
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
250
282
|
.SS "info"
|
251
283
|
Synopsis: \fBinfo\fP [\fBOPTIONS\fP] \fIFILE\fP
|
252
284
|
.P
|
@@ -395,6 +427,31 @@ If no \fIOUTPUT_SPEC\fP is given, files of the form \fIINPUT_0001\.pdf\fP, \fIIN
|
|
395
427
|
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
396
428
|
.P
|
397
429
|
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
430
|
+
.SS "watermark"
|
431
|
+
Synopsis: \fBwatermark\fP [\fBOPTIONS\fP] \fIINPUT\fP \fIOUTPUT\fP
|
432
|
+
.P
|
433
|
+
This command uses one ore more pages from a PDF file and applies them as background or stamp (depending on the \fB\-\-type\fP option) on another PDF file\. If multiple pages are selected from the watermark PDF, the \fB\-\-repeat\fP option can be used to specify how they should be applied\.
|
434
|
+
.TP
|
435
|
+
\fB\-w\fP \fIWATERMARK\fP, \fB\-\-watermark\-file\fP \fIWATERMARK\fP
|
436
|
+
The PDF file that should be used for watermarking\.
|
437
|
+
.TP
|
438
|
+
\fB\-i\fP \fIPAGES\fP, \fB\-\-pages\fP \fIPAGES\fP
|
439
|
+
The pages from the \fIWATERMARK\fP PDF that should be used\. The first \fIWATERMARK\fP page is applied to the first \fIINPUT\fP page, the second \fIWATERMARK\fP page to the second \fIINPUT\fP page and so on\. If there are fewer \fIWATERMARK\fP pages than \fIINPUT\fP pages, the \fB\-\-repeat\fP option comes into play\.
|
440
|
+
.RS
|
441
|
+
.P
|
442
|
+
See the \fBPAGES SPECIFICATION\fP below for details on the allowed format of \fIPAGES\fP\&\. Default: \fI1\fP\&\.
|
443
|
+
.RE
|
444
|
+
.TP
|
445
|
+
\fB\-r\fP \fIREPEAT_MODE\fP, \fB\-\-repeat\fP \fIREPEAT_MODE\fP
|
446
|
+
Specifies how the \fIWATERMARK\fP pages should be repeated: \fBlast\fP (the default) will only repeat the last \fIWATERMARK\fP page whereas \fBall\fP will cyclically repeat all \fIWATERMARK\fP pages\.
|
447
|
+
.TP
|
448
|
+
\fB\-t\fP \fIWATERMARK_TYPE\fP, \fB\-\-type\fP \fIWATERMARK_TYPE\fP
|
449
|
+
Specifies how the \fIWATERMARK\fP pages are applied to the \fIINPUT\fP pages: \fBbackground\fP (the default) applies them below the page contents and \fBstamp\fP applies them above the page contents\.
|
450
|
+
.TP
|
451
|
+
\fB\-p\fP \fIPASSWORD\fP, \fB\-\-password\fP \fIPASSWORD\fP
|
452
|
+
The password to decrypt the \fIINPUT\fP\&\. Use \fB\-\fP for \fIPASSWORD\fP for reading it from standard input\.
|
453
|
+
.P
|
454
|
+
Additionally, the \fBOptimization Options\fP and \fBEncryption Options\fP can be used\.
|
398
455
|
.SS "version"
|
399
456
|
This command shows the version of the hexapdf application\. It is an alternative to using the global \fB\-\-version\fP option\.
|
400
457
|
.SH "PAGES SPECIFICATION"
|
@@ -475,6 +532,14 @@ Optimization: Compress the \fBinput\.pdf\fP to get a smaller file size\.
|
|
475
532
|
\fBhexapdf split input\.pdf out_%02d\.pdf\fP
|
476
533
|
.P
|
477
534
|
Split the \fBinput\.pdf\fP into individual pages, naming the output files \fBout_01\.pdf\fP, \fBout_02\.pdf\fP, and so on\.
|
535
|
+
.SS "watermark"
|
536
|
+
\fBhexapdf watermark \-w watermark\.pdf \-t stamp input\.pdf output\.pdf\fP
|
537
|
+
.P
|
538
|
+
Applies the first page of the \fBwatermark\.pdf\fP as stamp on \fBinput\.pdf\fP\&\.
|
539
|
+
.P
|
540
|
+
\fBhexapdf watermark \-w watermark\.pdf \-i 2\-5 \-r all input\.pdf output\.pdf\fP
|
541
|
+
.P
|
542
|
+
Cyclically applies the pages 2 to 5 of the \fBwatermark\.pdf\fP as background on \fBinput\.pdf\fP\&\.
|
478
543
|
.SS "files"
|
479
544
|
\fBhexapdf files input\.pdf\fP
|
480
545
|
.br
|
@@ -487,6 +552,10 @@ Embedded files: The first command lists the embedded files in the \fBinput\.pdf\
|
|
487
552
|
\fBhexapdf images input\.pdf \-e \-\-prefix images/image\fP
|
488
553
|
.P
|
489
554
|
Image info and extraction: The first command lists the images of the \fBinput\.pdf\fP, the second one then extracts the images into the subdirectory \fBimages\fP with the prefix \fBimage\fP\&\.
|
555
|
+
.SS "image2pdf"
|
556
|
+
\fBhexapdf image2pdf output\.pdf image1\.jpg image2\.pdf image3\.png\fP
|
557
|
+
.P
|
558
|
+
Create a PDF file \fBoutput\.pdf\fP containing three pages with one image per page and the image fitted to the page\.
|
490
559
|
.SS "info"
|
491
560
|
\fBhexapdf info input\.pdf\fP
|
492
561
|
.P
|