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,60 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/ascii85_decode'
5
+
6
+ describe HexaPDF::Filter::ASCII85Decode do
7
+ include CommonFilterTests
8
+
9
+ before do
10
+ @obj = HexaPDF::Filter::ASCII85Decode
11
+ @all_test_cases ||= [['Nov shmoz ka pop.', ':2b:uF(fE/H6@!3+E27</c~>'],
12
+ ['Nov shmoz ka pop.1', ':2b:uF(fE/H6@!3+E27</hm~>'],
13
+ ['Nov shmoz ka pop.12', ':2b:uF(fE/H6@!3+E27</ho*~>'],
14
+ ['Nov shmoz ka pop.123', ':2b:uF(fE/H6@!3+E27</ho+;~>'],
15
+ ["\0\0\0\0Nov shmoz ka pop.", 'z:2b:uF(fE/H6@!3+E27</c~>'],
16
+ ["Nov \x0\x0\x0\x0shmoz ka pop.", ':2b:uzF(fE/H6@!3+E27</c~>'],
17
+ ]
18
+ @decoded = @all_test_cases[0][0]
19
+ @encoded = @all_test_cases[0][1]
20
+ end
21
+
22
+ describe "decoder" do
23
+ it "works with single byte input on specially crated input" do
24
+ assert_equal("Nov \0\0\0", collector(@obj.decoder(feeder(':2b:u!!!!~>', 1))))
25
+ end
26
+
27
+ it "ignores whitespace in the input" do
28
+ encoded = @encoded.dup.scan(/./).map {|a| "#{a} \r\t"}.join("\n")
29
+ assert_equal(@decoded, collector(@obj.decoder(feeder(encoded))))
30
+ end
31
+
32
+ it "works without the EOD marker" do
33
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded.sub(/~>/, '')))))
34
+ end
35
+
36
+ it "ignores data after the EOD marker" do
37
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded.dup + "~>abcdefg"))))
38
+ end
39
+
40
+ it "fails if the input contains invalid characters" do
41
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder(':2bwx!'))) }
42
+ end
43
+
44
+ it "fails if the input contains values outside the BASE85 range" do
45
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder('uuuuu'))) }
46
+ end
47
+
48
+ it "fails if the last rest contains a 'z' character" do
49
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder('uuz'))) }
50
+ end
51
+
52
+ it "fails if the last rest contains a '~' character" do
53
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder('uu~'))) }
54
+ end
55
+
56
+ it "fails if the last rest contains values outside the BASE85 range" do
57
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder('uuu>', 1))) }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/ascii_hex_decode'
5
+
6
+ describe HexaPDF::Filter::ASCIIHexDecode do
7
+ include CommonFilterTests
8
+
9
+ before do
10
+ @obj = HexaPDF::Filter::ASCIIHexDecode
11
+ @all_test_cases = [['Nov shmoz ka pop.', '4e6f762073686d6f7a206b6120706f702e>']]
12
+ @decoded = @all_test_cases[0][0]
13
+ @encoded = @all_test_cases[0][1]
14
+ end
15
+
16
+ describe "decoder" do
17
+ it "ignores whitespace in the input" do
18
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded.scan(/./).map {|a| "#{a} \r\t"}.join("\n"), 1))))
19
+ end
20
+
21
+ it "works without the EOD marker" do
22
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded.chop, 5))))
23
+ end
24
+
25
+ it "ignores data after the EOD marker" do
26
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded + '4e6f7gzz'))))
27
+ end
28
+
29
+ it "fails on invalid characters" do
30
+ assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder('f0f0z')).resume }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/encryption'
5
+
6
+ describe HexaPDF::Filter::Encryption do
7
+ before do
8
+ @obj = HexaPDF::Filter::Encryption
9
+ end
10
+
11
+ it "returns the correct decryption fiber" do
12
+ algorithm = Minitest::Mock.new
13
+ algorithm.expect(:decryption_fiber, :fiber, [:key, :source])
14
+ assert_equal(:fiber, @obj.decoder(:source, key: :key, algorithm: algorithm))
15
+ algorithm.verify
16
+ end
17
+
18
+ it "returns the correct encryption fiber" do
19
+ algorithm = Minitest::Mock.new
20
+ algorithm.expect(:encryption_fiber, :fiber, [:key, :source])
21
+ assert_equal(:fiber, @obj.encoder(:source, key: :key, algorithm: algorithm))
22
+ algorithm.verify
23
+ end
24
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/flate_decode'
5
+
6
+ describe HexaPDF::Filter::FlateDecode do
7
+ include CommonFilterTests
8
+
9
+ before do
10
+ @obj = HexaPDF::Filter::FlateDecode
11
+ @all_test_cases = [["abcdefg".force_encoding(Encoding::BINARY),
12
+ "x\xDAKLJNIMK\a\x00\n\xDB\x02\xBD".force_encoding(Encoding::BINARY)]]
13
+ @decoded = @all_test_cases[0][0]
14
+ @encoded = @all_test_cases[0][1]
15
+ @encoded_predictor = "x\xDAcJdbD@\x00\x05\x8F\x00v".force_encoding(Encoding::BINARY)
16
+ @predictor_opts = {Predictor: 12}
17
+ end
18
+
19
+ describe "decoder" do
20
+ it "applies the Predictor after decoding" do
21
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor.dup), @predictor_opts)))
22
+ end
23
+
24
+ it "fails on invalid input" do
25
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder("some test"))) }
26
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(Fiber.new {})) }
27
+ end
28
+ end
29
+
30
+ describe "encoder" do
31
+ it "applies the Predictor before encoding" do
32
+ assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded.dup), @predictor_opts)))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,52 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/lzw_decode'
5
+
6
+ describe HexaPDF::Filter::LZWDecode do
7
+ include CommonFilterTests
8
+
9
+ before do
10
+ @obj = HexaPDF::Filter::LZWDecode
11
+ @all_test_cases ||= [["-----A---B", "\x80\x0b\x60\x50\x22\x0c\x0c\x85\x01"],
12
+ ['abcabcaaaabbbcdeffffffagggggg', "\x80\x18LF8\x14\x10\xC3\a1BLfC)\x9A\x1D\x0F0\x99\xE2Q8\b"],
13
+ ].each {|a, b| a.force_encoding(Encoding::BINARY); b.force_encoding(Encoding::BINARY)}
14
+ @decoded = @all_test_cases[0][0]
15
+ @encoded = @all_test_cases[0][1]
16
+ @encoded_predictor = "\x80\x00\x85\xA0 \x04\x12\r\x05\n\x00\x9D\x90p\x10V\x02".force_encoding(Encoding::BINARY)
17
+ @predictor_opts = {Predictor: 12}
18
+ end
19
+
20
+ describe "decoder" do
21
+ it "applies the Predictor after decoding" do
22
+ assert_equal(@decoded, collector(@obj.decoder(feeder(@encoded_predictor.dup), @predictor_opts)))
23
+ end
24
+
25
+ it "fails if an unknown code is found after CLEAR_TABLE" do
26
+ assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder("\xff\xff")).resume }
27
+ end
28
+
29
+ it "fails if an unknown code is found elsewhere" do
30
+ assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder("\x00\x7f\xff\xf0")).resume }
31
+ end
32
+
33
+ it "fails if the code size would be more than 12bit" do
34
+ stream = HexaPDF::Utils::BitStreamWriter.new
35
+ result = stream.write(256, 9)
36
+ result << stream.write(65, 9)
37
+ 258.upto(510) {|i| result << stream.write(i, 9)}
38
+ 511.upto(1022) {|i| result << stream.write(i, 10)}
39
+ 1023.upto(2046) {|i| result << stream.write(i, 11)}
40
+ 2047.upto(4095) {|i| result << stream.write(i, 12)}
41
+ result << stream.write(96, 12)
42
+ result << stream.finalize
43
+ assert_raises(HexaPDF::FilterError) { @obj.decoder(feeder(result)).resume }
44
+ end
45
+ end
46
+
47
+ describe "encoder" do
48
+ it "applies the Predictor before encoding" do
49
+ assert_equal(@encoded_predictor, collector(@obj.encoder(feeder(@decoded.dup), @predictor_opts)))
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,183 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/predictor'
5
+
6
+ describe HexaPDF::Filter::Predictor do
7
+ include TestHelper
8
+
9
+ module CommonPredictorTests
10
+ def test_decoding_through_decoder_method
11
+ @testcases.each do |name, data|
12
+ assert_equal(data[:source], collector(@obj.decoder(feeder(data[:result].dup), data)), "test case: #{name}")
13
+ end
14
+ end
15
+
16
+ def test_encoding_through_encoder_method
17
+ @testcases.each do |name, data|
18
+ assert_equal(data[:result], collector(@obj.encoder(feeder(data[:source].dup), data)), "test case: #{name}")
19
+ end
20
+ end
21
+ end
22
+
23
+ before do
24
+ @obj = HexaPDF::Filter::Predictor
25
+ end
26
+
27
+ it "encoder fails on invalid Predictor value" do
28
+ data = {Predictor: 5}
29
+ assert_raises(HexaPDF::InvalidPDFObjectError) do
30
+ @obj.encoder(feeder("test"), data)
31
+ end
32
+ end
33
+
34
+ describe "png predictor" do
35
+ include CommonPredictorTests
36
+
37
+ before do
38
+ @testcases = {
39
+ 'none' => {
40
+ source: [110, 96].pack('C*'),
41
+ result: [0, 110, 96].pack('C*'),
42
+ Predictor: 10,
43
+ Colors: 1,
44
+ BitsPerComponent: 1,
45
+ Columns: 14,
46
+ },
47
+ 'sub' => {
48
+ source: [10, 20, 30, 40, 50, 10, 20, 30, 40, 50].pack('C*'),
49
+ result: [1, 10, 10, 10, 10, 10, 1, 10, 10, 10, 10, 10].pack('C*'),
50
+ Predictor: 11,
51
+ Colors: 2,
52
+ BitsPerComponent: 2,
53
+ Columns: 9,
54
+ },
55
+ 'up' => {
56
+ source: [10, 20, 30, 40, 50, 20, 30, 40, 50, 60].pack('C*'),
57
+ result: [2, 10, 20, 30, 40, 50, 2, 10, 10, 10, 10, 10].pack('C*'),
58
+ Predictor: 12,
59
+ Colors: 3,
60
+ BitsPerComponent: 4,
61
+ Columns: 3,
62
+ },
63
+ 'average' => {
64
+ source: [10, 20, 30, 40, 50, 60, 70, 80, 20, 30, 40, 50, 60, 70, 80, 90].pack('C*'),
65
+ result: [3, 10, 20, 25, 30, 35, 40, 45, 50, 3, 15, 20, 15, 15, 15, 15, 15, 15].pack('C*'),
66
+ Predictor: 13,
67
+ Colors: 4,
68
+ BitsPerComponent: 4,
69
+ Columns: 4,
70
+ },
71
+ 'paeth' => {
72
+ source: [10, 20, 30, 40, 50, 60, 70, 80, 20, 30, 40, 50, 60, 70, 80, 90].pack('C*'),
73
+ result: [4, 10, 20, 20, 20, 20, 20, 20, 20, 4, 10, 10, 10, 10, 10, 10, 10, 10].pack('C*'),
74
+ Predictor: 15,
75
+ Colors: 4,
76
+ BitsPerComponent: 4,
77
+ Columns: 4,
78
+ },
79
+ }
80
+ end
81
+
82
+ describe "encoder" do
83
+ it "works correctly" do
84
+ @testcases.each do |name, data|
85
+ encoder = @obj.png_execute(:encoder, feeder(data[:source].dup), data[:Predictor],
86
+ data[:Colors], data[:BitsPerComponent], data[:Columns])
87
+ assert_equal(data[:result], collector(encoder), "testcase #{name}")
88
+ end
89
+ end
90
+
91
+ it "fails if data is missing" do
92
+ assert_raises(HexaPDF::FilterError) do
93
+ data = @testcases['up']
94
+ encoder = @obj.png_execute(:encoder, feeder(data[:source][0..-2], 1), data[:Predictor],
95
+ data[:Colors], data[:BitsPerComponent], data[:Columns])
96
+ collector(encoder)
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "decoder" do
102
+ it "works correctly" do
103
+ @testcases.each do |name, data|
104
+ encoder = @obj.png_execute(:decoder, feeder(data[:result].dup), data[:Predictor],
105
+ data[:Colors], data[:BitsPerComponent], data[:Columns])
106
+ assert_equal(data[:source], collector(encoder), "testcase #{name}")
107
+ end
108
+ end
109
+
110
+ it "fails if data is missing" do
111
+ assert_raises(HexaPDF::FilterError) do
112
+ data = @testcases['up']
113
+ encoder = @obj.png_execute(:decoder, feeder(data[:result][0..-2], 1), data[:Predictor], data[:Colors],
114
+ data[:BitsPerComponent], data[:Columns])
115
+ collector(encoder)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "tiff predictor" do
122
+ include CommonPredictorTests
123
+
124
+ before do
125
+ @testcases = {
126
+ 'simple' => {
127
+ source: [0b10101010, 0b11111100].pack('C*'),
128
+ result: [0b11111111, 0b10000000].pack('C*'),
129
+ Predictor: 2,
130
+ Colors: 1,
131
+ BitsPerComponent: 1,
132
+ Columns: 14,
133
+ },
134
+ 'complex' => {
135
+ source: [0b10101010, 0b11110000, 0b10010100, 0b11010000].pack('C*'),
136
+ result: [0b10101000, 0b01010000, 0b10010110, 0b10000000].pack('C*'),
137
+ Predictor: 2,
138
+ Colors: 3,
139
+ BitsPerComponent: 2,
140
+ Columns: 2,
141
+ },
142
+ }
143
+ end
144
+
145
+ describe "encoder" do
146
+ it "works correctly" do
147
+ @testcases.each do |name, data|
148
+ encoder = @obj.tiff_execute(:encoder, feeder(data[:source].dup), data[:Colors],
149
+ data[:BitsPerComponent], data[:Columns])
150
+ assert_equal(data[:result], collector(encoder), "testcase #{name}")
151
+ end
152
+ end
153
+
154
+ it "fails if data is missing" do
155
+ assert_raises(HexaPDF::FilterError) do
156
+ data = @testcases['simple']
157
+ encoder = @obj.tiff_execute(:encoder, feeder(data[:source][0..-2], 1), data[:Colors],
158
+ data[:BitsPerComponent], data[:Columns])
159
+ collector(encoder)
160
+ end
161
+ end
162
+ end
163
+
164
+ describe "decoder" do
165
+ it "works correctly" do
166
+ @testcases.each do |name, data|
167
+ decoder = @obj.tiff_execute(:decoder, feeder(data[:result].dup), data[:Colors],
168
+ data[:BitsPerComponent], data[:Columns])
169
+ assert_equal(data[:source], collector(decoder), "testcase #{name}")
170
+ end
171
+ end
172
+
173
+ it "fails if data is missing" do
174
+ assert_raises(HexaPDF::FilterError) do
175
+ data = @testcases['simple']
176
+ decoder = @obj.tiff_execute(:decoder, feeder(data[:result][0..-2], 1), data[:Colors],
177
+ data[:BitsPerComponent], data[:Columns])
178
+ collector(decoder)
179
+ end
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require_relative 'common'
4
+ require 'hexapdf/filter/run_length_decode'
5
+
6
+ describe HexaPDF::Filter::RunLengthDecode do
7
+ include CommonFilterTests
8
+
9
+ before do
10
+ @obj = HexaPDF::Filter::RunLengthDecode
11
+ @all_test_cases ||= [['abcabcaaaabbbcdeffffffagggggg'.b,
12
+ "\x05abcabc\xFDa\xFEb\x02cde\xFBf\x00a\xFBg\x80".b]]
13
+ @decoded = @all_test_cases[0][0]
14
+ @encoded = @all_test_cases[0][1]
15
+ end
16
+
17
+ describe "decoder" do
18
+ it "fails if data is missing from the source stream" do
19
+ assert_raises(HexaPDF::FilterError) { collector(@obj.decoder(feeder(@encoded.chop.chop))) }
20
+ end
21
+ end
22
+
23
+ # Won't work because the encoding is dependent on the length of the data that is passed in
24
+ undef_method :test_encoder_works_with_single_byte_input
25
+
26
+ describe "encoder" do
27
+ it "works with single byte input" do
28
+ assert_equal(@encoded.chars.map {|a| "\0#{a}"}.join << "\x80".force_encoding(Encoding::BINARY),
29
+ collector(@obj.encoder(feeder(@encoded.dup, 1))))
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,67 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/cmap/parser'
5
+
6
+ describe HexaPDF::Font::CMap::Parser do
7
+ describe "::parse" do
8
+ it "parses CMap data correctly" do
9
+ data = <<EOF
10
+ /CIDInit /ProcSet findresource begin
11
+ 12 dict begin
12
+ begincmap
13
+ /CIDSystemInfo
14
+ << /Registry (Adobe)
15
+ /Ordering (UCS)
16
+ /Supplement 0
17
+ >> def
18
+ /CMapName /Adobe-Identity-UCS def
19
+ /CMapType 2 def
20
+ 1 begincodespacerange
21
+ <0000> <FFFF>
22
+ endcodespacerange
23
+ 2 beginbfrange
24
+ <0000> <005E> <0020>
25
+ <1379> <137B> <90FE>
26
+ <005F> <0061> [ <00660066> <00660069> <00660066006C> ]
27
+ endbfrange
28
+ 1 beginbfchar
29
+ <3A51> <D840DC3E>
30
+ endbfchar
31
+ endcmap
32
+ CMapName currentdict /CMap defineresource pop
33
+ end
34
+ end
35
+ EOF
36
+ cmap = HexaPDF::Font::CMap.parse(data)
37
+ assert_equal("Adobe", cmap.registry)
38
+ assert_equal("UCS", cmap.ordering)
39
+ assert_equal(0, cmap.supplement)
40
+ assert_equal("Adobe-Identity-UCS", cmap.name)
41
+ ((0x20.chr)..(0x7e.chr)).each_with_index do |str, index|
42
+ assert_equal(str, cmap.to_unicode(index))
43
+ end
44
+ assert_equal("\u{90FE}", cmap.to_unicode(0x13 * 256 + 0x79))
45
+ assert_equal("\u{90FF}", cmap.to_unicode(0x13 * 256 + 0x7A))
46
+ assert_equal("\u{9100}", cmap.to_unicode(0x13 * 256 + 0x7B))
47
+ assert_equal("ff", cmap.to_unicode(0x5F))
48
+ assert_equal("fi", cmap.to_unicode(0x60))
49
+ assert_equal("ffl", cmap.to_unicode(0x61))
50
+ assert_equal("\xD8\x40\xDC\x3E".encode("UTF-8", "UTF-16BE"),
51
+ cmap.to_unicode(0x3A * 256 + 0x51))
52
+ assert_equal("", cmap.to_unicode(0xFF))
53
+ end
54
+
55
+ it "fails if there is an invalid token inside the bfrange operator" do
56
+ assert_raises(HexaPDF::Error) do
57
+ HexaPDF::Font::CMap.parse("1 beginbfrange <0000> <0001> 5 endbfrange")
58
+ end
59
+ end
60
+
61
+ it "fails if the CMap is not correctly structured" do
62
+ assert_raises(HexaPDF::Error) do
63
+ HexaPDF::Font::CMap.parse("1 beginbfchar <0000> <0001>")
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,58 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/cmap/writer'
5
+
6
+ describe HexaPDF::Font::CMap::Writer do
7
+ before do
8
+ @cmap_data = <<EOF
9
+ /CIDInit /ProcSet findresource begin
10
+ 12 dict begin
11
+ begincmap
12
+ /CIDSystemInfo
13
+ << /Registry (Adobe)
14
+ /Ordering (UCS)
15
+ /Supplement 0
16
+ >> def
17
+ /CMapName /Adobe-Identity-UCS def
18
+ /CMapType 2 def
19
+ 1 begincodespacerange
20
+ <0000> <FFFF>
21
+ endcodespacerange
22
+ 2 beginbfchar
23
+ <0060><0090>
24
+ <3A51><d840dc3e>
25
+ endbfchar
26
+ 2 beginbfrange
27
+ <0000><005E><0020>
28
+ <1379><137B><90fe>
29
+ endbfrange
30
+ endcmap
31
+ CMapName currentdict /CMap defineresource pop
32
+ end
33
+ end
34
+ EOF
35
+ @mapping = []
36
+ 0x00.upto(0x5e) {|i| @mapping << [i, 0x20 + i]}
37
+ @mapping << [0x60, 0x90]
38
+ 0x1379.upto(0x137B) {|i| @mapping << [i, 0x90FE + i - 0x1379]}
39
+ @mapping << [0x3A51, 0x2003E]
40
+ end
41
+
42
+ describe "create_to_unicode_cmap" do
43
+ it "creates a correct CMap file" do
44
+ assert_equal(@cmap_data, HexaPDF::Font::CMap.create_to_unicode_cmap(@mapping))
45
+
46
+ # Test last item is a range
47
+ @mapping.pop
48
+ @cmap_data.sub!(/2 beginbfchar/, '1 beginbfchar')
49
+ @cmap_data.sub!(/<3A51><d840dc3e>\n/, '')
50
+ assert_equal(@cmap_data, HexaPDF::Font::CMap.create_to_unicode_cmap(@mapping))
51
+ end
52
+
53
+ it "returns an empty CMap if the mapping is empty" do
54
+ assert_equal(@cmap_data.sub(/\d+ beginbfchar.*endbfrange/m, ''),
55
+ HexaPDF::Font::CMap.create_to_unicode_cmap([]))
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/encoding/base'
5
+
6
+ describe HexaPDF::Font::Encoding::Base do
7
+ before do
8
+ @base = HexaPDF::Font::Encoding::Base.new
9
+ @base.code_to_name[65] = :A
10
+ end
11
+
12
+ it "returns nil for the encoding_name" do
13
+ assert_nil(@base.encoding_name)
14
+ end
15
+
16
+ describe "name" do
17
+ it "returns a mapped code" do
18
+ assert_equal(:A, @base.name(65))
19
+ end
20
+
21
+ it "returns .notdef for an unmapped code" do
22
+ assert_equal(:'.notdef', @base.name(66))
23
+ end
24
+ end
25
+
26
+ describe "unicode" do
27
+ it "returns the unicode value of the code" do
28
+ assert_equal("A", @base.unicode(65))
29
+ end
30
+
31
+ it "returns an empty string for an unmapped code" do
32
+ assert_equal('', @base.unicode(66))
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/encoding/difference_encoding'
5
+ require 'hexapdf/font/encoding/win_ansi_encoding'
6
+
7
+ describe HexaPDF::Font::Encoding::DifferenceEncoding do
8
+ before do
9
+ base = HexaPDF::Font::Encoding::WinAnsiEncoding.new
10
+ @enc = HexaPDF::Font::Encoding::DifferenceEncoding.new(base)
11
+ end
12
+
13
+ describe "name" do
14
+ it "takes the encoding differences into account" do
15
+ assert_equal(:A, @enc.name(65))
16
+ @enc.code_to_name[65] = :B
17
+ assert_equal(:B, @enc.name(65))
18
+ assert_equal(:B, @enc.name(66))
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/encoding/glyph_list'
5
+
6
+ describe HexaPDF::Font::Encoding::GlyphList do
7
+ before do
8
+ @list = HexaPDF::Font::Encoding::GlyphList.new
9
+ end
10
+
11
+ describe ".new" do
12
+ it "only ever creates one instance" do
13
+ assert_same(@list, HexaPDF::Font::Encoding::GlyphList.new)
14
+ end
15
+ end
16
+
17
+ describe "name_to_unicode" do
18
+ it "maps known glyph names to their unicode equivalent" do
19
+ assert_equal("A", @list.name_to_unicode(:A))
20
+ assert_equal("9", HexaPDF::Font::Encoding::GlyphList.name_to_unicode(:nine))
21
+ assert_equal("\u05da\u05b8", @list.name_to_unicode(:finalkafqamats))
22
+ end
23
+
24
+ it "maps special uniXXXX names to unicode values" do
25
+ assert_equal("A", @list.name_to_unicode(:uni0041))
26
+ assert_equal("\u1234", @list.name_to_unicode(:uni1234))
27
+ end
28
+
29
+ it "maps special uXXXX[XX] names to unicode values" do
30
+ assert_equal("A", @list.name_to_unicode(:u0041))
31
+ assert_equal("" << "1F000".hex, @list.name_to_unicode(:u1F000))
32
+ end
33
+
34
+ it "maps Zapf Dingbats glyph names to their unicode" do
35
+ assert_equal("A", @list.name_to_unicode(:A, zapf_dingbats: true))
36
+ assert_equal("\u275e", @list.name_to_unicode(:a100, zapf_dingbats: true))
37
+ end
38
+
39
+ it "returns an empty string for unknown glyph names" do
40
+ assert_equal('', @list.name_to_unicode(:MyUnknownGlyphName))
41
+ assert_equal('', @list.name_to_unicode(:a100))
42
+ end
43
+ end
44
+
45
+ describe "unicode_to_name" do
46
+ it "maps codepoints to names" do
47
+ assert_equal(:space, @list.unicode_to_name(" "))
48
+ assert_equal(:A, HexaPDF::Font::Encoding::GlyphList.unicode_to_name("A"))
49
+ assert_equal(:odieresis, @list.unicode_to_name("ö"))
50
+ assert_equal(:finalkafqamats, @list.unicode_to_name("\u05da\u05b8"))
51
+ assert_equal(:'.notdef', @list.unicode_to_name("ABCDEFG"))
52
+ end
53
+
54
+ it "maps Zapf Dingbats codepoints to names" do
55
+ assert_equal(:'.notdef', @list.unicode_to_name("\u2710"))
56
+ assert_equal(:a105, @list.unicode_to_name("\u2710", zapf_dingbats: true))
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,16 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/encoding/zapf_dingbats_encoding'
5
+
6
+ describe HexaPDF::Font::Encoding::ZapfDingbatsEncoding do
7
+ before do
8
+ @enc = HexaPDF::Font::Encoding::ZapfDingbatsEncoding.new
9
+ end
10
+
11
+ describe "unicode" do
12
+ it "uses the special ZapfDingbats glyph list" do
13
+ assert_equal("\u2721", @enc.unicode(65))
14
+ end
15
+ end
16
+ end