origami 1.2.7 → 2.0.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 +66 -0
- data/README.md +112 -0
- data/bin/config/pdfcop.conf.yml +232 -233
- data/bin/gui/about.rb +27 -37
- data/bin/gui/config.rb +108 -117
- data/bin/gui/file.rb +416 -365
- data/bin/gui/gtkhex.rb +1138 -1153
- data/bin/gui/hexview.rb +55 -57
- data/bin/gui/imgview.rb +48 -51
- data/bin/gui/menu.rb +388 -386
- data/bin/gui/properties.rb +114 -130
- data/bin/gui/signing.rb +571 -617
- data/bin/gui/textview.rb +77 -95
- data/bin/gui/treeview.rb +382 -387
- data/bin/gui/walker.rb +227 -232
- data/bin/gui/xrefs.rb +56 -60
- data/bin/pdf2pdfa +53 -57
- data/bin/pdf2ruby +212 -228
- data/bin/pdfcop +338 -348
- data/bin/pdfdecompress +58 -65
- data/bin/pdfdecrypt +56 -60
- data/bin/pdfencrypt +75 -80
- data/bin/pdfexplode +185 -182
- data/bin/pdfextract +201 -218
- data/bin/pdfmetadata +83 -82
- data/bin/pdfsh +4 -5
- data/bin/pdfwalker +1 -2
- data/bin/shell/.irbrc +45 -82
- data/bin/shell/console.rb +105 -130
- data/bin/shell/hexdump.rb +40 -64
- data/examples/README.md +34 -0
- data/examples/attachments/attachment.rb +38 -0
- data/examples/attachments/nested_document.rb +51 -0
- data/examples/encryption/encryption.rb +28 -0
- data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
- data/examples/flash/flash.rb +37 -0
- data/{samples → examples}/flash/helloworld.swf +0 -0
- data/examples/forms/javascript.rb +54 -0
- data/examples/forms/xfa.rb +115 -0
- data/examples/javascript/hello_world.rb +22 -0
- data/examples/javascript/js_emulation.rb +54 -0
- data/examples/loop/goto.rb +32 -0
- data/examples/loop/named.rb +33 -0
- data/examples/signature/signature.rb +65 -0
- data/examples/uri/javascript.rb +56 -0
- data/examples/uri/open-uri.rb +21 -0
- data/examples/uri/submitform.rb +47 -0
- data/lib/origami.rb +29 -42
- data/lib/origami/3d.rb +350 -225
- data/lib/origami/acroform.rb +262 -288
- data/lib/origami/actions.rb +268 -288
- data/lib/origami/annotations.rb +697 -722
- data/lib/origami/array.rb +258 -184
- data/lib/origami/boolean.rb +74 -84
- data/lib/origami/catalog.rb +397 -434
- data/lib/origami/collections.rb +144 -0
- data/lib/origami/destinations.rb +233 -194
- data/lib/origami/dictionary.rb +253 -232
- data/lib/origami/encryption.rb +1274 -1243
- data/lib/origami/export.rb +232 -268
- data/lib/origami/extensions/fdf.rb +307 -220
- data/lib/origami/extensions/ppklite.rb +368 -435
- data/lib/origami/filespec.rb +197 -0
- data/lib/origami/filters.rb +301 -295
- data/lib/origami/filters/ascii.rb +177 -180
- data/lib/origami/filters/ccitt.rb +528 -535
- data/lib/origami/filters/crypt.rb +26 -35
- data/lib/origami/filters/dct.rb +46 -52
- data/lib/origami/filters/flate.rb +95 -94
- data/lib/origami/filters/jbig2.rb +49 -55
- data/lib/origami/filters/jpx.rb +38 -44
- data/lib/origami/filters/lzw.rb +189 -183
- data/lib/origami/filters/predictors.rb +221 -235
- data/lib/origami/filters/runlength.rb +103 -104
- data/lib/origami/font.rb +173 -186
- data/lib/origami/functions.rb +67 -81
- data/lib/origami/graphics.rb +25 -21
- data/lib/origami/graphics/colors.rb +178 -187
- data/lib/origami/graphics/instruction.rb +79 -85
- data/lib/origami/graphics/path.rb +142 -148
- data/lib/origami/graphics/patterns.rb +160 -167
- data/lib/origami/graphics/render.rb +43 -50
- data/lib/origami/graphics/state.rb +138 -153
- data/lib/origami/graphics/text.rb +188 -205
- data/lib/origami/graphics/xobject.rb +819 -815
- data/lib/origami/header.rb +63 -78
- data/lib/origami/javascript.rb +596 -597
- data/lib/origami/linearization.rb +285 -290
- data/lib/origami/metadata.rb +139 -148
- data/lib/origami/name.rb +112 -148
- data/lib/origami/null.rb +53 -62
- data/lib/origami/numeric.rb +162 -175
- data/lib/origami/obfuscation.rb +186 -174
- data/lib/origami/object.rb +593 -573
- data/lib/origami/outline.rb +42 -47
- data/lib/origami/outputintents.rb +73 -82
- data/lib/origami/page.rb +703 -592
- data/lib/origami/parser.rb +238 -290
- data/lib/origami/parsers/fdf.rb +41 -33
- data/lib/origami/parsers/pdf.rb +75 -95
- data/lib/origami/parsers/pdf/lazy.rb +137 -0
- data/lib/origami/parsers/pdf/linear.rb +64 -66
- data/lib/origami/parsers/ppklite.rb +34 -70
- data/lib/origami/pdf.rb +1030 -1005
- data/lib/origami/reference.rb +102 -102
- data/lib/origami/signature.rb +591 -609
- data/lib/origami/stream.rb +668 -551
- data/lib/origami/string.rb +397 -373
- data/lib/origami/template/patterns.rb +56 -0
- data/lib/origami/template/widgets.rb +151 -0
- data/lib/origami/trailer.rb +144 -158
- data/lib/origami/tree.rb +62 -0
- data/lib/origami/version.rb +23 -0
- data/lib/origami/webcapture.rb +88 -79
- data/lib/origami/xfa.rb +2863 -2882
- data/lib/origami/xreftable.rb +472 -384
- data/test/dataset/calc.pdf +85 -0
- data/test/dataset/crypto.pdf +82 -0
- data/test/dataset/empty.pdf +49 -0
- data/test/test_actions.rb +27 -0
- data/test/test_annotations.rb +90 -0
- data/test/test_pages.rb +31 -0
- data/test/test_pdf.rb +16 -0
- data/test/test_pdf_attachment.rb +34 -0
- data/test/test_pdf_create.rb +24 -0
- data/test/test_pdf_encrypt.rb +95 -0
- data/test/test_pdf_parse.rb +96 -0
- data/test/test_pdf_sign.rb +58 -0
- data/test/test_streams.rb +182 -0
- data/test/test_xrefs.rb +67 -0
- metadata +88 -58
- data/README +0 -67
- data/bin/pdf2graph +0 -121
- data/bin/pdfcocoon +0 -104
- data/lib/origami/file.rb +0 -233
- data/samples/README.txt +0 -45
- data/samples/actions/launch/calc.rb +0 -87
- data/samples/actions/launch/winparams.rb +0 -22
- data/samples/actions/loop/loopgoto.rb +0 -24
- data/samples/actions/loop/loopnamed.rb +0 -21
- data/samples/actions/named/named.rb +0 -31
- data/samples/actions/samba/smbrelay.rb +0 -26
- data/samples/actions/webbug/submitform.js +0 -26
- data/samples/actions/webbug/webbug-browser.rb +0 -68
- data/samples/actions/webbug/webbug-js.rb +0 -67
- data/samples/actions/webbug/webbug-reader.rb +0 -90
- data/samples/attachments/attach.rb +0 -40
- data/samples/attachments/attached.txt +0 -1
- data/samples/crypto/crypto.rb +0 -28
- data/samples/digsig/signed.rb +0 -46
- data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
- data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
- data/samples/exploits/exploit_customdictopen.rb +0 -55
- data/samples/exploits/getannots.rb +0 -69
- data/samples/flash/flash.rb +0 -31
- data/samples/javascript/attached.txt +0 -1
- data/samples/javascript/js.rb +0 -52
- data/templates/patterns.rb +0 -66
- data/templates/widgets.rb +0 -173
- data/templates/xdp.rb +0 -92
- data/test/ts_pdf.rb +0 -50
data/lib/origami/boolean.rb
CHANGED
|
@@ -1,101 +1,91 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
-
GNU Lesser General Public License for more details.
|
|
20
|
-
|
|
21
|
-
You should have received a copy of the GNU Lesser General Public License
|
|
22
|
-
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
|
5
|
+
|
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
23
18
|
|
|
24
19
|
=end
|
|
25
20
|
|
|
26
21
|
module Origami
|
|
27
22
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
# Class representing a Boolean Object.
|
|
33
|
-
# A Boolean Object can be *true* or *false*.
|
|
34
|
-
#
|
|
35
|
-
class Boolean
|
|
36
|
-
|
|
37
|
-
include Origami::Object
|
|
38
|
-
|
|
39
|
-
TOKENS = [ %w{ true false } ] #:nodoc:
|
|
40
|
-
|
|
41
|
-
@@regexp = Regexp.new(WHITESPACES + "(#{TOKENS.first.join('|')})")
|
|
42
|
-
|
|
23
|
+
class InvalidBooleanObjectError < InvalidObjectError #:nodoc:
|
|
24
|
+
end
|
|
25
|
+
|
|
43
26
|
#
|
|
44
|
-
#
|
|
45
|
-
#
|
|
27
|
+
# Class representing a Boolean Object.
|
|
28
|
+
# A Boolean Object can be *true* or *false*.
|
|
46
29
|
#
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
unless value.is_a?(TrueClass) or value.is_a?(FalseClass)
|
|
50
|
-
raise TypeError, "Expected type TrueClass or FalseClass, received #{value.class}."
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
super()
|
|
54
|
-
|
|
55
|
-
@value = (value == nil || value == false) ? false : true
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def to_s #:nodoc:
|
|
59
|
-
super(@value.to_s)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def self.parse(stream, parser = nil) #:nodoc:
|
|
30
|
+
class Boolean
|
|
31
|
+
include Origami::Object
|
|
63
32
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if stream.scan(@@regexp).nil?
|
|
67
|
-
raise InvalidBooleanObjectError
|
|
68
|
-
end
|
|
33
|
+
TOKENS = %w{ true false } #:nodoc:
|
|
34
|
+
@@regexp = Regexp.new(WHITESPACES + "(?<value>#{Regexp.union(TOKENS)})")
|
|
69
35
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
36
|
+
#
|
|
37
|
+
# Creates a new Boolean value.
|
|
38
|
+
# _value_:: *true* or *false*.
|
|
39
|
+
#
|
|
40
|
+
def initialize(value)
|
|
41
|
+
unless value.is_a?(TrueClass) or value.is_a?(FalseClass)
|
|
42
|
+
raise TypeError, "Expected type TrueClass or FalseClass, received #{value.class}."
|
|
43
|
+
end
|
|
74
44
|
|
|
75
|
-
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
#
|
|
79
|
-
# Converts self into a Ruby boolean, that is TrueClass or FalseClass instance.
|
|
80
|
-
#
|
|
81
|
-
def value
|
|
82
|
-
@value
|
|
83
|
-
end
|
|
45
|
+
super()
|
|
84
46
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def false?
|
|
88
|
-
@value == false
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def true?
|
|
92
|
-
@value == true
|
|
93
|
-
end
|
|
47
|
+
@value = (value == true)
|
|
48
|
+
end
|
|
94
49
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
50
|
+
def to_s #:nodoc:
|
|
51
|
+
super(@value.to_s)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.parse(stream, parser = nil) #:nodoc:
|
|
55
|
+
offset = stream.pos
|
|
56
|
+
|
|
57
|
+
if stream.scan(@@regexp).nil?
|
|
58
|
+
raise InvalidBooleanObjectError
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
value = (stream['value'] == "true")
|
|
62
|
+
|
|
63
|
+
bool = Boolean.new(value)
|
|
64
|
+
bool.file_offset = offset
|
|
98
65
|
|
|
99
|
-
|
|
66
|
+
bool
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
#
|
|
70
|
+
# Converts self into a Ruby boolean, that is TrueClass or FalseClass instance.
|
|
71
|
+
#
|
|
72
|
+
def value
|
|
73
|
+
@value
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def self.native_type ; Boolean end
|
|
77
|
+
|
|
78
|
+
def false?
|
|
79
|
+
@value == false
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def true?
|
|
83
|
+
@value == true
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def ==(bool)
|
|
87
|
+
@value == bool
|
|
88
|
+
end
|
|
89
|
+
end
|
|
100
90
|
|
|
101
91
|
end
|
data/lib/origami/catalog.rb
CHANGED
|
@@ -1,485 +1,448 @@
|
|
|
1
1
|
=begin
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
19
|
-
GNU Lesser General Public License for more details.
|
|
20
|
-
|
|
21
|
-
You should have received a copy of the GNU Lesser General Public License
|
|
22
|
-
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
3
|
+
This file is part of Origami, PDF manipulation framework for Ruby
|
|
4
|
+
Copyright (C) 2016 Guillaume Delugré.
|
|
5
|
+
|
|
6
|
+
Origami is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU Lesser General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
Origami is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU Lesser General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU Lesser General Public License
|
|
17
|
+
along with Origami. If not, see <http://www.gnu.org/licenses/>.
|
|
23
18
|
|
|
24
19
|
=end
|
|
25
20
|
|
|
26
21
|
module Origami
|
|
27
22
|
|
|
28
|
-
|
|
23
|
+
class PDF
|
|
24
|
+
#
|
|
25
|
+
# Sets PDF extension level and version. Only supported values are "1.7" and 3.
|
|
26
|
+
#
|
|
27
|
+
def set_extension_level(version, level)
|
|
28
|
+
exts = (self.Catalog.Extensions ||= Extensions.new)
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def set_extension_level(version, level)
|
|
34
|
-
exts = (self.Catalog.Extensions ||= Extensions.new)
|
|
30
|
+
exts[:ADBE] = DeveloperExtension.new
|
|
31
|
+
exts[:ADBE].BaseVersion = Name.new(version)
|
|
32
|
+
exts[:ADBE].ExtensionLevel = level
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
exts[:ADBE].ExtensionLevel = level
|
|
34
|
+
self
|
|
35
|
+
end
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
#
|
|
38
|
+
# Returns the current Catalog Dictionary.
|
|
39
|
+
#
|
|
40
|
+
def Catalog
|
|
41
|
+
cat = trailer_key(:Root)
|
|
42
|
+
|
|
43
|
+
case cat
|
|
44
|
+
when Catalog then
|
|
45
|
+
cat
|
|
46
|
+
when Dictionary then
|
|
47
|
+
cat.cast_to(Catalog)
|
|
48
|
+
else
|
|
49
|
+
raise InvalidPDFError, "Broken catalog"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
42
52
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
53
|
+
#
|
|
54
|
+
# Sets the current Catalog Dictionary.
|
|
55
|
+
#
|
|
56
|
+
def Catalog=(cat)
|
|
57
|
+
cat = cat.cast_to(Catalog) unless cat.is_a? Catalog
|
|
58
|
+
|
|
59
|
+
delete_object(@revisions.last.trailer[:Root]) if @revisions.last.trailer[:Root]
|
|
60
|
+
|
|
61
|
+
@revisions.last.trailer.Root = self << cat
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Sets an action to run on document opening.
|
|
66
|
+
# _action_:: An Action Object.
|
|
67
|
+
#
|
|
68
|
+
def onDocumentOpen(action)
|
|
69
|
+
unless action.is_a?(Action) or action.is_a?(Destination) or action.is_a?(Reference)
|
|
70
|
+
raise TypeError, "An Action object must be passed."
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
unless self.Catalog
|
|
74
|
+
raise InvalidPDFError, "A catalog object must exist to add this action."
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
self.Catalog.OpenAction = action
|
|
78
|
+
|
|
79
|
+
self
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Sets an action to run on document closing.
|
|
84
|
+
# _action_:: A JavaScript Action Object.
|
|
85
|
+
#
|
|
86
|
+
def onDocumentClose(action)
|
|
87
|
+
unless action.is_a?(Action::JavaScript) or action.is_a?(Reference)
|
|
88
|
+
raise TypeError, "An Action::JavaScript object must be passed."
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
unless self.Catalog
|
|
92
|
+
raise InvalidPDFError, "A catalog object must exist to add this action."
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
self.Catalog.AA ||= CatalogAdditionalActions.new
|
|
96
|
+
self.Catalog.AA.WC = action
|
|
97
|
+
|
|
98
|
+
self
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
#
|
|
102
|
+
# Sets an action to run on document printing.
|
|
103
|
+
# _action_:: A JavaScript Action Object.
|
|
104
|
+
#
|
|
105
|
+
def onDocumentPrint(action)
|
|
106
|
+
unless action.is_a?(Action::JavaScript) or action.is_a?(Reference)
|
|
107
|
+
raise TypeError, "An Action::JavaScript object must be passed."
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
unless self.Catalog
|
|
111
|
+
raise InvalidPDFError, "A catalog object must exist to add this action."
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
self.Catalog.AA ||= CatalogAdditionalActions.new
|
|
115
|
+
self.Catalog.AA.WP = action
|
|
116
|
+
|
|
117
|
+
self
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
#
|
|
121
|
+
# Registers an object into a specific Names root dictionary.
|
|
122
|
+
# _root_:: The root dictionary (see Names::Root)
|
|
123
|
+
# _name_:: The value name.
|
|
124
|
+
# _value_:: The value to associate with this name.
|
|
125
|
+
#
|
|
126
|
+
def register(root, name, value)
|
|
127
|
+
self.Catalog.Names ||= Names.new
|
|
128
|
+
|
|
129
|
+
value.set_indirect(true) unless value.is_a?(Reference)
|
|
130
|
+
|
|
131
|
+
namesroot = self.Catalog.Names[root]
|
|
132
|
+
if namesroot.nil?
|
|
133
|
+
names = NameTreeNode.new(:Names => []).set_indirect(true)
|
|
134
|
+
self.Catalog.Names[root] = names
|
|
135
|
+
names.Names << name << value
|
|
136
|
+
else
|
|
137
|
+
namesroot.solve[:Names] << name << value
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
#
|
|
142
|
+
# Retrieve the corresponding value associated with _name_ in
|
|
143
|
+
# the specified _root_ name directory, or nil if the value does
|
|
144
|
+
# not exist.
|
|
145
|
+
#
|
|
146
|
+
def resolve_name(root, name)
|
|
147
|
+
namesroot = get_names_root(root)
|
|
148
|
+
return nil if namesroot.nil?
|
|
149
|
+
|
|
150
|
+
resolve_name_from_node(namesroot, name)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
#
|
|
154
|
+
# Returns a Hash of all names under the specified _root_ name directory.
|
|
155
|
+
#
|
|
156
|
+
def names(root)
|
|
157
|
+
self.each_name(root).to_h
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
#
|
|
161
|
+
# Returns an Enumerator of all names under the specified _root_ name directory.
|
|
162
|
+
#
|
|
163
|
+
def each_name(root, &block)
|
|
164
|
+
return enum_for(__method__, root) unless block_given?
|
|
165
|
+
|
|
166
|
+
names_root = get_names_root(root)
|
|
167
|
+
return if names_root.nil?
|
|
168
|
+
|
|
169
|
+
names_from_node(names_root, &block)
|
|
170
|
+
self
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
def names_from_node(node, browsed_nodes: [], &block) #:nodoc:
|
|
176
|
+
return if browsed_nodes.any?{|browsed| browsed.equal?(node)}
|
|
177
|
+
raise InvalidNameTreeError, "node is not a dictionary" unless node.is_a?(Dictionary)
|
|
178
|
+
|
|
179
|
+
browsed_nodes.push(node)
|
|
180
|
+
|
|
181
|
+
if node.has_key?(:Names) # leaf node
|
|
182
|
+
names = node.Names
|
|
183
|
+
raise InvalidNameTreeError, "Names must be an Array" unless names.is_a?(Array)
|
|
184
|
+
raise InvalidNameTreeError, "Odd number of elements" if names.length.odd?
|
|
185
|
+
|
|
186
|
+
for i in 0...names.length/2
|
|
187
|
+
yield(names[i * 2].solve, names[i * 2 + 1].solve)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
elsif node.has_key?(:Kids) # intermediate node
|
|
191
|
+
node.Kids.each do |kid|
|
|
192
|
+
names_from_node(kid.solve, browsed_nodes: browsed_nodes, &block)
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def resolve_name_from_node(node, name, browsed_nodes: []) #:nodoc:
|
|
198
|
+
return if browsed_nodes.any?{|browsed| browsed.equal?(node)}
|
|
199
|
+
raise InvalidNameTreeError, "node is not a Dictionary" unless node.is_a?(Dictionary)
|
|
200
|
+
|
|
201
|
+
browsed_nodes.push(node)
|
|
202
|
+
|
|
203
|
+
if node.has_key?(:Names) # leaf node
|
|
204
|
+
limits = node.Limits
|
|
205
|
+
names = node.Names
|
|
206
|
+
|
|
207
|
+
raise InvalidNameTreeError, "Names must be an Array" unless names.is_a?(Array)
|
|
208
|
+
raise InvalidNameTreeError, "Odd number of elements" if names.length.odd?
|
|
209
|
+
|
|
210
|
+
if limits.is_a?(Array)
|
|
211
|
+
raise InvalidNameTreeError, "Invalid Limits array" unless limits.length == 2
|
|
212
|
+
|
|
213
|
+
min, max = limits[0].value, limits[1].value
|
|
214
|
+
if name.to_str >= min and name.to_str <= max
|
|
215
|
+
names = Hash[*names]
|
|
216
|
+
target = names[name]
|
|
217
|
+
return target && target.solve
|
|
218
|
+
end
|
|
219
|
+
else
|
|
220
|
+
names = Hash[*names]
|
|
221
|
+
target = names[name]
|
|
222
|
+
return target && target.solve
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
elsif node.has_key?(:Kids) # intermediate node
|
|
226
|
+
raise InvalidNameTreeError, "Kids must be an Array" unless node.Kids.is_a?(Array)
|
|
227
|
+
|
|
228
|
+
node.Kids.each do |kid|
|
|
229
|
+
kid = kid.solve
|
|
230
|
+
limits = kid.Limits
|
|
231
|
+
unless limits.is_a?(Array) and limits.length == 2
|
|
232
|
+
raise InvalidNameTreeError, "Invalid Limits array"
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
min, max = limits[0].value, limits[1].value
|
|
236
|
+
|
|
237
|
+
if name.to_str >= min and name.to_str <= max
|
|
238
|
+
return resolve_name_from_node(kid, name, browsed_nodes: browsed_nodes)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def get_names_root(root) #:nodoc:
|
|
245
|
+
namedirs = self.Catalog.Names
|
|
246
|
+
return nil if namedirs.nil? or namedirs[root].nil?
|
|
247
|
+
|
|
248
|
+
namedirs[root].solve
|
|
249
|
+
end
|
|
78
250
|
end
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
raise TypeError, "An Action object must be passed."
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
unless self.Catalog
|
|
91
|
-
raise InvalidPDFError, "A catalog object must exist to add this action."
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
self.Catalog.OpenAction = action
|
|
95
|
-
|
|
96
|
-
self
|
|
251
|
+
|
|
252
|
+
module PageLayout #:nodoc:
|
|
253
|
+
SINGLE = :SinglePage
|
|
254
|
+
ONE_COLUMN = :OneColumn
|
|
255
|
+
TWO_COLUMN_LEFT = :TwoColumnLeft
|
|
256
|
+
TWO_COLUMN_RIGHT = :TwoColumnRight
|
|
257
|
+
TWO_PAGE_LEFT = :TwoPageLeft
|
|
258
|
+
TWO_PAGE_RIGHT = :TwoPageRight
|
|
97
259
|
end
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
raise TypeError, "An Action::JavaScript object must be passed."
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
unless self.Catalog
|
|
110
|
-
raise InvalidPDFError, "A catalog object must exist to add this action."
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
self.Catalog.AA ||= CatalogAdditionalActions.new
|
|
114
|
-
self.Catalog.AA.WC = action
|
|
115
|
-
|
|
116
|
-
self
|
|
260
|
+
|
|
261
|
+
module PageMode #:nodoc:
|
|
262
|
+
NONE = :UseNone
|
|
263
|
+
OUTLINES = :UseOutlines
|
|
264
|
+
THUMBS = :UseThumbs
|
|
265
|
+
FULLSCREEN = :FullScreen
|
|
266
|
+
OPTIONAL_CONTENT = :UseOC
|
|
267
|
+
ATTACHMENTS = :UseAttachments
|
|
117
268
|
end
|
|
118
|
-
|
|
269
|
+
|
|
119
270
|
#
|
|
120
|
-
#
|
|
121
|
-
# _action_:: A JavaScript Action Object.
|
|
271
|
+
# Class representing additional actions which can be associated with a Catalog.
|
|
122
272
|
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
self.Catalog.AA ||= CatalogAdditionalActions.new
|
|
134
|
-
self.Catalog.AA.WP = action
|
|
135
|
-
|
|
273
|
+
class CatalogAdditionalActions < Dictionary
|
|
274
|
+
include StandardObject
|
|
275
|
+
|
|
276
|
+
field :WC, :Type => Action, :Version => "1.4"
|
|
277
|
+
field :WS, :Type => Action, :Version => "1.4"
|
|
278
|
+
field :DS, :Type => Action, :Version => "1.4"
|
|
279
|
+
field :WP, :Type => Action, :Version => "1.4"
|
|
280
|
+
field :DP, :Type => Action, :Version => "1.4"
|
|
136
281
|
end
|
|
137
282
|
|
|
138
283
|
#
|
|
139
|
-
#
|
|
140
|
-
# _root_:: The root dictionary (see Names::Root)
|
|
141
|
-
# _name_:: The value name.
|
|
142
|
-
# _value_:: The value to associate with this name.
|
|
284
|
+
# Class representing the Names Dictionary of a PDF file.
|
|
143
285
|
#
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
286
|
+
class Names < Dictionary
|
|
287
|
+
include StandardObject
|
|
288
|
+
|
|
289
|
+
#
|
|
290
|
+
# Defines constants for Names tree root entries.
|
|
291
|
+
#
|
|
292
|
+
DESTINATIONS = :Dests
|
|
293
|
+
AP = :AP
|
|
294
|
+
JAVASCRIPT = :JavaScript
|
|
295
|
+
PAGES = :Pages
|
|
296
|
+
TEMPLATES = :Templates
|
|
297
|
+
IDS = :IDS
|
|
298
|
+
URLS = :URLS
|
|
299
|
+
EMBEDDED_FILES = :EmbeddedFiles
|
|
300
|
+
ALTERNATE_PRESENTATIONS = :AlternatePresentations
|
|
301
|
+
RENDITIONS = :Renditions
|
|
302
|
+
XFA_RESOURCES = :XFAResources
|
|
303
|
+
|
|
304
|
+
field DESTINATIONS, :Type => NameTreeNode.of([DestinationDictionary, Destination]), :Version => "1.2"
|
|
305
|
+
field AP, :Type => NameTreeNode.of(Annotation::AppearanceStream), :Version => "1.3"
|
|
306
|
+
field JAVASCRIPT, :Type => NameTreeNode.of(Action::JavaScript), :Version => "1.3"
|
|
307
|
+
field PAGES, :Type => NameTreeNode.of(Page), :Version => "1.3"
|
|
308
|
+
field TEMPLATES, :Type => NameTreeNode.of(Page), :Version => "1.3"
|
|
309
|
+
field IDS, :Type => NameTreeNode.of(WebCapture::ContentSet), :Version => "1.3"
|
|
310
|
+
field URLS, :Type => NameTreeNode.of(WebCapture::ContentSet), :Version => "1.3"
|
|
311
|
+
field EMBEDDED_FILES, :Type => NameTreeNode.of(FileSpec), :Version => "1.4"
|
|
312
|
+
field ALTERNATE_PRESENTATIONS, :Type => NameTreeNode, :Version => "1.4"
|
|
313
|
+
field RENDITIONS, :Type => NameTreeNode, :Version => "1.5"
|
|
314
|
+
field XFA_RESOURCES, :Type => NameTreeNode.of(XFAStream), :Version => "1.7", :ExtensionLevel => 3
|
|
165
315
|
end
|
|
166
316
|
|
|
167
317
|
#
|
|
168
|
-
#
|
|
169
|
-
# the specified _root_ name directory, or nil if the value does
|
|
170
|
-
# not exist.
|
|
318
|
+
# Class representing a leaf in a Name tree.
|
|
171
319
|
#
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
320
|
+
class NameLeaf < Array.of(String, Object)
|
|
321
|
+
|
|
322
|
+
#
|
|
323
|
+
# Creates a new leaf in a Name tree.
|
|
324
|
+
# _hash_:: A hash of couples, associating a Name with an Reference.
|
|
325
|
+
#
|
|
326
|
+
def initialize(hash = {})
|
|
327
|
+
super(hash.flat_map {|name, obj| [name.dup, obj]})
|
|
328
|
+
end
|
|
177
329
|
end
|
|
178
330
|
|
|
179
331
|
#
|
|
180
|
-
#
|
|
181
|
-
#
|
|
332
|
+
# Class representing the ViewerPreferences Dictionary of a PDF.
|
|
333
|
+
# This dictionary modifies the way the UI looks when the file is opened in a viewer.
|
|
182
334
|
#
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
return {} if namesroot.nil?
|
|
335
|
+
class ViewerPreferences < Dictionary
|
|
336
|
+
include StandardObject
|
|
186
337
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
Hash[*names]
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
private
|
|
196
|
-
|
|
197
|
-
def names_from_node(node, browsed_nodes = []) #:nodoc:
|
|
198
|
-
children = []
|
|
199
|
-
|
|
200
|
-
unless browsed_nodes.any? {|browsed| browsed.equal?(node)}
|
|
201
|
-
browsed_nodes.push(node)
|
|
202
|
-
if node.has_key?(:Names) # leaf node
|
|
203
|
-
children.concat(node.Names)
|
|
204
|
-
elsif node.has_key?(:Kids) # intermediate node
|
|
205
|
-
node.Kids.each do |kid|
|
|
206
|
-
children.concat(names_from_node(kid.solve, browsed_nodes))
|
|
207
|
-
end
|
|
338
|
+
# Valid values for the Enforce field.
|
|
339
|
+
module Enforce
|
|
340
|
+
PRINT_SCALING = :PrintScaling
|
|
208
341
|
end
|
|
209
|
-
end
|
|
210
342
|
|
|
211
|
-
|
|
343
|
+
field :HideToolbar, :Type => Boolean, :Default => false
|
|
344
|
+
field :HideMenubar, :Type => Boolean, :Default => false
|
|
345
|
+
field :HideWindowUI, :Type => Boolean, :Default => false
|
|
346
|
+
field :FitWindow, :Type => Boolean, :Default => false
|
|
347
|
+
field :CenterWindow, :Type => Boolean, :Default => false
|
|
348
|
+
field :DisplayDocTitle, :Type => Boolean, :Default => false, :Version => "1.4"
|
|
349
|
+
field :NonFullScreenPageMode, :Type => Name, :Default => :UseNone
|
|
350
|
+
field :Direction, :Type => Name, :Default => :L2R
|
|
351
|
+
field :ViewArea, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
|
352
|
+
field :ViewClip, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
|
353
|
+
field :PrintArea, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
|
354
|
+
field :PrintClip, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
|
355
|
+
field :PrintScaling, :Type => Name, :Default => :AppDefault, :Version => "1.6"
|
|
356
|
+
field :Duplex, :Type => Name, :Default => :Simplex, :Version => "1.7"
|
|
357
|
+
field :PickTrayByPDFSize, :Type => Boolean, :Version => "1.7"
|
|
358
|
+
field :PrintPageRange, :Type => Array.of(Integer), :Version => "1.7"
|
|
359
|
+
field :NumCopies, :Type => Integer, :Version => "1.7"
|
|
360
|
+
field :Enforce, :Type => Array.of(Name), :Version => "1.7", :ExtensionLevel => 3
|
|
212
361
|
end
|
|
213
362
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
browsed_nodes.push(node)
|
|
363
|
+
class Requirement < Dictionary
|
|
364
|
+
include StandardObject
|
|
217
365
|
|
|
218
|
-
|
|
219
|
-
|
|
366
|
+
class Handler < Dictionary
|
|
367
|
+
include StandardObject
|
|
220
368
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
names = Hash[*node.Names]
|
|
225
|
-
target = names[name]
|
|
226
|
-
return target && target.solve
|
|
227
|
-
end
|
|
228
|
-
else
|
|
229
|
-
names = Hash[*node.Names]
|
|
230
|
-
target = names[name]
|
|
231
|
-
return target && target.solve
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
elsif node.has_key?(:Kids) # intermediate node
|
|
235
|
-
node.Kids.each do |kid|
|
|
236
|
-
kid = kid.solve
|
|
237
|
-
limits = kid.Limits
|
|
238
|
-
min, max = limits[0].value, limits[1].value
|
|
239
|
-
|
|
240
|
-
if (min..max) === name.to_str
|
|
241
|
-
return resolve_name_from_node(kid, name, browsed_nodes)
|
|
369
|
+
module Type
|
|
370
|
+
JS = :JS
|
|
371
|
+
NOOP = :NoOp
|
|
242
372
|
end
|
|
243
|
-
end
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
end
|
|
247
373
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
names.each_pair do |name, value|
|
|
252
|
-
b.call(name, value.solve)
|
|
253
|
-
end
|
|
254
|
-
elsif node.has_key?(:Kids) # intermediate node
|
|
255
|
-
node.Kids.each do |kid|
|
|
256
|
-
each_name_from_node(kid.solve, browsed_nodes, &b)
|
|
374
|
+
field :Type, :Type => Name, :Default => :ReqHandler
|
|
375
|
+
field :S, :Type => Name, :Default => Type::NOOP, :Required => true
|
|
376
|
+
field :Script, :Type => String
|
|
257
377
|
end
|
|
258
|
-
|
|
378
|
+
|
|
379
|
+
field :Type, :Type => Name, :Default => :Requirement
|
|
380
|
+
field :S, :Type => Name, :Default => :EnableJavaScripts, :Version => "1.7", :Required => true
|
|
381
|
+
field :RH, :Type => Array.of(Handler)
|
|
259
382
|
end
|
|
260
383
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
384
|
+
#
|
|
385
|
+
# Class representing a developer extension.
|
|
386
|
+
#
|
|
387
|
+
class DeveloperExtension < Dictionary
|
|
388
|
+
include StandardObject
|
|
264
389
|
|
|
265
|
-
|
|
390
|
+
field :Type, :Type => Name, :Default => :DeveloperExtensions
|
|
391
|
+
field :BaseVersion, :Type => Name, :Required => true
|
|
392
|
+
field :ExtensionLevel, :Type => Integer, :Required => true
|
|
266
393
|
end
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
module PageLayout #:nodoc:
|
|
270
|
-
SINGLE = :SinglePage
|
|
271
|
-
ONE_COLUMN = :OneColumn
|
|
272
|
-
TWO_COLUMN_LEFT = :TwoColumnLeft
|
|
273
|
-
TWO_COLUMN_RIGHT = :TwoColumnRight
|
|
274
|
-
TWO_PAGE_LEFT = :TwoPageLeft
|
|
275
|
-
TWO_PAGE_RIGHT = :TwoPageRight
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
module PageMode #:nodoc:
|
|
279
|
-
NONE = :UseNone
|
|
280
|
-
OUTLINES = :UseOutlines
|
|
281
|
-
THUMBS = :UseThumbs
|
|
282
|
-
FULLSCREEN = :FullScreen
|
|
283
|
-
OPTIONAL_CONTENT = :UseOC
|
|
284
|
-
ATTACHMENTS = :UseAttachments
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
#
|
|
288
|
-
# Class representing additional actions which can be associated with a Catalog.
|
|
289
|
-
#
|
|
290
|
-
class CatalogAdditionalActions < Dictionary
|
|
291
|
-
include StandardObject
|
|
292
|
-
|
|
293
|
-
field :WC, :Type => Dictionary, :Version => "1.4"
|
|
294
|
-
field :WS, :Type => Dictionary, :Version => "1.4"
|
|
295
|
-
field :DS, :Type => Dictionary, :Version => "1.4"
|
|
296
|
-
field :WP, :Type => Dictionary, :Version => "1.4"
|
|
297
|
-
field :DP, :Type => Dictionary, :Version => "1.4"
|
|
298
|
-
end
|
|
299
|
-
|
|
300
|
-
class InvalidNameTreeError < Exception #:nodoc:
|
|
301
|
-
end
|
|
302
|
-
|
|
303
|
-
#
|
|
304
|
-
# Class representing the Names Dictionary of a PDF file.
|
|
305
|
-
#
|
|
306
|
-
class Names < Dictionary
|
|
307
|
-
include StandardObject
|
|
308
|
-
|
|
394
|
+
|
|
309
395
|
#
|
|
310
|
-
#
|
|
396
|
+
# Class representing an extension Dictionary.
|
|
311
397
|
#
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
TEMPLATES = :Templates
|
|
318
|
-
IDS = :IDS
|
|
319
|
-
URLS = :URLS
|
|
320
|
-
EMBEDDEDFILES = :EmbeddedFiles
|
|
321
|
-
ALTERNATEPRESENTATIONS = :AlternatePresentations
|
|
322
|
-
RENDITIONS = :Renditions
|
|
323
|
-
XFARESOURCES = :XFAResources
|
|
398
|
+
class Extensions < Dictionary
|
|
399
|
+
include StandardObject
|
|
400
|
+
|
|
401
|
+
field :Type, :Type => Name, :Default => :Extensions
|
|
402
|
+
field :ADBE, :Type => DeveloperExtension
|
|
324
403
|
end
|
|
325
404
|
|
|
326
|
-
field Root::DESTS, :Type => Dictionary, :Version => "1.2"
|
|
327
|
-
field Root::AP, :Type => Dictionary, :Version => "1.3"
|
|
328
|
-
field Root::JAVASCRIPT, :Type => Dictionary, :Version => "1.3"
|
|
329
|
-
field Root::PAGES, :Type => Dictionary, :Version => "1.3"
|
|
330
|
-
field Root::TEMPLATES, :Type => Dictionary, :Version => "1.3"
|
|
331
|
-
field Root::IDS, :Type => Dictionary, :Version => "1.3"
|
|
332
|
-
field Root::URLS, :Type => Dictionary, :Version => "1.3"
|
|
333
|
-
field Root::EMBEDDEDFILES, :Type => Dictionary, :Version => "1.4"
|
|
334
|
-
field Root::ALTERNATEPRESENTATIONS, :Type => Dictionary, :Version => "1.4"
|
|
335
|
-
field Root::RENDITIONS, :Type => Dictionary, :Version => "1.5"
|
|
336
|
-
field Root::XFARESOURCES, :Type => Dictionary, :Version => "1.7", :ExtensionLevel => 3
|
|
337
|
-
end
|
|
338
|
-
|
|
339
|
-
#
|
|
340
|
-
# Class representing a node in a Name tree.
|
|
341
|
-
#
|
|
342
|
-
class NameTreeNode < Dictionary
|
|
343
|
-
include StandardObject
|
|
344
|
-
|
|
345
|
-
field :Kids, :Type => Array
|
|
346
|
-
field :Names, :Type => Array
|
|
347
|
-
field :Limits, :Type => Array
|
|
348
|
-
end
|
|
349
|
-
|
|
350
|
-
#
|
|
351
|
-
# Class representing a leaf in a Name tree.
|
|
352
|
-
#
|
|
353
|
-
class NameLeaf < Origami::Array
|
|
354
|
-
|
|
355
405
|
#
|
|
356
|
-
#
|
|
357
|
-
# _hash_:: A hash of couples, associating a Name with an Reference.
|
|
406
|
+
# Class representing the Catalog Dictionary of a PDF file.
|
|
358
407
|
#
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
class Requirement < Dictionary
|
|
399
|
-
include StandardObject
|
|
400
|
-
|
|
401
|
-
class Handler < Dictionary
|
|
402
|
-
include StandardObject
|
|
403
|
-
|
|
404
|
-
module Type
|
|
405
|
-
JS = :JS
|
|
406
|
-
NOOP = :NoOp
|
|
407
|
-
end
|
|
408
|
-
|
|
409
|
-
field :Type, :Type => Name, :Default => :ReqHandler
|
|
410
|
-
field :S, :Type => Name, :Default => Type::NOOP, :Required => true
|
|
411
|
-
field :Script, :Type => ByteString
|
|
408
|
+
class Catalog < Dictionary
|
|
409
|
+
include StandardObject
|
|
410
|
+
|
|
411
|
+
field :Type, :Type => Name, :Default => :Catalog, :Required => true
|
|
412
|
+
field :Version, :Type => Name, :Version => "1.4"
|
|
413
|
+
field :Pages, :Type => PageTreeNode, :Required => true
|
|
414
|
+
field :PageLabels, :Type => NumberTreeNode.of(PageLabel), :Version => "1.3"
|
|
415
|
+
field :Names, :Type => Names, :Version => "1.2"
|
|
416
|
+
field :Dests, :Type => Dictionary, :Version => "1.1"
|
|
417
|
+
field :ViewerPreferences, :Type => ViewerPreferences, :Version => "1.2"
|
|
418
|
+
field :PageLayout, :Type => Name, :Default => PageLayout::SINGLE
|
|
419
|
+
field :PageMode, :Type => Name, :Default => PageMode::NONE
|
|
420
|
+
field :Outlines, :Type => Outline
|
|
421
|
+
field :Threads, :Type => Array, :Version => "1.1"
|
|
422
|
+
field :OpenAction, :Type => [ Array, Dictionary ], :Version => "1.1"
|
|
423
|
+
field :AA, :Type => CatalogAdditionalActions, :Version => "1.4"
|
|
424
|
+
field :URI, :Type => Dictionary, :Version => "1.1"
|
|
425
|
+
field :AcroForm, :Type => InteractiveForm, :Version => "1.2"
|
|
426
|
+
field :Metadata, :Type => MetadataStream, :Version => "1.4"
|
|
427
|
+
field :StructTreeRoot, :Type => Dictionary, :Version => "1.3"
|
|
428
|
+
field :MarkInfo, :Type => Dictionary, :Version => "1.4"
|
|
429
|
+
field :Lang, :Type => String, :Version => "1.4"
|
|
430
|
+
field :SpiderInfo, :Type => WebCapture::SpiderInfo, :Version => "1.3"
|
|
431
|
+
field :OutputIntents, :Type => Array.of(OutputIntent), :Version => "1.4"
|
|
432
|
+
field :PieceInfo, :Type => Dictionary, :Version => "1.4"
|
|
433
|
+
field :OCProperties, :Type => Dictionary, :Version => "1.5"
|
|
434
|
+
field :Perms, :Type => Dictionary, :Version => "1.5"
|
|
435
|
+
field :Legal, :Type => Dictionary, :Version => "1.5"
|
|
436
|
+
field :Requirements, :Type => Array.of(Requirement), :Version => "1.7"
|
|
437
|
+
field :Collection, :Type => Collection, :Version => "1.7"
|
|
438
|
+
field :NeedsRendering, :Type => Boolean, :Version => "1.7", :Default => false
|
|
439
|
+
field :Extensions, :Type => Extensions, :Version => "1.7", :ExtensionLevel => 3
|
|
440
|
+
|
|
441
|
+
def initialize(hash = {}, parser = nil)
|
|
442
|
+
set_indirect(true)
|
|
443
|
+
|
|
444
|
+
super(hash, parser)
|
|
445
|
+
end
|
|
412
446
|
end
|
|
413
447
|
|
|
414
|
-
field :Type, :Type => Name, :Default => :Requirement
|
|
415
|
-
field :S, :Type => Name, :Default => :EnableJavaScripts, :Version => "1.7", :Required => true
|
|
416
|
-
field :RH, :Type => Array
|
|
417
|
-
end
|
|
418
|
-
|
|
419
|
-
#
|
|
420
|
-
# Class representing an extension Dictionary.
|
|
421
|
-
#
|
|
422
|
-
class Extensions < Dictionary
|
|
423
|
-
include StandardObject
|
|
424
|
-
|
|
425
|
-
field :Type, :Type => Name, :Default => :Extensions
|
|
426
|
-
end
|
|
427
|
-
|
|
428
|
-
#
|
|
429
|
-
# Class representing a developer extension.
|
|
430
|
-
#
|
|
431
|
-
class DeveloperExtension < Dictionary
|
|
432
|
-
include StandardObject
|
|
433
|
-
|
|
434
|
-
field :Type, :Type => Name, :Default => :DeveloperExtensions
|
|
435
|
-
field :BaseVersion, :Type => Name, :Required => true
|
|
436
|
-
field :ExtensionLevel, :Type => Integer, :Required => true
|
|
437
|
-
|
|
438
|
-
end
|
|
439
|
-
|
|
440
|
-
#
|
|
441
|
-
# Class representing the Catalog Dictionary of a PDF file.
|
|
442
|
-
#
|
|
443
|
-
class Catalog < Dictionary
|
|
444
|
-
|
|
445
|
-
include StandardObject
|
|
446
|
-
|
|
447
|
-
field :Type, :Type => Name, :Default => :Catalog, :Required => true
|
|
448
|
-
field :Version, :Type => Name, :Version => "1.4"
|
|
449
|
-
field :Pages, :Type => Dictionary, :Required => true
|
|
450
|
-
field :PageLabels, :Type => Dictionary, :Version => "1.3"
|
|
451
|
-
field :Names, :Type => Dictionary, :Version => "1.2"
|
|
452
|
-
field :Dests, :Type => Dictionary, :Version => "1.1"
|
|
453
|
-
field :ViewerPreferences, :Type => ViewerPreferences, :Version => "1.2"
|
|
454
|
-
field :PageLayout, :Type => Name, :Default => PageLayout::SINGLE
|
|
455
|
-
field :PageMode, :Type => Name, :Default => PageMode::NONE
|
|
456
|
-
field :Outlines, :Type => Dictionary
|
|
457
|
-
field :Threads, :Type => Array, :Version => "1.1"
|
|
458
|
-
field :OpenAction, :Type => [ Array, Dictionary ], :Version => "1.1"
|
|
459
|
-
field :AA, :Type => Dictionary, :Version => "1.4"
|
|
460
|
-
field :URI, :Type => Dictionary, :Version => "1.1"
|
|
461
|
-
field :AcroForm, :Type => Dictionary, :Version => "1.2"
|
|
462
|
-
field :Metadata, :Type => Stream, :Version => "1.4"
|
|
463
|
-
field :StructTreeRoot, :Type => Dictionary, :Version => "1.3"
|
|
464
|
-
field :MarkInfo, :Type => Dictionary, :Version => "1.4"
|
|
465
|
-
field :Lang, :Type => String, :Version => "1.4"
|
|
466
|
-
field :SpiderInfo, :Type => Dictionary, :Version => "1.3"
|
|
467
|
-
field :OutputIntents, :Type => Array, :Version => "1.4"
|
|
468
|
-
field :PieceInfo, :Type => Dictionary, :Version => "1.4"
|
|
469
|
-
field :OCProperties, :Type => Dictionary, :Version => "1.5"
|
|
470
|
-
field :Perms, :Type => Dictionary, :Version => "1.5"
|
|
471
|
-
field :Legal, :Type => Dictionary, :Version => "1.5"
|
|
472
|
-
field :Requirements, :Type => Array, :Version => "1.7"
|
|
473
|
-
field :Collection, :Type => Dictionary, :Version => "1.7"
|
|
474
|
-
field :NeedsRendering, :Type => Boolean, :Version => "1.7", :Default => false
|
|
475
|
-
field :Extensions, :Type => Dictionary, :Version => "1.7", :ExtensionLevel => 3
|
|
476
|
-
|
|
477
|
-
def initialize(hash = {})
|
|
478
|
-
set_indirect(true)
|
|
479
|
-
|
|
480
|
-
super(hash)
|
|
481
|
-
end
|
|
482
|
-
|
|
483
|
-
end
|
|
484
|
-
|
|
485
448
|
end
|