hexapdf 0.1.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 (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,225 @@
1
+ # -----------------------------------------------------------
2
+ # Copyright 2002, 2010, 2015 Adobe Systems Incorporated.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
5
+ # may not use this file except in compliance with the License. You may
6
+ # obtain a copy of the License at
7
+ # http://www.apache.org/licenses/LICENSE-2.0.html
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
+ # implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ # -----------------------------------------------------------
15
+ # Name: ITC Zapf Dingbats Glyph List
16
+ # Table version: 2.0
17
+ # Date: September 20, 2002
18
+ # URL: https://github.com/adobe-type-tools/agl-aglfn
19
+ #
20
+ # Format: two semicolon-delimited fields:
21
+ # (1) glyph name--upper/lowercase letters and digits
22
+ # (2) Unicode scalar value--four uppercase hexadecimal digits
23
+ #
24
+ a100;275E
25
+ a101;2761
26
+ a102;2762
27
+ a103;2763
28
+ a104;2764
29
+ a105;2710
30
+ a106;2765
31
+ a107;2766
32
+ a108;2767
33
+ a109;2660
34
+ a10;2721
35
+ a110;2665
36
+ a111;2666
37
+ a112;2663
38
+ a117;2709
39
+ a118;2708
40
+ a119;2707
41
+ a11;261B
42
+ a120;2460
43
+ a121;2461
44
+ a122;2462
45
+ a123;2463
46
+ a124;2464
47
+ a125;2465
48
+ a126;2466
49
+ a127;2467
50
+ a128;2468
51
+ a129;2469
52
+ a12;261E
53
+ a130;2776
54
+ a131;2777
55
+ a132;2778
56
+ a133;2779
57
+ a134;277A
58
+ a135;277B
59
+ a136;277C
60
+ a137;277D
61
+ a138;277E
62
+ a139;277F
63
+ a13;270C
64
+ a140;2780
65
+ a141;2781
66
+ a142;2782
67
+ a143;2783
68
+ a144;2784
69
+ a145;2785
70
+ a146;2786
71
+ a147;2787
72
+ a148;2788
73
+ a149;2789
74
+ a14;270D
75
+ a150;278A
76
+ a151;278B
77
+ a152;278C
78
+ a153;278D
79
+ a154;278E
80
+ a155;278F
81
+ a156;2790
82
+ a157;2791
83
+ a158;2792
84
+ a159;2793
85
+ a15;270E
86
+ a160;2794
87
+ a161;2192
88
+ a162;27A3
89
+ a163;2194
90
+ a164;2195
91
+ a165;2799
92
+ a166;279B
93
+ a167;279C
94
+ a168;279D
95
+ a169;279E
96
+ a16;270F
97
+ a170;279F
98
+ a171;27A0
99
+ a172;27A1
100
+ a173;27A2
101
+ a174;27A4
102
+ a175;27A5
103
+ a176;27A6
104
+ a177;27A7
105
+ a178;27A8
106
+ a179;27A9
107
+ a17;2711
108
+ a180;27AB
109
+ a181;27AD
110
+ a182;27AF
111
+ a183;27B2
112
+ a184;27B3
113
+ a185;27B5
114
+ a186;27B8
115
+ a187;27BA
116
+ a188;27BB
117
+ a189;27BC
118
+ a18;2712
119
+ a190;27BD
120
+ a191;27BE
121
+ a192;279A
122
+ a193;27AA
123
+ a194;27B6
124
+ a195;27B9
125
+ a196;2798
126
+ a197;27B4
127
+ a198;27B7
128
+ a199;27AC
129
+ a19;2713
130
+ a1;2701
131
+ a200;27AE
132
+ a201;27B1
133
+ a202;2703
134
+ a203;2750
135
+ a204;2752
136
+ a205;276E
137
+ a206;2770
138
+ a20;2714
139
+ a21;2715
140
+ a22;2716
141
+ a23;2717
142
+ a24;2718
143
+ a25;2719
144
+ a26;271A
145
+ a27;271B
146
+ a28;271C
147
+ a29;2722
148
+ a2;2702
149
+ a30;2723
150
+ a31;2724
151
+ a32;2725
152
+ a33;2726
153
+ a34;2727
154
+ a35;2605
155
+ a36;2729
156
+ a37;272A
157
+ a38;272B
158
+ a39;272C
159
+ a3;2704
160
+ a40;272D
161
+ a41;272E
162
+ a42;272F
163
+ a43;2730
164
+ a44;2731
165
+ a45;2732
166
+ a46;2733
167
+ a47;2734
168
+ a48;2735
169
+ a49;2736
170
+ a4;260E
171
+ a50;2737
172
+ a51;2738
173
+ a52;2739
174
+ a53;273A
175
+ a54;273B
176
+ a55;273C
177
+ a56;273D
178
+ a57;273E
179
+ a58;273F
180
+ a59;2740
181
+ a5;2706
182
+ a60;2741
183
+ a61;2742
184
+ a62;2743
185
+ a63;2744
186
+ a64;2745
187
+ a65;2746
188
+ a66;2747
189
+ a67;2748
190
+ a68;2749
191
+ a69;274A
192
+ a6;271D
193
+ a70;274B
194
+ a71;25CF
195
+ a72;274D
196
+ a73;25A0
197
+ a74;274F
198
+ a75;2751
199
+ a76;25B2
200
+ a77;25BC
201
+ a78;25C6
202
+ a79;2756
203
+ a7;271E
204
+ a81;25D7
205
+ a82;2758
206
+ a83;2759
207
+ a84;275A
208
+ a85;276F
209
+ a86;2771
210
+ a87;2772
211
+ a88;2773
212
+ a89;2768
213
+ a8;271F
214
+ a90;2769
215
+ a91;276C
216
+ a92;276D
217
+ a93;276A
218
+ a94;276B
219
+ a95;2774
220
+ a96;2775
221
+ a97;275B
222
+ a98;275C
223
+ a99;275D
224
+ a9;2720
225
+ #END
data/examples/arc.rb ADDED
@@ -0,0 +1,50 @@
1
+ # ## Arcs and Solid Arcs
2
+ #
3
+ # This example shows how to use the graphic objects `:arc` and `:solid_arc` to
4
+ # draw simple pie charts.
5
+ #
6
+ # Usage:
7
+ # : `ruby arc.rb`
8
+ #
9
+
10
+ require 'hexapdf'
11
+
12
+ doc = HexaPDF::Document.new
13
+ page = doc.pages.add_page
14
+ canvas = page.canvas
15
+
16
+ radius = 75
17
+
18
+ # Left pie chart
19
+ center = [page.box.width * 0.25, page.box.height * 0.85]
20
+ pie = canvas.graphic_object(:solid_arc, cx: center[0], cy: center[1],
21
+ outer_a: radius, outer_b: radius)
22
+ canvas.fill_color('ddddff')
23
+ canvas.draw(pie, start_angle: 30, end_angle: 110).fill
24
+ canvas.fill_color('ffdddd')
25
+ canvas.draw(pie, start_angle: 110, end_angle: 130).fill
26
+ canvas.fill_color('ddffdd')
27
+ canvas.draw(pie, start_angle: 130, end_angle: 30).fill
28
+
29
+ arc = canvas.graphic_object(:arc, cx: center[0], cy: center[1],
30
+ a: radius, b: radius)
31
+ canvas.stroke_color('0000ff')
32
+ canvas.draw(arc, start_angle: 30, end_angle: 110).stroke
33
+ canvas.stroke_color('ff0000')
34
+ canvas.draw(arc, start_angle: 110, end_angle: 130).stroke
35
+ canvas.stroke_color('00ff00')
36
+ canvas.draw(arc, start_angle: 130, end_angle: 30).stroke
37
+
38
+ # Right pie chart
39
+ center = [page.box.width * 0.75, page.box.height * 0.85]
40
+ canvas.stroke_color('777777')
41
+ pie = canvas.graphic_object(:solid_arc, cx: center[0], cy: center[1],
42
+ outer_a: radius, outer_b: radius)
43
+ canvas.fill_color('ddddff')
44
+ canvas.draw(pie, start_angle: 30, end_angle: 110).fill_stroke
45
+ canvas.fill_color('ffdddd')
46
+ canvas.draw(pie, start_angle: 110, end_angle: 130).fill_stroke
47
+ canvas.fill_color('ddffdd')
48
+ canvas.draw(pie, start_angle: 130, end_angle: 30).fill_stroke
49
+
50
+ doc.write('arc.pdf', optimize: true)
@@ -0,0 +1,274 @@
1
+ # ## Graphics Primitives
2
+ #
3
+ # This example shows many of the operations that the canvas implementation
4
+ # allows.
5
+ #
6
+ # Note that the PDF canvas has its origin in the lower left corner of the page.
7
+ # This means the coordinate (100, 50) is 100 PDF points from the left side and
8
+ # 50 PDF points from the bottom. One PDF point is equal to 1/72 inch.
9
+ #
10
+ # Usage:
11
+ # : `ruby graphics.rb`
12
+ #
13
+
14
+ require 'hexapdf'
15
+
16
+ doc = HexaPDF::Document.new
17
+ page = doc.pages.add_page
18
+ canvas = page.canvas
19
+
20
+ # Draws the shape that is used to showcase the transformations in the given
21
+ # color.
22
+ def transformation_shape(canvas, *color)
23
+ canvas.stroke_color(*color)
24
+ canvas.polygon(0, 0, 0, 80, 30, 50, 60, 80, 60, 0, 30, 30)
25
+ canvas.line(-30, 0, 30, 0)
26
+ canvas.line(0, 30, 0, -30)
27
+ canvas.stroke
28
+ end
29
+
30
+ # Basic transformations: translate, scale, rotate, skew
31
+ canvas.translate(0, 710) do
32
+ normal_color = [0.7, 0.7, 0.3]
33
+ transformed_color = [0.3, 0.7, 0.7]
34
+
35
+ canvas.translate(50, 0) do
36
+ transformation_shape(canvas, normal_color)
37
+ canvas.translate(40, 40) { transformation_shape(canvas, transformed_color) }
38
+ end
39
+
40
+ canvas.translate(180, 0) do
41
+ transformation_shape(canvas, normal_color)
42
+ canvas.scale(1.7, 1.3) { transformation_shape(canvas, transformed_color) }
43
+ end
44
+
45
+ canvas.translate(330, 0) do
46
+ transformation_shape(canvas, normal_color)
47
+ canvas.rotate(30) { transformation_shape(canvas, transformed_color) }
48
+ end
49
+
50
+ canvas.translate(430, 0) do
51
+ transformation_shape(canvas, normal_color)
52
+ canvas.skew(15, 30) { transformation_shape(canvas, transformed_color) }
53
+ end
54
+ end
55
+
56
+ # Draws a thin white line over a thick black line.
57
+ def dual_lines(canvas)
58
+ canvas.stroke_color(0)
59
+ canvas.line_width = 15
60
+ yield
61
+ canvas.stroke
62
+ canvas.stroke_color(1.0)
63
+ canvas.line_width = 1
64
+ yield
65
+ canvas.stroke
66
+ end
67
+
68
+ # Graphics state: line width, line cap style, line join style, miter limit,
69
+ # line dash pattern
70
+ canvas.translate(0, 550) do
71
+ canvas.translate(50, 0) do
72
+ [1, 5, 10, 15].each_with_index do |i, index|
73
+ canvas.stroke_color(0)
74
+ canvas.line_width(i)
75
+ canvas.line(20 * index, 0, 20 * index, 100)
76
+ canvas.stroke
77
+ end
78
+ end
79
+
80
+ canvas.translate(150, 0) do
81
+ 0.upto(2) do |i|
82
+ canvas.line_cap_style = i
83
+ dual_lines(canvas) { canvas.line(20 * i, 0, 20 * i, 100) }
84
+ end
85
+ end
86
+
87
+ canvas.translate(230, 0) do
88
+ 0.upto(2) do |i|
89
+ canvas.line_join_style = i
90
+ dual_lines(canvas) { canvas.polyline(0, 30 * i, 40, 50 + 30 * i, 80, 30 * i) }
91
+ end
92
+ end
93
+
94
+ canvas.translate(350, 0) do
95
+ canvas.line_join_style = :miter
96
+ canvas.miter_limit = 1
97
+ dual_lines(canvas) { canvas.polyline(0, 0, 20, 80, 40, 0) }
98
+ canvas.miter_limit = 10
99
+ dual_lines(canvas) { canvas.polyline(60, 0, 80, 80, 100, 0) }
100
+ end
101
+
102
+ canvas.translate(490, 0) do
103
+ canvas.line_width(1)
104
+ [[[1, 1]],
105
+ [[3, 1]],
106
+ [[3, 3]],
107
+ [[5, 1, 1, 1, 1, 1]],
108
+ [[3, 5], 6]].each_with_index do |(value, phase), index|
109
+ canvas.line_dash_pattern(value, phase || 0)
110
+ canvas.line(20 * index, 0, 20 * index, 100)
111
+ canvas.stroke
112
+ end
113
+ end
114
+ end
115
+
116
+ # Basic shapes: line, polyline, (rounded) rectangle, (rounded) polygon, circle, ellipse
117
+ canvas.translate(0, 420) do
118
+ canvas.line(50, 0, 50, 100)
119
+ canvas.polyline(80, 0, 80, 20, 70, 30, 90, 40, 70, 50, 90, 60, 70, 70, 80, 80, 80, 100)
120
+ canvas.rectangle(110, 0, 50, 100)
121
+ canvas.rectangle(180, 0, 50, 100, radius: 20)
122
+ canvas.polygon(250, 0, 250, 100, 280, 70, 310, 100, 310, 0, 280, 30)
123
+ canvas.polygon(330, 0, 330, 100, 360, 70, 390, 100, 390, 0, 360, 30, radius: 20)
124
+ canvas.circle(440, 50, 30)
125
+ canvas.ellipse(520, 50, a: 30, b: 15, inclination: 45)
126
+ canvas.stroke
127
+ end
128
+
129
+ # Various arcs w/wo filling, using the Canvas#arc method as well as directly
130
+ # working with the arc objects
131
+ canvas.translate(0, 320) do
132
+ canvas.arc(50, 50, a: 10, start_angle: -60, end_angle: 115)
133
+ canvas.arc(100, 50, a: 40, b: 20, start_angle: -60, end_angle: 115)
134
+ canvas.arc(180, 50, a: 40, b: 20, start_angle: -60, end_angle: 115, inclination: 45)
135
+ canvas.stroke
136
+
137
+ canvas.fill_color(0.4, 0.3, 0.4)
138
+ canvas.arc(250, 50, a: 10, start_angle: -60, end_angle: 115)
139
+ canvas.arc(300, 50, a: 40, b: 20, start_angle: -60, end_angle: 115)
140
+ canvas.arc(380, 50, a: 40, b: 20, start_angle: -60, end_angle: 115, inclination: 45)
141
+ canvas.fill
142
+
143
+ arc = canvas.graphic_object(:arc, cx: 450, cy: 50, a: 30, b: 30,
144
+ start_angle: -30, end_angle: 105)
145
+ canvas.fill_color(0.4, 0.3, 0.4)
146
+ canvas.move_to(450, 50)
147
+ canvas.line_to(*arc.start_point)
148
+ arc.curves.each {|c| canvas.curve_to(*c)}
149
+ canvas.fill
150
+ arc.configure(start_angle: 105, end_angle: -30)
151
+ canvas.fill_color(0.3, 0.7, 0.7)
152
+ canvas.move_to(450, 50)
153
+ canvas.line_to(*arc.start_point)
154
+ arc.curves.each {|c| canvas.curve_to(*c)}
155
+ canvas.fill
156
+
157
+ arc = canvas.graphic_object(:arc, cx: 530, cy: 50, a: 40, b: 20,
158
+ start_angle: -30, end_angle: 105)
159
+ canvas.fill_color(0.4, 0.3, 0.4)
160
+ canvas.move_to(530, 50)
161
+ canvas.line_to(*arc.start_point)
162
+ arc.curves.each {|c| canvas.curve_to(*c)}
163
+ canvas.fill
164
+ arc.configure(start_angle: 105, end_angle: -30)
165
+ canvas.fill_color(0.7, 0.7, 0.3)
166
+ canvas.move_to(530, 50)
167
+ canvas.line_to(*arc.start_point)
168
+ arc.curves.each {|c| canvas.curve_to(*c)}
169
+ canvas.fill
170
+ end
171
+
172
+ # Draws a circle and two half circles inside with different directions.
173
+ def shapes_to_paint(canvas)
174
+ canvas.line_width = 2
175
+ canvas.arc(50, 50, a: 50)
176
+ canvas.arc(50, 60, a: 25, end_angle: 180, clockwise: false)
177
+ canvas.arc(50, 40, a: 25, end_angle: 180, clockwise: true)
178
+ end
179
+
180
+ # Draws arrows showing the direction of the #shapes_to_paint
181
+ def arrows(canvas)
182
+ canvas.line_width = 1
183
+ canvas.polyline(95, 45, 100, 50, 105, 45)
184
+ canvas.polyline(55, 105, 50, 100, 55, 95)
185
+ canvas.polyline(-5, 55, 0, 50, 5, 55)
186
+ canvas.polyline(45, 5, 50, 0, 45, -5)
187
+ canvas.polyline(55, 90, 50, 85, 55, 80)
188
+ canvas.polyline(55, 20, 50, 15, 55, 10)
189
+ canvas.stroke
190
+ end
191
+
192
+ # Path painting and clipping operations: stroke, close and stroke, fill nonzero,
193
+ # fill even-odd, fill nonzero and stroke, fill even-odd and stroke, close and
194
+ # fill nonzero and stroke, close fill even-odd and stroke, clip even-odd, clip
195
+ # nonzero
196
+ canvas.translate(0, 190) do
197
+ canvas.fill_color(0.3, 0.7, 0.7)
198
+
199
+ [[:stroke], [:close_stroke], [:fill, :nonzero], [:fill, :even_odd],
200
+ [:fill_stroke, :nonzero], [:fill_stroke, :even_odd],
201
+ [:close_fill_stroke, :nonzero], [:close_fill_stroke, :even_odd],
202
+ ].each_with_index do |op, index|
203
+ row = (1 - (index / 4))
204
+ column = index % 4
205
+ x = 50 + 80 * column
206
+ y = 80 * row
207
+ canvas.transform(0.6, 0, 0, 0.6, x, y) do
208
+ shapes_to_paint(canvas)
209
+ canvas.send(*op)
210
+ arrows(canvas)
211
+ end
212
+ end
213
+
214
+ canvas.fill_color(0.7, 0.7, 0.3)
215
+
216
+ [:even_odd, :nonzero].each_with_index do |op, index|
217
+ canvas.translate(370 + 110 * index, 20) do
218
+ canvas.circle(50, 50, 50)
219
+ canvas.circle(50, 50, 20)
220
+ canvas.clip_path(op)
221
+ canvas.end_path
222
+ canvas.rectangle(0, 0, 100, 100, radius: 100)
223
+ canvas.fill_stroke
224
+ end
225
+ end
226
+ end
227
+
228
+ # Some composite shapes, an image and a form XObject
229
+ canvas.translate(0, 80) do
230
+ canvas.fill_color(0.3, 0.7, 0.7)
231
+ canvas.rectangle(50, 0, 80, 80, radius: 80)
232
+ canvas.fill
233
+
234
+ solid = canvas.graphic_object(:solid_arc, cx: 190, cy: 40, inner_a: 20, inner_b: 15,
235
+ outer_a: 40, outer_b: 30, start_angle: 10, end_angle: 130)
236
+
237
+ canvas.line_width(0.5)
238
+ canvas.opacity(fill_alpha: 0.5, stroke_alpha: 0.2) do
239
+ canvas.fill_color('AA8888').draw(solid).fill_stroke
240
+ canvas.fill_color('88AA88').draw(solid, start_angle: 130, end_angle: 220).fill_stroke
241
+ canvas.fill_color('8888AA').draw(solid, start_angle: 220, end_angle: 10).fill_stroke
242
+
243
+ solid.configure(inner_a: 0, inner_b: 0, outer_a: 40, outer_b: 40, cx: 290)
244
+ canvas.fill_color('AA8888').draw(solid, start_angle: 10, end_angle: 130).fill_stroke
245
+ canvas.fill_color('88AA88').draw(solid, start_angle: 130, end_angle: 220).fill_stroke
246
+ canvas.fill_color('8888AA').draw(solid, start_angle: 220, end_angle: 10).fill_stroke
247
+
248
+ canvas.image(File.join(__dir__, 'machupicchu.jpg'), at: [350, 0], height: 80)
249
+ end
250
+ end
251
+
252
+ # Reusing the already draw graphics for an XObject
253
+ # Note that converting the page to a form XObject automatically closes all open
254
+ # graphics states, therefore this can't be inside the above Canvas#translate
255
+ # call
256
+ form = doc.add(page.to_form_xobject(reference: false))
257
+ canvas.rectangle(480, 80, form.box.width * (100 / form.box.height.to_f), 100).stroke
258
+ canvas.xobject(form, at: [480, 80], height: 100)
259
+
260
+ # A simple rainbow color band
261
+ canvas.translate(0, 20) do
262
+ canvas.line_width = 10
263
+ freq = 0.3
264
+ 0.upto(50) do |i|
265
+ r = Math.sin(freq * i) * 127 + 128
266
+ g = Math.sin(freq * i + 2) * 127 + 128
267
+ b = Math.sin(freq * i + 4) * 127 + 128
268
+ canvas.stroke_color(r.to_i, g.to_i, b.to_i)
269
+ canvas.line(50 + i * 10, 0, 50 + i * 10, 40)
270
+ canvas.stroke
271
+ end
272
+ end
273
+
274
+ doc.write('graphics.pdf', optimize: true)
@@ -0,0 +1,16 @@
1
+ # ## Hello World
2
+ #
3
+ # This simple example mimics the classic "hello world" examples from
4
+ # programming languages.
5
+ #
6
+ # Usage:
7
+ # : `ruby hello_world.rb`
8
+ #
9
+
10
+ require 'hexapdf'
11
+
12
+ doc = HexaPDF::Document.new
13
+ canvas = doc.pages.add_page.canvas
14
+ canvas.font('Helvetica', size: 100)
15
+ canvas.text("Hello World!", at: [20, 400])
16
+ doc.write("hello_world.pdf", optimize: true)
Binary file
@@ -0,0 +1,24 @@
1
+ # ## Merging PDF Files
2
+ #
3
+ # Merging of PDF files can be done in various ways of sophistication.
4
+ #
5
+ # The easiest way, which this example shows, just imports the pages of
6
+ # the source files into the target file. This preserves the page
7
+ # contents themselves but nothing else.
8
+ #
9
+ # For example, named destinations are not properly handled by the code.
10
+ # Sometimes other things like attached files or a document outline
11
+ # should also be preserved.
12
+ #
13
+ # Usage:
14
+ # : `ruby merging.rb INPUT1.PDF INPUT2.PDF ...`
15
+ #
16
+
17
+ require 'hexapdf'
18
+
19
+ target = HexaPDF::Document.new
20
+ ARGV.each do |file|
21
+ pdf = HexaPDF::Document.open(file)
22
+ pdf.pages.each_page {|page| target.pages.add_page(target.import(page))}
23
+ end
24
+ target.write("merging.pdf", optimize: true)
@@ -0,0 +1,20 @@
1
+ # ## Optimizing a PDF File
2
+ #
3
+ # This example shows how to read a PDF file, optimize it and write it
4
+ # out again.
5
+ #
6
+ # The heavy work is done by the `:optimize` task which allows control
7
+ # over which aspects should be optimized. See [HexaPDF::Task::Optimize]
8
+ # for detailed information.
9
+ #
10
+ # Usage:
11
+ # : `ruby optimizing.rb INPUT.PDF`
12
+ #
13
+
14
+ require 'hexapdf'
15
+
16
+ HexaPDF::Document.open(ARGV.shift) do |doc|
17
+ doc.task(:optimize, compact: true, object_streams: :generate,
18
+ compress_pages: false)
19
+ doc.write('optimizing.pdf')
20
+ end
@@ -0,0 +1,55 @@
1
+ # ## Show Character Bounding Boxes
2
+ #
3
+ # This examples shows how to process the contents of a page. It finds all
4
+ # characters on a page and surrounds them with their bounding box. Additionally,
5
+ # all consecutive text runs are also surrounded by box.
6
+ #
7
+ # The code provides two ways of generating the boxes. The commented part of
8
+ # `ShowTextProcessor#show_text` uses a polyline since some characters may be
9
+ # transforemd (rotated or skewed). The un-commented part uses rectangles which
10
+ # is faster and correct in most cases.
11
+ #
12
+ # Usage:
13
+ # : `ruby show_char_boxes.rb INPUT.PDF`
14
+ #
15
+
16
+ require 'hexapdf'
17
+
18
+ class ShowTextProcessor < HexaPDF::Content::Processor
19
+
20
+ def initialize(page)
21
+ super()
22
+ @canvas = page.canvas(type: :overlay)
23
+ end
24
+
25
+ def show_text(str)
26
+ boxes = decode_text_with_positioning(str)
27
+ return if boxes.string.empty?
28
+
29
+ @canvas.line_width = 1
30
+ @canvas.stroke_color(224, 0, 0)
31
+ # Polyline for transformed characters
32
+ #boxes.each {|box| @canvas.polyline(*box.points).close_subpath.stroke}
33
+ # Using rectangles is faster but not 100% correct
34
+ boxes.each do |box|
35
+ x, y = *box.lower_left
36
+ tx, ty = *box.upper_right
37
+ @canvas.rectangle(x, y, tx - x, ty - y).stroke
38
+ end
39
+
40
+ @canvas.line_width = 0.5
41
+ @canvas.stroke_color(0, 224, 0)
42
+ @canvas.polyline(*boxes.lower_left, *boxes.lower_right,
43
+ *boxes.upper_right, *boxes.upper_left).close_subpath.stroke
44
+ end
45
+ alias :show_text_with_positioning :show_text
46
+
47
+ end
48
+
49
+ doc = HexaPDF::Document.open(ARGV.shift)
50
+ doc.pages.each_page.with_index do |page, index|
51
+ puts "Processing page #{index + 1}"
52
+ processor = ShowTextProcessor.new(page)
53
+ page.process_contents(processor)
54
+ end
55
+ doc.write('show_char_boxes.pdf', optimize: true)