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,148 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'tempfile'
5
+ require 'stringio'
6
+ require 'hexapdf/type/file_specification'
7
+ require 'hexapdf/document'
8
+
9
+ describe HexaPDF::Type::FileSpecification::EFDictionary do
10
+ it "uses a custom type" do
11
+ obj = HexaPDF::Type::FileSpecification::EFDictionary.new({})
12
+ assert_equal(:XXFilespecEFDictionary, obj.type)
13
+ end
14
+ end
15
+
16
+ describe HexaPDF::Type::FileSpecification do
17
+ before do
18
+ @doc = HexaPDF::Document.new
19
+ @obj = HexaPDF::Type::FileSpecification.new({}, document: @doc)
20
+ end
21
+
22
+ it "can be asked whether it is a URL or a file" do
23
+ refute(@obj.url?)
24
+ @obj[:FS] = :URL
25
+ assert(@obj.url?)
26
+ end
27
+
28
+ describe "path" do
29
+ it "returns the first useable file spec string" do
30
+ @obj[:DOS] = 'hälo'.b
31
+ assert_equal('hälo'.b, @obj.path)
32
+
33
+ @obj[:UF] = 'hälo'
34
+ assert_equal('hälo', @obj.path)
35
+ end
36
+
37
+ it "unescapes the path string according to the PDF spec" do
38
+ @obj[:F] = "dir/in\\/out\\too"
39
+ assert_equal('dir/in/out/too', @obj.path)
40
+ end
41
+ end
42
+
43
+ describe "path=" do
44
+ it "only sets /UF and /F, deleting /Mac, /Unix, /DOS entries if they exist" do
45
+ @obj[:Unix] = @obj[:Mac] = @obj[:DOS] = 'a'
46
+ @obj.path = 'file/test'
47
+ assert_equal('file/test', @obj[:UF])
48
+ assert_equal('file/test', @obj[:F])
49
+ refute(@obj.key?(:Unix))
50
+ refute(@obj.key?(:Mac))
51
+ refute(@obj.key?(:DOS))
52
+ end
53
+
54
+ it 'resets the /FS value' do
55
+ @obj[:FS] = :Something
56
+ @obj.path = 'file'
57
+ refute(@obj.key?(:FS))
58
+ end
59
+ end
60
+
61
+ describe "url=" do
62
+ it "sets the path and the file system entry" do
63
+ url = 'http://example.com/some?test=ing#done'
64
+ @obj.url = url
65
+ assert_equal(url, @obj.path)
66
+ assert(@obj.url?)
67
+ end
68
+
69
+ it "fails if the provided string is not a valid URL" do
70
+ assert_raises(HexaPDF::Error) { @obj.url = "a false \\ URL" }
71
+ end
72
+ end
73
+
74
+ describe "embedded_file?" do
75
+ it "checks whether the specification has an embedded file" do
76
+ refute(@obj.embedded_file?)
77
+ @obj[:EF] = {UF: {}}
78
+ assert(@obj.embedded_file?)
79
+ end
80
+ end
81
+
82
+ describe "embedded_file_stream" do
83
+ it "returns the associated embedded file stream" do
84
+ assert_nil(@obj.embedded_file_stream)
85
+ @obj[:EF] = {F: 'data'}
86
+ assert_equal('data', @obj.embedded_file_stream)
87
+ end
88
+ end
89
+
90
+ describe "embed/unembed" do
91
+ before do
92
+ @file = Tempfile.new('file-embed-test')
93
+ @file.write("embed-test")
94
+ @file.close
95
+ end
96
+
97
+ after do
98
+ @file.unlink
99
+ end
100
+
101
+ it "requires the name argument when given an IO object" do
102
+ assert_raises(ArgumentError) { @obj.embed(StringIO.new) }
103
+ end
104
+
105
+ it "embeds the given file and registers it with the global name registry" do
106
+ stream = @obj.embed(@file.path)
107
+ assert_equal(stream, @obj[:EF][:UF])
108
+ assert_equal(stream, @obj[:EF][:F])
109
+ assert_equal(File.basename(@file.path), @obj.path)
110
+ assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry(@obj.path))
111
+ assert_equal(:FlateDecode, stream[:Filter])
112
+ assert_equal('embed-test', stream.stream)
113
+ end
114
+
115
+ it "embeds the given IO object" do
116
+ @file.open
117
+ stream = @obj.embed(@file, name: 'test')
118
+ assert_equal('embed-test', stream.stream)
119
+
120
+ stream = @obj.embed(StringIO.new('test'), name: 'test')
121
+ assert_equal('test', stream.stream)
122
+ end
123
+
124
+ it "allows overriding the name" do
125
+ @obj.embed(@file.path, name: 'test')
126
+ assert_equal('test', @obj.path)
127
+ assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry('test'))
128
+ end
129
+
130
+ it "doesn't register the embedded file if instructed to do so" do
131
+ @obj.embed(@file.path, name: 'test', register: false)
132
+ assert_nil(@doc.catalog[:Names])
133
+ end
134
+
135
+ it "replaces the value of an already registered name" do
136
+ (@doc.catalog[:Names] ||= {})[:EmbeddedFiles] = {}
137
+ @doc.catalog[:Names][:EmbeddedFiles].add_entry('test', 'data')
138
+ @obj.embed(@file.path, name: 'test')
139
+ assert_equal(@obj, @doc.catalog[:Names][:EmbeddedFiles].find_entry('test'))
140
+ end
141
+
142
+ it "unembeds an already embedded file before embedding the new one" do
143
+ @obj.embed(@file.path, name: 'test1')
144
+ @obj.embed(@file.path, name: 'test2')
145
+ assert_equal([['test2', @obj]], @doc.catalog[:Names][:EmbeddedFiles].each_entry.to_a)
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/font'
6
+
7
+ describe HexaPDF::Type::Font do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ cmap = @doc.add({}, stream: <<-EOF)
11
+ 2 beginbfchar
12
+ <20> <0041>
13
+ <22> <0042>
14
+ endbfchar
15
+ EOF
16
+ @font = @doc.add({Type: :Font, BaseFont: :TestFont, ToUnicode: cmap})
17
+ end
18
+
19
+ it "must always be an indirect" do
20
+ assert(@font.must_be_indirect?)
21
+ end
22
+
23
+ describe "to_utf" do
24
+ it "uses the /ToUnicode CMap if it is available" do
25
+ assert_equal("A", @font.to_utf8(32))
26
+ assert_equal("B", @font.to_utf8(34))
27
+ assert_equal("", @font.to_utf8(0))
28
+ end
29
+
30
+ it "returns an empty string if no /ToUnicode CMap is available" do
31
+ @font.delete(:ToUnicode)
32
+ assert_equal("", @font.to_utf8(32))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,51 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/font_descriptor'
6
+
7
+ describe HexaPDF::Type::FontDescriptor do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @font_desc = @doc.add(Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001, ItalicAngle: 10)
11
+ end
12
+
13
+ describe "flags" do
14
+ it "returns all flags" do
15
+ assert_equal([:fixed_pitch, :script, :italic], @font_desc.flags)
16
+ end
17
+ end
18
+
19
+ describe "flagged?" do
20
+ it "returns true if the given flag is set" do
21
+ assert(@font_desc.flagged?(:fixed_pitch))
22
+ refute(@font_desc.flagged?(:serif))
23
+ end
24
+
25
+ it "raises an error if an unknown flag name is provided" do
26
+ assert_raises(ArgumentError) { @font_desc.flagged?(:unknown) }
27
+ end
28
+ end
29
+
30
+ describe "flag" do
31
+ it "sets the given flag bits" do
32
+ @font_desc.flag(:serif)
33
+ assert_equal([:fixed_pitch, :serif, :script, :italic], @font_desc.flags)
34
+ @font_desc.flag(:symbolic, clear_existing: true)
35
+ assert_equal([:symbolic], @font_desc.flags)
36
+ end
37
+ end
38
+
39
+ describe "validation" do
40
+ it "fails if more than one of /FontFile{,2,3} are set" do
41
+ assert(@font_desc.validate {|*args| p args})
42
+ @font_desc[:FontFile] = @font_desc[:FontFile2] = @doc.add({}, stream: 'test')
43
+ refute(@font_desc.validate)
44
+ end
45
+
46
+ it "fails if /Descent is not a negative number" do
47
+ @font_desc[:Descent] = 5
48
+ refute(@font_desc.validate)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,190 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/font_simple'
6
+
7
+ describe HexaPDF::Type::FontSimple do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ cmap = @doc.add({}, stream: <<-EOF)
11
+ 2 beginbfchar
12
+ <20> <0041>
13
+ <22> <0042>
14
+ endbfchar
15
+ EOF
16
+ font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
+ Descent: -100, CapHeight: 800, StemV: 20)
19
+ @font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
20
+ BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
21
+ FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]
22
+ }, type: HexaPDF::Type::FontSimple)
23
+ end
24
+
25
+ describe "encoding" do
26
+ it "fails if /Encoding is absent because encoding_from_font is not implemented" do
27
+ @font.delete(:Encoding)
28
+ assert_raises(NotImplementedError) { @font.encoding }
29
+ end
30
+
31
+ describe "/Encoding is a name" do
32
+ it "returns a predefined encoding if /Encoding specifies one" do
33
+ assert_equal(HexaPDF::Font::Encoding.for_name(:WinAnsiEncoding), @font.encoding)
34
+ end
35
+
36
+ it "fails if /Encoding is an invalid name because encoding_from_font is not implemented" do
37
+ @font[:Encoding] = :SomethingUnknown
38
+ assert_raises(NotImplementedError) { @font.encoding }
39
+ end
40
+ end
41
+
42
+ describe "/Encoding is a dictionary" do
43
+ before do
44
+ @font[:Encoding] = {}
45
+ end
46
+
47
+ describe "no /BaseEncoding is specified" do
48
+ it "fails if the font is embedded because encoding_from_font is not implemented" do
49
+ @font[:FontDescriptor][:FontFile] = 5
50
+ assert_raises(NotImplementedError) { @font.encoding }
51
+ end
52
+
53
+ it "fails for a symbolic non-embedded font because encoding_from_font is not implemented" do
54
+ @font[:FontDescriptor].flag(:symbolic, clear_existing: true)
55
+ assert_raises(NotImplementedError) { @font.encoding }
56
+ end
57
+
58
+ it "returns the StandardEncoding for a non-symbolic non-embedded font" do
59
+ @font[:FontDescriptor].flag(clear_existing: true)
60
+ assert_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
61
+ end
62
+ end
63
+
64
+ it "returns the encoding specified by /BaseEncoding" do
65
+ @font[:Encoding] = {BaseEncoding: :WinAnsiEncoding}
66
+ assert_equal(HexaPDF::Font::Encoding.for_name(:WinAnsiEncoding), @font.encoding)
67
+ end
68
+
69
+ it "fails if /BaseEncoding is invalid because encoding_from_font is not implemented" do
70
+ @font[:Encoding] = {BaseEncoding: :SomethingUnknown}
71
+ assert_raises(NotImplementedError) { @font.encoding }
72
+ end
73
+
74
+ it "returns a difference encoding if /Differences is specified" do
75
+ @font[:FontDescriptor].flag(clear_existing: true)
76
+ @font[:Encoding][:Differences] = [32, :A, :B, 34, :Z]
77
+ refute_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
78
+ assert_equal(:A, @font.encoding.name(32))
79
+ assert_equal(:B, @font.encoding.name(33))
80
+ assert_equal(:Z, @font.encoding.name(34))
81
+ end
82
+
83
+ it "fails if the /Differences array contains invalid data" do
84
+ @font[:Encoding][:BaseEncoding] = :WinAnsiEncoding
85
+ @font[:Encoding][:Differences] = [:B, 32, :A, :B, 34, :Z]
86
+ assert_raises(HexaPDF::Error) { @font.encoding }
87
+
88
+ @font[:Encoding][:Differences] = [32, "data", :A, :B, 34, :Z]
89
+ assert_raises(HexaPDF::Error) { @font.encoding }
90
+ end
91
+ end
92
+
93
+ it "fails if /Encoding contains an invalid value" do
94
+ @font[:Encoding] = 5
95
+ assert_raises(HexaPDF::Error) { @font.encoding }
96
+ end
97
+ end
98
+
99
+ describe "decode" do
100
+ it "just returns the bytes of the string since this is a simple 1-byte-per-code font" do
101
+ assert_equal([65, 66], @font.decode("AB"))
102
+ end
103
+ end
104
+
105
+ describe "to_utf" do
106
+ it "uses a /ToUnicode CMap if it is available" do
107
+ assert_equal("A", @font.to_utf8(32))
108
+ end
109
+
110
+ it "uses the font's encoding to map the code to an UTF-8 string if the /ToUnicode is missing" do
111
+ @font.delete(:ToUnicode)
112
+ assert_equal(" ", @font.to_utf8(32))
113
+ end
114
+
115
+ it "returns an empty string if no correct mapping could be found" do
116
+ @font.delete(:ToUnicode)
117
+ assert_equal("", @font.to_utf8(0))
118
+ end
119
+ end
120
+
121
+ describe "writing_mode" do
122
+ it "is always horizontal" do
123
+ assert_equal(:horizontal, @font.writing_mode)
124
+ end
125
+ end
126
+
127
+ describe "width" do
128
+ it "returns the glyph width for a valid code point" do
129
+ assert_equal(600, @font.width(32))
130
+ end
131
+
132
+ it "returns the /MissingWidth of a /FontDescriptor if available and the width was not found" do
133
+ assert_equal(0, @font.width(0))
134
+ @font[:FontDescriptor][:MissingWidth] = 99
135
+ assert_equal(99, @font.width(0))
136
+ end
137
+
138
+ it "returns 0 for a missing code point when FontDescriptor is not available" do
139
+ @font.delete(:FontDescriptor)
140
+ assert_equal(0, @font.width(0))
141
+ end
142
+ end
143
+
144
+ describe "bounding_box" do
145
+ it "returns the bounding box" do
146
+ assert_equal([0, 1, 2, 3], @font.bounding_box)
147
+ end
148
+
149
+ it "returns nil if no bounding box information can be found" do
150
+ @font[:FontDescriptor].delete(:FontBBox)
151
+ assert_nil(@font.bounding_box)
152
+ end
153
+ end
154
+
155
+ describe "embedded" do
156
+ it "returns true if the font is embedded" do
157
+ refute(@font.embedded?)
158
+ @font[:FontDescriptor][:FontFile] = 5
159
+ assert(@font.embedded?)
160
+ end
161
+ end
162
+
163
+ describe "symbolic?" do
164
+ it "return true if the font is symbolic" do
165
+ @font[:FontDescriptor].flag(clear_existing: true)
166
+ refute(@font.symbolic?)
167
+
168
+ @font[:FontDescriptor].flag(:symbolic)
169
+ assert(@font.symbolic?)
170
+ end
171
+
172
+ it "returns nil if it cannot be determined whether the font is symbolic" do
173
+ @font.delete(:FontDescriptor)
174
+ assert_nil(@font.symbolic?)
175
+ end
176
+ end
177
+
178
+ describe "validation" do
179
+ it "validates the existence of required keys" do
180
+ assert(@font.validate)
181
+ @font.delete(:FirstChar)
182
+ refute(@font.validate)
183
+ end
184
+
185
+ it "validates the lengths of the /Widths field" do
186
+ @font[:Widths] = [65]
187
+ refute(@font.validate)
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,128 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/font_type1'
6
+
7
+ describe HexaPDF::Type::FontType1::StandardFonts do
8
+ before do
9
+ @obj = HexaPDF::Type::FontType1::StandardFonts
10
+ end
11
+
12
+ it "checks whether a given name corresponds to a standard font via #standard_font?" do
13
+ assert(@obj.standard_font?(:"Times-Roman"))
14
+ assert(@obj.standard_font?(:TimesNewRoman))
15
+ refute(@obj.standard_font?(:LibreSans))
16
+ end
17
+
18
+ it "returns the standard PDF name for an alias via #standard_name" do
19
+ assert_equal(:"Times-Roman", @obj.standard_name(:TimesNewRoman))
20
+ end
21
+
22
+ describe "font" do
23
+ it "returns the Type1 font object for a given standard name" do
24
+ font = @obj.font(:"Times-Roman")
25
+ assert_equal("Times Roman", font.full_name)
26
+ end
27
+
28
+ it "caches the font for reuse" do
29
+ font = @obj.font(:"Times-Roman")
30
+ assert_same(font, @obj.font(:"Times-Roman"))
31
+ end
32
+
33
+ it "returns nil if the given name doesn't belong to a standard font" do
34
+ refute_nil(@obj.font(:TimesNewRoman))
35
+ end
36
+ end
37
+ end
38
+
39
+ describe HexaPDF::Type::FontType1 do
40
+ before do
41
+ @doc = HexaPDF::Document.new
42
+ @font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
43
+ BaseFont: :"Times-Roman")
44
+
45
+ font_file = @doc.add({}, stream: <<-EOF)
46
+ /Encoding 256 array
47
+ 0 1 255 {1 index exch /.notdef put} for
48
+ dup 32 /A put
49
+ dup 34 /B put
50
+ readonly def
51
+ EOF
52
+ font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
53
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
54
+ Descent: -100, CapHeight: 800, StemV: 20, FontFile: font_file)
55
+ @embedded_font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
56
+ BaseFont: :Embedded, FontDescriptor: font_descriptor,
57
+ FirstChar: 32, LastChar: 34, Widths: [600, 0, 700])
58
+ end
59
+
60
+ describe "encoding" do
61
+ it "returns the the standard font's encoding" do
62
+ @font.delete(:Encoding)
63
+ assert_equal(HexaPDF::Font::Encoding.for_name(:StandardEncoding), @font.encoding)
64
+ end
65
+
66
+ it "uses the encoding of the embedded font when necessary" do
67
+ @embedded_font.delete(:Encoding)
68
+ assert_equal({32 => :A, 34 => :B}, @embedded_font.encoding.code_to_name)
69
+ end
70
+
71
+ it "fails if the encoding needs to be read from the font but is is not embedded" do
72
+ @embedded_font.delete(:Encoding)
73
+ @embedded_font[:FontDescriptor].delete(:FontFile)
74
+ assert_raises(HexaPDF::Error) { @embedded_font.encoding }
75
+ end
76
+ end
77
+
78
+ describe "width" do
79
+ it "returns the glyph width when using a standard font" do
80
+ assert_equal(250, @font.width(32))
81
+ end
82
+
83
+ it "defers to its superclass for all other cases" do
84
+ assert_equal(600, @embedded_font.width(32))
85
+ end
86
+ end
87
+
88
+ describe "bounding_box" do
89
+ it "returns the bounding box for a standard font" do
90
+ font = HexaPDF::Type::FontType1::StandardFonts.font(:"Times-Roman")
91
+ assert_equal(font.bounding_box, @font.bounding_box)
92
+ end
93
+
94
+ it "defers to its superclass for all other cases" do
95
+ assert_equal([0, 1, 2, 3], @embedded_font.bounding_box)
96
+ end
97
+
98
+ it "returns nil for non-standard fonts without bounding box information" do
99
+ @embedded_font[:FontDescriptor].delete(:FontBBox)
100
+ assert_nil(@embedded_font.bounding_box)
101
+ end
102
+ end
103
+
104
+ describe "symbolic?" do
105
+ it "return true for the standard fonts Symbol and ZapfDingbats" do
106
+ @font[:BaseFont] = :Symbol
107
+ assert(@font.symbolic?)
108
+
109
+ @font[:BaseFont] = :ZapfDingbats
110
+ assert(@font.symbolic?)
111
+ end
112
+
113
+ it "defers to its superclass for all other cases" do
114
+ assert(@embedded_font.symbolic?)
115
+ end
116
+
117
+ it "returns nil if it cannot be determined whether the font is symbolic" do
118
+ @embedded_font.delete(:FontDescriptor)
119
+ assert_nil(@embedded_font.symbolic?)
120
+ end
121
+ end
122
+
123
+ describe "validation" do
124
+ it "allows empty fields for standard fonts" do
125
+ assert(@font.validate)
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,60 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require_relative '../content/common'
5
+ require 'hexapdf/document'
6
+ require 'hexapdf/type/form'
7
+
8
+ describe HexaPDF::Type::Form do
9
+ before do
10
+ @doc = HexaPDF::Document.new
11
+ @form = @doc.wrap({}, subtype: :Form)
12
+ end
13
+
14
+ describe "box" do
15
+ it "returns the /BBox entry" do
16
+ @form[:BBox] = :media
17
+ assert_equal(:media, @form.box)
18
+ end
19
+ end
20
+
21
+ describe "contents" do
22
+ it "returns a duplicate of the stream" do
23
+ @form.stream = 'test'
24
+ assert_equal(@form.stream, @form.contents)
25
+ @form.contents.gsub!(/test/, 'other')
26
+ assert_equal(@form.stream, @form.contents)
27
+ end
28
+ end
29
+
30
+ describe "contents=" do
31
+ it "set the stream contents" do
32
+ @form.contents = 'test'
33
+ assert_equal('test', @form.stream)
34
+ end
35
+ end
36
+
37
+ describe "resources" do
38
+ it "creates the resource dictionary if it is not found" do
39
+ resources = @form.resources
40
+ assert_equal(:XXResources, resources.type)
41
+ assert_equal({}, resources.value)
42
+ end
43
+
44
+ it "returns the already used resource dictionary" do
45
+ @form[:Resources] = {Font: nil}
46
+ resources = @form.resources
47
+ assert_equal(:XXResources, resources.type)
48
+ assert_equal(@form[:Resources], resources)
49
+ end
50
+ end
51
+
52
+ describe "process_contents" do
53
+ it "parses the contents and processes it" do
54
+ @form.stream = '10 w'
55
+ processor = TestHelper::OperatorRecorder.new
56
+ @form.process_contents(processor)
57
+ assert_equal([[:set_line_width, [10]]], processor.recorded_ops)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+ require 'hexapdf/type/info'
3
+
4
+ describe HexaPDF::Type::Info do
5
+ it "must always be indirect" do
6
+ obj = HexaPDF::Type::Info.new({})
7
+ assert(obj.must_be_indirect?)
8
+ end
9
+
10
+ it "uses a custom type" do
11
+ obj = HexaPDF::Type::Info.new({})
12
+ assert_equal(:XXInfo, obj.type)
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+ require 'hexapdf/type/names'
3
+
4
+ describe HexaPDF::Type::Names do
5
+ it "uses a custom type" do
6
+ obj = HexaPDF::Type::Names.new({})
7
+ assert_equal(:XXNames, obj.type)
8
+ end
9
+ end