hexapdf 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (346) hide show
  1. checksums.yaml +7 -0
  2. data/CONTRIBUTERS +3 -0
  3. data/LICENSE +26 -0
  4. data/README.md +88 -0
  5. data/Rakefile +121 -0
  6. data/VERSION +1 -0
  7. data/agpl-3.0.txt +661 -0
  8. data/bin/hexapdf +6 -0
  9. data/data/hexapdf/afm/Courier-Bold.afm +342 -0
  10. data/data/hexapdf/afm/Courier-BoldOblique.afm +342 -0
  11. data/data/hexapdf/afm/Courier-Oblique.afm +342 -0
  12. data/data/hexapdf/afm/Courier.afm +342 -0
  13. data/data/hexapdf/afm/Helvetica-Bold.afm +2827 -0
  14. data/data/hexapdf/afm/Helvetica-BoldOblique.afm +2827 -0
  15. data/data/hexapdf/afm/Helvetica-Oblique.afm +3051 -0
  16. data/data/hexapdf/afm/Helvetica.afm +3051 -0
  17. data/data/hexapdf/afm/MustRead.html +1 -0
  18. data/data/hexapdf/afm/Symbol.afm +213 -0
  19. data/data/hexapdf/afm/Times-Bold.afm +2588 -0
  20. data/data/hexapdf/afm/Times-BoldItalic.afm +2384 -0
  21. data/data/hexapdf/afm/Times-Italic.afm +2667 -0
  22. data/data/hexapdf/afm/Times-Roman.afm +2419 -0
  23. data/data/hexapdf/afm/ZapfDingbats.afm +225 -0
  24. data/data/hexapdf/encoding/glyphlist.txt +4305 -0
  25. data/data/hexapdf/encoding/zapfdingbats.txt +225 -0
  26. data/examples/arc.rb +50 -0
  27. data/examples/graphics.rb +274 -0
  28. data/examples/hello_world.rb +16 -0
  29. data/examples/machupicchu.jpg +0 -0
  30. data/examples/merging.rb +24 -0
  31. data/examples/optimizing.rb +20 -0
  32. data/examples/show_char_bboxes.rb +55 -0
  33. data/examples/standard_pdf_fonts.rb +72 -0
  34. data/examples/truetype.rb +45 -0
  35. data/lib/hexapdf/cli/extract.rb +128 -0
  36. data/lib/hexapdf/cli/info.rb +121 -0
  37. data/lib/hexapdf/cli/inspect.rb +157 -0
  38. data/lib/hexapdf/cli/modify.rb +218 -0
  39. data/lib/hexapdf/cli.rb +121 -0
  40. data/lib/hexapdf/configuration.rb +392 -0
  41. data/lib/hexapdf/content/canvas.rb +1974 -0
  42. data/lib/hexapdf/content/color_space.rb +364 -0
  43. data/lib/hexapdf/content/graphic_object/arc.rb +267 -0
  44. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +208 -0
  45. data/lib/hexapdf/content/graphic_object/solid_arc.rb +173 -0
  46. data/lib/hexapdf/content/graphic_object.rb +81 -0
  47. data/lib/hexapdf/content/graphics_state.rb +579 -0
  48. data/lib/hexapdf/content/operator.rb +1072 -0
  49. data/lib/hexapdf/content/parser.rb +204 -0
  50. data/lib/hexapdf/content/processor.rb +451 -0
  51. data/lib/hexapdf/content/transformation_matrix.rb +172 -0
  52. data/lib/hexapdf/content.rb +47 -0
  53. data/lib/hexapdf/data_dir.rb +51 -0
  54. data/lib/hexapdf/dictionary.rb +303 -0
  55. data/lib/hexapdf/dictionary_fields.rb +382 -0
  56. data/lib/hexapdf/document.rb +589 -0
  57. data/lib/hexapdf/document_utils.rb +209 -0
  58. data/lib/hexapdf/encryption/aes.rb +206 -0
  59. data/lib/hexapdf/encryption/arc4.rb +93 -0
  60. data/lib/hexapdf/encryption/fast_aes.rb +79 -0
  61. data/lib/hexapdf/encryption/fast_arc4.rb +67 -0
  62. data/lib/hexapdf/encryption/identity.rb +63 -0
  63. data/lib/hexapdf/encryption/ruby_aes.rb +447 -0
  64. data/lib/hexapdf/encryption/ruby_arc4.rb +96 -0
  65. data/lib/hexapdf/encryption/security_handler.rb +494 -0
  66. data/lib/hexapdf/encryption/standard_security_handler.rb +616 -0
  67. data/lib/hexapdf/encryption.rb +94 -0
  68. data/lib/hexapdf/error.rb +73 -0
  69. data/lib/hexapdf/filter/ascii85_decode.rb +160 -0
  70. data/lib/hexapdf/filter/ascii_hex_decode.rb +87 -0
  71. data/lib/hexapdf/filter/dct_decode.rb +57 -0
  72. data/lib/hexapdf/filter/encryption.rb +59 -0
  73. data/lib/hexapdf/filter/flate_decode.rb +93 -0
  74. data/lib/hexapdf/filter/jpx_decode.rb +56 -0
  75. data/lib/hexapdf/filter/lzw_decode.rb +191 -0
  76. data/lib/hexapdf/filter/predictor.rb +266 -0
  77. data/lib/hexapdf/filter/run_length_decode.rb +108 -0
  78. data/lib/hexapdf/filter.rb +176 -0
  79. data/lib/hexapdf/font/cmap/parser.rb +146 -0
  80. data/lib/hexapdf/font/cmap/writer.rb +176 -0
  81. data/lib/hexapdf/font/cmap.rb +90 -0
  82. data/lib/hexapdf/font/encoding/base.rb +77 -0
  83. data/lib/hexapdf/font/encoding/difference_encoding.rb +64 -0
  84. data/lib/hexapdf/font/encoding/glyph_list.rb +150 -0
  85. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +221 -0
  86. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +265 -0
  87. data/lib/hexapdf/font/encoding/standard_encoding.rb +205 -0
  88. data/lib/hexapdf/font/encoding/symbol_encoding.rb +244 -0
  89. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +280 -0
  90. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +250 -0
  91. data/lib/hexapdf/font/encoding.rb +68 -0
  92. data/lib/hexapdf/font/true_type/font.rb +179 -0
  93. data/lib/hexapdf/font/true_type/table/cmap.rb +103 -0
  94. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +384 -0
  95. data/lib/hexapdf/font/true_type/table/directory.rb +92 -0
  96. data/lib/hexapdf/font/true_type/table/glyf.rb +166 -0
  97. data/lib/hexapdf/font/true_type/table/head.rb +143 -0
  98. data/lib/hexapdf/font/true_type/table/hhea.rb +109 -0
  99. data/lib/hexapdf/font/true_type/table/hmtx.rb +79 -0
  100. data/lib/hexapdf/font/true_type/table/loca.rb +79 -0
  101. data/lib/hexapdf/font/true_type/table/maxp.rb +112 -0
  102. data/lib/hexapdf/font/true_type/table/name.rb +218 -0
  103. data/lib/hexapdf/font/true_type/table/os2.rb +200 -0
  104. data/lib/hexapdf/font/true_type/table/post.rb +230 -0
  105. data/lib/hexapdf/font/true_type/table.rb +155 -0
  106. data/lib/hexapdf/font/true_type.rb +48 -0
  107. data/lib/hexapdf/font/true_type_wrapper.rb +240 -0
  108. data/lib/hexapdf/font/type1/afm_parser.rb +230 -0
  109. data/lib/hexapdf/font/type1/character_metrics.rb +67 -0
  110. data/lib/hexapdf/font/type1/font.rb +123 -0
  111. data/lib/hexapdf/font/type1/font_metrics.rb +117 -0
  112. data/lib/hexapdf/font/type1/pfb_parser.rb +71 -0
  113. data/lib/hexapdf/font/type1.rb +52 -0
  114. data/lib/hexapdf/font/type1_wrapper.rb +193 -0
  115. data/lib/hexapdf/font_loader/from_configuration.rb +70 -0
  116. data/lib/hexapdf/font_loader/standard14.rb +98 -0
  117. data/lib/hexapdf/font_loader.rb +85 -0
  118. data/lib/hexapdf/font_utils.rb +89 -0
  119. data/lib/hexapdf/image_loader/jpeg.rb +166 -0
  120. data/lib/hexapdf/image_loader/pdf.rb +89 -0
  121. data/lib/hexapdf/image_loader/png.rb +410 -0
  122. data/lib/hexapdf/image_loader.rb +68 -0
  123. data/lib/hexapdf/importer.rb +139 -0
  124. data/lib/hexapdf/name_tree_node.rb +78 -0
  125. data/lib/hexapdf/number_tree_node.rb +67 -0
  126. data/lib/hexapdf/object.rb +363 -0
  127. data/lib/hexapdf/parser.rb +349 -0
  128. data/lib/hexapdf/rectangle.rb +99 -0
  129. data/lib/hexapdf/reference.rb +98 -0
  130. data/lib/hexapdf/revision.rb +206 -0
  131. data/lib/hexapdf/revisions.rb +194 -0
  132. data/lib/hexapdf/serializer.rb +326 -0
  133. data/lib/hexapdf/stream.rb +279 -0
  134. data/lib/hexapdf/task/dereference.rb +109 -0
  135. data/lib/hexapdf/task/optimize.rb +230 -0
  136. data/lib/hexapdf/task.rb +68 -0
  137. data/lib/hexapdf/tokenizer.rb +406 -0
  138. data/lib/hexapdf/type/catalog.rb +107 -0
  139. data/lib/hexapdf/type/embedded_file.rb +87 -0
  140. data/lib/hexapdf/type/file_specification.rb +232 -0
  141. data/lib/hexapdf/type/font.rb +81 -0
  142. data/lib/hexapdf/type/font_descriptor.rb +109 -0
  143. data/lib/hexapdf/type/font_simple.rb +190 -0
  144. data/lib/hexapdf/type/font_true_type.rb +47 -0
  145. data/lib/hexapdf/type/font_type1.rb +162 -0
  146. data/lib/hexapdf/type/form.rb +103 -0
  147. data/lib/hexapdf/type/graphics_state_parameter.rb +79 -0
  148. data/lib/hexapdf/type/image.rb +73 -0
  149. data/lib/hexapdf/type/info.rb +70 -0
  150. data/lib/hexapdf/type/names.rb +69 -0
  151. data/lib/hexapdf/type/object_stream.rb +224 -0
  152. data/lib/hexapdf/type/page.rb +355 -0
  153. data/lib/hexapdf/type/page_tree_node.rb +269 -0
  154. data/lib/hexapdf/type/resources.rb +212 -0
  155. data/lib/hexapdf/type/trailer.rb +128 -0
  156. data/lib/hexapdf/type/viewer_preferences.rb +73 -0
  157. data/lib/hexapdf/type/xref_stream.rb +204 -0
  158. data/lib/hexapdf/type.rb +67 -0
  159. data/lib/hexapdf/utils/bit_field.rb +87 -0
  160. data/lib/hexapdf/utils/bit_stream.rb +148 -0
  161. data/lib/hexapdf/utils/lru_cache.rb +65 -0
  162. data/lib/hexapdf/utils/math_helpers.rb +55 -0
  163. data/lib/hexapdf/utils/object_hash.rb +130 -0
  164. data/lib/hexapdf/utils/pdf_doc_encoding.rb +93 -0
  165. data/lib/hexapdf/utils/sorted_tree_node.rb +339 -0
  166. data/lib/hexapdf/version.rb +39 -0
  167. data/lib/hexapdf/writer.rb +199 -0
  168. data/lib/hexapdf/xref_section.rb +152 -0
  169. data/lib/hexapdf.rb +34 -0
  170. data/man/man1/hexapdf.1 +249 -0
  171. data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
  172. data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
  173. data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
  174. data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
  175. data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
  176. data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
  177. data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
  178. data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
  179. data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
  180. data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
  181. data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
  182. data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
  183. data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
  184. data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
  185. data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
  186. data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
  187. data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
  188. data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
  189. data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
  190. data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
  191. data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
  192. data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
  193. data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
  194. data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
  195. data/test/data/fonts/Ubuntu-Title.ttf +0 -0
  196. data/test/data/images/cmyk.jpg +0 -0
  197. data/test/data/images/fillbytes.jpg +0 -0
  198. data/test/data/images/gray.jpg +0 -0
  199. data/test/data/images/greyscale-1bit.png +0 -0
  200. data/test/data/images/greyscale-2bit.png +0 -0
  201. data/test/data/images/greyscale-4bit.png +0 -0
  202. data/test/data/images/greyscale-8bit.png +0 -0
  203. data/test/data/images/greyscale-alpha-8bit.png +0 -0
  204. data/test/data/images/greyscale-trns-8bit.png +0 -0
  205. data/test/data/images/greyscale-with-gamma1.0.png +0 -0
  206. data/test/data/images/greyscale-with-gamma1.5.png +0 -0
  207. data/test/data/images/indexed-1bit.png +0 -0
  208. data/test/data/images/indexed-2bit.png +0 -0
  209. data/test/data/images/indexed-4bit.png +0 -0
  210. data/test/data/images/indexed-8bit.png +0 -0
  211. data/test/data/images/indexed-alpha-4bit.png +0 -0
  212. data/test/data/images/indexed-alpha-8bit.png +0 -0
  213. data/test/data/images/rgb.jpg +0 -0
  214. data/test/data/images/truecolour-8bit.png +0 -0
  215. data/test/data/images/truecolour-alpha-8bit.png +0 -0
  216. data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
  217. data/test/data/images/truecolour-srgb-8bit.png +0 -0
  218. data/test/data/minimal.pdf +44 -0
  219. data/test/data/standard-security-handler/README +9 -0
  220. data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +44 -0
  221. data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
  222. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +43 -0
  223. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +43 -0
  224. data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
  225. data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +43 -0
  226. data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
  227. data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +43 -0
  228. data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +43 -0
  229. data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +43 -0
  230. data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
  231. data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +43 -0
  232. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +43 -0
  233. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +43 -0
  234. data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +43 -0
  235. data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +43 -0
  236. data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +43 -0
  237. data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
  238. data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
  239. data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +43 -0
  240. data/test/hexapdf/common_tokenizer_tests.rb +204 -0
  241. data/test/hexapdf/content/common.rb +31 -0
  242. data/test/hexapdf/content/graphic_object/test_arc.rb +93 -0
  243. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +91 -0
  244. data/test/hexapdf/content/graphic_object/test_solid_arc.rb +86 -0
  245. data/test/hexapdf/content/test_canvas.rb +1113 -0
  246. data/test/hexapdf/content/test_color_space.rb +97 -0
  247. data/test/hexapdf/content/test_graphics_state.rb +138 -0
  248. data/test/hexapdf/content/test_operator.rb +619 -0
  249. data/test/hexapdf/content/test_parser.rb +66 -0
  250. data/test/hexapdf/content/test_processor.rb +156 -0
  251. data/test/hexapdf/content/test_transformation_matrix.rb +64 -0
  252. data/test/hexapdf/encryption/common.rb +87 -0
  253. data/test/hexapdf/encryption/test_aes.rb +121 -0
  254. data/test/hexapdf/encryption/test_arc4.rb +39 -0
  255. data/test/hexapdf/encryption/test_fast_aes.rb +17 -0
  256. data/test/hexapdf/encryption/test_fast_arc4.rb +12 -0
  257. data/test/hexapdf/encryption/test_identity.rb +21 -0
  258. data/test/hexapdf/encryption/test_ruby_aes.rb +23 -0
  259. data/test/hexapdf/encryption/test_ruby_arc4.rb +20 -0
  260. data/test/hexapdf/encryption/test_security_handler.rb +356 -0
  261. data/test/hexapdf/encryption/test_standard_security_handler.rb +274 -0
  262. data/test/hexapdf/filter/common.rb +53 -0
  263. data/test/hexapdf/filter/test_ascii85_decode.rb +60 -0
  264. data/test/hexapdf/filter/test_ascii_hex_decode.rb +33 -0
  265. data/test/hexapdf/filter/test_encryption.rb +24 -0
  266. data/test/hexapdf/filter/test_flate_decode.rb +35 -0
  267. data/test/hexapdf/filter/test_lzw_decode.rb +52 -0
  268. data/test/hexapdf/filter/test_predictor.rb +183 -0
  269. data/test/hexapdf/filter/test_run_length_decode.rb +32 -0
  270. data/test/hexapdf/font/cmap/test_parser.rb +67 -0
  271. data/test/hexapdf/font/cmap/test_writer.rb +58 -0
  272. data/test/hexapdf/font/encoding/test_base.rb +35 -0
  273. data/test/hexapdf/font/encoding/test_difference_encoding.rb +21 -0
  274. data/test/hexapdf/font/encoding/test_glyph_list.rb +59 -0
  275. data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +16 -0
  276. data/test/hexapdf/font/test_encoding.rb +27 -0
  277. data/test/hexapdf/font/test_true_type_wrapper.rb +110 -0
  278. data/test/hexapdf/font/test_type1_wrapper.rb +66 -0
  279. data/test/hexapdf/font/true_type/common.rb +19 -0
  280. data/test/hexapdf/font/true_type/table/test_cmap.rb +59 -0
  281. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +133 -0
  282. data/test/hexapdf/font/true_type/table/test_directory.rb +35 -0
  283. data/test/hexapdf/font/true_type/table/test_glyf.rb +58 -0
  284. data/test/hexapdf/font/true_type/table/test_head.rb +76 -0
  285. data/test/hexapdf/font/true_type/table/test_hhea.rb +40 -0
  286. data/test/hexapdf/font/true_type/table/test_hmtx.rb +38 -0
  287. data/test/hexapdf/font/true_type/table/test_loca.rb +43 -0
  288. data/test/hexapdf/font/true_type/table/test_maxp.rb +62 -0
  289. data/test/hexapdf/font/true_type/table/test_name.rb +95 -0
  290. data/test/hexapdf/font/true_type/table/test_os2.rb +65 -0
  291. data/test/hexapdf/font/true_type/table/test_post.rb +89 -0
  292. data/test/hexapdf/font/true_type/test_font.rb +120 -0
  293. data/test/hexapdf/font/true_type/test_table.rb +41 -0
  294. data/test/hexapdf/font/type1/test_afm_parser.rb +51 -0
  295. data/test/hexapdf/font/type1/test_font.rb +68 -0
  296. data/test/hexapdf/font/type1/test_pfb_parser.rb +37 -0
  297. data/test/hexapdf/font_loader/test_from_configuration.rb +28 -0
  298. data/test/hexapdf/font_loader/test_standard14.rb +22 -0
  299. data/test/hexapdf/image_loader/test_jpeg.rb +83 -0
  300. data/test/hexapdf/image_loader/test_pdf.rb +47 -0
  301. data/test/hexapdf/image_loader/test_png.rb +258 -0
  302. data/test/hexapdf/task/test_dereference.rb +46 -0
  303. data/test/hexapdf/task/test_optimize.rb +137 -0
  304. data/test/hexapdf/test_configuration.rb +82 -0
  305. data/test/hexapdf/test_data_dir.rb +32 -0
  306. data/test/hexapdf/test_dictionary.rb +284 -0
  307. data/test/hexapdf/test_dictionary_fields.rb +185 -0
  308. data/test/hexapdf/test_document.rb +574 -0
  309. data/test/hexapdf/test_document_utils.rb +144 -0
  310. data/test/hexapdf/test_filter.rb +96 -0
  311. data/test/hexapdf/test_font_utils.rb +47 -0
  312. data/test/hexapdf/test_importer.rb +78 -0
  313. data/test/hexapdf/test_object.rb +177 -0
  314. data/test/hexapdf/test_parser.rb +394 -0
  315. data/test/hexapdf/test_rectangle.rb +36 -0
  316. data/test/hexapdf/test_reference.rb +41 -0
  317. data/test/hexapdf/test_revision.rb +139 -0
  318. data/test/hexapdf/test_revisions.rb +93 -0
  319. data/test/hexapdf/test_serializer.rb +169 -0
  320. data/test/hexapdf/test_stream.rb +262 -0
  321. data/test/hexapdf/test_tokenizer.rb +30 -0
  322. data/test/hexapdf/test_writer.rb +120 -0
  323. data/test/hexapdf/test_xref_section.rb +35 -0
  324. data/test/hexapdf/type/test_catalog.rb +30 -0
  325. data/test/hexapdf/type/test_embedded_file.rb +16 -0
  326. data/test/hexapdf/type/test_file_specification.rb +148 -0
  327. data/test/hexapdf/type/test_font.rb +35 -0
  328. data/test/hexapdf/type/test_font_descriptor.rb +51 -0
  329. data/test/hexapdf/type/test_font_simple.rb +190 -0
  330. data/test/hexapdf/type/test_font_type1.rb +128 -0
  331. data/test/hexapdf/type/test_form.rb +60 -0
  332. data/test/hexapdf/type/test_info.rb +14 -0
  333. data/test/hexapdf/type/test_names.rb +9 -0
  334. data/test/hexapdf/type/test_object_stream.rb +84 -0
  335. data/test/hexapdf/type/test_page.rb +260 -0
  336. data/test/hexapdf/type/test_page_tree_node.rb +255 -0
  337. data/test/hexapdf/type/test_resources.rb +167 -0
  338. data/test/hexapdf/type/test_trailer.rb +109 -0
  339. data/test/hexapdf/type/test_xref_stream.rb +131 -0
  340. data/test/hexapdf/utils/test_bit_field.rb +47 -0
  341. data/test/hexapdf/utils/test_lru_cache.rb +22 -0
  342. data/test/hexapdf/utils/test_object_hash.rb +115 -0
  343. data/test/hexapdf/utils/test_pdf_doc_encoding.rb +18 -0
  344. data/test/hexapdf/utils/test_sorted_tree_node.rb +232 -0
  345. data/test/test_helper.rb +56 -0
  346. metadata +427 -0
@@ -0,0 +1,199 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2016 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/error'
35
+ require 'hexapdf/serializer'
36
+ require 'hexapdf/xref_section'
37
+ require 'hexapdf/version'
38
+
39
+ module HexaPDF
40
+
41
+ # Writes the contents of a PDF document to an IO stream.
42
+ class Writer
43
+
44
+ # Writes the document to the IO object.
45
+ def self.write(document, io)
46
+ new(document, io).write
47
+ end
48
+
49
+ # Creates a new writer object for the given HexaPDF document that gets written to the IO
50
+ # object.
51
+ def initialize(document, io)
52
+ @document = document
53
+ @io = io
54
+
55
+ @io.binmode
56
+ @io.seek(0, IO::SEEK_SET) # TODO: incremental update!
57
+
58
+ @serializer = Serializer.new
59
+ @rev_size = 0
60
+ end
61
+
62
+ # Writes the document to the IO object.
63
+ def write
64
+ @serializer.encrypter = @document.encrypted? ? @document.security_handler : nil
65
+
66
+ write_file_header
67
+
68
+ pos = nil
69
+ @document.trailer.info[:Producer] = "HexaPDF version #{HexaPDF::VERSION}"
70
+ @document.revisions.each do |rev|
71
+ pos = write_revision(rev, pos)
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ # Writes the PDF file header.
78
+ #
79
+ # See: PDF1.7 s7.5.2
80
+ def write_file_header
81
+ @io << "%PDF-#{@document.version}\n%\xCF\xEC\xFF\xE8\xD7\xCB\xCD\n"
82
+ end
83
+
84
+ # Writes the given revision.
85
+ #
86
+ # The optional +previous_xref_pos+ argument needs to contain the byte position of the previous
87
+ # cross-reference section or stream if applicable.
88
+ def write_revision(rev, previous_xref_pos = nil)
89
+ xref_stream, object_streams = xref_and_object_streams(rev)
90
+ obj_to_stm = object_streams.each_with_object({}) {|stm, m| m.update(stm.write_objects(rev))}
91
+
92
+ xref_section = XRefSection.new
93
+ xref_section.add_free_entry(0, 65535) if previous_xref_pos.nil?
94
+ rev.each do |obj|
95
+ if obj.null?
96
+ xref_section.add_free_entry(obj.oid, obj.gen)
97
+ elsif (objstm = obj_to_stm[obj])
98
+ xref_section.add_compressed_entry(obj.oid, objstm.oid, objstm.object_index(obj))
99
+ elsif obj != xref_stream
100
+ xref_section.add_in_use_entry(obj.oid, obj.gen, @io.pos)
101
+ write_indirect_object(obj)
102
+ end
103
+ end
104
+
105
+ trailer = rev.trailer.value.dup
106
+ if previous_xref_pos
107
+ trailer[:Prev] = previous_xref_pos
108
+ else
109
+ trailer.delete(:Prev)
110
+ end
111
+ @rev_size = rev.next_free_oid if rev.next_free_oid > @rev_size
112
+ trailer[:Size] = @rev_size
113
+
114
+ startxref = @io.pos
115
+ if xref_stream
116
+ xref_section.add_in_use_entry(xref_stream.oid, xref_stream.gen, startxref)
117
+ xref_stream.update_with_xref_section_and_trailer(xref_section, trailer)
118
+ write_indirect_object(xref_stream)
119
+ else
120
+ write_xref_section(xref_section)
121
+ write_trailer(trailer)
122
+ end
123
+
124
+ write_startxref(startxref)
125
+
126
+ startxref
127
+ end
128
+
129
+ # :call-seq:
130
+ # writer.xref_and_object_streams -> [xref_stream, object_streams]
131
+ #
132
+ # Returns the cross-reference and object streams of the given revision.
133
+ #
134
+ # An error is raised if the revision contains object streams and no cross-reference stream. If
135
+ # it contains multiple cross-reference streams only the first one is used, the rest are
136
+ # ignored.
137
+ def xref_and_object_streams(rev)
138
+ xref_stream = nil
139
+ object_streams = []
140
+
141
+ rev.each do |obj|
142
+ if obj.type == :ObjStm
143
+ object_streams << obj
144
+ elsif !xref_stream && obj.type == :XRef
145
+ xref_stream = obj
146
+ end
147
+ end
148
+
149
+ if object_streams.size > 0 && xref_stream.nil?
150
+ raise HexaPDF::Error, "Cannot use object streams when there is no xref stream"
151
+ end
152
+
153
+ [xref_stream, object_streams]
154
+ end
155
+
156
+ # Writes the single indirect object which may be a stream object or another object.
157
+ def write_indirect_object(obj)
158
+ @io << "#{obj.oid} #{obj.gen} obj\n".freeze
159
+ @serializer.serialize_to_io(obj, @io)
160
+ @io << "\nendobj\n".freeze
161
+ end
162
+
163
+ # Writes the cross-reference section.
164
+ #
165
+ # See: PDF1.7 s7.5.4
166
+ def write_xref_section(xref_section)
167
+ @io << "xref\n"
168
+ xref_section.each_subsection do |entries|
169
+ @io << "#{entries.empty? ? 0 : entries.first.oid} #{entries.size}\n"
170
+ entries.each do |entry|
171
+ if entry.in_use?
172
+ @io << sprintf("%010d %05d n \n".freeze, entry.pos, entry.gen).freeze
173
+ elsif entry.free?
174
+ @io << "0000000000 65535 f \n".freeze
175
+ else
176
+ # Should never occur since we create the xref section!
177
+ raise HexaPDF::Error, "Cannot use xref type #{entry.type} in cross-reference section"
178
+ end
179
+ end
180
+ end
181
+ end
182
+
183
+ # Writes the trailer dictionary.
184
+ #
185
+ # See: PDF1.7 s7.5.5
186
+ def write_trailer(trailer)
187
+ @io << "trailer\n#{@serializer.serialize(trailer)}\n"
188
+ end
189
+
190
+ # Writes the startxref line needed for cross-reference sections and cross-reference streams.
191
+ #
192
+ # See: PDF1.7 s7.5.5, s7.5.8
193
+ def write_startxref(startxref)
194
+ @io << "startxref\n#{startxref}\n%%EOF\n"
195
+ end
196
+
197
+ end
198
+
199
+ end
@@ -0,0 +1,152 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2016 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/utils/object_hash'
35
+
36
+ module HexaPDF
37
+
38
+ # Manages the indirect objects of one cross-reference section or stream.
39
+ #
40
+ # A PDF file can have more than one cross-reference section or stream which are all
41
+ # daisy-chained together. This allows later sections to override entries in prior ones. This is
42
+ # automatically and transparently done by HexaPDF.
43
+ #
44
+ # Note that a cross-reference section may contain a single object number only once.
45
+ #
46
+ # See: HexaPDF::Revision, PDF1.7 s7.5.4, s7.5.8
47
+ class XRefSection < Utils::ObjectHash
48
+
49
+ # One entry of a cross-reference section or stream.
50
+ #
51
+ # An entry has the attributes +type+, +oid+, +gen+, +pos+ and +objstm+ and can be created like
52
+ # this:
53
+ #
54
+ # Entry.new(type, oid, gen, pos, objstm) -> entry
55
+ #
56
+ # The +type+ attribute can be:
57
+ #
58
+ # :free:: Denotes a free entry.
59
+ #
60
+ # :in_use:: A used entry that resides in the body of the PDF file. The +pos+ attribute defines
61
+ # the position in the file at which the object can be found.
62
+ #
63
+ # :compressed:: A used entry that resides in an object stream. The +objstm+ attribute contains
64
+ # the reference to the object stream in which the object can be found and the
65
+ # +pos+ attribute contains the index into the object stream.
66
+ #
67
+ # Objects in an object stream always have a generation number of 0!
68
+ #
69
+ # See: PDF1.7 s7.5.4, s7.5.8
70
+ Entry = Struct.new(:type, :oid, :gen, :pos, :objstm) do
71
+ def free?
72
+ type == :free
73
+ end
74
+
75
+ def in_use?
76
+ type == :in_use
77
+ end
78
+
79
+ def compressed?
80
+ type == :compressed
81
+ end
82
+ end
83
+
84
+ # Creates an in-use cross-reference entry. See Entry for details on the arguments.
85
+ def self.in_use_entry(oid, gen, pos)
86
+ Entry.new(:in_use, oid, gen, pos)
87
+ end
88
+
89
+ # Creates a free cross-reference entry. See Entry for details on the arguments.
90
+ def self.free_entry(oid, gen)
91
+ Entry.new(:free, oid, gen)
92
+ end
93
+
94
+ # Creates a compressed cross-reference entry. See Entry for details on the arguments.
95
+ def self.compressed_entry(oid, objstm, pos)
96
+ Entry.new(:compressed, oid, 0, pos, objstm)
97
+ end
98
+
99
+ # Make the assignment method private so that only the provided convenience methods can be
100
+ # used.
101
+ private :"[]="
102
+
103
+ # Adds an in-use entry to the cross-reference section.
104
+ #
105
+ # See: ::in_use_entry
106
+ def add_in_use_entry(oid, gen, pos)
107
+ self[oid, gen] = self.class.in_use_entry(oid, gen, pos)
108
+ end
109
+
110
+ # Adds a free entry to the cross-reference section.
111
+ #
112
+ # See: ::free_entry
113
+ def add_free_entry(oid, gen)
114
+ self[oid, gen] = self.class.free_entry(oid, gen)
115
+ end
116
+
117
+ # Adds a compressed entry to the cross-reference section.
118
+ #
119
+ # See: ::compressed_entry
120
+ def add_compressed_entry(oid, objstm, pos)
121
+ self[oid, 0] = self.class.compressed_entry(oid, objstm, pos)
122
+ end
123
+
124
+ # :call-seq:
125
+ # xref_section.each_subsection {|sub| block } -> xref_section
126
+ # xref_section.each_subsection -> Enumerator
127
+ #
128
+ # Calls the given block once for every subsection of this cross-reference section. Each
129
+ # yielded subsection is a sorted array of cross-reference entries.
130
+ #
131
+ # If this section contains no objects, a single empty array is yielded (corresponding to a
132
+ # subsection with zero elements).
133
+ #
134
+ # The subsections are dynamically generated based on the object numbers in this section.
135
+ def each_subsection
136
+ return to_enum(__method__) unless block_given?
137
+
138
+ temp = []
139
+ oids.sort.each do |oid|
140
+ if !temp.empty? && temp[-1].oid + 1 != oid
141
+ yield(temp)
142
+ temp = []
143
+ end
144
+ temp << self[oid]
145
+ end
146
+ yield(temp)
147
+ self
148
+ end
149
+
150
+ end
151
+
152
+ end
data/lib/hexapdf.rb ADDED
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+ #
3
+ #--
4
+ # This file is part of HexaPDF.
5
+ #
6
+ # HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby
7
+ # Copyright (C) 2016 Thomas Leitner
8
+ #
9
+ # HexaPDF is free software: you can redistribute it and/or modify it
10
+ # under the terms of the GNU Affero General Public License version 3 as
11
+ # published by the Free Software Foundation with the addition of the
12
+ # following permission added to Section 15 as permitted in Section 7(a):
13
+ # FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY
14
+ # THOMAS LEITNER, THOMAS LEITNER DISCLAIMS THE WARRANTY OF NON
15
+ # INFRINGEMENT OF THIRD PARTY RIGHTS.
16
+ #
17
+ # HexaPDF is distributed in the hope that it will be useful, but WITHOUT
18
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
+ # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
20
+ # License for more details.
21
+ #
22
+ # You should have received a copy of the GNU Affero General Public License
23
+ # along with HexaPDF. If not, see <http://www.gnu.org/licenses/>.
24
+ #
25
+ # The interactive user interfaces in modified source and object code
26
+ # versions of HexaPDF must display Appropriate Legal Notices, as required
27
+ # under Section 5 of the GNU Affero General Public License version 3.
28
+ #
29
+ # In accordance with Section 7(b) of the GNU Affero General Public
30
+ # License, a covered work must retain the producer line in every PDF that
31
+ # is created or manipulated using HexaPDF.
32
+ #++
33
+
34
+ require 'hexapdf/document'
@@ -0,0 +1,249 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "HEXAPDF" "1" "October 2016" "" ""
5
+ .
6
+ .SH "NAME"
7
+ hexapdf \- A Versatile PDF Manipulation Application
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBhexapdf\fR [\fBOPTIONS\fR] \fBcommand\fR [\fBCOMMAND OPTIONS\fR]\.\.\.
11
+ .
12
+ .SH "DESCRIPTION"
13
+ hexapdf is an application for PDF manipulation\. It is part of the hexapdf \fIhttp://hexapdf\.gettalong\.org\fR library which also allows PDF creation, among other things\.
14
+ .
15
+ .P
16
+ Using the hexapdf application the following tasks can be performed with PDF files:
17
+ .
18
+ .IP "\(bu" 4
19
+ Extracting embedded files (see the \fBextract\fR command)
20
+ .
21
+ .IP "\(bu" 4
22
+ Showing general information of a PDF file (see the \fBinfo\fR command)
23
+ .
24
+ .IP "\(bu" 4
25
+ Inspecting the internal structure of a PDF file (see the \fBinspect\fR command)
26
+ .
27
+ .IP "\(bu" 4
28
+ Modifying an existing PDF file (see the \fBmodify\fR command)
29
+ .
30
+ .IP "" 0
31
+ .
32
+ .P
33
+ The application contains a built\-in \fBhelp\fR command that can be used to provide a quick reminder of a command\'s purpose and its options\.
34
+ .
35
+ .SH "OPTIONS"
36
+ The following options can only be used when no command is specified:
37
+ .
38
+ .TP
39
+ \fB\-v\fR, \fB\-\-version\fR
40
+ Show the version of the hexapdf application and exit\.
41
+ .
42
+ .P
43
+ These options are available on every command (except if they are overridden):
44
+ .
45
+ .TP
46
+ \fB\-h\fR, \fB\-\-help\fR
47
+ Show the help for the application if no command was specified, or the command help otherwise\.
48
+ .
49
+ .SH "COMMANDS"
50
+ hexapdf uses a command\-style interface\. This means that it provides different functionalities depending on the used command and each command can have its own options\.
51
+ .
52
+ .P
53
+ There is no need to write the full command name for hexapdf to understand it, the only requirement is that is must be unambiguous\. So using \fBe\fR for the \fBextract\fR command is sufficient\.
54
+ .
55
+ .SS "extract"
56
+ Synopsis: \fBextract\fR [\fBOPTIONS\fR] \fIFILE\fR
57
+ .
58
+ .P
59
+ This command extracts embedded files from the PDF \fIFILE\fR\. If the \fB\-\-indices\fR option is not specified, the names and indices of the embedded files are just listed\.
60
+ .
61
+ .TP
62
+ \fB\-i\fR, \fB\-\-indices\fR \fIA,B,C,\.\.\.\fR
63
+ The indices of the embedded files that should be extract\. The value \fI0\fR can be used to extract all embedded files\.
64
+ .
65
+ .TP
66
+ \fB\-s\fR, \fB\-\-[no\-]search\fR
67
+ Search the whole PDF file instead of the standard locations, i\.e\. files attached to the document as a whole or to an individual page\. Defaults to \fIfalse\fR\.
68
+ .
69
+ .TP
70
+ \fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
71
+ The password to decrypt the PDF \fIFILE\fR\. Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
72
+ .
73
+ .SS "help"
74
+ Synopsis: \fBhelp\fR \fICOMMAND\fR\.\.\.
75
+ .
76
+ .P
77
+ This command prints the application help if no arguments are given\. If one or more command names are given as arguments, these arguments are interpreted as a list of commands with sub\-commands and the help for the innermost command is shown\.
78
+ .
79
+ .SS "info"
80
+ Synopsis: \fBinfo\fR [\fBOPTIONS\fR] \fIFILE\fR
81
+ .
82
+ .P
83
+ This command reads the \fIFILE\fR file and shows general information about it, like author information, PDF version used, encryption information and so on\.
84
+ .
85
+ .TP
86
+ \fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
87
+ The password to decrypt the PDF \fIFILE\fR\. Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
88
+ .
89
+ .SS "inspect"
90
+ Synopsis: \fBinspect\fR [\fBOPTIONS\fR] \fIFILE\fR
91
+ .
92
+ .P
93
+ This command is useful when one needs to inspect the internal object structure or a stream of a PDF file\.
94
+ .
95
+ .P
96
+ If no option is given, the main PDF object, the catalog, is shown\. Otherwise the various, mutually exclusive display options define what is shown\. If multiple such options are specified only the last one is respected\. Note that PDF objects are always shown in the PDF syntax\.
97
+ .
98
+ .TP
99
+ \fB\-t\fR, \fB\-\-trailer\fR
100
+ Show the trailer dictionary\.
101
+ .
102
+ .TP
103
+ \fB\-c\fR, \fB\-\-page\-count\fR
104
+ Print the number of pages\.
105
+ .
106
+ .TP
107
+ \fB\-\-pages\fR [\fIPAGES\fR]
108
+ Show the pages with their object and generation numbers and their associated content streams\. If a range is specified, only those pages are listed\. See the \fBPAGES SPECIFICATION\fR below for details on the allowed format of \fIPAGES\fR\.
109
+ .
110
+ .TP
111
+ \fB\-o\fR, \fB\-\-object\fR \fIOID\fR[,\fIGEN\fR]
112
+ Show the object with the given object and generation numbers\. The generation number defaults to 0 if not given\.
113
+ .
114
+ .TP
115
+ \fB\-s\fR, \fB\-\-stream\fR \fIOID\fR[,\fIGEN\fR]
116
+ Show the filtered stream data (add \fB\-\-raw\fR to get the raw stream data) of the object with the given object and generation numbers\. The generation number defaults to 0 if not given\.
117
+ .
118
+ .TP
119
+ \fB\-\-raw\fR
120
+ Modifies \fB\-\-stream\fR to show the raw stream data instead of the filtered one\.
121
+ .
122
+ .TP
123
+ \fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
124
+ The password to decrypt the PDF \fIFILE\fR\. Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
125
+ .
126
+ .SS "modify"
127
+ Synopsis: \fBmodify\fR [\fBOPTIONS\fR] \fIINPUT_FILE\fR \fIOUTPUT_FILE\fR
128
+ .
129
+ .P
130
+ This command modifies a PDF file\. It can be used to encrypt/decrypt a file, to optimize it and remove unused entries and to generate or delete object and cross\-reference streams\.
131
+ .
132
+ .TP
133
+ \fB\-p\fR, \fB\-\-password\fR \fIPASSWORD\fR
134
+ The password to decrypt the PDF \fIINPUT_FILE\fR\. Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
135
+ .
136
+ .TP
137
+ \fB\-\-pages\fR \fIPAGES\fR
138
+ The pages (optionally rotated) that should be included in the \fIOUTPUT_FILE\fR\. See the \fBPAGES SPECIFICATION\fR below for details on the allowed format of \fIPAGES\fR\. Default: \fI1\-e\fR (i\.e\. all pages with no additional rotation applied)\.
139
+ .
140
+ .TP
141
+ \fB\-\-embed\fR \fIFILE\fR
142
+ Embed the given file into the \fIOUTPUT_FILE\fR using built\-in features of PDF\. This option can be used multiple times to embed more than one file\.
143
+ .
144
+ .TP
145
+ \fB\-\-[no\-]compact\fR
146
+ Delete unnecessary PDF objects\. This includes merging the base revision and all incremental updates into a single revision\. Default: \fIyes\fR\.
147
+ .
148
+ .TP
149
+ \fB\-\-object\-streams MODE\fR
150
+ Defines how object streams should be treated: \fIgenerate\fR will remove all exisiting object streams and generate new ones, \fIdelete\fR will only remove existing object streams and \fIpreserve\fR will do nothing\. Default: \fIpreserve\fR\.
151
+ .
152
+ .TP
153
+ \fB\-\-xref\-streams MODE\fR
154
+ Defines how cross\-reference streams should be treated: \fIgenerate\fR will add them, \fIdelete\fR will remove them and \fIpreserve\fR will do nothing\. Default: \fIpreserve\fR\.
155
+ .
156
+ .TP
157
+ \fB\-\-streams MODE\fR
158
+ Defines how streams should be treated: \fIcompress\fR will compress them when possible, \fIuncompress\fR will uncompress them when possible and \fIpreserve\fR will do nothing to them\. Default: \fIpreserve\fR\.
159
+ .
160
+ .P
161
+ Encryption related options (all options except \fB\-\-decrypt\fR automatically enabled \fB\-\-encrypt\fR):
162
+ .
163
+ .TP
164
+ \fB\-\-decrypt\fR
165
+ Remove any encryption\.
166
+ .
167
+ .IP
168
+ If neither \fB\-\-decrypt\fR nor \fB\-\-encrypt\fR is specified, the existing encryption configuration is preserved\.
169
+ .
170
+ .TP
171
+ \fB\-\-encrypt\fR
172
+ Encrypt the \fIOUTPUT_FILE\fR\.
173
+ .
174
+ .IP
175
+ If neither \fB\-\-decrypt\fR nor \fB\-\-encrypt\fR is specified, the existing encryption configuration is preserved\.
176
+ .
177
+ .TP
178
+ \fB\-\-owner\-password\fR \fIPASSWORD\fR
179
+ The owner password to be set on the \fIOUTPUT_FILE\fR\. This password is needed when operations not allowed by the permissions need to be done\. It can also be used when opening the PDF file\.
180
+ .
181
+ .IP
182
+ Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
183
+ .
184
+ .TP
185
+ \fB\-\-user\-password\fR \fIPASSWORD\fR
186
+ The user password to be set on the \fIOUTPUT_FILE\fR\. This password is needed when opening the PDF file\. The application should restrict the operations to those allowed by the permissions\.
187
+ .
188
+ .IP
189
+ Use \fB\-\fR for \fIPASSWORD\fR for reading it from standard input\.
190
+ .
191
+ .TP
192
+ \fB\-\-algorithm\fR \fIALGORITHM\fR
193
+ The encryption algorithm to use on the \fIOUTPUT_FILE\fR\. Allowed algorithms are \fIaes\fR and \fIarc4\fR but \fIarc4\fR should only be used if it is absolutely necessary\. Default: \fIaes\fR\.
194
+ .
195
+ .TP
196
+ \fB\-\-key\-length\fR \fIBITS\fR
197
+ The length of the encryption key in bits\. The allowed values differ based on the chosen algorithm: A number divisible by eight between 40 to 128 for \fIarc4\fR and 128 or 256 for \fIaes\fR\. Default: \fB128\fR
198
+ .
199
+ .TP
200
+ \fB\-\-force\-V4\fR
201
+ Force the use of PDF encryption version 4 if key length is \fI128\fR and algorithm is \fIarc4\fR\. This option is probably only useful for testing the implementation of PDF libraries\' encryption handling\.
202
+ .
203
+ .TP
204
+ \fB\-\-permissions\fR \fIPERMS\fR
205
+ A comma separated list of permissions to be set on the \fIOUTPUT_FILE\fR\.
206
+ .
207
+ .IP
208
+ Possible values: \fIprint\fR (allow printing), \fImodify_content\fR (allow modification of the content of pages), \fIcopy_content\fR (allow text extraction and similar operations), \fImodify_annotation\fR (allow creation and modification of annotations and filling in of forms), \fIfill_in_forms\fR (allow filling in of forms even if \fImodify_annotation\fR is not set), \fIextract_content\fR (allow text and graphics extraction in accessibility cases), \fIassemble_document\fR (allow page modifications and bookmark creation), and \fIhigh_quality_print\fR (allow high quality printing)\.
209
+ .
210
+ .SS "version"
211
+ This command shows the version of the hexapdf application\. It is an alternative to using the global \fB\-\-version\fR option\.
212
+ .
213
+ .SH "PAGES SPECIFICATION"
214
+ Some commands allow the specification of pages using a \fIPAGES\fR argument\. This argument is expected to be a comma separated list of single page numbers or page ranges of the form \fISTART\fR\-\fIEND\fR\. The character \'\fBe\fR\' represents the last page and can be used instead of a single number or in a range\. The pages are used in the order in which the are specified\.
215
+ .
216
+ .P
217
+ Additionally, the page numbers and ranges can be suffixed with a rotation modifier: \fBl\fR (for rotating a page left, i\.e\. 90 degrees counterclockwise), \fBr\fR (for rotating a page right, i\.e\. 90 degrees clockwise), \fBd\fR (for rotating a page 180 degrees) and \fBn\fR (for removing any set page rotation)\. Note that this additional functionality may not be used by all commands\.
218
+ .
219
+ .P
220
+ Examples:
221
+ .
222
+ .IP "\(bu" 4
223
+ \fB1,2,3\fR: The pages one, two and three\.
224
+ .
225
+ .IP "\(bu" 4
226
+ \fB11,4\-9,1,e\fR: The pages eleven, four to nine, one and the last page, in exactly this order\.
227
+ .
228
+ .IP "\(bu" 4
229
+ \fB1\-e\fR: All pages of the document\.
230
+ .
231
+ .IP "\(bu" 4
232
+ \fBe\-1\fR: All pages of the document in reverse order\.
233
+ .
234
+ .IP "\(bu" 4
235
+ \fB1l,2r,3\-5d,6n\fR: The pages one (rotate to the left), two (rotated to the right), three to five (all rotated 180 degrees) and six (any possibly set rotation removed)\.
236
+ .
237
+ .IP "" 0
238
+ .
239
+ .SH "EXIT STATUS"
240
+ The exit status is 0 if no error happened\. Otherwise it is 1\.
241
+ .
242
+ .SH "SEE ALSO"
243
+ The hexapdf website \fIhttp://hexapdf\.gettalong\.org/\fR for more information
244
+ .
245
+ .SH "AUTHOR"
246
+ hexapdf was written by Thomas Leitner \fIt_leitner@gmx\.at\fR\.
247
+ .
248
+ .P
249
+ This manual page was written by Thomas Leitner \fIt_leitner@gmx\.at\fR\.