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.
Files changed (139) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +89 -0
  3. data/COPYING.LESSER +165 -0
  4. data/README.md +131 -0
  5. data/bin/config/pdfcop.conf.yml +236 -0
  6. data/bin/pdf2pdfa +87 -0
  7. data/bin/pdf2ruby +333 -0
  8. data/bin/pdfcop +476 -0
  9. data/bin/pdfdecompress +97 -0
  10. data/bin/pdfdecrypt +91 -0
  11. data/bin/pdfencrypt +113 -0
  12. data/bin/pdfexplode +223 -0
  13. data/bin/pdfextract +277 -0
  14. data/bin/pdfmetadata +143 -0
  15. data/bin/pdfsh +12 -0
  16. data/bin/shell/console.rb +128 -0
  17. data/bin/shell/hexdump.rb +59 -0
  18. data/bin/shell/irbrc +69 -0
  19. data/examples/README.md +34 -0
  20. data/examples/attachments/attachment.rb +38 -0
  21. data/examples/attachments/nested_document.rb +51 -0
  22. data/examples/encryption/encryption.rb +28 -0
  23. data/examples/events/events.rb +72 -0
  24. data/examples/flash/flash.rb +37 -0
  25. data/examples/flash/helloworld.swf +0 -0
  26. data/examples/forms/javascript.rb +54 -0
  27. data/examples/forms/xfa.rb +115 -0
  28. data/examples/javascript/hello_world.rb +22 -0
  29. data/examples/javascript/js_emulation.rb +54 -0
  30. data/examples/loop/goto.rb +32 -0
  31. data/examples/loop/named.rb +33 -0
  32. data/examples/signature/signature.rb +65 -0
  33. data/examples/uri/javascript.rb +56 -0
  34. data/examples/uri/open-uri.rb +21 -0
  35. data/examples/uri/submitform.rb +47 -0
  36. data/lib/origami/3d.rb +364 -0
  37. data/lib/origami/acroform.rb +321 -0
  38. data/lib/origami/actions.rb +318 -0
  39. data/lib/origami/annotations.rb +711 -0
  40. data/lib/origami/array.rb +242 -0
  41. data/lib/origami/boolean.rb +90 -0
  42. data/lib/origami/catalog.rb +418 -0
  43. data/lib/origami/collections.rb +144 -0
  44. data/lib/origami/compound.rb +161 -0
  45. data/lib/origami/destinations.rb +252 -0
  46. data/lib/origami/dictionary.rb +192 -0
  47. data/lib/origami/encryption.rb +1084 -0
  48. data/lib/origami/extensions/fdf.rb +347 -0
  49. data/lib/origami/extensions/ppklite.rb +422 -0
  50. data/lib/origami/filespec.rb +197 -0
  51. data/lib/origami/filters/ascii.rb +211 -0
  52. data/lib/origami/filters/ccitt/tables.rb +267 -0
  53. data/lib/origami/filters/ccitt.rb +357 -0
  54. data/lib/origami/filters/crypt.rb +38 -0
  55. data/lib/origami/filters/dct.rb +54 -0
  56. data/lib/origami/filters/flate.rb +69 -0
  57. data/lib/origami/filters/jbig2.rb +57 -0
  58. data/lib/origami/filters/jpx.rb +47 -0
  59. data/lib/origami/filters/lzw.rb +170 -0
  60. data/lib/origami/filters/predictors.rb +292 -0
  61. data/lib/origami/filters/runlength.rb +129 -0
  62. data/lib/origami/filters.rb +364 -0
  63. data/lib/origami/font.rb +196 -0
  64. data/lib/origami/functions.rb +79 -0
  65. data/lib/origami/graphics/colors.rb +230 -0
  66. data/lib/origami/graphics/instruction.rb +98 -0
  67. data/lib/origami/graphics/path.rb +182 -0
  68. data/lib/origami/graphics/patterns.rb +174 -0
  69. data/lib/origami/graphics/render.rb +62 -0
  70. data/lib/origami/graphics/state.rb +149 -0
  71. data/lib/origami/graphics/text.rb +225 -0
  72. data/lib/origami/graphics/xobject.rb +918 -0
  73. data/lib/origami/graphics.rb +38 -0
  74. data/lib/origami/header.rb +75 -0
  75. data/lib/origami/javascript.rb +713 -0
  76. data/lib/origami/linearization.rb +330 -0
  77. data/lib/origami/metadata.rb +172 -0
  78. data/lib/origami/name.rb +135 -0
  79. data/lib/origami/null.rb +65 -0
  80. data/lib/origami/numeric.rb +181 -0
  81. data/lib/origami/obfuscation.rb +245 -0
  82. data/lib/origami/object.rb +760 -0
  83. data/lib/origami/optionalcontent.rb +183 -0
  84. data/lib/origami/outline.rb +54 -0
  85. data/lib/origami/outputintents.rb +85 -0
  86. data/lib/origami/page.rb +722 -0
  87. data/lib/origami/parser.rb +269 -0
  88. data/lib/origami/parsers/fdf.rb +56 -0
  89. data/lib/origami/parsers/pdf/lazy.rb +176 -0
  90. data/lib/origami/parsers/pdf/linear.rb +122 -0
  91. data/lib/origami/parsers/pdf.rb +118 -0
  92. data/lib/origami/parsers/ppklite.rb +57 -0
  93. data/lib/origami/pdf.rb +1108 -0
  94. data/lib/origami/reference.rb +134 -0
  95. data/lib/origami/signature.rb +702 -0
  96. data/lib/origami/stream.rb +705 -0
  97. data/lib/origami/string.rb +444 -0
  98. data/lib/origami/template/patterns.rb +56 -0
  99. data/lib/origami/template/widgets.rb +151 -0
  100. data/lib/origami/trailer.rb +190 -0
  101. data/lib/origami/tree.rb +62 -0
  102. data/lib/origami/version.rb +23 -0
  103. data/lib/origami/webcapture.rb +100 -0
  104. data/lib/origami/xfa/config.rb +453 -0
  105. data/lib/origami/xfa/connectionset.rb +146 -0
  106. data/lib/origami/xfa/datasets.rb +49 -0
  107. data/lib/origami/xfa/localeset.rb +42 -0
  108. data/lib/origami/xfa/package.rb +59 -0
  109. data/lib/origami/xfa/pdf.rb +73 -0
  110. data/lib/origami/xfa/signature.rb +42 -0
  111. data/lib/origami/xfa/sourceset.rb +43 -0
  112. data/lib/origami/xfa/stylesheet.rb +44 -0
  113. data/lib/origami/xfa/template.rb +1691 -0
  114. data/lib/origami/xfa/xdc.rb +42 -0
  115. data/lib/origami/xfa/xfa.rb +146 -0
  116. data/lib/origami/xfa/xfdf.rb +43 -0
  117. data/lib/origami/xfa/xmpmeta.rb +43 -0
  118. data/lib/origami/xfa.rb +62 -0
  119. data/lib/origami/xreftable.rb +557 -0
  120. data/lib/origami.rb +47 -0
  121. data/test/dataset/calc.pdf +85 -0
  122. data/test/dataset/crypto.pdf +36 -0
  123. data/test/dataset/empty.pdf +49 -0
  124. data/test/test_actions.rb +27 -0
  125. data/test/test_annotations.rb +68 -0
  126. data/test/test_forms.rb +30 -0
  127. data/test/test_native_types.rb +83 -0
  128. data/test/test_object_tree.rb +33 -0
  129. data/test/test_pages.rb +60 -0
  130. data/test/test_pdf.rb +20 -0
  131. data/test/test_pdf_attachment.rb +34 -0
  132. data/test/test_pdf_create.rb +24 -0
  133. data/test/test_pdf_encrypt.rb +102 -0
  134. data/test/test_pdf_parse.rb +134 -0
  135. data/test/test_pdf_parse_lazy.rb +69 -0
  136. data/test/test_pdf_sign.rb +97 -0
  137. data/test/test_streams.rb +184 -0
  138. data/test/test_xrefs.rb +67 -0
  139. metadata +280 -0
@@ -0,0 +1,347 @@
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
+ require 'origami/object'
22
+ require 'origami/name'
23
+ require 'origami/dictionary'
24
+ require 'origami/reference'
25
+ require 'origami/boolean'
26
+ require 'origami/numeric'
27
+ require 'origami/string'
28
+ require 'origami/array'
29
+ require 'origami/trailer'
30
+ require 'origami/xreftable'
31
+
32
+ require 'origami/parsers/fdf'
33
+
34
+ module Origami
35
+
36
+ #
37
+ # Class representing an AcroForm Forms Data Format file.
38
+ #
39
+ class FDF
40
+
41
+ def self.read(path, options = {})
42
+ path = File.expand_path(path) if path.is_a?(::String)
43
+
44
+ FDF::Parser.new(options).parse(path)
45
+ end
46
+
47
+ class Header
48
+ MAGIC = /%FDF-(?<major>\d)\.(?<minor>\d)/
49
+
50
+ attr_accessor :major_version, :minor_version
51
+
52
+ #
53
+ # Creates a file header, with the given major and minor versions.
54
+ # _major_version_:: Major version.
55
+ # _minor_version_:: Minor version.
56
+ #
57
+ def initialize(major_version = 1, minor_version = 2)
58
+ @major_version, @minor_version = major_version, minor_version
59
+ end
60
+
61
+ def self.parse(stream) #:nodoc:
62
+ scanner = Parser.init_scanner(stream)
63
+
64
+ if not scanner.scan(MAGIC).nil?
65
+ maj = scanner['major'].to_i
66
+ min = scanner['minor'].to_i
67
+ else
68
+ raise InvalidHeader, "Invalid header format"
69
+ end
70
+
71
+ scanner.skip(REGEXP_WHITESPACES)
72
+
73
+ FDF::Header.new(maj, min)
74
+ end
75
+
76
+ def to_s(eol: $/)
77
+ "%FDF-#{@major_version}.#{@minor_version}".b + eol
78
+ end
79
+
80
+ def to_sym #:nodoc:
81
+ "#{@major_version}.#{@minor_version}".to_sym
82
+ end
83
+
84
+ def to_f #:nodoc:
85
+ to_sym.to_s.to_f
86
+ end
87
+ end
88
+
89
+ class Revision #:nodoc;
90
+ attr_accessor :document
91
+ attr_accessor :body, :xreftable
92
+ attr_reader :trailer
93
+
94
+ def initialize(fdf)
95
+ @document = fdf
96
+ @body = {}
97
+ @xreftable = nil
98
+ @trailer = nil
99
+ end
100
+
101
+ def trailer=(trl)
102
+ trl.document = @document
103
+ @trailer = trl
104
+ end
105
+
106
+ def each_object(&b)
107
+ @body.each_value(&b)
108
+ end
109
+
110
+ def objects
111
+ @body.values
112
+ end
113
+ end
114
+
115
+ class JavaScript < Dictionary
116
+ include StandardObject
117
+
118
+ field :Before, :Type => [ String, Stream ]
119
+ field :After, :Type => [ String, Stream ]
120
+ field :AfterPermsReady, :Type => [ String, Stream ]
121
+ field :Doc, :Type => Array.of(Name, String)
122
+ end
123
+
124
+ class IconFit < Dictionary
125
+ include StandardObject
126
+
127
+ ALWAYS_SCALE = :A
128
+ SCALE_WHEN_BIGGER = :B
129
+ SCALE_WHEN_SMALLER = :S
130
+ NEVER_SCALE = :N
131
+
132
+ field :SW, :Type => Name
133
+ field :S, :Type => Name
134
+ field :A, :Type => Array.of(Number, length: 2)
135
+ field :FB, :Type => Boolean
136
+ end
137
+
138
+ class NamedPageReference < Dictionary
139
+ include StandardObject
140
+
141
+ field :Name, :Type => String, :Required => true
142
+ field :F, :Type => FileSpec
143
+ end
144
+
145
+ class Field < Dictionary
146
+ include StandardObject
147
+
148
+ field :Kids, :Type => Array.of(Field)
149
+ field :T, :Type => String, :Required => true
150
+ field :V, :Type => Dictionary
151
+ field :Ff, :Type => Integer
152
+ field :SetFf, :Type => Integer
153
+ field :ClrFf, :Type => Integer
154
+ field :F, :Type => Integer
155
+ field :SetF, :Type => Integer
156
+ field :ClrF, :Type => Integer
157
+ field :AP, :Type => Annotation::AppearanceDictionary
158
+ field :APRef, :Type => Dictionary
159
+ field :IF, :Type => IconFit
160
+ field :Opt, :Type => Array.of([String, Array.of(String, String)])
161
+ field :A, :Type => Action
162
+ field :AA, :Type => Annotation::AdditionalActions
163
+ field :RV, :Type => [ String, Stream ]
164
+ end
165
+
166
+ class Template < Dictionary
167
+ include StandardObject
168
+
169
+ field :TRef, :Type => NamedPageReference, :Required => true
170
+ field :Fields, :Type => Array.of(Field)
171
+ field :Rename, :Type => Boolean
172
+ end
173
+
174
+ class Page < Dictionary
175
+ include StandardObject
176
+
177
+ field :Templates, :Type => Array.of(Template), :Required => true
178
+ field :Info, :Type => Dictionary
179
+ end
180
+
181
+ class Annotation < Origami::Annotation
182
+ field :Page, :Type => Integer, :Required => true
183
+ end
184
+
185
+ class Dictionary < Origami::Dictionary
186
+ include StandardObject
187
+
188
+ field :F, :Type => FileSpec
189
+ field :ID, :Type => Array.of(String, length: 2)
190
+ field :Fields, :Type => Array.of(FDF::Field)
191
+ field :Status, :Type => String
192
+ field :Pages, :Type => Array.of(FDF::Page)
193
+ field :Encoding, :Type => Name
194
+ field :Annots, :Type => Array.of(FDF::Annotation)
195
+ field :Differences, :Type => Stream
196
+ field :Target, :Type => String
197
+ field :EmbeddedFDFs, :Type => Array.of(FileSpec)
198
+ field :JavaScript, :Type => JavaScript
199
+ end
200
+
201
+ class Catalog < Dictionary
202
+ include StandardObject
203
+
204
+ field :Version, :Type => Name
205
+ field :FDF, :Type => FDF::Dictionary, :Required => true
206
+ end
207
+
208
+ attr_accessor :header, :revisions
209
+
210
+ def initialize(parser = nil) #:nodoc:
211
+ @header = FDF::Header.new
212
+ @revisions = [ Revision.new(self) ]
213
+ @revisions.first.trailer = Trailer.new
214
+ @parser = parser
215
+
216
+ init if parser.nil?
217
+ end
218
+
219
+ def <<(object)
220
+ object.set_indirect(true)
221
+ object.set_document(self)
222
+
223
+ if object.no.zero?
224
+ maxno = 1
225
+ maxno = maxno.succ while get_object(maxno)
226
+
227
+ object.generation = 0
228
+ object.no = maxno
229
+ end
230
+
231
+ @revisions.first.body[object.reference] = object
232
+
233
+ object.reference
234
+ end
235
+ alias insert <<
236
+
237
+ def get_object(no, generation = 0) #:nodoc:
238
+ case no
239
+ when Reference
240
+ target = no
241
+ when ::Integer
242
+ target = Reference.new(no, generation)
243
+ when Origami::Object
244
+ return no
245
+ end
246
+
247
+ @revisions.first.body[target]
248
+ end
249
+
250
+ def indirect_objects
251
+ @revisions.inject([]) do |set, rev| set.concat(rev.objects) end
252
+ end
253
+ alias root_objects indirect_objects
254
+
255
+ def cast_object(reference, type) #:nodoc:
256
+ @revisions.each do |rev|
257
+ if rev.body.include?(reference) and type < rev.body[reference].class
258
+ rev.body[reference] = rev.body[reference].cast_to(type, @parser)
259
+
260
+ rev.body[reference]
261
+ else
262
+ nil
263
+ end
264
+ end
265
+ end
266
+
267
+ def Catalog
268
+ get_object(@revisions.first.trailer.Root)
269
+ end
270
+
271
+ def save(path)
272
+ bin = "".b
273
+ bin << @header.to_s
274
+
275
+ lastno, brange = 0, 0
276
+
277
+ xrefs = [ XRef.new(0, XRef::FIRSTFREE, XRef::FREE) ]
278
+ xrefsection = XRef::Section.new
279
+
280
+ @revisions.first.body.values.sort.each { |obj|
281
+ if (obj.no - lastno).abs > 1
282
+ xrefsection << XRef::Subsection.new(brange, xrefs)
283
+ brange = obj.no
284
+ xrefs.clear
285
+ end
286
+
287
+ xrefs << XRef.new(bin.size, obj.generation, XRef::USED)
288
+ lastno = obj.no
289
+
290
+ obj.pre_build
291
+
292
+ bin << obj.to_s
293
+
294
+ obj.post_build
295
+ }
296
+
297
+ xrefsection << XRef::Subsection.new(brange, xrefs)
298
+
299
+ @xreftable = xrefsection
300
+ @trailer ||= Trailer.new
301
+ @trailer.Size = @revisions.first.body.size + 1
302
+ @trailer.startxref = bin.size
303
+
304
+ bin << @xreftable.to_s
305
+ bin << @trailer.to_s
306
+
307
+ if path.respond_to?(:write)
308
+ io = path
309
+ else
310
+ path = File.expand_path(path)
311
+ io = File.open(path, "wb", encoding: 'binary')
312
+ close = true
313
+ end
314
+
315
+ begin
316
+ io.write(bin)
317
+ ensure
318
+ io.close if close
319
+ end
320
+
321
+ self
322
+ end
323
+
324
+ private
325
+
326
+ def init
327
+ catalog = Catalog.new(:FDF => FDF::Dictionary.new)
328
+
329
+ @revisions.first.trailer.Root = self.insert(catalog)
330
+ end
331
+
332
+ def get_object_offset(no,generation) #:nodoc:
333
+ bodyoffset = @header.to_s.size
334
+ objectoffset = bodyoffset
335
+
336
+ @revisions.first.body.values.each { |object|
337
+ if object.no == no and object.generation == generation then return objectoffset
338
+ else
339
+ objectoffset += object.to_s.size
340
+ end
341
+ }
342
+
343
+ nil
344
+ end
345
+
346
+ end
347
+ end