origami 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. data/COPYING.LESSER +165 -0
  2. data/README +77 -0
  3. data/VERSION +1 -0
  4. data/bin/config/pdfcop.conf.yml +237 -0
  5. data/bin/gui/about.rb +46 -0
  6. data/bin/gui/config.rb +132 -0
  7. data/bin/gui/file.rb +385 -0
  8. data/bin/gui/hexdump.rb +74 -0
  9. data/bin/gui/hexview.rb +91 -0
  10. data/bin/gui/imgview.rb +72 -0
  11. data/bin/gui/menu.rb +392 -0
  12. data/bin/gui/properties.rb +132 -0
  13. data/bin/gui/signing.rb +635 -0
  14. data/bin/gui/textview.rb +107 -0
  15. data/bin/gui/treeview.rb +409 -0
  16. data/bin/gui/walker.rb +282 -0
  17. data/bin/gui/xrefs.rb +79 -0
  18. data/bin/pdf2graph +121 -0
  19. data/bin/pdf2ruby +353 -0
  20. data/bin/pdfcocoon +104 -0
  21. data/bin/pdfcop +455 -0
  22. data/bin/pdfdecompress +104 -0
  23. data/bin/pdfdecrypt +95 -0
  24. data/bin/pdfencrypt +112 -0
  25. data/bin/pdfextract +221 -0
  26. data/bin/pdfmetadata +123 -0
  27. data/bin/pdfsh +13 -0
  28. data/bin/pdfwalker +7 -0
  29. data/bin/shell/.irbrc +104 -0
  30. data/bin/shell/console.rb +136 -0
  31. data/bin/shell/hexdump.rb +83 -0
  32. data/origami.rb +36 -0
  33. data/origami/3d.rb +239 -0
  34. data/origami/acroform.rb +321 -0
  35. data/origami/actions.rb +299 -0
  36. data/origami/adobe/fdf.rb +259 -0
  37. data/origami/adobe/ppklite.rb +489 -0
  38. data/origami/annotations.rb +775 -0
  39. data/origami/array.rb +187 -0
  40. data/origami/boolean.rb +101 -0
  41. data/origami/catalog.rb +486 -0
  42. data/origami/destinations.rb +213 -0
  43. data/origami/dictionary.rb +188 -0
  44. data/origami/docmdp.rb +96 -0
  45. data/origami/encryption.rb +1293 -0
  46. data/origami/export.rb +283 -0
  47. data/origami/file.rb +222 -0
  48. data/origami/filters.rb +250 -0
  49. data/origami/filters/ascii.rb +189 -0
  50. data/origami/filters/ccitt.rb +515 -0
  51. data/origami/filters/crypt.rb +47 -0
  52. data/origami/filters/dct.rb +61 -0
  53. data/origami/filters/flate.rb +112 -0
  54. data/origami/filters/jbig2.rb +63 -0
  55. data/origami/filters/jpx.rb +53 -0
  56. data/origami/filters/lzw.rb +195 -0
  57. data/origami/filters/predictors.rb +276 -0
  58. data/origami/filters/runlength.rb +117 -0
  59. data/origami/font.rb +209 -0
  60. data/origami/functions.rb +93 -0
  61. data/origami/graphics.rb +33 -0
  62. data/origami/graphics/colors.rb +191 -0
  63. data/origami/graphics/instruction.rb +126 -0
  64. data/origami/graphics/path.rb +154 -0
  65. data/origami/graphics/patterns.rb +180 -0
  66. data/origami/graphics/state.rb +164 -0
  67. data/origami/graphics/text.rb +224 -0
  68. data/origami/graphics/xobject.rb +493 -0
  69. data/origami/header.rb +90 -0
  70. data/origami/linearization.rb +318 -0
  71. data/origami/metadata.rb +114 -0
  72. data/origami/name.rb +170 -0
  73. data/origami/null.rb +75 -0
  74. data/origami/numeric.rb +188 -0
  75. data/origami/obfuscation.rb +233 -0
  76. data/origami/object.rb +527 -0
  77. data/origami/outline.rb +59 -0
  78. data/origami/page.rb +559 -0
  79. data/origami/parser.rb +268 -0
  80. data/origami/parsers/fdf.rb +45 -0
  81. data/origami/parsers/pdf.rb +27 -0
  82. data/origami/parsers/pdf/linear.rb +113 -0
  83. data/origami/parsers/ppklite.rb +86 -0
  84. data/origami/pdf.rb +1144 -0
  85. data/origami/reference.rb +113 -0
  86. data/origami/signature.rb +474 -0
  87. data/origami/stream.rb +575 -0
  88. data/origami/string.rb +416 -0
  89. data/origami/trailer.rb +173 -0
  90. data/origami/webcapture.rb +87 -0
  91. data/origami/xfa.rb +3027 -0
  92. data/origami/xreftable.rb +447 -0
  93. data/templates/patterns.rb +66 -0
  94. data/templates/widgets.rb +173 -0
  95. data/templates/xdp.rb +92 -0
  96. data/tests/dataset/test.dummycrt +28 -0
  97. data/tests/dataset/test.dummykey +27 -0
  98. data/tests/tc_actions.rb +32 -0
  99. data/tests/tc_annotations.rb +85 -0
  100. data/tests/tc_pages.rb +37 -0
  101. data/tests/tc_pdfattach.rb +24 -0
  102. data/tests/tc_pdfencrypt.rb +110 -0
  103. data/tests/tc_pdfnew.rb +32 -0
  104. data/tests/tc_pdfparse.rb +98 -0
  105. data/tests/tc_pdfsig.rb +37 -0
  106. data/tests/tc_streams.rb +129 -0
  107. data/tests/ts_pdf.rb +45 -0
  108. metadata +193 -0
@@ -0,0 +1,59 @@
1
+ =begin
2
+
3
+ = File
4
+ outline.rb
5
+
6
+ = Info
7
+ This file is part of Origami, PDF manipulation framework for Ruby
8
+ Copyright (C) 2010 Guillaume Delugré <guillaume@security-labs.org>
9
+ All right reserved.
10
+
11
+ Origami is free software: you can redistribute it and/or modify
12
+ it under the terms of the GNU Lesser General Public License as published by
13
+ the Free Software Foundation, either version 3 of the License, or
14
+ (at your option) any later version.
15
+
16
+ Origami is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
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/>.
23
+
24
+ =end
25
+
26
+ module Origami
27
+
28
+ class Outline < Dictionary
29
+ include StandardObject
30
+
31
+ field :Type, :Type => Name, :Default => :Outlines
32
+ field :First, :Type => Dictionary
33
+ field :Last, :Type => Dictionary
34
+ field :Count, :Type => Integer
35
+ end
36
+
37
+ class OutlineItem < Dictionary
38
+ include StandardObject
39
+
40
+ module Style
41
+ ITALIC = 1 << 0
42
+ BOLD = 1 << 1
43
+ end
44
+
45
+ field :Title, :Type => String, :Required => true
46
+ field :Parent, :Type => Dictionary, :Required => true
47
+ field :Prev, :Type => Dictionary
48
+ field :Next, :Type => Dictionary
49
+ field :First, :Type => Dictionary
50
+ field :Last, :Type => Dictionary
51
+ field :Count, :Type => Integer
52
+ field :Dest, :Type => [ Name, String, Array ]
53
+ field :A, :Type => Dictionary, :Version => "1.1"
54
+ field :SE, :Type => Dictionary, :Version => "1.3"
55
+ field :C, :Type => Array, :Default => [ 0.0, 0.0, 0.0 ], :Version => "1.4"
56
+ field :F, :Type => Integer, :Default => 0, :Version => "1.4"
57
+ end
58
+
59
+ end
@@ -0,0 +1,559 @@
1
+ =begin
2
+
3
+ = File
4
+ page.rb
5
+
6
+ = Info
7
+ Origami is free software: you can redistribute it and/or modify
8
+ it under the terms of the GNU Lesser General Public License as published by
9
+ the Free Software Foundation, either version 3 of the License, or
10
+ (at your option) any later version.
11
+
12
+ Origami is distributed in the hope that it will be useful,
13
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ GNU Lesser General Public License for more details.
16
+
17
+ You should have received a copy of the GNU Lesser General Public License
18
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
19
+
20
+ =end
21
+
22
+ module Origami
23
+
24
+ class PDF
25
+
26
+ def append_page(page = Page.new, *more)
27
+ raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
28
+ pages = [ page ].concat(more)
29
+
30
+ treeroot = self.Catalog.Pages
31
+
32
+ treeroot.Kids ||= [] #:nodoc:
33
+ treeroot.Kids.concat(pages)
34
+ treeroot.Count = treeroot.Kids.length
35
+
36
+ pages.each do |page|
37
+ page.Parent = treeroot
38
+ end
39
+
40
+ self
41
+ end
42
+
43
+ def insert_page(index, page)
44
+ raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
45
+
46
+ self.Catalog.Pages.insert_page(index, page)
47
+ self
48
+ end
49
+
50
+ #
51
+ # Returns an array of Page
52
+ #
53
+ def pages
54
+ raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
55
+
56
+ self.Catalog.Pages.children
57
+ end
58
+
59
+ #
60
+ # Iterate through each page, returns self.
61
+ #
62
+ def each_page(&b)
63
+ raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
64
+
65
+ self.Catalog.Pages.each_page(&b)
66
+ self
67
+ end
68
+
69
+ #
70
+ # Get the n-th Page object.
71
+ #
72
+ def get_page(n)
73
+ raise InvalidPDFError, "Invalid page tree" if not self.Catalog or not self.Catalog.Pages or not self.Catalog.Pages.is_a?(PageTreeNode)
74
+
75
+ self.Catalog.Pages.get_page(n)
76
+ end
77
+
78
+ #
79
+ # Lookup page in the page name directory.
80
+ #
81
+ def get_page_by_name(name)
82
+ resolve_name Names::Root::PAGES, name
83
+ end
84
+
85
+ #
86
+ # Calls block for each named page.
87
+ #
88
+ def each_named_page(&b)
89
+ each_name(Names::Root::PAGES, &b)
90
+ end
91
+ end
92
+
93
+ module ResourcesHolder
94
+
95
+ def add_extgstate(name, extgstate)
96
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
97
+
98
+ target.ExtGState ||= {}
99
+ target.ExtGState[name] = extgstate
100
+
101
+ self
102
+ end
103
+
104
+ def add_colorspace(name, colorspace)
105
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
106
+
107
+ csdir = target[:ColorSpace] ||= {}
108
+ (csdir.is_a?(Reference) ? csdir.solve : csdir)[name] = colorspace
109
+
110
+ self
111
+ end
112
+
113
+ def add_pattern(name, pattern)
114
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
115
+
116
+ target.Pattern ||= {}
117
+ target.Pattern[name] = pattern
118
+
119
+ self
120
+ end
121
+
122
+ def add_shading(name, shading)
123
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
124
+
125
+ target.Shading ||= {}
126
+ target.Shading[name] = shading
127
+
128
+ self
129
+ end
130
+
131
+ def add_xobject(name, xobject)
132
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
133
+
134
+ target.XObject ||= {}
135
+ target.XObject[name] = xobject
136
+
137
+ self
138
+ end
139
+
140
+ def add_font(name, font)
141
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
142
+
143
+ target.Font ||= {}
144
+ target.Font[name] = font
145
+
146
+ self
147
+ end
148
+
149
+ def add_properties(name, properties)
150
+ target = self.is_a?(Resources) ? self : (self.Resources ||= Resources.new)
151
+
152
+ target.Properties ||= {}
153
+ target.Properties[name] = properties
154
+
155
+ self
156
+ end
157
+
158
+ end
159
+
160
+ #
161
+ # Class representing a Resources Dictionary for a Page.
162
+ #
163
+ class Resources < Dictionary
164
+
165
+ include StandardObject
166
+ include ResourcesHolder
167
+
168
+ field :ExtGState, :Type => Dictionary
169
+ field :ColorSpace, :Type => Dictionary
170
+ field :Pattern, :Type => Dictionary
171
+ field :Shading, :Type => Dictionary, :Version => "1.3"
172
+ field :XObject, :Type => Dictionary
173
+ field :Font, :Type => Dictionary
174
+ field :ProcSet, :Type => Array
175
+ field :Properties, :Type => Dictionary, :Version => "1.2"
176
+
177
+ def pre_build
178
+ unless self.Font
179
+ fnt = Font::Type1::Standard::Helvetica.new.pre_build
180
+ fnt.Name = :F1
181
+
182
+ add_font(fnt.Name, fnt)
183
+ end
184
+
185
+ super
186
+ end
187
+
188
+ end
189
+
190
+ #
191
+ # Class representing a node in a Page tree.
192
+ #
193
+ class PageTreeNode < Dictionary
194
+ include StandardObject
195
+
196
+ field :Type, :Type => Name, :Default => :Pages, :Required => true
197
+ field :Parent, :Type => Dictionary
198
+ field :Kids, :Type => Array, :Default => [], :Required => true
199
+ field :Count, :Type => Integer, :Default => 0, :Required => true
200
+
201
+ def initialize(hash = {})
202
+ self.Count = 0
203
+ self.Kids = []
204
+
205
+ super(hash)
206
+
207
+ set_indirect(true)
208
+ end
209
+
210
+ def pre_build #:nodoc:
211
+ self.Count = self.children.length
212
+
213
+ super
214
+ end
215
+
216
+ def insert_page(index, page)
217
+
218
+ if index > self.Count
219
+ raise IndexError, "Invalid index for page tree"
220
+ end
221
+
222
+ count = 0
223
+ kids = self.Kids
224
+
225
+ kids.length.times { |n|
226
+ if count == index
227
+ kids.insert(n, page)
228
+ self.Count = self.Count + 1
229
+ page.Parent = self
230
+ return self
231
+ else
232
+ node = kids[n].is_a?(Reference) ? kids[n].solve : kids[n]
233
+ case node
234
+ when Page
235
+ count = count + 1
236
+ next
237
+ when PageTreeNode
238
+ if count + node.Count > index
239
+ node.insert_page(index - count, page)
240
+ self.Count = self.Count + 1
241
+ return self
242
+ else
243
+ count = count + node.Count
244
+ next
245
+ end
246
+ end
247
+ end
248
+ }
249
+
250
+ if count == index
251
+ self << page
252
+ else
253
+ raise IndexError, "An error occured while inserting page"
254
+ end
255
+
256
+ self
257
+ end
258
+
259
+ #
260
+ # Returns an array of Page inheriting this tree node.
261
+ #
262
+ def children
263
+ pageset = []
264
+
265
+ unless self.Count.nil?
266
+ [ self.Count.value, self.Kids.length ].min.times do |n|
267
+ node = self.Kids[n].is_a?(Reference) ? self.Kids[n].solve : self.Kids[n]
268
+ case node
269
+ when PageTreeNode then pageset.concat(node.children)
270
+ when Page then pageset << node
271
+ end
272
+ end
273
+ end
274
+
275
+ pageset
276
+ end
277
+
278
+ #
279
+ # Iterate through each page of that node.
280
+ #
281
+ def each_page(&b)
282
+ unless self.Count.nil?
283
+ [ self.Count.value, self.Kids.length ].min.times do |n|
284
+ node = self.Kids[n].is_a?(Reference) ? self.Kids[n].solve : self.Kids[n]
285
+ case node
286
+ when PageTreeNode then node.each_page(&b)
287
+ when Page then b.call(node)
288
+ end
289
+ end
290
+ end
291
+ end
292
+
293
+ #
294
+ # Get the n-th Page object in this node, starting from 1.
295
+ #
296
+ def get_page(n)
297
+ raise IndexError, "Page numbers are referenced starting from 1" if n < 1
298
+
299
+ decount = n
300
+ loop do
301
+ [ self.Count.value, self.Kids.length ].min.times do |i|
302
+ node = self.Kids[i].is_a?(Reference) ? self.Kids[i].solve : self.Kids[i]
303
+
304
+ case node
305
+ when Page
306
+ decount = decount - 1
307
+ return node if decount == 0
308
+
309
+ when PageTreeNode
310
+ nchilds = [ node.Count.value, node.Kids.length ].min
311
+ if nchilds >= decount
312
+ return node.get_page(decount)
313
+ else
314
+ decount -= nchilds
315
+ end
316
+ end
317
+ end
318
+ end
319
+ end
320
+
321
+ def << (pageset)
322
+ pageset = [pageset] unless pageset.is_a?(::Array)
323
+ raise TypeError, "Cannot add anything but Page and PageTreeNode to this node" unless pageset.all? { |item| item.is_a?(Page) or item.is_a?(PageTreeNode) }
324
+
325
+ self.Kids ||= Array.new
326
+ self.Kids.concat(pageset)
327
+ self.Count = self.Kids.length
328
+
329
+ pageset.each do |node|
330
+ node.Parent = self
331
+ end
332
+ end
333
+ end
334
+
335
+ #
336
+ # Class representing a Page in the PDF document.
337
+ #
338
+ class Page < Dictionary
339
+
340
+ include StandardObject
341
+ include ResourcesHolder
342
+
343
+ field :Type, :Type => Name, :Default => :Page, :Required => true
344
+ field :Parent, :Type => Dictionary, :Required => true
345
+ field :LastModified, :Type => String, :Version => "1.3"
346
+ field :Resources, :Type => Dictionary, :Required => true
347
+ field :MediaBox, :Type => Array, :Default => Rectangle[ :llx => 0, :lly => 0, :urx => 795, :ury => 842 ], :Required => true
348
+ field :CropBox, :Type => Array
349
+ field :BleedBox, :Type => Array, :Version => "1.3"
350
+ field :TrimBox, :Type => Array, :Version => "1.3"
351
+ field :ArtBox, :Type => Array, :Version => "1.3"
352
+ field :BoxColorInfo, :Type => Dictionary, :Version => "1.4"
353
+ field :Contents, :Type => [ Stream, Array ]
354
+ field :Rotate, :Type => Integer, :Default => 0
355
+ field :Group, :Type => Dictionary, :Version => "1.4"
356
+ field :Thumb, :Type => Stream
357
+ field :B, :Type => Array, :Version => "1.1"
358
+ field :Dur, :Type => Integer, :Version => "1.1"
359
+ field :Trans, :Type => Dictionary, :Version => "1.1"
360
+ field :Annots, :Type => Array
361
+ field :AA, :Type => Dictionary, :Version => "1.2"
362
+ field :Metadata, :Type => Stream, :Version => "1.4"
363
+ field :PieceInfo, :Type => Dictionary, :Version => "1.2"
364
+ field :StructParents, :Type => Integer, :Version => "1.3"
365
+ field :ID, :Type => String
366
+ field :PZ, :Type => Number
367
+ field :SeparationInfo, :Type => Dictionary, :Version => "1.3"
368
+ field :Tabs, :Type => Name, :Version => "1.5"
369
+ field :TemplateAssociated, :Type => Name, :Version => "1.5"
370
+ field :PresSteps, :Type => Dictionary, :Version => "1.5"
371
+ field :UserUnit, :Type => Number, :Default => 1.0, :Version => "1.6"
372
+ field :VP, :Type => Dictionary, :Version => "1.6"
373
+
374
+ def initialize(hash = {})
375
+ super(hash)
376
+
377
+ set_indirect(true)
378
+ end
379
+
380
+ def pre_build
381
+ self.Resources = Resources.new.pre_build unless self.has_key?(:Resources)
382
+
383
+ super
384
+ end
385
+
386
+ #
387
+ # Add an Annotation to the Page.
388
+ #
389
+ def add_annot(*annotations)
390
+ unless annotations.all?{|annot| annot.is_a?(Annotation) or annot.is_a?(Reference)}
391
+ raise TypeError, "Only Annotation objects must be passed."
392
+ end
393
+
394
+ self.Annots ||= []
395
+
396
+ annotations.each do |annot|
397
+ annot.solve[:P] = self if is_indirect?
398
+ self.Annots << annot
399
+ end
400
+ end
401
+
402
+ #
403
+ # Iterate through each Annotation of the Page.
404
+ #
405
+ def each_annot(&b)
406
+ annots = self.Annots
407
+ return unless annots.is_a?(Array)
408
+
409
+ annots.each do |annot|
410
+ b.call(annot.solve)
411
+ end
412
+ end
413
+
414
+ #
415
+ # Embed a SWF Flash application in the page.
416
+ #
417
+ def add_flash_application(swfspec, params = {})
418
+ options =
419
+ {
420
+ :windowed => false,
421
+ :transparent => false,
422
+ :navigation_pane => false,
423
+ :toolbar => false,
424
+ :pass_context_click => false,
425
+ :activation => Annotation::RichMedia::Activation::PAGE_OPEN,
426
+ :deactivation => Annotation::RichMedia::Deactivation::PAGE_CLOSE,
427
+ :flash_vars => nil
428
+ }
429
+ options.update(params)
430
+
431
+ annot = create_richmedia(:Flash, swfspec, options)
432
+ add_annot(annot)
433
+
434
+ annot
435
+ end
436
+
437
+ #
438
+ # Will execute an action when the page is opened.
439
+ #
440
+ def onOpen(action)
441
+ unless action.is_a?(Action) or action.is_a?(Reference)
442
+ raise TypeError, "An Action object must be passed."
443
+ end
444
+
445
+ self.AA ||= PageAdditionalActions.new
446
+ self.AA.O = action
447
+
448
+ self
449
+ end
450
+
451
+ #
452
+ # Will execute an action when the page is closed.
453
+ #
454
+ def onClose(action)
455
+ unless action.is_a?(Action) or action.is_a?(Reference)
456
+ raise TypeError, "An Action object must be passed."
457
+ end
458
+
459
+ self.AA ||= PageAdditionalActions.new
460
+ self.AA.C = action
461
+
462
+ self
463
+ end
464
+
465
+ #
466
+ # Will execute an action when navigating forward from this page.
467
+ #
468
+ def onNavigateForward(action) #:nodoc:
469
+ unless action.is_a?(Action) or action.is_a?(Reference)
470
+ raise TypeError, "An Action object must be passed."
471
+ end
472
+
473
+ self.PresSteps ||= NavigationNode.new
474
+ self.PresSteps.NA = action
475
+
476
+ self
477
+ end
478
+
479
+ #
480
+ # Will execute an action when navigating backward from this page.
481
+ #
482
+ def onNavigateBackward(action) #:nodoc:
483
+ unless action.is_a?(Action) or action.is_a?(Reference)
484
+ raise TypeError, "An Action object must be passed."
485
+ end
486
+
487
+ self.PresSteps ||= NavigationNode.new
488
+ self.PresSteps.PA = action
489
+
490
+ self
491
+ end
492
+
493
+ private
494
+
495
+ def create_richmedia(type, content, params) #:nodoc:
496
+ content.set_indirect(true)
497
+ richmedia = Annotation::RichMedia.new.set_indirect(true)
498
+
499
+ rminstance = Annotation::RichMedia::Instance.new.set_indirect(true)
500
+ rmparams = rminstance.Params = Annotation::RichMedia::Parameters.new
501
+ rmparams.Binding = Annotation::RichMedia::Parameters::Binding::BACKGROUND
502
+ rmparams.FlashVars = params[:flash_vars]
503
+ rminstance.Asset = content
504
+
505
+ rmconfig = Annotation::RichMedia::Configuration.new.set_indirect(true)
506
+ rmconfig.Instances = [ rminstance ]
507
+ rmconfig.Subtype = type
508
+
509
+ rmcontent = richmedia.RichMediaContent = Annotation::RichMedia::Content.new.set_indirect(true)
510
+ rmcontent.Assets = NameTreeNode.new
511
+ rmcontent.Assets.Names = NameLeaf.new(content.F.value => content)
512
+
513
+ rmcontent.Configurations = [ rmconfig ]
514
+
515
+ rmsettings = richmedia.RichMediaSettings = Annotation::RichMedia::Settings.new
516
+ rmactivation = rmsettings.Activation = Annotation::RichMedia::Activation.new
517
+ rmactivation.Condition = params[:activation]
518
+ rmactivation.Configuration = rmconfig
519
+ rmactivation.Animation = Annotation::RichMedia::Animation.new(:PlayCount => -1, :Subtype => :Linear, :Speed => 1.0)
520
+ rmpres = rmactivation.Presentation = Annotation::RichMedia::Presentation.new
521
+ rmpres.Style = Annotation::RichMedia::Presentation::WINDOWED if params[:windowed]
522
+ rmpres.Transparent = params[:transparent]
523
+ rmpres.NavigationPane = params[:navigation_pane]
524
+ rmpres.Toolbar = params[:toolbar]
525
+ rmpres.PassContextClick = params[:pass_context_click]
526
+
527
+ rmdeactivation = rmsettings.Deactivation = Annotation::RichMedia::Deactivation.new
528
+ rmdeactivation.Condition = params[:deactivation]
529
+
530
+ richmedia
531
+ end
532
+
533
+ end
534
+
535
+ #
536
+ # Class representing additional actions which can be associated to a Page.
537
+ #
538
+ class PageAdditionalActions < Dictionary
539
+ include StandardObject
540
+
541
+ field :O, :Type => Dictionary, :Version => "1.2" # Page Open
542
+ field :C, :Type => Dictionary, :Version => "1.2" # Page Close
543
+ end
544
+
545
+ #
546
+ # Class representing a navigation node associated to a Page.
547
+ #
548
+ class NavigationNode < Dictionary
549
+ include StandardObject
550
+
551
+ field :Type, :Type => Name, :Default => :NavNode
552
+ field :NA, :Type => Dictionary # Next action
553
+ field :PA, :Type => Dictionary # Prev action
554
+ field :Next, :Type => Dictionary
555
+ field :Prev, :Type => Dictionary
556
+ field :Dur, :Type => Number
557
+ end
558
+
559
+ end