origami 1.2.7 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -0
  3. data/README.md +112 -0
  4. data/bin/config/pdfcop.conf.yml +232 -233
  5. data/bin/gui/about.rb +27 -37
  6. data/bin/gui/config.rb +108 -117
  7. data/bin/gui/file.rb +416 -365
  8. data/bin/gui/gtkhex.rb +1138 -1153
  9. data/bin/gui/hexview.rb +55 -57
  10. data/bin/gui/imgview.rb +48 -51
  11. data/bin/gui/menu.rb +388 -386
  12. data/bin/gui/properties.rb +114 -130
  13. data/bin/gui/signing.rb +571 -617
  14. data/bin/gui/textview.rb +77 -95
  15. data/bin/gui/treeview.rb +382 -387
  16. data/bin/gui/walker.rb +227 -232
  17. data/bin/gui/xrefs.rb +56 -60
  18. data/bin/pdf2pdfa +53 -57
  19. data/bin/pdf2ruby +212 -228
  20. data/bin/pdfcop +338 -348
  21. data/bin/pdfdecompress +58 -65
  22. data/bin/pdfdecrypt +56 -60
  23. data/bin/pdfencrypt +75 -80
  24. data/bin/pdfexplode +185 -182
  25. data/bin/pdfextract +201 -218
  26. data/bin/pdfmetadata +83 -82
  27. data/bin/pdfsh +4 -5
  28. data/bin/pdfwalker +1 -2
  29. data/bin/shell/.irbrc +45 -82
  30. data/bin/shell/console.rb +105 -130
  31. data/bin/shell/hexdump.rb +40 -64
  32. data/examples/README.md +34 -0
  33. data/examples/attachments/attachment.rb +38 -0
  34. data/examples/attachments/nested_document.rb +51 -0
  35. data/examples/encryption/encryption.rb +28 -0
  36. data/{samples/actions/triggerevents/trigger.rb → examples/events/events.rb} +13 -16
  37. data/examples/flash/flash.rb +37 -0
  38. data/{samples → examples}/flash/helloworld.swf +0 -0
  39. data/examples/forms/javascript.rb +54 -0
  40. data/examples/forms/xfa.rb +115 -0
  41. data/examples/javascript/hello_world.rb +22 -0
  42. data/examples/javascript/js_emulation.rb +54 -0
  43. data/examples/loop/goto.rb +32 -0
  44. data/examples/loop/named.rb +33 -0
  45. data/examples/signature/signature.rb +65 -0
  46. data/examples/uri/javascript.rb +56 -0
  47. data/examples/uri/open-uri.rb +21 -0
  48. data/examples/uri/submitform.rb +47 -0
  49. data/lib/origami.rb +29 -42
  50. data/lib/origami/3d.rb +350 -225
  51. data/lib/origami/acroform.rb +262 -288
  52. data/lib/origami/actions.rb +268 -288
  53. data/lib/origami/annotations.rb +697 -722
  54. data/lib/origami/array.rb +258 -184
  55. data/lib/origami/boolean.rb +74 -84
  56. data/lib/origami/catalog.rb +397 -434
  57. data/lib/origami/collections.rb +144 -0
  58. data/lib/origami/destinations.rb +233 -194
  59. data/lib/origami/dictionary.rb +253 -232
  60. data/lib/origami/encryption.rb +1274 -1243
  61. data/lib/origami/export.rb +232 -268
  62. data/lib/origami/extensions/fdf.rb +307 -220
  63. data/lib/origami/extensions/ppklite.rb +368 -435
  64. data/lib/origami/filespec.rb +197 -0
  65. data/lib/origami/filters.rb +301 -295
  66. data/lib/origami/filters/ascii.rb +177 -180
  67. data/lib/origami/filters/ccitt.rb +528 -535
  68. data/lib/origami/filters/crypt.rb +26 -35
  69. data/lib/origami/filters/dct.rb +46 -52
  70. data/lib/origami/filters/flate.rb +95 -94
  71. data/lib/origami/filters/jbig2.rb +49 -55
  72. data/lib/origami/filters/jpx.rb +38 -44
  73. data/lib/origami/filters/lzw.rb +189 -183
  74. data/lib/origami/filters/predictors.rb +221 -235
  75. data/lib/origami/filters/runlength.rb +103 -104
  76. data/lib/origami/font.rb +173 -186
  77. data/lib/origami/functions.rb +67 -81
  78. data/lib/origami/graphics.rb +25 -21
  79. data/lib/origami/graphics/colors.rb +178 -187
  80. data/lib/origami/graphics/instruction.rb +79 -85
  81. data/lib/origami/graphics/path.rb +142 -148
  82. data/lib/origami/graphics/patterns.rb +160 -167
  83. data/lib/origami/graphics/render.rb +43 -50
  84. data/lib/origami/graphics/state.rb +138 -153
  85. data/lib/origami/graphics/text.rb +188 -205
  86. data/lib/origami/graphics/xobject.rb +819 -815
  87. data/lib/origami/header.rb +63 -78
  88. data/lib/origami/javascript.rb +596 -597
  89. data/lib/origami/linearization.rb +285 -290
  90. data/lib/origami/metadata.rb +139 -148
  91. data/lib/origami/name.rb +112 -148
  92. data/lib/origami/null.rb +53 -62
  93. data/lib/origami/numeric.rb +162 -175
  94. data/lib/origami/obfuscation.rb +186 -174
  95. data/lib/origami/object.rb +593 -573
  96. data/lib/origami/outline.rb +42 -47
  97. data/lib/origami/outputintents.rb +73 -82
  98. data/lib/origami/page.rb +703 -592
  99. data/lib/origami/parser.rb +238 -290
  100. data/lib/origami/parsers/fdf.rb +41 -33
  101. data/lib/origami/parsers/pdf.rb +75 -95
  102. data/lib/origami/parsers/pdf/lazy.rb +137 -0
  103. data/lib/origami/parsers/pdf/linear.rb +64 -66
  104. data/lib/origami/parsers/ppklite.rb +34 -70
  105. data/lib/origami/pdf.rb +1030 -1005
  106. data/lib/origami/reference.rb +102 -102
  107. data/lib/origami/signature.rb +591 -609
  108. data/lib/origami/stream.rb +668 -551
  109. data/lib/origami/string.rb +397 -373
  110. data/lib/origami/template/patterns.rb +56 -0
  111. data/lib/origami/template/widgets.rb +151 -0
  112. data/lib/origami/trailer.rb +144 -158
  113. data/lib/origami/tree.rb +62 -0
  114. data/lib/origami/version.rb +23 -0
  115. data/lib/origami/webcapture.rb +88 -79
  116. data/lib/origami/xfa.rb +2863 -2882
  117. data/lib/origami/xreftable.rb +472 -384
  118. data/test/dataset/calc.pdf +85 -0
  119. data/test/dataset/crypto.pdf +82 -0
  120. data/test/dataset/empty.pdf +49 -0
  121. data/test/test_actions.rb +27 -0
  122. data/test/test_annotations.rb +90 -0
  123. data/test/test_pages.rb +31 -0
  124. data/test/test_pdf.rb +16 -0
  125. data/test/test_pdf_attachment.rb +34 -0
  126. data/test/test_pdf_create.rb +24 -0
  127. data/test/test_pdf_encrypt.rb +95 -0
  128. data/test/test_pdf_parse.rb +96 -0
  129. data/test/test_pdf_sign.rb +58 -0
  130. data/test/test_streams.rb +182 -0
  131. data/test/test_xrefs.rb +67 -0
  132. metadata +88 -58
  133. data/README +0 -67
  134. data/bin/pdf2graph +0 -121
  135. data/bin/pdfcocoon +0 -104
  136. data/lib/origami/file.rb +0 -233
  137. data/samples/README.txt +0 -45
  138. data/samples/actions/launch/calc.rb +0 -87
  139. data/samples/actions/launch/winparams.rb +0 -22
  140. data/samples/actions/loop/loopgoto.rb +0 -24
  141. data/samples/actions/loop/loopnamed.rb +0 -21
  142. data/samples/actions/named/named.rb +0 -31
  143. data/samples/actions/samba/smbrelay.rb +0 -26
  144. data/samples/actions/webbug/submitform.js +0 -26
  145. data/samples/actions/webbug/webbug-browser.rb +0 -68
  146. data/samples/actions/webbug/webbug-js.rb +0 -67
  147. data/samples/actions/webbug/webbug-reader.rb +0 -90
  148. data/samples/attachments/attach.rb +0 -40
  149. data/samples/attachments/attached.txt +0 -1
  150. data/samples/crypto/crypto.rb +0 -28
  151. data/samples/digsig/signed.rb +0 -46
  152. data/samples/exploits/cve-2008-2992-utilprintf.rb +0 -87
  153. data/samples/exploits/cve-2009-0927-geticon.rb +0 -65
  154. data/samples/exploits/exploit_customdictopen.rb +0 -55
  155. data/samples/exploits/getannots.rb +0 -69
  156. data/samples/flash/flash.rb +0 -31
  157. data/samples/javascript/attached.txt +0 -1
  158. data/samples/javascript/js.rb +0 -52
  159. data/templates/patterns.rb +0 -66
  160. data/templates/widgets.rb +0 -173
  161. data/templates/xdp.rb +0 -92
  162. data/test/ts_pdf.rb +0 -50
@@ -1,83 +1,59 @@
1
1
  =begin
2
2
 
3
- = File
4
- hexdump.rb
3
+ This file is part of Origami, PDF manipulation framework for Ruby
4
+ Copyright (C) 2016 Guillaume Delugré.
5
5
 
6
- = Info
7
- This file is part of Origami, PDF manipulation framework for Ruby
8
- Copyright (C) 2009 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 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.
6
+ Origami is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU 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.
15
10
 
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 General Public License for more details.
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 General Public License for more details.
20
15
 
21
- You should have received a copy of the GNU General Public License
22
- along with Origami. If not, see <http://www.gnu.org/licenses/>.
16
+ You should have received a copy of the GNU General Public License
17
+ along with Origami. If not, see <http://www.gnu.org/licenses/>.
23
18
 
24
19
  =end
25
20
 
26
- if RUBY_VERSION < '1.9'
27
- class Fixnum
28
- def ord; self; end
29
- end
30
- end
21
+ require 'colorize'
31
22
 
32
23
  class String #:nodoc:
33
24
 
34
- def hexdump(bytesperline = 16, upcase = true, offsets = true, delta = 0)
35
-
36
- dump = ""
37
- counter = 0
25
+ def hexdump(bytesperline: 16, upcase: true, offsets: true, delta: 0)
26
+ dump = ""
27
+ counter = 0
38
28
 
39
- while counter < length
29
+ while counter < length
30
+ offset = sprintf("%010X", counter + delta)
40
31
 
41
- offset = sprintf("%010X", counter + delta)
32
+ linelen = (counter < length - bytesperline) ? bytesperline : (length - counter)
33
+ bytes = ""
34
+ linelen.times do |i|
35
+ byte = self[counter + i].ord.to_s(16)
36
+ byte.insert(0, "0") if byte.size < 2
37
+ bytes << byte
38
+ bytes << " " unless i == bytesperline - 1
39
+ end
40
+
41
+ ascii = self[counter, linelen].ascii_print
42
42
 
43
- linelen = (counter < length - bytesperline) ? bytesperline : (length - counter)
44
- bytes = ""
45
- linelen.times do |i|
46
-
47
- byte = self[counter + i].ord.to_s(base=16)
48
- if byte.size < 2 then byte.insert(0, "0") end
49
- bytes << byte
50
- bytes << " " unless i == bytesperline - 1
51
-
52
- end
53
-
54
- ascii = self[counter, linelen].ascii_print
43
+ if upcase
44
+ offset.upcase!
45
+ bytes.upcase!
46
+ end
55
47
 
56
- if upcase
57
- offset.upcase!
58
- bytes.upcase!
59
- end
60
-
61
- if RUBY_PLATFORM =~ /win32/
62
- dump << "#{offset if offsets} #{bytes.to_s.ljust(bytesperline * 3 - 1)} #{ascii}\n"
63
- else
64
- dump << "#{Console.colorize(offset, Console::Colors::YELLOW) if offsets} #{Console.colorize(bytes.to_s.ljust(bytesperline * 3 - 1), Console::Colors::BRIGHT_GREY)} #{ascii}\n"
65
- end
66
-
67
- counter += bytesperline
68
- end
69
-
70
- dump
71
- end
72
-
73
- def ascii_print
48
+ dump << "#{offset.yellow if offsets} #{bytes.to_s.ljust(bytesperline * 3 - 1).bold} #{ascii}\n"
74
49
 
75
- printable = ""
76
- self.each_byte { |c|
77
- if c >= ' '[0].ord && c <= '~'[0].ord then printable << c else printable << '.' end
78
- }
50
+ counter += bytesperline
51
+ end
79
52
 
80
- return printable
81
- end
53
+ dump
54
+ end
82
55
 
56
+ def ascii_print
57
+ self.gsub(/[^[[:print:]]]/, ".")
58
+ end
83
59
  end
@@ -0,0 +1,34 @@
1
+ # Origami samples
2
+
3
+ ## ``attachments``
4
+
5
+ Adding a file attachment to a PDF document.
6
+
7
+ ## ``javascript``
8
+
9
+ Adding JavaScript to a document and emulating it.
10
+
11
+ ## ``encryption``
12
+
13
+ PDF encryption (supports RC4 40-128 bits, and AES128).
14
+ Create a new encrypted document.
15
+
16
+ ## ``signature``
17
+
18
+ PDF digital signatures. Create a new document and signs it.
19
+
20
+ ## ``flash``
21
+
22
+ Create a document with an embedded SWF file.
23
+
24
+ ## ``loop``
25
+
26
+ Create a looping document using ``GoTo`` and ``Named`` actions.
27
+
28
+ ## ``events``
29
+
30
+ Create a document running JavaScript on various events.
31
+
32
+ ## ``uri``
33
+
34
+ Various methods for connecting to a remote URL.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
12
+
13
+ # Creating a new file
14
+ pdf = PDF.new
15
+
16
+ # Embedding the file into the PDF.
17
+ pdf.attach_file(DATA,
18
+ name: "README.txt",
19
+ filter: :ASCIIHexDecode
20
+ )
21
+
22
+ contents = ContentStream.new
23
+ contents.write "File attachment sample",
24
+ x: 150, y: 750, rendering: Text::Rendering::FILL, size: 30
25
+
26
+ pdf.append_page Page.new.setContents(contents)
27
+
28
+ pdf.onDocumentOpen Action::JavaScript <<JS
29
+ this.exportDataObject({cName:"README.txt", nLaunch:2});
30
+ JS
31
+
32
+
33
+ pdf.save(OUTPUT_FILE)
34
+
35
+ puts "PDF file saved as #{OUTPUT_FILE}."
36
+
37
+ __END__
38
+ This is the attached file contents.
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, '../../lib')
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ require 'stringio'
12
+
13
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
14
+ EMBEDDED_NAME = "#{('a'..'z').to_a.sample(8).join}.pdf"
15
+
16
+ #
17
+ # Creates the nested document.
18
+ # A simple document displaying a message box.
19
+ #
20
+ output_str = StringIO.new
21
+ nested_doc = PDF.write(output_str) do |pdf|
22
+ pdf.onDocumentOpen Action::JavaScript "app.alert('Hello world!');"
23
+ end
24
+
25
+ output_str.rewind
26
+
27
+ # The envelope document.
28
+ pdf = PDF.new.append_page
29
+
30
+ # Create an object stream to compress objects.
31
+ objstm = ObjectStream.new
32
+ objstm.Filter = :FlateDecode
33
+
34
+ pdf.insert(objstm)
35
+
36
+ objstm.insert pdf.attach_file(output_str, register: true, name: EMBEDDED_NAME)
37
+
38
+ # Compress the page tree.
39
+ objstm.insert(pdf.Catalog.Pages)
40
+ objstm.insert(pdf.pages.first)
41
+
42
+ # Compress the name tree.
43
+ objstm.insert(pdf.Catalog.Names)
44
+ objstm.insert(pdf.Catalog.Names.EmbeddedFiles)
45
+
46
+ # Compress the catalog.
47
+ objstm.insert(pdf.Catalog)
48
+
49
+ pdf.pages.first.onOpen Action::GoToE[EMBEDDED_NAME]
50
+
51
+ pdf.save(OUTPUT_FILE, noindent: true)
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ #
12
+ # Encrypts a document with an empty password.
13
+ #
14
+
15
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
16
+
17
+ # Creates an encrypted document with AES256 and a null password.
18
+ pdf = PDF.new.encrypt(cipher: 'aes', key_size: 256)
19
+
20
+ contents = ContentStream.new
21
+ contents.write "Encrypted document sample",
22
+ x: 100, y: 750, rendering: Text::Rendering::STROKE, size: 30
23
+
24
+ pdf.append_page Page.new.setContents(contents)
25
+
26
+ pdf.save(OUTPUT_FILE)
27
+
28
+ puts "PDF file saved as #{OUTPUT_FILE}."
@@ -1,25 +1,22 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/ruby
2
2
 
3
3
  begin
4
- require 'origami'
4
+ require 'origami'
5
5
  rescue LoadError
6
- ORIGAMIDIR = "#{File.dirname(__FILE__)}/../../../lib"
7
- $: << ORIGAMIDIR
8
- require 'origami'
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
9
8
  end
10
9
  include Origami
11
10
 
12
- OUTPUTFILE = "#{File.basename(__FILE__, ".rb")}.pdf"
13
-
14
- puts "Now generating a new PDF file from scratch!"
11
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
15
12
 
16
13
  pdf = PDF.new
17
14
 
18
15
  page = Page.new
19
16
 
20
17
  contents = ContentStream.new
21
- contents.write "Pass your mouse over the yellow square",
22
- :x => 250, :y => 750, :size => 15
18
+ contents.write "Pass your mouse over the square",
19
+ x: 180, y: 750, size: 15
23
20
 
24
21
  page.setContents( contents )
25
22
 
@@ -41,9 +38,9 @@ pdf.onDocumentOpen(ondocumentopen)
41
38
  pdf.onDocumentClose(ondocumentclose)
42
39
  page.onOpen(onpageopen).onClose(onpageclose)
43
40
 
44
- pdf.register(Names::Root::JAVASCRIPT, "test", namedscript)
41
+ pdf.register(Names::JAVASCRIPT, "test", namedscript)
45
42
 
46
- rect_coord = Rectangle[:llx => 350, :lly => 700, :urx => 415, :ury => 640]
43
+ rect_coord = Rectangle[llx: 270, lly: 700, urx: 330, ury: 640]
47
44
 
48
45
  # Just draw a yellow rectangle.
49
46
  rect = Annotation::Square.new
@@ -64,12 +61,12 @@ annot.onPageClose(onparentclose)
64
61
  annot.onPageVisible(onparentvisible)
65
62
  annot.onPageInvisible(onparentinvisible)
66
63
 
67
- page.add_annot(annot)
68
- page.add_annot(rect)
64
+ page.add_annotation(annot)
65
+ page.add_annotation(rect)
69
66
 
70
67
  pdf.append_page(page)
71
68
 
72
69
  # Save the resulting file.
73
- pdf.save(OUTPUTFILE)
70
+ pdf.save(OUTPUT_FILE)
74
71
 
75
- puts "PDF file saved as #{OUTPUTFILE}."
72
+ puts "PDF file saved as #{OUTPUT_FILE}."
@@ -0,0 +1,37 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ #
12
+ # Embeding a Flash asset inside a PDF document.
13
+ #
14
+
15
+ SWF_PATH = File.join(__dir__, "helloworld.swf")
16
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
17
+
18
+ # Creating a new file
19
+ pdf = PDF.new
20
+
21
+ # Embedding the SWF file into the PDF.
22
+ swf = pdf.attach_file(SWF_PATH)
23
+
24
+ # Creating a Flash annotation on the page.
25
+ pdf.append_page do |page|
26
+ annot = page.add_flash_application(swf,
27
+ windowed: true,
28
+ navigation_pane: true,
29
+ toolbar: true)
30
+
31
+ # Setting the player position on the page.
32
+ annot.Rect = Rectangle.new [204, 573, 403, 718]
33
+ end
34
+
35
+ pdf.save(OUTPUT_FILE)
36
+
37
+ puts "PDF file saved as #{OUTPUT_FILE}."
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ #
12
+ # Interactive JavaScript interpreter using an Acrobat Form.
13
+ #
14
+
15
+ require 'origami/template/widgets'
16
+
17
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
18
+
19
+ pdf = PDF.new.append_page(page = Page.new)
20
+
21
+ contents = ContentStream.new.setFilter(:FlateDecode)
22
+
23
+ contents.write "Write your JavaScript below and run it",
24
+ x: 100, y: 750, size: 24, rendering: Text::Rendering::FILL,
25
+ fill_color: Graphics::Color::RGB.new(0xFF, 0x80, 0x80)
26
+
27
+ contents.write "You need at least Acrobat Reader 8 to use this document.",
28
+ x: 50, y: 80, size: 12, rendering: Text::Rendering::FILL
29
+
30
+ contents.write "\nGenerated with Origami #{Origami::VERSION}.",
31
+ color: Graphics::Color::RGB.new(0, 0, 255)
32
+
33
+ contents.draw_rectangle(45, 35, 320, 60,
34
+ line_width: 2.0, dash: Graphics::DashPattern.new([3]),
35
+ fill: false, stroke: true, stroke_color: Graphics::Color::GrayScale.new(0.7))
36
+
37
+ page.Contents = contents
38
+
39
+ ml = Template::MultiLineEdit.new('scriptedit', x: 50, y: 280, width: 500, height: 400)
40
+ ml.V = <<JS
41
+ console.show();
42
+ console.println('Script entry point');
43
+ app.alert("Hello");
44
+ JS
45
+
46
+ button = Template::Button.new("Run!", x: 490, y: 240, width: 60, height: 30)
47
+ button.onActivate Action::JavaScript["eval(this.getField('scriptedit').value);"]
48
+
49
+ page.add_annotation(ml, button)
50
+ pdf.create_form(button, ml)
51
+
52
+ pdf.save(OUTPUT_FILE, noindent: true)
53
+
54
+ puts "PDF file saved as #{OUTPUT_FILE}."
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/ruby
2
+
3
+ begin
4
+ require 'origami'
5
+ rescue LoadError
6
+ $: << File.join(__dir__, "../../lib")
7
+ require 'origami'
8
+ end
9
+ include Origami
10
+
11
+ require 'origami/template/widgets'
12
+
13
+ OUTPUT_FILE = "#{File.basename(__FILE__, ".rb")}.pdf"
14
+
15
+ #
16
+ # Interactive FormCalc interpreter using a XFA form.
17
+ #
18
+
19
+ #
20
+ # XDP Packet holding the Form.
21
+ #
22
+ class SampleXDP < XDP::Package
23
+ def initialize(script = "")
24
+ super()
25
+
26
+ self.root.add_element(create_config_packet)
27
+ self.root.add_element(create_template_packet(script))
28
+ self.root.add_element(create_datasets_packet)
29
+ end
30
+
31
+ def create_config_packet
32
+ config = XDP::Packet::Config.new
33
+
34
+ present = config.add_element(XFA::Element.new("present"))
35
+ pdf = present.add_element(XFA::Element.new("pdf"))
36
+ interactive = pdf.add_element(XFA::Element.new("interactive"))
37
+ interactive.text = 1
38
+
39
+ config
40
+ end
41
+
42
+ def create_template_packet(script)
43
+ template = XDP::Packet::Template.new
44
+
45
+ form1 = template.add_subform(layout: 'tb', name: 'form1')
46
+ form1.add_pageSet
47
+ form1.add_event(activity: 'initialize', name: 'event__ready')
48
+ .add_script(contentType: 'application/x-formcalc')
49
+ .text = script
50
+
51
+ subform = form1.add_subform
52
+
53
+ button = subform.add_field(name: 'Button1')
54
+ button.add_ui.add_button(highlight: 'inverted')
55
+ btncaption = button.add_caption
56
+ btncaption.add_value.add_text.text = "Send!"
57
+ btncaption.add_para(vAlign: 'middle', hAlign: 'center')
58
+ button.add_bind(match: 'none')
59
+ button.add_event(activity: 'click', name: 'event__click')
60
+ .add_script(contentType: 'application/x-formcalc')
61
+ .text = script
62
+
63
+ txtfield = subform.add_field(name: 'TextField1')
64
+ txtfield.add_ui.add_textEdit.add_border.add_edge(stroke: 'lowered')
65
+
66
+ template
67
+ end
68
+
69
+ def create_datasets_packet
70
+ datasets = XDP::Packet::Datasets.new
71
+ data = datasets.add_element(XDP::Packet::Datasets::Data.new)
72
+
73
+ data.add_element(XFA::Element.new('form1'))
74
+ .add_element(XFA::Element.new('TextField1'))
75
+ .text = '$host.messageBox("Hello from FormCalc!")'
76
+
77
+ datasets
78
+ end
79
+ end
80
+
81
+ pdf = PDF.new.append_page(page = Page.new)
82
+
83
+ contents = ContentStream.new.setFilter(:FlateDecode)
84
+
85
+ contents.write "Write your FormCalc below and run it",
86
+ x: 100, y: 750, size: 24, rendering: Text::Rendering::FILL,
87
+ fill_color: Graphics::Color::RGB.new(0xFF, 0x80, 0x80)
88
+
89
+ contents.write "You need at least Acrobat Reader 8 to use this document.",
90
+ x: 50, y: 80, size: 12, rendering: Text::Rendering::FILL
91
+
92
+ contents.write "\nGenerated with Origami #{Origami::VERSION}.",
93
+ color: Graphics::Color::RGB.new(0, 0, 255)
94
+
95
+ contents.draw_rectangle(45, 35, 320, 60,
96
+ line_width: 2.0, dash: Graphics::DashPattern.new([3]),
97
+ fill: false, stroke: true, stroke_color: Graphics::Color::GrayScale.new(0.7))
98
+
99
+ page.Contents = contents
100
+
101
+ ml = Template::MultiLineEdit.new('TextField1[0]', x: 50, y: 280, width: 500, height: 400)
102
+ button = Template::Button.new('Send!', id: 'Button1[0]', x: 490, y: 240, width: 60, height: 30)
103
+
104
+ page.add_annotation(ml, button)
105
+
106
+ form1 = Field::Subform.new(T: "form1[0]")
107
+ form1.add_fields(subform = Field::Subform.new(T: "#subform[0]"))
108
+ subform.add_fields(ml, button)
109
+
110
+ xdp = SampleXDP.new('Eval(Ref(form1[0].#subform[0].TextField1[0]))').to_s
111
+ pdf.create_xfa_form(xdp, form1)
112
+
113
+ pdf.save(OUTPUT_FILE)
114
+
115
+ puts "PDF file saved as #{OUTPUT_FILE}."