origamindee 3.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 +7 -0
- data/CHANGELOG.md +89 -0
- data/COPYING.LESSER +165 -0
- data/README.md +131 -0
- data/bin/config/pdfcop.conf.yml +236 -0
- data/bin/pdf2pdfa +87 -0
- data/bin/pdf2ruby +333 -0
- data/bin/pdfcop +476 -0
- data/bin/pdfdecompress +97 -0
- data/bin/pdfdecrypt +91 -0
- data/bin/pdfencrypt +113 -0
- data/bin/pdfexplode +223 -0
- data/bin/pdfextract +277 -0
- data/bin/pdfmetadata +143 -0
- data/bin/pdfsh +12 -0
- data/bin/shell/console.rb +128 -0
- data/bin/shell/hexdump.rb +59 -0
- data/bin/shell/irbrc +69 -0
- 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/examples/events/events.rb +72 -0
- data/examples/flash/flash.rb +37 -0
- data/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/3d.rb +364 -0
- data/lib/origami/acroform.rb +321 -0
- data/lib/origami/actions.rb +318 -0
- data/lib/origami/annotations.rb +711 -0
- data/lib/origami/array.rb +242 -0
- data/lib/origami/boolean.rb +90 -0
- data/lib/origami/catalog.rb +418 -0
- data/lib/origami/collections.rb +144 -0
- data/lib/origami/compound.rb +161 -0
- data/lib/origami/destinations.rb +252 -0
- data/lib/origami/dictionary.rb +192 -0
- data/lib/origami/encryption.rb +1084 -0
- data/lib/origami/extensions/fdf.rb +347 -0
- data/lib/origami/extensions/ppklite.rb +422 -0
- data/lib/origami/filespec.rb +197 -0
- data/lib/origami/filters/ascii.rb +211 -0
- data/lib/origami/filters/ccitt/tables.rb +267 -0
- data/lib/origami/filters/ccitt.rb +357 -0
- data/lib/origami/filters/crypt.rb +38 -0
- data/lib/origami/filters/dct.rb +54 -0
- data/lib/origami/filters/flate.rb +69 -0
- data/lib/origami/filters/jbig2.rb +57 -0
- data/lib/origami/filters/jpx.rb +47 -0
- data/lib/origami/filters/lzw.rb +170 -0
- data/lib/origami/filters/predictors.rb +292 -0
- data/lib/origami/filters/runlength.rb +129 -0
- data/lib/origami/filters.rb +364 -0
- data/lib/origami/font.rb +196 -0
- data/lib/origami/functions.rb +79 -0
- data/lib/origami/graphics/colors.rb +230 -0
- data/lib/origami/graphics/instruction.rb +98 -0
- data/lib/origami/graphics/path.rb +182 -0
- data/lib/origami/graphics/patterns.rb +174 -0
- data/lib/origami/graphics/render.rb +62 -0
- data/lib/origami/graphics/state.rb +149 -0
- data/lib/origami/graphics/text.rb +225 -0
- data/lib/origami/graphics/xobject.rb +918 -0
- data/lib/origami/graphics.rb +38 -0
- data/lib/origami/header.rb +75 -0
- data/lib/origami/javascript.rb +713 -0
- data/lib/origami/linearization.rb +330 -0
- data/lib/origami/metadata.rb +172 -0
- data/lib/origami/name.rb +135 -0
- data/lib/origami/null.rb +65 -0
- data/lib/origami/numeric.rb +181 -0
- data/lib/origami/obfuscation.rb +245 -0
- data/lib/origami/object.rb +760 -0
- data/lib/origami/optionalcontent.rb +183 -0
- data/lib/origami/outline.rb +54 -0
- data/lib/origami/outputintents.rb +85 -0
- data/lib/origami/page.rb +722 -0
- data/lib/origami/parser.rb +269 -0
- data/lib/origami/parsers/fdf.rb +56 -0
- data/lib/origami/parsers/pdf/lazy.rb +176 -0
- data/lib/origami/parsers/pdf/linear.rb +122 -0
- data/lib/origami/parsers/pdf.rb +118 -0
- data/lib/origami/parsers/ppklite.rb +57 -0
- data/lib/origami/pdf.rb +1108 -0
- data/lib/origami/reference.rb +134 -0
- data/lib/origami/signature.rb +702 -0
- data/lib/origami/stream.rb +705 -0
- data/lib/origami/string.rb +444 -0
- data/lib/origami/template/patterns.rb +56 -0
- data/lib/origami/template/widgets.rb +151 -0
- data/lib/origami/trailer.rb +190 -0
- data/lib/origami/tree.rb +62 -0
- data/lib/origami/version.rb +23 -0
- data/lib/origami/webcapture.rb +100 -0
- data/lib/origami/xfa/config.rb +453 -0
- data/lib/origami/xfa/connectionset.rb +146 -0
- data/lib/origami/xfa/datasets.rb +49 -0
- data/lib/origami/xfa/localeset.rb +42 -0
- data/lib/origami/xfa/package.rb +59 -0
- data/lib/origami/xfa/pdf.rb +73 -0
- data/lib/origami/xfa/signature.rb +42 -0
- data/lib/origami/xfa/sourceset.rb +43 -0
- data/lib/origami/xfa/stylesheet.rb +44 -0
- data/lib/origami/xfa/template.rb +1691 -0
- data/lib/origami/xfa/xdc.rb +42 -0
- data/lib/origami/xfa/xfa.rb +146 -0
- data/lib/origami/xfa/xfdf.rb +43 -0
- data/lib/origami/xfa/xmpmeta.rb +43 -0
- data/lib/origami/xfa.rb +62 -0
- data/lib/origami/xreftable.rb +557 -0
- data/lib/origami.rb +47 -0
- data/test/dataset/calc.pdf +85 -0
- data/test/dataset/crypto.pdf +36 -0
- data/test/dataset/empty.pdf +49 -0
- data/test/test_actions.rb +27 -0
- data/test/test_annotations.rb +68 -0
- data/test/test_forms.rb +30 -0
- data/test/test_native_types.rb +83 -0
- data/test/test_object_tree.rb +33 -0
- data/test/test_pages.rb +60 -0
- data/test/test_pdf.rb +20 -0
- data/test/test_pdf_attachment.rb +34 -0
- data/test/test_pdf_create.rb +24 -0
- data/test/test_pdf_encrypt.rb +102 -0
- data/test/test_pdf_parse.rb +134 -0
- data/test/test_pdf_parse_lazy.rb +69 -0
- data/test/test_pdf_sign.rb +97 -0
- data/test/test_streams.rb +184 -0
- data/test/test_xrefs.rb +67 -0
- metadata +280 -0
@@ -0,0 +1,418 @@
|
|
1
|
+
=begin
|
2
|
+
|
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/>.
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
module Origami
|
22
|
+
|
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
|
+
|
30
|
+
exts[:ADBE] = DeveloperExtension.new
|
31
|
+
exts[:ADBE].BaseVersion = Name.new(version)
|
32
|
+
exts[:ADBE].ExtensionLevel = level
|
33
|
+
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# Returns the current Catalog Dictionary.
|
39
|
+
#
|
40
|
+
def Catalog
|
41
|
+
cat = trailer_key(:Root)
|
42
|
+
raise InvalidPDFError, "Broken catalog" unless cat.is_a?(Catalog)
|
43
|
+
|
44
|
+
cat
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Sets the current Catalog Dictionary.
|
49
|
+
#
|
50
|
+
def Catalog=(cat)
|
51
|
+
raise TypeError, "Must be a Catalog object" unless cat.is_a?(Catalog)
|
52
|
+
|
53
|
+
delete_object(@revisions.last.trailer[:Root]) if @revisions.last.trailer[:Root]
|
54
|
+
|
55
|
+
@revisions.last.trailer.Root = self << cat
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Sets an action to run on document opening.
|
60
|
+
# _action_:: An Action Object.
|
61
|
+
#
|
62
|
+
def onDocumentOpen(action)
|
63
|
+
self.Catalog.OpenAction = action
|
64
|
+
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
#
|
69
|
+
# Sets an action to run on document closing.
|
70
|
+
# _action_:: A JavaScript Action Object.
|
71
|
+
#
|
72
|
+
def onDocumentClose(action)
|
73
|
+
self.Catalog.AA ||= CatalogAdditionalActions.new
|
74
|
+
self.Catalog.AA.WC = action
|
75
|
+
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# Sets an action to run on document printing.
|
81
|
+
# _action_:: A JavaScript Action Object.
|
82
|
+
#
|
83
|
+
def onDocumentPrint(action)
|
84
|
+
self.Catalog.AA ||= CatalogAdditionalActions.new
|
85
|
+
self.Catalog.AA.WP = action
|
86
|
+
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
#
|
91
|
+
# Registers an object into a specific Names root dictionary.
|
92
|
+
# _root_:: The root dictionary (see Names::Root)
|
93
|
+
# _name_:: The value name.
|
94
|
+
# _value_:: The value to associate with this name.
|
95
|
+
#
|
96
|
+
def register(root, name, value)
|
97
|
+
self.Catalog.Names ||= Names.new
|
98
|
+
|
99
|
+
value.set_indirect(true) unless value.is_a?(Reference)
|
100
|
+
|
101
|
+
namesroot = self.Catalog.Names[root]
|
102
|
+
if namesroot.nil?
|
103
|
+
names = NameTreeNode.new(:Names => []).set_indirect(true)
|
104
|
+
self.Catalog.Names[root] = names
|
105
|
+
names.Names << name << value
|
106
|
+
else
|
107
|
+
namesroot.solve[:Names] << name << value
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Retrieve the corresponding value associated with _name_ in
|
113
|
+
# the specified _root_ name directory, or nil if the value does
|
114
|
+
# not exist.
|
115
|
+
#
|
116
|
+
def resolve_name(root, name)
|
117
|
+
namesroot = get_names_root(root)
|
118
|
+
return nil if namesroot.nil?
|
119
|
+
|
120
|
+
resolve_name_from_node(namesroot, name)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Returns a Hash of all names under the specified _root_ name directory.
|
125
|
+
#
|
126
|
+
def names(root)
|
127
|
+
self.each_name(root).to_h
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Returns an Enumerator of all names under the specified _root_ name directory.
|
132
|
+
#
|
133
|
+
def each_name(root, &block)
|
134
|
+
return enum_for(__method__, root) unless block_given?
|
135
|
+
|
136
|
+
names_root = get_names_root(root)
|
137
|
+
return if names_root.nil?
|
138
|
+
|
139
|
+
names_from_node(names_root, &block)
|
140
|
+
self
|
141
|
+
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def names_from_node(node, browsed_nodes: [], &block) #:nodoc:
|
146
|
+
return if browsed_nodes.any?{|browsed| browsed.equal?(node)}
|
147
|
+
raise InvalidNameTreeError, "node is not a dictionary" unless node.is_a?(Dictionary)
|
148
|
+
|
149
|
+
browsed_nodes.push(node)
|
150
|
+
|
151
|
+
if node.has_key?(:Names) # leaf node
|
152
|
+
names = node.Names
|
153
|
+
raise InvalidNameTreeError, "Names must be an Array" unless names.is_a?(Array)
|
154
|
+
raise InvalidNameTreeError, "Odd number of elements" if names.length.odd?
|
155
|
+
|
156
|
+
for i in 0...names.length/2
|
157
|
+
yield(names[i * 2].solve, names[i * 2 + 1].solve)
|
158
|
+
end
|
159
|
+
|
160
|
+
elsif node.has_key?(:Kids) # intermediate node
|
161
|
+
node.Kids.each do |kid|
|
162
|
+
names_from_node(kid.solve, browsed_nodes: browsed_nodes, &block)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def resolve_name_from_node(node, name, browsed_nodes: []) #:nodoc:
|
168
|
+
return if browsed_nodes.any?{|browsed| browsed.equal?(node)}
|
169
|
+
raise InvalidNameTreeError, "node is not a Dictionary" unless node.is_a?(Dictionary)
|
170
|
+
|
171
|
+
browsed_nodes.push(node)
|
172
|
+
|
173
|
+
if node.has_key?(:Names) # leaf node
|
174
|
+
limits = node.Limits
|
175
|
+
names = node.Names
|
176
|
+
|
177
|
+
raise InvalidNameTreeError, "Names must be an Array" unless names.is_a?(Array)
|
178
|
+
raise InvalidNameTreeError, "Odd number of elements" if names.length.odd?
|
179
|
+
|
180
|
+
if limits.is_a?(Array)
|
181
|
+
raise InvalidNameTreeError, "Invalid Limits array" unless limits.length == 2
|
182
|
+
|
183
|
+
min, max = limits[0].value, limits[1].value
|
184
|
+
if name.to_str >= min and name.to_str <= max
|
185
|
+
names = Hash[*names]
|
186
|
+
target = names[name]
|
187
|
+
return target && target.solve
|
188
|
+
end
|
189
|
+
else
|
190
|
+
names = Hash[*names]
|
191
|
+
target = names[name]
|
192
|
+
return target && target.solve
|
193
|
+
end
|
194
|
+
|
195
|
+
elsif node.has_key?(:Kids) # intermediate node
|
196
|
+
raise InvalidNameTreeError, "Kids must be an Array" unless node.Kids.is_a?(Array)
|
197
|
+
|
198
|
+
node.Kids.each do |kid|
|
199
|
+
kid = kid.solve
|
200
|
+
limits = kid.Limits
|
201
|
+
unless limits.is_a?(Array) and limits.length == 2
|
202
|
+
raise InvalidNameTreeError, "Invalid Limits array"
|
203
|
+
end
|
204
|
+
|
205
|
+
min, max = limits[0].value, limits[1].value
|
206
|
+
|
207
|
+
if name.to_str >= min and name.to_str <= max
|
208
|
+
return resolve_name_from_node(kid, name, browsed_nodes: browsed_nodes)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def get_names_root(root) #:nodoc:
|
215
|
+
namedirs = self.Catalog.Names
|
216
|
+
return nil if namedirs.nil? or namedirs[root].nil?
|
217
|
+
|
218
|
+
namedirs[root].solve
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
module PageLayout #:nodoc:
|
223
|
+
SINGLE = :SinglePage
|
224
|
+
ONE_COLUMN = :OneColumn
|
225
|
+
TWO_COLUMN_LEFT = :TwoColumnLeft
|
226
|
+
TWO_COLUMN_RIGHT = :TwoColumnRight
|
227
|
+
TWO_PAGE_LEFT = :TwoPageLeft
|
228
|
+
TWO_PAGE_RIGHT = :TwoPageRight
|
229
|
+
end
|
230
|
+
|
231
|
+
module PageMode #:nodoc:
|
232
|
+
NONE = :UseNone
|
233
|
+
OUTLINES = :UseOutlines
|
234
|
+
THUMBS = :UseThumbs
|
235
|
+
FULLSCREEN = :FullScreen
|
236
|
+
OPTIONAL_CONTENT = :UseOC
|
237
|
+
ATTACHMENTS = :UseAttachments
|
238
|
+
end
|
239
|
+
|
240
|
+
#
|
241
|
+
# Class representing additional actions which can be associated with a Catalog.
|
242
|
+
#
|
243
|
+
class CatalogAdditionalActions < Dictionary
|
244
|
+
include StandardObject
|
245
|
+
|
246
|
+
field :WC, :Type => Action, :Version => "1.4"
|
247
|
+
field :WS, :Type => Action, :Version => "1.4"
|
248
|
+
field :DS, :Type => Action, :Version => "1.4"
|
249
|
+
field :WP, :Type => Action, :Version => "1.4"
|
250
|
+
field :DP, :Type => Action, :Version => "1.4"
|
251
|
+
end
|
252
|
+
|
253
|
+
#
|
254
|
+
# Class representing the Names Dictionary of a PDF file.
|
255
|
+
#
|
256
|
+
class Names < Dictionary
|
257
|
+
include StandardObject
|
258
|
+
|
259
|
+
#
|
260
|
+
# Defines constants for Names tree root entries.
|
261
|
+
#
|
262
|
+
DESTINATIONS = :Dests
|
263
|
+
AP = :AP
|
264
|
+
JAVASCRIPT = :JavaScript
|
265
|
+
PAGES = :Pages
|
266
|
+
TEMPLATES = :Templates
|
267
|
+
IDS = :IDS
|
268
|
+
URLS = :URLS
|
269
|
+
EMBEDDED_FILES = :EmbeddedFiles
|
270
|
+
ALTERNATE_PRESENTATIONS = :AlternatePresentations
|
271
|
+
RENDITIONS = :Renditions
|
272
|
+
XFA_RESOURCES = :XFAResources
|
273
|
+
|
274
|
+
field DESTINATIONS, :Type => NameTreeNode.of([DestinationDictionary, Destination]), :Version => "1.2"
|
275
|
+
field AP, :Type => NameTreeNode.of(Annotation::AppearanceStream), :Version => "1.3"
|
276
|
+
field JAVASCRIPT, :Type => NameTreeNode.of(Action::JavaScript), :Version => "1.3"
|
277
|
+
field PAGES, :Type => NameTreeNode.of(Page), :Version => "1.3"
|
278
|
+
field TEMPLATES, :Type => NameTreeNode.of(Page), :Version => "1.3"
|
279
|
+
field IDS, :Type => NameTreeNode.of(WebCapture::ContentSet), :Version => "1.3"
|
280
|
+
field URLS, :Type => NameTreeNode.of(WebCapture::ContentSet), :Version => "1.3"
|
281
|
+
field EMBEDDED_FILES, :Type => NameTreeNode.of(FileSpec), :Version => "1.4"
|
282
|
+
field ALTERNATE_PRESENTATIONS, :Type => NameTreeNode, :Version => "1.4"
|
283
|
+
field RENDITIONS, :Type => NameTreeNode, :Version => "1.5"
|
284
|
+
field XFA_RESOURCES, :Type => NameTreeNode.of(XFAStream), :Version => "1.7", :ExtensionLevel => 3
|
285
|
+
end
|
286
|
+
|
287
|
+
#
|
288
|
+
# Class representing a leaf in a Name tree.
|
289
|
+
#
|
290
|
+
class NameLeaf < Array.of(String, Object)
|
291
|
+
|
292
|
+
#
|
293
|
+
# Creates a new leaf in a Name tree.
|
294
|
+
# _hash_:: A hash of couples, associating a Name with an Reference.
|
295
|
+
#
|
296
|
+
def initialize(hash = {})
|
297
|
+
super(hash.flat_map {|name, obj| [name.dup, obj]})
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
#
|
302
|
+
# Class representing the ViewerPreferences Dictionary of a PDF.
|
303
|
+
# This dictionary modifies the way the UI looks when the file is opened in a viewer.
|
304
|
+
#
|
305
|
+
class ViewerPreferences < Dictionary
|
306
|
+
include StandardObject
|
307
|
+
|
308
|
+
# Valid values for the Enforce field.
|
309
|
+
module Enforce
|
310
|
+
PRINT_SCALING = :PrintScaling
|
311
|
+
end
|
312
|
+
|
313
|
+
field :HideToolbar, :Type => Boolean, :Default => false
|
314
|
+
field :HideMenubar, :Type => Boolean, :Default => false
|
315
|
+
field :HideWindowUI, :Type => Boolean, :Default => false
|
316
|
+
field :FitWindow, :Type => Boolean, :Default => false
|
317
|
+
field :CenterWindow, :Type => Boolean, :Default => false
|
318
|
+
field :DisplayDocTitle, :Type => Boolean, :Default => false, :Version => "1.4"
|
319
|
+
field :NonFullScreenPageMode, :Type => Name, :Default => :UseNone
|
320
|
+
field :Direction, :Type => Name, :Default => :L2R
|
321
|
+
field :ViewArea, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
322
|
+
field :ViewClip, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
323
|
+
field :PrintArea, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
324
|
+
field :PrintClip, :Type => Name, :Default => :CropBox, :Version => "1.4"
|
325
|
+
field :PrintScaling, :Type => Name, :Default => :AppDefault, :Version => "1.6"
|
326
|
+
field :Duplex, :Type => Name, :Default => :Simplex, :Version => "1.7"
|
327
|
+
field :PickTrayByPDFSize, :Type => Boolean, :Version => "1.7"
|
328
|
+
field :PrintPageRange, :Type => Array.of(Integer), :Version => "1.7"
|
329
|
+
field :NumCopies, :Type => Integer, :Version => "1.7"
|
330
|
+
field :Enforce, :Type => Array.of(Name), :Version => "1.7", :ExtensionLevel => 3
|
331
|
+
end
|
332
|
+
|
333
|
+
class Requirement < Dictionary
|
334
|
+
include StandardObject
|
335
|
+
|
336
|
+
class Handler < Dictionary
|
337
|
+
include StandardObject
|
338
|
+
|
339
|
+
module Type
|
340
|
+
JS = :JS
|
341
|
+
NOOP = :NoOp
|
342
|
+
end
|
343
|
+
|
344
|
+
field :Type, :Type => Name, :Default => :ReqHandler
|
345
|
+
field :S, :Type => Name, :Default => Type::NOOP, :Required => true
|
346
|
+
field :Script, :Type => String
|
347
|
+
end
|
348
|
+
|
349
|
+
field :Type, :Type => Name, :Default => :Requirement
|
350
|
+
field :S, :Type => Name, :Default => :EnableJavaScripts, :Version => "1.7", :Required => true
|
351
|
+
field :RH, :Type => Array.of(Handler)
|
352
|
+
end
|
353
|
+
|
354
|
+
#
|
355
|
+
# Class representing a developer extension.
|
356
|
+
#
|
357
|
+
class DeveloperExtension < Dictionary
|
358
|
+
include StandardObject
|
359
|
+
|
360
|
+
field :Type, :Type => Name, :Default => :DeveloperExtensions
|
361
|
+
field :BaseVersion, :Type => Name, :Required => true
|
362
|
+
field :ExtensionLevel, :Type => Integer, :Required => true
|
363
|
+
end
|
364
|
+
|
365
|
+
#
|
366
|
+
# Class representing an extension Dictionary.
|
367
|
+
#
|
368
|
+
class Extensions < Dictionary
|
369
|
+
include StandardObject
|
370
|
+
|
371
|
+
field :Type, :Type => Name, :Default => :Extensions
|
372
|
+
field :ADBE, :Type => DeveloperExtension
|
373
|
+
end
|
374
|
+
|
375
|
+
#
|
376
|
+
# Class representing the Catalog Dictionary of a PDF file.
|
377
|
+
#
|
378
|
+
class Catalog < Dictionary
|
379
|
+
include StandardObject
|
380
|
+
|
381
|
+
field :Type, :Type => Name, :Default => :Catalog, :Required => true
|
382
|
+
field :Version, :Type => Name, :Version => "1.4"
|
383
|
+
field :Pages, :Type => PageTreeNode, :Required => true
|
384
|
+
field :PageLabels, :Type => NumberTreeNode.of(PageLabel), :Version => "1.3"
|
385
|
+
field :Names, :Type => Names, :Version => "1.2"
|
386
|
+
field :Dests, :Type => Dictionary, :Version => "1.1"
|
387
|
+
field :ViewerPreferences, :Type => ViewerPreferences, :Version => "1.2"
|
388
|
+
field :PageLayout, :Type => Name, :Default => PageLayout::SINGLE
|
389
|
+
field :PageMode, :Type => Name, :Default => PageMode::NONE
|
390
|
+
field :Outlines, :Type => Outline
|
391
|
+
field :Threads, :Type => Array, :Version => "1.1"
|
392
|
+
field :OpenAction, :Type => [ Array, Dictionary ], :Version => "1.1"
|
393
|
+
field :AA, :Type => CatalogAdditionalActions, :Version => "1.4"
|
394
|
+
field :URI, :Type => Dictionary, :Version => "1.1"
|
395
|
+
field :AcroForm, :Type => InteractiveForm, :Version => "1.2"
|
396
|
+
field :Metadata, :Type => MetadataStream, :Version => "1.4"
|
397
|
+
field :StructTreeRoot, :Type => Dictionary, :Version => "1.3"
|
398
|
+
field :MarkInfo, :Type => Dictionary, :Version => "1.4"
|
399
|
+
field :Lang, :Type => String, :Version => "1.4"
|
400
|
+
field :SpiderInfo, :Type => WebCapture::SpiderInfo, :Version => "1.3"
|
401
|
+
field :OutputIntents, :Type => Array.of(OutputIntent), :Version => "1.4"
|
402
|
+
field :PieceInfo, :Type => Dictionary, :Version => "1.4"
|
403
|
+
field :OCProperties, :Type => OptionalContent::Properties, :Version => "1.5"
|
404
|
+
field :Perms, :Type => Dictionary, :Version => "1.5"
|
405
|
+
field :Legal, :Type => Dictionary, :Version => "1.5"
|
406
|
+
field :Requirements, :Type => Array.of(Requirement), :Version => "1.7"
|
407
|
+
field :Collection, :Type => Collection, :Version => "1.7"
|
408
|
+
field :NeedsRendering, :Type => Boolean, :Version => "1.7", :Default => false
|
409
|
+
field :Extensions, :Type => Extensions, :Version => "1.7", :ExtensionLevel => 3
|
410
|
+
|
411
|
+
def initialize(hash = {}, parser = nil)
|
412
|
+
set_indirect(true)
|
413
|
+
|
414
|
+
super(hash, parser)
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
=begin
|
2
|
+
|
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/>.
|
18
|
+
|
19
|
+
=end
|
20
|
+
|
21
|
+
module Origami
|
22
|
+
|
23
|
+
class PDF
|
24
|
+
#
|
25
|
+
# Returns true if the document behaves as a portfolio for embedded files.
|
26
|
+
#
|
27
|
+
def portfolio?
|
28
|
+
self.Catalog.Collection.is_a?(Dictionary)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Collection < Dictionary
|
33
|
+
include StandardObject
|
34
|
+
|
35
|
+
module View
|
36
|
+
DETAILS = :D
|
37
|
+
TILE = :T
|
38
|
+
HIDDEN = :H
|
39
|
+
end
|
40
|
+
|
41
|
+
class Schema < Dictionary
|
42
|
+
include StandardObject
|
43
|
+
|
44
|
+
field :Type, :Type => Name, :Default => :CollectionSchema
|
45
|
+
end
|
46
|
+
|
47
|
+
class Navigator < Dictionary
|
48
|
+
include StandardObject
|
49
|
+
|
50
|
+
module Type
|
51
|
+
FLEX = :Module
|
52
|
+
FLASH = :Default
|
53
|
+
end
|
54
|
+
|
55
|
+
field :SWF, :Type => String, :Required => true
|
56
|
+
field :Name, :Type => String, :Required => true
|
57
|
+
field :Desc, :Type => String
|
58
|
+
field :Category, :Type => String
|
59
|
+
field :ID, :Type => String, :Required => true
|
60
|
+
field :Version, :Type => String
|
61
|
+
field :APIVersion, :Type => String, :Required => true
|
62
|
+
field :LoadType, :Type => Name, :Default => Type::FLASH
|
63
|
+
field :Icon, :Type => String
|
64
|
+
field :Locale, :Type => String
|
65
|
+
field :Strings, :Type => NameTreeNode.of(String)
|
66
|
+
field :InitialFields, :Type => Schema
|
67
|
+
field :Resources, :Type => NameTreeNode.of(Stream), :Required => true
|
68
|
+
end
|
69
|
+
|
70
|
+
class Color < Dictionary
|
71
|
+
include StandardObject
|
72
|
+
|
73
|
+
field :Background, :Type => Array.of(Number, length: 3)
|
74
|
+
field :CardBackground, :Type => Array.of(Number, length: 3)
|
75
|
+
field :CardBorder, :Type => Array.of(Number, length: 3)
|
76
|
+
field :PrimaryText, :Type => Array.of(Number, length: 3)
|
77
|
+
field :SecondaryText, :Type => Array.of(Number, length: 3)
|
78
|
+
end
|
79
|
+
|
80
|
+
class Split < Dictionary
|
81
|
+
include StandardObject
|
82
|
+
|
83
|
+
HORIZONTAL = :H
|
84
|
+
VERTICAL = :V
|
85
|
+
NONE = :N
|
86
|
+
|
87
|
+
field :Direction, :Type => Name
|
88
|
+
field :Position, :Type => Number
|
89
|
+
end
|
90
|
+
|
91
|
+
class Item < Dictionary
|
92
|
+
include StandardObject
|
93
|
+
|
94
|
+
field :Type, :Type => Name, :Default => :CollectionItem
|
95
|
+
end
|
96
|
+
|
97
|
+
class Subitem < Dictionary
|
98
|
+
include StandardObject
|
99
|
+
|
100
|
+
field :Type, :Type => Name, :Default => :CollectionSubitem
|
101
|
+
field :D, :Type => [ String, Number ]
|
102
|
+
field :P, :Type => String
|
103
|
+
end
|
104
|
+
|
105
|
+
class Folder < Dictionary
|
106
|
+
include StandardObject
|
107
|
+
|
108
|
+
field :Type, :Type => Name, :Default => :Folder
|
109
|
+
field :ID, :Type => Integer, :Required => true
|
110
|
+
field :Name, :Type => String, :Required => true
|
111
|
+
field :Parent, :Type => Folder
|
112
|
+
field :Child, :Type => Folder
|
113
|
+
field :Next, :Type => Folder
|
114
|
+
field :CI, :Type => Item
|
115
|
+
field :Desc, :Type => String
|
116
|
+
field :CreationDate, :Type => String
|
117
|
+
field :ModDate, :Type => String
|
118
|
+
field :Thumb, :Type => Stream
|
119
|
+
field :Free, :Type => Array.of(Array.of(Integer, length: 2))
|
120
|
+
end
|
121
|
+
|
122
|
+
class Sort < Dictionary
|
123
|
+
include StandardObject
|
124
|
+
|
125
|
+
field :Type, :Type => Name, :Default => :CollectionSort
|
126
|
+
field :S, :Type => [ Name, Array.of(Name) ]
|
127
|
+
field :A, :Type => [ Boolean, Array.of(Boolean) ]
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Collection fields.
|
132
|
+
#
|
133
|
+
field :Type, :Type => Name, :Default => :Collection
|
134
|
+
field :Schema, :Type => Schema
|
135
|
+
field :D, :Type => String
|
136
|
+
field :View, :Type => Name, :Default => View::DETAILS
|
137
|
+
field :Sort, :Type => Sort
|
138
|
+
field :Navigator, :Type => Navigator, :ExtensionLevel => 3
|
139
|
+
field :Resources, :Type => NameTreeNode.of(Stream), :ExtensionLevel => 3
|
140
|
+
field :Colors, :Type => Color, :ExtensionLevel => 3
|
141
|
+
field :Folders, :Type => Folder, :ExtensionLevel => 3
|
142
|
+
field :Split, :Type => Split, :ExtensionLevel => 3
|
143
|
+
end
|
144
|
+
end
|