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,43 @@
1
+ %PDF-1.7
2
+ %����
3
+ 1 0 obj
4
+ << /Extensions << /ADBE << /BaseVersion /1.7 /ExtensionLevel 8 >> >> /Pages 3 0 R /Type /Catalog >>
5
+ endobj
6
+ 2 0 obj
7
+ << /ModDate <b96936934c92f6becc11a0c5fa22e8dd9bc6e03ddd57ef3bf97bea18282fdf47f060dc40e90a8ac1ddaf2c1211327a16> >>
8
+ endobj
9
+ 3 0 obj
10
+ << /Count 1 /Kids [ 4 0 R ] /MediaBox [ 0 0 612 446 ] /Type /Pages >>
11
+ endobj
12
+ 4 0 obj
13
+ << /Contents 5 0 R /Parent 3 0 R /Resources 6 0 R /Type /Page >>
14
+ endobj
15
+ 5 0 obj
16
+ << /Length 80 >>
17
+ stream
18
+ -�µi�#���yG��E����[�G�oE[z4k�_*_:z2�-m�"xт�^���5)G$�V:K�s&ۘAiE��ij�jWendstream
19
+ endobj
20
+ 6 0 obj
21
+ << /Font << /F1 7 0 R >> /ProcSet [ /PDF /Text ] >>
22
+ endobj
23
+ 7 0 obj
24
+ << /BaseFont /Helvetica /Name /F1 /Subtype /Type1 /Type /Font >>
25
+ endobj
26
+ 8 0 obj
27
+ << /CF << /StdCF << /AuthEvent /DocOpen /CFM /AESV3 /Length 32 >> >> /Filter /Standard /Length 256 /O <371f521e2a1d5e550454704e52b598897491ff515d37b82648cf5f8f067b2076f271e7c6415ad9cef7a2f2683999a984> /OE <8a33575bdaef7c0bdae19fa684f26f1cb257c4efa3f30dd19196383cfe52de1b> /P -4 /Perms <003a9be14d9b17bf018c4b8cdb74934f> /R 6 /StmF /StdCF /StrF /StdCF /U <f8ad231585ebecdd9f64b5975bf57d1c3a0298937c1870abb91b93d920cddd878909d17f739201d1a7cde787148521e7> /UE <53452d54254f6bbabf566b41dd9302ae3863021efeb6af13adc6d512768d9829> /V 5 >>
28
+ endobj
29
+ xref
30
+ 0 9
31
+ 0000000000 65535 f
32
+ 0000000015 00000 n
33
+ 0000000130 00000 n
34
+ 0000000259 00000 n
35
+ 0000000344 00000 n
36
+ 0000000424 00000 n
37
+ 0000000553 00000 n
38
+ 0000000620 00000 n
39
+ 0000000700 00000 n
40
+ trailer << /Info 2 0 R /Root 1 0 R /Size 9 /ID [<6790ffa610024e78369114311fc0df96><ebca00a8b6842be1f05f9356799522b4>] /Encrypt 8 0 R >>
41
+ startxref
42
+ 1247
43
+ %%EOF
@@ -0,0 +1,43 @@
1
+ %PDF-1.3
2
+ %����
3
+ 1 0 obj
4
+ << /Pages 3 0 R /Type /Catalog >>
5
+ endobj
6
+ 2 0 obj
7
+ << /ModDate <6a8f7aee72b95ba745f34cb4d716b1f9> >>
8
+ endobj
9
+ 3 0 obj
10
+ << /Count 1 /Kids [ 4 0 R ] /MediaBox [ 0 0 612 446 ] /Type /Pages >>
11
+ endobj
12
+ 4 0 obj
13
+ << /Contents 5 0 R /Parent 3 0 R /Resources 6 0 R /Type /Page >>
14
+ endobj
15
+ 5 0 obj
16
+ << /Length 51 >>
17
+ stream
18
+ ��<��.���:αu�g�>k|O,�.wq�د�m�qBZ{�I�~�y��endstream
19
+ endobj
20
+ 6 0 obj
21
+ << /Font << /F1 7 0 R >> /ProcSet [ /PDF /Text ] >>
22
+ endobj
23
+ 7 0 obj
24
+ << /BaseFont /Helvetica /Name /F1 /Subtype /Type1 /Type /Font >>
25
+ endobj
26
+ 8 0 obj
27
+ << /Filter /Standard /Length 40 /O <c94a371cecfd0749dece3d88358ef57d9c31b4312dcc0e8e6a30032b8fb0ab5b> /P -4 /R 2 /U <bf3574d85c47a8ae0f5e7f59d499a785944f96280b201f41ec92f6bf682dd20a> /V 1 >>
28
+ endobj
29
+ xref
30
+ 0 9
31
+ 0000000000 65535 f
32
+ 0000000015 00000 n
33
+ 0000000064 00000 n
34
+ 0000000129 00000 n
35
+ 0000000214 00000 n
36
+ 0000000294 00000 n
37
+ 0000000394 00000 n
38
+ 0000000461 00000 n
39
+ 0000000541 00000 n
40
+ trailer << /Info 2 0 R /Root 1 0 R /Size 9 /ID [<6790ffa610024e78369114311fc0df96><7fdb6c0379284bdb698f2c7884d09ff8>] /Encrypt 8 0 R >>
41
+ startxref
42
+ 747
43
+ %%EOF
@@ -0,0 +1,204 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+
5
+ module CommonTokenizerTests
6
+ extend Minitest::Spec::DSL
7
+
8
+ it "next_token: returns all available kinds of tokens on next_token" do
9
+ create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
10
+ % Regular tokens
11
+
12
+ true false
13
+ 123 +17 -98 0 0059
14
+ 34.5 -3.62 +123.6 4. -.002 .002 0.0
15
+
16
+ % Keywords
17
+ obj endobj f* *f
18
+
19
+ % Specials
20
+ { }
21
+
22
+ % Literal string tests
23
+ (parenthese\\s ( ) and \\(\r
24
+ special \\0053\\053\\53characters\r (*!&}^% and \\
25
+ so \\\r
26
+ on).\\n)
27
+ ()
28
+
29
+ % Hex strings
30
+ <4E6F762073 686D6F7A20 6B612070
31
+ 6F702E>
32
+ < 901FA3 ><901fA>
33
+
34
+ % Names
35
+ /Name1
36
+ /ASomewhatLongerName
37
+ /A;Name_With-Various***Characters?
38
+ /1.2/$$
39
+ /@pattern
40
+ /.notdef
41
+ /lime#20Green
42
+ /paired#28#29parentheses
43
+ /The_Key_of_F#23_Minor
44
+ /A#42
45
+ /
46
+
47
+ % Arrays
48
+ [ 5 6 /Name ]
49
+ [5 6 /Name]
50
+
51
+ % Dictionaries
52
+ <</Name 5>>
53
+
54
+ % Test
55
+ EOF
56
+
57
+ expected_tokens = [
58
+ true, false,
59
+ 123, 17, -98, 0, 59,
60
+ 34.5, -3.62, 123.6, 4.0, -0.002, 0.002, 0.0,
61
+ 'obj', 'endobj', 'f*', '*f', '{', '}',
62
+ "parentheses ( ) and (\nspecial \0053++characters\n (*!&}^% and so on).\n", '',
63
+ "Nov shmoz ka pop.", "\x90\x1F\xA3", "\x90\x1F\xA0",
64
+ :Name1, :ASomewhatLongerName, :"A;Name_With-Various***Characters?",
65
+ :"1.2", :"$$", :"@pattern", :".notdef", :"lime Green", :"paired()parentheses",
66
+ :"The_Key_of_F#_Minor", :AB, :"",
67
+ '[', 5, 6, :Name, ']', '[', 5, 6, :Name, ']',
68
+ '<<', :Name, 5, '>>'
69
+ ].each {|t| t.force_encoding('BINARY') if t.respond_to?(:force_encoding)}
70
+
71
+ while expected_tokens.length > 0
72
+ expected_token = expected_tokens.shift
73
+ token = @tokenizer.next_token
74
+ assert_equal(expected_token, token)
75
+ assert_equal(Encoding::BINARY, token.encoding) if token.kind_of?(String)
76
+ end
77
+ assert_equal(0, expected_tokens.length)
78
+ assert_equal(HexaPDF::Tokenizer::NO_MORE_TOKENS, @tokenizer.next_token)
79
+ end
80
+
81
+ it "next_token: should return name tokens in US-ASCII/UTF-8 or binary encoding" do
82
+ create_tokenizer("/ASomewhatLongerName")
83
+ token = @tokenizer.next_token
84
+ assert_equal(:ASomewhatLongerName, token)
85
+ assert_equal(Encoding::US_ASCII, token.encoding)
86
+
87
+ create_tokenizer("/Hößgang")
88
+ token = @tokenizer.next_token
89
+ assert_equal(:"Hößgang", token)
90
+ assert_equal(Encoding::UTF_8, token.encoding)
91
+
92
+ create_tokenizer('/H#c3#b6#c3#9fgang')
93
+ token = @tokenizer.next_token
94
+ assert_equal(:"Hößgang", token)
95
+ assert_equal(Encoding::UTF_8, token.encoding)
96
+
97
+ create_tokenizer('/H#E8lp')
98
+ token = @tokenizer.next_token
99
+ assert_equal("H\xE8lp".b.intern, token)
100
+ assert_equal(Encoding::BINARY, token.encoding)
101
+ end
102
+
103
+ it "next_token: fails on a greater than sign that is not part of a hex string" do
104
+ create_tokenizer(" >")
105
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_token }
106
+ end
107
+
108
+ it "next_token: fails on a missing greater than sign in a hex string" do
109
+ create_tokenizer("<ABCD")
110
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_token }
111
+ end
112
+
113
+ it "next_token: fails on unbalanced parentheses in a literal string" do
114
+ create_tokenizer("(href(test)")
115
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_token }
116
+ end
117
+
118
+ it "next_object: works for all PDF object types, including array and dictionary" do
119
+ create_tokenizer(<<-EOF.chomp.gsub(/^ {8}/, ''))
120
+ true false null 123 34.5 (string) <4E6F76> /Name
121
+ [5 6 /Name] <</Name 5>>
122
+ EOF
123
+ assert_equal(true, @tokenizer.next_object)
124
+ assert_equal(false, @tokenizer.next_object)
125
+ assert_nil(@tokenizer.next_object)
126
+ assert_equal(123, @tokenizer.next_object)
127
+ assert_equal(34.5, @tokenizer.next_object)
128
+ assert_equal("string".b, @tokenizer.next_object)
129
+ assert_equal("Nov".b, @tokenizer.next_object)
130
+ assert_equal(:Name, @tokenizer.next_object)
131
+ assert_equal([5, 6, :Name], @tokenizer.next_object)
132
+ assert_equal({Name: 5}, @tokenizer.next_object)
133
+ end
134
+
135
+ it "next_object: allows keywords if the corresponding option is set" do
136
+ create_tokenizer("name")
137
+ obj = @tokenizer.next_object(allow_keyword: true)
138
+ assert_kind_of(HexaPDF::Tokenizer::Token, obj)
139
+ assert_equal('name', obj)
140
+ end
141
+
142
+ it "next_object: fails if the value is not a correct object" do
143
+ create_tokenizer("<< /name ] >>")
144
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
145
+ create_tokenizer("other")
146
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
147
+ create_tokenizer("<< (string) (key) >>")
148
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
149
+ create_tokenizer("<< /NoValueForKey >>")
150
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
151
+ end
152
+
153
+ it "returns the correct position on operations" do
154
+ create_tokenizer("hallo du" + " " * 50000 + "hallo du")
155
+ @tokenizer.next_token
156
+ assert_equal(5, @tokenizer.pos)
157
+
158
+ @tokenizer.skip_whitespace
159
+ assert_equal(6, @tokenizer.pos)
160
+
161
+ @tokenizer.next_byte
162
+ assert_equal(7, @tokenizer.pos)
163
+
164
+ @tokenizer.peek_token
165
+ assert_equal(7, @tokenizer.pos)
166
+
167
+ @tokenizer.next_token
168
+ assert_equal(8, @tokenizer.pos)
169
+
170
+ @tokenizer.next_token
171
+ assert_equal(50013, @tokenizer.pos)
172
+
173
+ @tokenizer.next_token
174
+ assert_equal(50016, @tokenizer.pos)
175
+
176
+ @tokenizer.next_token
177
+ assert_equal(50016, @tokenizer.pos)
178
+ end
179
+
180
+ it "returns the next byte" do
181
+ create_tokenizer('hallo')
182
+ assert_equal('h'.ord, @tokenizer.next_byte)
183
+ assert_equal('a'.ord, @tokenizer.next_byte)
184
+ end
185
+
186
+ it "returns the next token but doesn't advance the position on peek_token" do
187
+ create_tokenizer("hallo du")
188
+ 2.times do
189
+ assert_equal('hallo', @tokenizer.peek_token)
190
+ assert_equal(0, @tokenizer.pos)
191
+ end
192
+ end
193
+
194
+ it "next_xref_entry: works on correct entries" do
195
+ create_tokenizer("0000000001 00001 n \n0000000001 00032 f \n")
196
+ assert_equal([1, 1, 'n'], @tokenizer.next_xref_entry)
197
+ assert_equal([1, 32, 'f'], @tokenizer.next_xref_entry)
198
+ end
199
+
200
+ it "next_xref_entry: fails on invalidly formatted entries" do
201
+ create_tokenizer("0000000001 00001 g \n")
202
+ assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_xref_entry }
203
+ end
204
+ end
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/content/processor'
5
+
6
+ module TestHelper
7
+
8
+ # Can be used to to record operators parsed from content streams.
9
+ class OperatorRecorder < HexaPDF::Content::Processor
10
+
11
+ undef :paint_xobject
12
+
13
+ attr_reader :recorded_ops
14
+
15
+ def initialize
16
+ super
17
+ operators.clear
18
+ @recorded_ops = []
19
+ end
20
+
21
+ def respond_to_missing?(*)
22
+ true
23
+ end
24
+
25
+ def method_missing(msg, *params)
26
+ @recorded_ops << (params.empty? ? [msg] : [msg, params])
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,93 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/content'
6
+ require 'hexapdf/content/graphic_object'
7
+
8
+ describe HexaPDF::Content::GraphicObject::Arc do
9
+ before do
10
+ @arc = HexaPDF::Content::GraphicObject::Arc.configure(start_angle: -30, end_angle: 30,
11
+ inclination: 90)
12
+ end
13
+
14
+ describe "initialize" do
15
+ it "creates a default arc representing the counterclockwise unit circle at the origin" do
16
+ arc = HexaPDF::Content::GraphicObject::Arc.new
17
+ assert_equal(0, arc.cx)
18
+ assert_equal(0, arc.cy)
19
+ assert_equal(1, arc.a)
20
+ assert_equal(1, arc.b)
21
+ assert_equal(0, arc.start_angle)
22
+ assert_equal(360, arc.end_angle)
23
+ assert_equal(0, arc.inclination)
24
+ end
25
+ end
26
+
27
+ it "returns the start and end points" do
28
+ x, y = @arc.start_point
29
+ assert_in_delta(0.5, x, 0.00001)
30
+ assert_in_delta(Math.sin(Math::PI / 3), y, 0.00001)
31
+
32
+ x, y = @arc.end_point
33
+ assert_in_delta(-0.5, x, 0.00001)
34
+ assert_in_delta(Math.sin(Math::PI / 3), y, 0.00001)
35
+ end
36
+
37
+ describe "point_at" do
38
+ it "returns an arbitrary point on the arc" do
39
+ x, y = @arc.point_at(0)
40
+ assert_in_delta(0, x, 0.00001)
41
+ assert_in_delta(1, y, 0.00001)
42
+ end
43
+ end
44
+
45
+ describe "configure" do
46
+ it "fails if a == 0 or b == 0" do
47
+ assert_raises(HexaPDF::Error) do
48
+ HexaPDF::Content::GraphicObject::Arc.configure(a: 0)
49
+ end
50
+ assert_raises(HexaPDF::Error) do
51
+ HexaPDF::Content::GraphicObject::Arc.configure(b: 0)
52
+ end
53
+ end
54
+ end
55
+
56
+ describe "curves" do
57
+ def assert_curve_values(exp, act)
58
+ assert_in_delta(exp[0], act[0], 0.00001)
59
+ assert_in_delta(exp[1], act[1], 0.00001)
60
+ assert_in_delta(exp[2][:p1][0], act[2][:p1][0], 0.00001)
61
+ assert_in_delta(exp[2][:p1][1], act[2][:p1][1], 0.00001)
62
+ assert_in_delta(exp[2][:p2][0], act[2][:p2][0], 0.00001)
63
+ assert_in_delta(exp[2][:p2][1], act[2][:p2][1], 0.00001)
64
+ end
65
+
66
+ it "returns the curves for the arc" do
67
+ arc = HexaPDF::Content::GraphicObject::Arc.configure(end_angle: 180)
68
+ arc.max_curves = 4
69
+ curves = arc.curves
70
+ assert_equal(2, curves.size)
71
+ assert_curve_values([0, 1, p1: [1, 0.548584], p2: [0.548584, 1]], curves[0])
72
+ assert_curve_values([-1, 0, p1: [-0.548584, 1], p2: [-1, 0.548584]], curves[1])
73
+
74
+ arc.configure(clockwise: true)
75
+ curves = arc.curves
76
+ assert_equal(2, curves.size)
77
+ assert_curve_values([0, -1, p1: [1, -0.548584], p2: [0.548584, -1]], curves[0])
78
+ assert_curve_values([-1, 0, p1: [-0.548584, -1], p2: [-1, -0.548584]], curves[1])
79
+ end
80
+ end
81
+
82
+ describe "draw" do
83
+ it "draws the arc onto the canvas" do
84
+ doc = HexaPDF::Document.new
85
+ page = doc.pages.add_page
86
+ canvas = page.canvas
87
+ @arc.max_curves = 4
88
+ @arc.draw(canvas)
89
+ assert_equal(doc.config['graphic_object.arc.max_curves'], @arc.max_curves)
90
+ refute(page.contents.empty?)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,91 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/content/canvas'
5
+ require 'hexapdf/content/graphic_object'
6
+ require 'hexapdf/document'
7
+
8
+ describe HexaPDF::Content::GraphicObject::EndpointArc do
9
+ describe "initialize" do
10
+ it "creates a default arc representing a line from the current point to the origin" do
11
+ arc = HexaPDF::Content::GraphicObject::EndpointArc.new
12
+ assert_equal(0, arc.x)
13
+ assert_equal(0, arc.y)
14
+ assert_equal(0, arc.a)
15
+ assert_equal(0, arc.b)
16
+ assert_equal(0, arc.inclination)
17
+ assert(arc.large_arc)
18
+ refute(arc.clockwise)
19
+ end
20
+ end
21
+
22
+
23
+ describe "configure" do
24
+ it "changes the values" do
25
+ arc = HexaPDF::Content::GraphicObject::EndpointArc.new
26
+ arc.configure(x: 1, y: 2, a: 3, b: 4, inclination: 5, large_arc: false, clockwise: true)
27
+ assert_equal(1, arc.x)
28
+ assert_equal(2, arc.y)
29
+ assert_equal(3, arc.a)
30
+ assert_equal(4, arc.b)
31
+ assert_equal(5, arc.inclination)
32
+ refute(arc.large_arc)
33
+ assert(arc.clockwise)
34
+ end
35
+ end
36
+
37
+ describe "draw" do
38
+ before do
39
+ @doc = HexaPDF::Document.new
40
+ @page = @doc.pages.add_page
41
+ end
42
+
43
+ it "draws nothing if the endpoint is the same as the current point" do
44
+ canvas = @page.canvas
45
+ canvas.move_to(50, 50)
46
+ canvas.draw(:endpoint_arc, x: 50, y: 50, a: 50, b: 25)
47
+ assert_equal("50 50 m\n", canvas.contents)
48
+ end
49
+
50
+ it "draws only a straight line if either one of the semi-axis is zero" do
51
+ canvas = @page.canvas
52
+ canvas.move_to(50, 50)
53
+ canvas.draw(:endpoint_arc, x: 100, y: 50, a: 0, b: 25)
54
+ assert_equal("50 50 m\n100 50 l\n", canvas.contents)
55
+ end
56
+
57
+ it "draws the arc onto the canvas" do
58
+ {
59
+ [false, false] => {cx: 100, cy: 50, start_angle: 180, end_angle: 270, clockwise: false},
60
+ [false, true] => {cx: 50, cy: 25, start_angle: 90, end_angle: 0, clockwise: true},
61
+ [true, false] => {cx: 50, cy: 25, start_angle: 90, end_angle: 360, clockwise: false},
62
+ [true, true] => {cx: 100, cy: 50, start_angle: 180, end_angle: -90, clockwise: true},
63
+ }.each do |(large_arc, clockwise), data|
64
+ @page.delete(:Contents)
65
+ canvas = @page.canvas
66
+ canvas.draw(:arc, a: 50, b: 25, inclination: 0, **data)
67
+ arc_data = @page.contents
68
+
69
+ canvas.contents.clear
70
+ assert(@page.contents.empty?)
71
+ canvas.move_to(50.0, 50.0)
72
+ canvas.draw(:endpoint_arc, x: 100, y: 25, a: 50, b: 25, inclination: 0,
73
+ large_arc: large_arc, clockwise: clockwise)
74
+ assert_equal(arc_data, @page.contents)
75
+ end
76
+ end
77
+
78
+ it "draws the correct arc even if it is inclined" do
79
+ canvas = @page.canvas
80
+ canvas.draw(:arc, cx: 25, cy: 0, a: 50, b: 25, start_angle: 90, end_angle: 270,
81
+ inclination: 90, clockwise: false)
82
+ arc_data = @page.contents
83
+
84
+ canvas.contents.clear
85
+ canvas.move_to(0.0, 1e-15)
86
+ canvas.draw(:endpoint_arc, x: 50, y: 0, a: 20, b: 10, inclination: 90, large_arc: false,
87
+ clockwise: false)
88
+ assert_equal(arc_data, @page.contents)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,86 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require_relative '../common'
5
+ require 'hexapdf/document'
6
+ require 'hexapdf/content'
7
+ require 'hexapdf/content/graphic_object'
8
+
9
+ describe HexaPDF::Content::GraphicObject::SolidArc do
10
+ describe "initialize" do
11
+ it "creates a default solid arc representing the disk at the origin" do
12
+ arc = HexaPDF::Content::GraphicObject::SolidArc.configure
13
+ assert_equal(0, arc.cx)
14
+ assert_equal(0, arc.cy)
15
+ assert_equal(0, arc.inner_a)
16
+ assert_equal(0, arc.inner_b)
17
+ assert_equal(1, arc.outer_a)
18
+ assert_equal(1, arc.outer_b)
19
+ assert_equal(0, arc.start_angle)
20
+ assert_equal(0, arc.end_angle)
21
+ assert_equal(0, arc.inclination)
22
+ end
23
+ end
24
+
25
+ describe "configure" do
26
+ it "changes the values" do
27
+ arc = HexaPDF::Content::GraphicObject::SolidArc.new
28
+ arc.configure(cx: 1, cy: 2, inner_a: 3, inner_b: 4, outer_a: 5, outer_b: 6,
29
+ start_angle: 7, end_angle: 8, inclination: 9)
30
+ assert_equal(1, arc.cx)
31
+ assert_equal(2, arc.cy)
32
+ assert_equal(3, arc.inner_a)
33
+ assert_equal(4, arc.inner_b)
34
+ assert_equal(5, arc.outer_a)
35
+ assert_equal(6, arc.outer_b)
36
+ assert_equal(7, arc.start_angle)
37
+ assert_equal(8, arc.end_angle)
38
+ assert_equal(9, arc.inclination)
39
+ end
40
+ end
41
+
42
+ describe "draw" do
43
+ def operators(content)
44
+ processor = TestHelper::OperatorRecorder.new
45
+ parser = HexaPDF::Content::Parser.new
46
+ parser.parse(content, processor)
47
+ processor.recorded_ops
48
+ end
49
+
50
+ before do
51
+ @doc = HexaPDF::Document.new
52
+ @doc.config['graphic_object.arc.max_curves'] = 4
53
+ @page = @doc.pages.add_page
54
+ @canvas = @page.canvas
55
+ end
56
+
57
+ it "draws a disk" do
58
+ @canvas.draw(:solid_arc)
59
+ ops = operators(@canvas.contents)
60
+ assert_equal([:move_to, :curve_to, :curve_to, :curve_to, :curve_to, :close_subpath],
61
+ ops.map(&:first))
62
+ end
63
+
64
+ it "draws a sector" do
65
+ @canvas.draw(:solid_arc, end_angle: 90)
66
+ ops = operators(@canvas.contents)
67
+ assert_equal([:move_to, :line_to, :curve_to, :close_subpath],
68
+ ops.map(&:first))
69
+ end
70
+
71
+ it "draws an annulus" do
72
+ @canvas.draw(:solid_arc, inner_a: 5, inner_b: 5)
73
+ ops = operators(@canvas.contents)
74
+ assert_equal([:move_to, :curve_to, :curve_to, :curve_to, :curve_to, :close_subpath,
75
+ :move_to, :curve_to, :curve_to, :curve_to, :curve_to, :close_subpath],
76
+ ops.map(&:first))
77
+ end
78
+
79
+ it "draws an annular sector" do
80
+ @canvas.draw(:solid_arc, inner_a: 5, inner_b: 5, end_angle: 90)
81
+ ops = operators(@canvas.contents)
82
+ assert_equal([:move_to, :curve_to, :line_to, :curve_to, :close_subpath],
83
+ ops.map(&:first))
84
+ end
85
+ end
86
+ end