hexapdf 0.15.8 → 0.17.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (446) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hexapdf/cli/batch.rb +1 -1
  3. data/lib/hexapdf/cli/command.rb +10 -1
  4. data/lib/hexapdf/cli/files.rb +1 -1
  5. data/lib/hexapdf/cli/fonts.rb +145 -0
  6. data/lib/hexapdf/cli/form.rb +27 -26
  7. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  8. data/lib/hexapdf/cli/images.rb +1 -10
  9. data/lib/hexapdf/cli/info.rb +1 -1
  10. data/lib/hexapdf/cli/inspect.rb +1 -1
  11. data/lib/hexapdf/cli/merge.rb +1 -1
  12. data/lib/hexapdf/cli/modify.rb +1 -1
  13. data/lib/hexapdf/cli/optimize.rb +1 -1
  14. data/lib/hexapdf/cli/split.rb +1 -1
  15. data/lib/hexapdf/cli/watermark.rb +1 -1
  16. data/lib/hexapdf/cli.rb +3 -1
  17. data/lib/hexapdf/composer.rb +1 -1
  18. data/lib/hexapdf/configuration.rb +11 -2
  19. data/lib/hexapdf/content/canvas.rb +658 -167
  20. data/lib/hexapdf/content/color_space.rb +185 -3
  21. data/lib/hexapdf/content/graphic_object/arc.rb +111 -12
  22. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  23. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  24. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  25. data/lib/hexapdf/content/graphic_object.rb +1 -1
  26. data/lib/hexapdf/content/graphics_state.rb +1 -1
  27. data/lib/hexapdf/content/operator.rb +1 -1
  28. data/lib/hexapdf/content/parser.rb +1 -1
  29. data/lib/hexapdf/content/processor.rb +1 -1
  30. data/lib/hexapdf/content/transformation_matrix.rb +1 -1
  31. data/lib/hexapdf/content.rb +1 -1
  32. data/lib/hexapdf/data_dir.rb +1 -1
  33. data/lib/hexapdf/dictionary.rb +1 -1
  34. data/lib/hexapdf/dictionary_fields.rb +30 -4
  35. data/lib/hexapdf/document/files.rb +3 -3
  36. data/lib/hexapdf/document/fonts.rb +1 -1
  37. data/lib/hexapdf/document/images.rb +1 -1
  38. data/lib/hexapdf/document/pages.rb +1 -1
  39. data/lib/hexapdf/document.rb +1 -1
  40. data/lib/hexapdf/encryption/aes.rb +1 -1
  41. data/lib/hexapdf/encryption/arc4.rb +1 -1
  42. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  43. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  44. data/lib/hexapdf/encryption/identity.rb +1 -1
  45. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  46. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  47. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  48. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  49. data/lib/hexapdf/encryption.rb +1 -1
  50. data/lib/hexapdf/error.rb +1 -1
  51. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  52. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  53. data/lib/hexapdf/filter/crypt.rb +1 -1
  54. data/lib/hexapdf/filter/encryption.rb +1 -1
  55. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  56. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  57. data/lib/hexapdf/filter/pass_through.rb +1 -1
  58. data/lib/hexapdf/filter/predictor.rb +1 -1
  59. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  60. data/lib/hexapdf/filter.rb +1 -1
  61. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  62. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  63. data/lib/hexapdf/font/cmap.rb +1 -1
  64. data/lib/hexapdf/font/encoding/base.rb +1 -1
  65. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  66. data/lib/hexapdf/font/encoding/glyph_list.rb +1 -1
  67. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  68. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  69. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  70. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  71. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  72. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  73. data/lib/hexapdf/font/encoding.rb +1 -1
  74. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  75. data/lib/hexapdf/font/true_type/builder.rb +1 -1
  76. data/lib/hexapdf/font/true_type/font.rb +1 -1
  77. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  78. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  79. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  80. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  81. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  82. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  83. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  84. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  85. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  86. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  87. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  88. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  89. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  90. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  91. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  92. data/lib/hexapdf/font/true_type/table.rb +1 -1
  93. data/lib/hexapdf/font/true_type.rb +1 -1
  94. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  95. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  96. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  97. data/lib/hexapdf/font/type1/font.rb +1 -1
  98. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  99. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  100. data/lib/hexapdf/font/type1.rb +1 -1
  101. data/lib/hexapdf/font/type1_wrapper.rb +1 -1
  102. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  103. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  104. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  105. data/lib/hexapdf/font_loader.rb +1 -1
  106. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  107. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  108. data/lib/hexapdf/image_loader/png.rb +1 -1
  109. data/lib/hexapdf/image_loader.rb +1 -1
  110. data/lib/hexapdf/importer.rb +1 -1
  111. data/lib/hexapdf/layout/box.rb +4 -2
  112. data/lib/hexapdf/layout/frame.rb +1 -1
  113. data/lib/hexapdf/layout/image_box.rb +1 -1
  114. data/lib/hexapdf/layout/inline_box.rb +1 -1
  115. data/lib/hexapdf/layout/line.rb +1 -1
  116. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  117. data/lib/hexapdf/layout/style.rb +40 -2
  118. data/lib/hexapdf/layout/text_box.rb +1 -1
  119. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  120. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  121. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  122. data/lib/hexapdf/layout/width_from_polygon.rb +2 -2
  123. data/lib/hexapdf/layout.rb +1 -1
  124. data/lib/hexapdf/name_tree_node.rb +1 -1
  125. data/lib/hexapdf/number_tree_node.rb +1 -1
  126. data/lib/hexapdf/object.rb +1 -1
  127. data/lib/hexapdf/parser.rb +2 -2
  128. data/lib/hexapdf/pdf_array.rb +1 -1
  129. data/lib/hexapdf/rectangle.rb +1 -1
  130. data/lib/hexapdf/reference.rb +1 -1
  131. data/lib/hexapdf/revision.rb +1 -1
  132. data/lib/hexapdf/revisions.rb +1 -1
  133. data/lib/hexapdf/serializer.rb +1 -1
  134. data/lib/hexapdf/stream.rb +1 -1
  135. data/lib/hexapdf/task/dereference.rb +1 -1
  136. data/lib/hexapdf/task/optimize.rb +1 -1
  137. data/lib/hexapdf/task.rb +1 -1
  138. data/lib/hexapdf/tokenizer.rb +1 -1
  139. data/lib/hexapdf/type/acro_form/appearance_generator.rb +14 -7
  140. data/lib/hexapdf/type/acro_form/button_field.rb +53 -28
  141. data/lib/hexapdf/type/acro_form/choice_field.rb +1 -1
  142. data/lib/hexapdf/type/acro_form/field.rb +21 -2
  143. data/lib/hexapdf/type/acro_form/form.rb +48 -29
  144. data/lib/hexapdf/type/acro_form/text_field.rb +2 -2
  145. data/lib/hexapdf/type/acro_form/variable_text_field.rb +17 -9
  146. data/lib/hexapdf/type/acro_form.rb +1 -1
  147. data/lib/hexapdf/type/action.rb +1 -1
  148. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  149. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  150. data/lib/hexapdf/type/actions/launch.rb +1 -1
  151. data/lib/hexapdf/type/actions/uri.rb +1 -1
  152. data/lib/hexapdf/type/actions.rb +1 -1
  153. data/lib/hexapdf/type/annotation.rb +1 -1
  154. data/lib/hexapdf/type/annotations/link.rb +1 -1
  155. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  156. data/lib/hexapdf/type/annotations/text.rb +1 -1
  157. data/lib/hexapdf/type/annotations/widget.rb +2 -2
  158. data/lib/hexapdf/type/annotations.rb +1 -1
  159. data/lib/hexapdf/type/catalog.rb +1 -1
  160. data/lib/hexapdf/type/cid_font.rb +1 -1
  161. data/lib/hexapdf/type/embedded_file.rb +1 -1
  162. data/lib/hexapdf/type/file_specification.rb +1 -1
  163. data/lib/hexapdf/type/font.rb +1 -1
  164. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  165. data/lib/hexapdf/type/font_simple.rb +1 -1
  166. data/lib/hexapdf/type/font_true_type.rb +1 -1
  167. data/lib/hexapdf/type/font_type0.rb +1 -1
  168. data/lib/hexapdf/type/font_type1.rb +1 -1
  169. data/lib/hexapdf/type/font_type3.rb +1 -1
  170. data/lib/hexapdf/type/form.rb +1 -1
  171. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  172. data/lib/hexapdf/type/icon_fit.rb +1 -1
  173. data/lib/hexapdf/type/image.rb +1 -1
  174. data/lib/hexapdf/type/info.rb +1 -1
  175. data/lib/hexapdf/type/names.rb +1 -1
  176. data/lib/hexapdf/type/object_stream.rb +1 -1
  177. data/lib/hexapdf/type/page.rb +15 -1
  178. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  179. data/lib/hexapdf/type/resources.rb +1 -1
  180. data/lib/hexapdf/type/trailer.rb +1 -1
  181. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  182. data/lib/hexapdf/type/xref_stream.rb +1 -1
  183. data/lib/hexapdf/type.rb +1 -1
  184. data/lib/hexapdf/utils/bit_field.rb +1 -1
  185. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  186. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  187. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  188. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  189. data/lib/hexapdf/utils/object_hash.rb +1 -1
  190. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  191. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  192. data/lib/hexapdf/version.rb +2 -2
  193. data/lib/hexapdf/writer.rb +1 -1
  194. data/lib/hexapdf/xref_section.rb +1 -1
  195. data/lib/hexapdf.rb +1 -1
  196. metadata +5 -264
  197. data/CHANGELOG.md +0 -954
  198. data/LICENSE +0 -29
  199. data/README.md +0 -120
  200. data/Rakefile +0 -108
  201. data/agpl-3.0.txt +0 -661
  202. data/examples/001-hello_world.rb +0 -16
  203. data/examples/002-graphics.rb +0 -275
  204. data/examples/003-arcs.rb +0 -50
  205. data/examples/004-optimizing.rb +0 -23
  206. data/examples/005-merging.rb +0 -27
  207. data/examples/006-standard_pdf_fonts.rb +0 -73
  208. data/examples/007-truetype.rb +0 -42
  209. data/examples/008-show_char_bboxes.rb +0 -55
  210. data/examples/009-text_layouter_alignment.rb +0 -47
  211. data/examples/010-text_layouter_inline_boxes.rb +0 -64
  212. data/examples/011-text_layouter_line_wrapping.rb +0 -57
  213. data/examples/012-text_layouter_styling.rb +0 -122
  214. data/examples/013-text_layouter_shapes.rb +0 -176
  215. data/examples/014-text_in_polygon.rb +0 -60
  216. data/examples/015-boxes.rb +0 -76
  217. data/examples/016-frame_automatic_box_placement.rb +0 -90
  218. data/examples/017-frame_text_flow.rb +0 -60
  219. data/examples/018-composer.rb +0 -44
  220. data/examples/019-acro_form.rb +0 -88
  221. data/examples/emoji-smile.png +0 -0
  222. data/examples/emoji-wink.png +0 -0
  223. data/examples/machupicchu.jpg +0 -0
  224. data/test/data/aes-test-vectors/CBCGFSbox-128-decrypt.data.gz +0 -0
  225. data/test/data/aes-test-vectors/CBCGFSbox-128-encrypt.data.gz +0 -0
  226. data/test/data/aes-test-vectors/CBCGFSbox-192-decrypt.data.gz +0 -0
  227. data/test/data/aes-test-vectors/CBCGFSbox-192-encrypt.data.gz +0 -0
  228. data/test/data/aes-test-vectors/CBCGFSbox-256-decrypt.data.gz +0 -0
  229. data/test/data/aes-test-vectors/CBCGFSbox-256-encrypt.data.gz +0 -0
  230. data/test/data/aes-test-vectors/CBCKeySbox-128-decrypt.data.gz +0 -0
  231. data/test/data/aes-test-vectors/CBCKeySbox-128-encrypt.data.gz +0 -0
  232. data/test/data/aes-test-vectors/CBCKeySbox-192-decrypt.data.gz +0 -0
  233. data/test/data/aes-test-vectors/CBCKeySbox-192-encrypt.data.gz +0 -0
  234. data/test/data/aes-test-vectors/CBCKeySbox-256-decrypt.data.gz +0 -0
  235. data/test/data/aes-test-vectors/CBCKeySbox-256-encrypt.data.gz +0 -0
  236. data/test/data/aes-test-vectors/CBCVarKey-128-decrypt.data.gz +0 -0
  237. data/test/data/aes-test-vectors/CBCVarKey-128-encrypt.data.gz +0 -0
  238. data/test/data/aes-test-vectors/CBCVarKey-192-decrypt.data.gz +0 -0
  239. data/test/data/aes-test-vectors/CBCVarKey-192-encrypt.data.gz +0 -0
  240. data/test/data/aes-test-vectors/CBCVarKey-256-decrypt.data.gz +0 -0
  241. data/test/data/aes-test-vectors/CBCVarKey-256-encrypt.data.gz +0 -0
  242. data/test/data/aes-test-vectors/CBCVarTxt-128-decrypt.data.gz +0 -0
  243. data/test/data/aes-test-vectors/CBCVarTxt-128-encrypt.data.gz +0 -0
  244. data/test/data/aes-test-vectors/CBCVarTxt-192-decrypt.data.gz +0 -0
  245. data/test/data/aes-test-vectors/CBCVarTxt-192-encrypt.data.gz +0 -0
  246. data/test/data/aes-test-vectors/CBCVarTxt-256-decrypt.data.gz +0 -0
  247. data/test/data/aes-test-vectors/CBCVarTxt-256-encrypt.data.gz +0 -0
  248. data/test/data/fonts/Ubuntu-Title.ttf +0 -0
  249. data/test/data/images/cmyk.jpg +0 -0
  250. data/test/data/images/fillbytes.jpg +0 -0
  251. data/test/data/images/gray.jpg +0 -0
  252. data/test/data/images/greyscale-1bit.png +0 -0
  253. data/test/data/images/greyscale-2bit.png +0 -0
  254. data/test/data/images/greyscale-4bit.png +0 -0
  255. data/test/data/images/greyscale-8bit.png +0 -0
  256. data/test/data/images/greyscale-alpha-8bit.png +0 -0
  257. data/test/data/images/greyscale-trns-8bit.png +0 -0
  258. data/test/data/images/greyscale-with-gamma1.0.png +0 -0
  259. data/test/data/images/greyscale-with-gamma1.5.png +0 -0
  260. data/test/data/images/indexed-1bit.png +0 -0
  261. data/test/data/images/indexed-2bit.png +0 -0
  262. data/test/data/images/indexed-4bit.png +0 -0
  263. data/test/data/images/indexed-8bit.png +0 -0
  264. data/test/data/images/indexed-alpha-4bit.png +0 -0
  265. data/test/data/images/indexed-alpha-8bit.png +0 -0
  266. data/test/data/images/rgb.jpg +0 -0
  267. data/test/data/images/truecolour-8bit.png +0 -0
  268. data/test/data/images/truecolour-alpha-8bit.png +0 -0
  269. data/test/data/images/truecolour-gama-chrm-8bit.png +0 -0
  270. data/test/data/images/truecolour-srgb-8bit.png +0 -0
  271. data/test/data/images/ycck.jpg +0 -0
  272. data/test/data/minimal.pdf +0 -44
  273. data/test/data/standard-security-handler/README +0 -9
  274. data/test/data/standard-security-handler/bothpwd-aes-128bit-V4.pdf +0 -44
  275. data/test/data/standard-security-handler/bothpwd-aes-256bit-V5.pdf +0 -0
  276. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V2.pdf +0 -43
  277. data/test/data/standard-security-handler/bothpwd-arc4-128bit-V4.pdf +0 -43
  278. data/test/data/standard-security-handler/bothpwd-arc4-40bit-V1.pdf +0 -0
  279. data/test/data/standard-security-handler/nopwd-aes-128bit-V4.pdf +0 -43
  280. data/test/data/standard-security-handler/nopwd-aes-256bit-V5.pdf +0 -0
  281. data/test/data/standard-security-handler/nopwd-arc4-128bit-V2.pdf +0 -43
  282. data/test/data/standard-security-handler/nopwd-arc4-128bit-V4.pdf +0 -43
  283. data/test/data/standard-security-handler/nopwd-arc4-40bit-V1.pdf +0 -43
  284. data/test/data/standard-security-handler/ownerpwd-aes-128bit-V4.pdf +0 -0
  285. data/test/data/standard-security-handler/ownerpwd-aes-256bit-V5.pdf +0 -43
  286. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V2.pdf +0 -43
  287. data/test/data/standard-security-handler/ownerpwd-arc4-128bit-V4.pdf +0 -43
  288. data/test/data/standard-security-handler/ownerpwd-arc4-40bit-V1.pdf +0 -43
  289. data/test/data/standard-security-handler/userpwd-aes-128bit-V4.pdf +0 -43
  290. data/test/data/standard-security-handler/userpwd-aes-256bit-V5.pdf +0 -43
  291. data/test/data/standard-security-handler/userpwd-arc4-128bit-V2.pdf +0 -0
  292. data/test/data/standard-security-handler/userpwd-arc4-128bit-V4.pdf +0 -0
  293. data/test/data/standard-security-handler/userpwd-arc4-40bit-V1.pdf +0 -43
  294. data/test/hexapdf/common_tokenizer_tests.rb +0 -236
  295. data/test/hexapdf/content/common.rb +0 -39
  296. data/test/hexapdf/content/graphic_object/test_arc.rb +0 -93
  297. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +0 -90
  298. data/test/hexapdf/content/graphic_object/test_geom2d.rb +0 -79
  299. data/test/hexapdf/content/graphic_object/test_solid_arc.rb +0 -86
  300. data/test/hexapdf/content/test_canvas.rb +0 -1216
  301. data/test/hexapdf/content/test_color_space.rb +0 -164
  302. data/test/hexapdf/content/test_graphics_state.rb +0 -151
  303. data/test/hexapdf/content/test_operator.rb +0 -619
  304. data/test/hexapdf/content/test_parser.rb +0 -99
  305. data/test/hexapdf/content/test_processor.rb +0 -163
  306. data/test/hexapdf/content/test_transformation_matrix.rb +0 -64
  307. data/test/hexapdf/document/test_files.rb +0 -72
  308. data/test/hexapdf/document/test_fonts.rb +0 -60
  309. data/test/hexapdf/document/test_images.rb +0 -72
  310. data/test/hexapdf/document/test_pages.rb +0 -130
  311. data/test/hexapdf/encryption/common.rb +0 -87
  312. data/test/hexapdf/encryption/test_aes.rb +0 -129
  313. data/test/hexapdf/encryption/test_arc4.rb +0 -39
  314. data/test/hexapdf/encryption/test_fast_aes.rb +0 -17
  315. data/test/hexapdf/encryption/test_fast_arc4.rb +0 -12
  316. data/test/hexapdf/encryption/test_identity.rb +0 -21
  317. data/test/hexapdf/encryption/test_ruby_aes.rb +0 -23
  318. data/test/hexapdf/encryption/test_ruby_arc4.rb +0 -20
  319. data/test/hexapdf/encryption/test_security_handler.rb +0 -380
  320. data/test/hexapdf/encryption/test_standard_security_handler.rb +0 -322
  321. data/test/hexapdf/filter/common.rb +0 -53
  322. data/test/hexapdf/filter/test_ascii85_decode.rb +0 -59
  323. data/test/hexapdf/filter/test_ascii_hex_decode.rb +0 -38
  324. data/test/hexapdf/filter/test_crypt.rb +0 -21
  325. data/test/hexapdf/filter/test_encryption.rb +0 -24
  326. data/test/hexapdf/filter/test_flate_decode.rb +0 -44
  327. data/test/hexapdf/filter/test_lzw_decode.rb +0 -52
  328. data/test/hexapdf/filter/test_predictor.rb +0 -219
  329. data/test/hexapdf/filter/test_run_length_decode.rb +0 -32
  330. data/test/hexapdf/font/cmap/test_parser.rb +0 -102
  331. data/test/hexapdf/font/cmap/test_writer.rb +0 -66
  332. data/test/hexapdf/font/encoding/test_base.rb +0 -45
  333. data/test/hexapdf/font/encoding/test_difference_encoding.rb +0 -29
  334. data/test/hexapdf/font/encoding/test_glyph_list.rb +0 -59
  335. data/test/hexapdf/font/encoding/test_zapf_dingbats_encoding.rb +0 -16
  336. data/test/hexapdf/font/test_cmap.rb +0 -104
  337. data/test/hexapdf/font/test_encoding.rb +0 -27
  338. data/test/hexapdf/font/test_invalid_glyph.rb +0 -34
  339. data/test/hexapdf/font/test_true_type_wrapper.rb +0 -186
  340. data/test/hexapdf/font/test_type1_wrapper.rb +0 -107
  341. data/test/hexapdf/font/true_type/common.rb +0 -17
  342. data/test/hexapdf/font/true_type/table/common.rb +0 -27
  343. data/test/hexapdf/font/true_type/table/test_cmap.rb +0 -47
  344. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +0 -141
  345. data/test/hexapdf/font/true_type/table/test_directory.rb +0 -30
  346. data/test/hexapdf/font/true_type/table/test_glyf.rb +0 -58
  347. data/test/hexapdf/font/true_type/table/test_head.rb +0 -56
  348. data/test/hexapdf/font/true_type/table/test_hhea.rb +0 -26
  349. data/test/hexapdf/font/true_type/table/test_hmtx.rb +0 -30
  350. data/test/hexapdf/font/true_type/table/test_kern.rb +0 -61
  351. data/test/hexapdf/font/true_type/table/test_loca.rb +0 -33
  352. data/test/hexapdf/font/true_type/table/test_maxp.rb +0 -50
  353. data/test/hexapdf/font/true_type/table/test_name.rb +0 -76
  354. data/test/hexapdf/font/true_type/table/test_os2.rb +0 -55
  355. data/test/hexapdf/font/true_type/table/test_post.rb +0 -78
  356. data/test/hexapdf/font/true_type/test_builder.rb +0 -42
  357. data/test/hexapdf/font/true_type/test_font.rb +0 -116
  358. data/test/hexapdf/font/true_type/test_optimizer.rb +0 -26
  359. data/test/hexapdf/font/true_type/test_subsetter.rb +0 -73
  360. data/test/hexapdf/font/true_type/test_table.rb +0 -48
  361. data/test/hexapdf/font/type1/common.rb +0 -6
  362. data/test/hexapdf/font/type1/test_afm_parser.rb +0 -65
  363. data/test/hexapdf/font/type1/test_font.rb +0 -104
  364. data/test/hexapdf/font/type1/test_font_metrics.rb +0 -22
  365. data/test/hexapdf/font/type1/test_pfb_parser.rb +0 -37
  366. data/test/hexapdf/font_loader/test_from_configuration.rb +0 -43
  367. data/test/hexapdf/font_loader/test_from_file.rb +0 -36
  368. data/test/hexapdf/font_loader/test_standard14.rb +0 -33
  369. data/test/hexapdf/image_loader/test_jpeg.rb +0 -93
  370. data/test/hexapdf/image_loader/test_pdf.rb +0 -47
  371. data/test/hexapdf/image_loader/test_png.rb +0 -259
  372. data/test/hexapdf/layout/test_box.rb +0 -152
  373. data/test/hexapdf/layout/test_frame.rb +0 -350
  374. data/test/hexapdf/layout/test_image_box.rb +0 -73
  375. data/test/hexapdf/layout/test_inline_box.rb +0 -71
  376. data/test/hexapdf/layout/test_line.rb +0 -206
  377. data/test/hexapdf/layout/test_style.rb +0 -779
  378. data/test/hexapdf/layout/test_text_box.rb +0 -140
  379. data/test/hexapdf/layout/test_text_fragment.rb +0 -375
  380. data/test/hexapdf/layout/test_text_layouter.rb +0 -758
  381. data/test/hexapdf/layout/test_text_shaper.rb +0 -62
  382. data/test/hexapdf/layout/test_width_from_polygon.rb +0 -108
  383. data/test/hexapdf/task/test_dereference.rb +0 -51
  384. data/test/hexapdf/task/test_optimize.rb +0 -162
  385. data/test/hexapdf/test_composer.rb +0 -258
  386. data/test/hexapdf/test_configuration.rb +0 -93
  387. data/test/hexapdf/test_data_dir.rb +0 -32
  388. data/test/hexapdf/test_dictionary.rb +0 -340
  389. data/test/hexapdf/test_dictionary_fields.rb +0 -245
  390. data/test/hexapdf/test_document.rb +0 -641
  391. data/test/hexapdf/test_filter.rb +0 -100
  392. data/test/hexapdf/test_importer.rb +0 -106
  393. data/test/hexapdf/test_object.rb +0 -258
  394. data/test/hexapdf/test_parser.rb +0 -637
  395. data/test/hexapdf/test_pdf_array.rb +0 -169
  396. data/test/hexapdf/test_rectangle.rb +0 -73
  397. data/test/hexapdf/test_reference.rb +0 -50
  398. data/test/hexapdf/test_revision.rb +0 -188
  399. data/test/hexapdf/test_revisions.rb +0 -196
  400. data/test/hexapdf/test_serializer.rb +0 -195
  401. data/test/hexapdf/test_stream.rb +0 -274
  402. data/test/hexapdf/test_tokenizer.rb +0 -80
  403. data/test/hexapdf/test_type.rb +0 -18
  404. data/test/hexapdf/test_writer.rb +0 -140
  405. data/test/hexapdf/test_xref_section.rb +0 -61
  406. data/test/hexapdf/type/acro_form/test_appearance_generator.rb +0 -794
  407. data/test/hexapdf/type/acro_form/test_button_field.rb +0 -302
  408. data/test/hexapdf/type/acro_form/test_choice_field.rb +0 -220
  409. data/test/hexapdf/type/acro_form/test_field.rb +0 -247
  410. data/test/hexapdf/type/acro_form/test_form.rb +0 -353
  411. data/test/hexapdf/type/acro_form/test_signature_field.rb +0 -38
  412. data/test/hexapdf/type/acro_form/test_text_field.rb +0 -195
  413. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +0 -77
  414. data/test/hexapdf/type/actions/test_launch.rb +0 -24
  415. data/test/hexapdf/type/actions/test_uri.rb +0 -23
  416. data/test/hexapdf/type/annotations/test_markup_annotation.rb +0 -22
  417. data/test/hexapdf/type/annotations/test_text.rb +0 -34
  418. data/test/hexapdf/type/annotations/test_widget.rb +0 -225
  419. data/test/hexapdf/type/test_annotation.rb +0 -97
  420. data/test/hexapdf/type/test_catalog.rb +0 -48
  421. data/test/hexapdf/type/test_cid_font.rb +0 -61
  422. data/test/hexapdf/type/test_file_specification.rb +0 -141
  423. data/test/hexapdf/type/test_font.rb +0 -67
  424. data/test/hexapdf/type/test_font_descriptor.rb +0 -61
  425. data/test/hexapdf/type/test_font_simple.rb +0 -176
  426. data/test/hexapdf/type/test_font_true_type.rb +0 -31
  427. data/test/hexapdf/type/test_font_type0.rb +0 -120
  428. data/test/hexapdf/type/test_font_type1.rb +0 -142
  429. data/test/hexapdf/type/test_font_type3.rb +0 -26
  430. data/test/hexapdf/type/test_form.rb +0 -120
  431. data/test/hexapdf/type/test_image.rb +0 -261
  432. data/test/hexapdf/type/test_info.rb +0 -9
  433. data/test/hexapdf/type/test_object_stream.rb +0 -117
  434. data/test/hexapdf/type/test_page.rb +0 -587
  435. data/test/hexapdf/type/test_page_tree_node.rb +0 -315
  436. data/test/hexapdf/type/test_resources.rb +0 -209
  437. data/test/hexapdf/type/test_trailer.rb +0 -116
  438. data/test/hexapdf/type/test_xref_stream.rb +0 -143
  439. data/test/hexapdf/utils/test_bit_field.rb +0 -63
  440. data/test/hexapdf/utils/test_bit_stream.rb +0 -69
  441. data/test/hexapdf/utils/test_graphics_helpers.rb +0 -37
  442. data/test/hexapdf/utils/test_lru_cache.rb +0 -22
  443. data/test/hexapdf/utils/test_object_hash.rb +0 -120
  444. data/test/hexapdf/utils/test_pdf_doc_encoding.rb +0 -18
  445. data/test/hexapdf/utils/test_sorted_tree_node.rb +0 -239
  446. data/test/test_helper.rb +0 -58
@@ -1,1216 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'test_helper'
4
- require_relative 'common'
5
- require 'hexapdf/content/canvas'
6
- require 'hexapdf/document'
7
- require 'hexapdf/content/processor'
8
- require 'hexapdf/content/parser'
9
-
10
- describe HexaPDF::Content::Canvas do
11
- before do
12
- @doc = HexaPDF::Document.new
13
- @doc.config['graphic_object.arc.max_curves'] = 4
14
- @page = @doc.pages.add
15
- @canvas = @page.canvas
16
- end
17
-
18
- # Asserts that a specific operator is invoked when the block is executed.
19
- def assert_operator_invoked(op, *args)
20
- mock = Minitest::Mock.new
21
- if args.empty?
22
- mock.expect(:invoke, nil) { true }
23
- mock.expect(:serialize, '') { true }
24
- else
25
- mock.expect(:invoke, nil, [@canvas] + args)
26
- mock.expect(:serialize, '', [@canvas.instance_variable_get(:@serializer)] + args)
27
- end
28
- op_before = @canvas.instance_variable_get(:@operators)[op]
29
- @canvas.instance_variable_get(:@operators)[op] = mock
30
- yield
31
- assert(mock.verify)
32
- ensure
33
- @canvas.instance_variable_get(:@operators)[op] = op_before
34
- end
35
-
36
- # Asserts that the block raises an error when in one of the given graphics objects.
37
- def assert_raises_in_graphics_object(*objects, &block)
38
- objects.each do |graphics_object|
39
- @canvas.graphics_object = graphics_object
40
- assert_raises(HexaPDF::Error, &block)
41
- end
42
- end
43
-
44
- describe "contents" do
45
- it "returns the serialized contents of the canvas operations" do
46
- @canvas.save_graphics_state {}
47
- assert_equal("q\nQ\n", @canvas.contents)
48
- end
49
- end
50
-
51
- describe "stream_data" do
52
- it "it closes an open path object" do
53
- @canvas.move_to(5, 5)
54
- assert_equal("5 5 m\nn\n", @canvas.stream_data.fiber.resume)
55
- end
56
-
57
- it "it closes an open text object" do
58
- @canvas.begin_text
59
- assert_equal("BT\nET\n", @canvas.stream_data.fiber.resume)
60
- end
61
-
62
- it "rewinds the graphics state stack" do
63
- @canvas.save_graphics_state
64
- @canvas.begin_text
65
- assert_equal("q\nBT\nET\nQ\n", @canvas.stream_data.fiber.resume)
66
- end
67
- end
68
-
69
- describe "resources" do
70
- it "returns the resources of the context object" do
71
- assert_equal(@page.resources, @canvas.resources)
72
- end
73
- end
74
-
75
- describe "save_graphics_state" do
76
- it "invokes the operator implementation" do
77
- assert_operator_invoked(:q) { @canvas.save_graphics_state }
78
- end
79
-
80
- it "is serialized correctly when no block is used" do
81
- @canvas.save_graphics_state
82
- assert_operators(@canvas.contents, [[:save_graphics_state]])
83
- end
84
-
85
- it "is serialized correctly when a block is used" do
86
- @canvas.save_graphics_state {}
87
- assert_operators(@canvas.contents, [[:save_graphics_state], [:restore_graphics_state]])
88
- end
89
-
90
- it "saves needed font state information not stored in the graphics state" do
91
- @canvas.save_graphics_state do
92
- @canvas.font("Times", size: 12)
93
- @canvas.save_graphics_state do
94
- @canvas.font("Helvetica")
95
- end
96
- assert_equal("Times-Roman", @canvas.font.wrapped_font.font_name)
97
- end
98
- assert_nil(@canvas.font)
99
- end
100
-
101
- it "fails if invoked while in an unsupported graphics objects" do
102
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.save_graphics_state }
103
- end
104
- end
105
-
106
- describe "restore_graphics_state" do
107
- it "invokes the operator implementation" do
108
- assert_operator_invoked(:Q) { @canvas.restore_graphics_state }
109
- end
110
-
111
- it "is serialized correctly" do
112
- @canvas.graphics_state.save
113
- @canvas.restore_graphics_state
114
- assert_operators(@page.contents, [[:restore_graphics_state]])
115
- end
116
-
117
- it "fails if invoked while in an unsupported graphics objects" do
118
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.restore_graphics_state }
119
- end
120
- end
121
-
122
- describe "transform" do
123
- it "invokes the operator implementation" do
124
- assert_operator_invoked(:cm, 1, 2, 3, 4, 5, 6) { @canvas.transform(1, 2, 3, 4, 5, 6) }
125
- end
126
-
127
- it "is serialized correctly when no block is used" do
128
- @canvas.transform(1, 2, 3, 4, 5, 6)
129
- assert_operators(@page.contents, [[:concatenate_matrix, [1, 2, 3, 4, 5, 6]]])
130
- end
131
-
132
- it "is serialized correctly when a block is used" do
133
- @canvas.transform(1, 2, 3, 4, 5, 6) {}
134
- assert_operators(@page.contents, [[:save_graphics_state],
135
- [:concatenate_matrix, [1, 2, 3, 4, 5, 6]],
136
- [:restore_graphics_state]])
137
- end
138
-
139
- it "fails if invoked while in an unsupported graphics objects" do
140
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.transform(1, 2, 3, 4, 5, 6) }
141
- end
142
- end
143
-
144
- describe "rotate" do
145
- it "can rotate around the origin" do
146
- @canvas.rotate(90)
147
- assert_operators(@page.contents, [[:concatenate_matrix, [0, 1, -1, 0, 0, 0]]])
148
- end
149
-
150
- it "can rotate about an arbitrary point" do
151
- @canvas.rotate(90, origin: [100, 200])
152
- assert_operators(@page.contents, [[:concatenate_matrix, [0.0, 1.0, -1.0, 0.0, 300.0, 100.0]]])
153
- end
154
- end
155
-
156
- describe "scale" do
157
- it "can scale from the origin" do
158
- @canvas.scale(5, 10)
159
- assert_operators(@page.contents, [[:concatenate_matrix, [5, 0, 0, 10, 0, 0]]])
160
- end
161
-
162
- it "can scale from an arbitrary point" do
163
- @canvas.scale(5, 10, origin: [100, 200])
164
- assert_operators(@page.contents, [[:concatenate_matrix, [5, 0, 0, 10, -400, -1800]]])
165
- end
166
-
167
- it "works with a single scale factor" do
168
- @canvas.scale(5)
169
- assert_operators(@page.contents, [[:concatenate_matrix, [5, 0, 0, 5, 0, 0]]])
170
- end
171
- end
172
-
173
- describe "translate" do
174
- it "translates the origin" do
175
- @canvas.translate(100, 200)
176
- assert_operators(@page.contents, [[:concatenate_matrix, [1, 0, 0, 1, 100, 200]]])
177
- end
178
- end
179
-
180
- describe "skew" do
181
- it "can skew from the origin" do
182
- @canvas.skew(45, 0)
183
- assert_operators(@page.contents, [[:concatenate_matrix, [1, 1, 0, 1, 0, 0]]])
184
- end
185
-
186
- it "can skew from an arbitrary point" do
187
- @canvas.skew(45, 0, origin: [100, 200])
188
- assert_operators(@page.contents, [[:concatenate_matrix, [1, 1, 0, 1, 0, -100]]])
189
- end
190
- end
191
-
192
- describe "private gs_getter_setter" do
193
- it "returns the current value when used with a nil argument" do
194
- @canvas.graphics_state.line_width = 5
195
- assert_equal(5, @canvas.send(:gs_getter_setter, :line_width, :w, nil))
196
- end
197
-
198
- it "returns the canvas object when used with a non-nil argument or a block" do
199
- assert_equal(@canvas, @canvas.send(:gs_getter_setter, :line_width, :w, 15))
200
- assert_equal(@canvas, @canvas.send(:gs_getter_setter, :line_width, :w, 15) {})
201
- end
202
-
203
- it "invokes the operator implementation when a non-nil argument is used" do
204
- assert_operator_invoked(:w, 5) { @canvas.send(:gs_getter_setter, :line_width, :w, 5) }
205
- assert_operator_invoked(:w, 15) { @canvas.send(:gs_getter_setter, :line_width, :w, 15) {} }
206
- end
207
-
208
- it "doesn't add an operator if the value is equal to the current one" do
209
- @canvas.send(:gs_getter_setter, :line_width, :w,
210
- @canvas.send(:gs_getter_setter, :line_width, :w, nil))
211
- assert_operators(@page.contents, [])
212
- end
213
-
214
- it "always saves and restores the graphics state if a block is used" do
215
- @canvas.send(:gs_getter_setter, :line_width, :w,
216
- @canvas.send(:gs_getter_setter, :line_width, :w, nil)) {}
217
- assert_operators(@page.contents, [[:save_graphics_state], [:restore_graphics_state]])
218
- end
219
-
220
- it "is serialized correctly when no block is used" do
221
- @canvas.send(:gs_getter_setter, :line_width, :w, 5)
222
- assert_operators(@page.contents, [[:set_line_width, [5]]])
223
- end
224
-
225
- it "is serialized correctly when a block is used" do
226
- @canvas.send(:gs_getter_setter, :line_width, :w, 5) do
227
- @canvas.send(:gs_getter_setter, :line_width, :w, 15)
228
- end
229
- assert_operators(@page.contents, [[:save_graphics_state],
230
- [:set_line_width, [5]],
231
- [:set_line_width, [15]],
232
- [:restore_graphics_state]])
233
- end
234
-
235
- it "fails if a block is given without an argument" do
236
- assert_raises(ArgumentError) { @canvas.send(:gs_getter_setter, :line_width, :w, nil) {} }
237
- end
238
-
239
- it "fails if invoked while in an unsupported graphics objects" do
240
- assert_raises_in_graphics_object(:path, :clipping_path) do
241
- @canvas.send(:gs_getter_setter, :line_width, :w, 5)
242
- end
243
- end
244
- end
245
-
246
- # Asserts that the method +name+ invoked with +values+ invokes the #gs_getter_setter helper method
247
- # with the +name+, +operator+ and +expected_value+ as arguments.
248
- def assert_gs_getter_setter(name, operator, expected_value, *values)
249
- args = [name, operator, expected_value]
250
- assert_method_invoked(@canvas, :gs_getter_setter, args, check_block: true) do
251
- @canvas.send(name, *values) {}
252
- end
253
- unless values.compact.empty?
254
- @canvas.send(name, *values)
255
- assert_equal(expected_value, @canvas.graphics_state.send(name))
256
- end
257
- assert_respond_to(@canvas, name)
258
- end
259
-
260
- describe "line_width" do
261
- it "uses the gs_getter_setter implementation" do
262
- assert_gs_getter_setter(:line_width, :w, 5, 5)
263
- assert_gs_getter_setter(:line_width, :w, nil, nil)
264
- end
265
- end
266
-
267
- describe "line_cap_style" do
268
- it "uses the gs_getter_setter implementation" do
269
- assert_gs_getter_setter(:line_cap_style, :J, 1, :round)
270
- assert_gs_getter_setter(:line_cap_style, :J, nil, nil)
271
- end
272
- end
273
-
274
- describe "line_join_style" do
275
- it "uses the gs_getter_setter implementation" do
276
- assert_gs_getter_setter(:line_join_style, :j, 1, :round)
277
- assert_gs_getter_setter(:line_join_style, :j, nil, nil)
278
- end
279
- end
280
-
281
- describe "miter_limit" do
282
- it "uses the gs_getter_setter implementation" do
283
- assert_gs_getter_setter(:miter_limit, :M, 15, 15)
284
- assert_gs_getter_setter(:miter_limit, :M, nil, nil)
285
- end
286
- end
287
-
288
- describe "line_dash_pattern" do
289
- it "uses the gs_getter_setter implementation" do
290
- assert_gs_getter_setter(:line_dash_pattern, :d, nil, nil)
291
- assert_gs_getter_setter(:line_dash_pattern, :d,
292
- HexaPDF::Content::LineDashPattern.new, 0)
293
- assert_gs_getter_setter(:line_dash_pattern, :d,
294
- HexaPDF::Content::LineDashPattern.new([5]), 5)
295
- assert_gs_getter_setter(:line_dash_pattern, :d,
296
- HexaPDF::Content::LineDashPattern.new([5], 2), 5, 2)
297
- assert_gs_getter_setter(:line_dash_pattern, :d,
298
- HexaPDF::Content::LineDashPattern.new([5, 3], 2), [5, 3], 2)
299
- assert_gs_getter_setter(:line_dash_pattern, :d,
300
- HexaPDF::Content::LineDashPattern.new([5, 3], 2),
301
- HexaPDF::Content::LineDashPattern.new([5, 3], 2))
302
- end
303
- end
304
-
305
- describe "rendering_intent" do
306
- it "uses the gs_getter_setter implementation" do
307
- assert_gs_getter_setter(:rendering_intent, :ri, :Perceptual, :Perceptual)
308
- assert_gs_getter_setter(:rendering_intent, :ri, nil, nil)
309
- end
310
- end
311
-
312
- describe "opacity" do
313
- it "returns the current values when no argument/nil arguments are provided" do
314
- assert_equal({fill_alpha: 1.0, stroke_alpha: 1.0}, @canvas.opacity)
315
- end
316
-
317
- it "returns the canvas object when at least one non-nil argument is provided" do
318
- assert_equal(@canvas, @canvas.opacity(fill_alpha: 0.5))
319
- end
320
-
321
- it "invokes the operator implementation when at least one non-nil argument is used" do
322
- assert_operator_invoked(:gs, :GS1) do
323
- @canvas.opacity(fill_alpha: 1.0, stroke_alpha: 0.5)
324
- end
325
- end
326
-
327
- it "doesn't add an operator if the values are not really changed" do
328
- @canvas.opacity(fill_alpha: 1.0, stroke_alpha: 1.0)
329
- assert_operators(@page.contents, [])
330
- end
331
-
332
- it "always saves and restores the graphics state if a block is used" do
333
- @canvas.opacity(fill_alpha: 1.0, stroke_alpha: 1.0) {}
334
- assert_operators(@page.contents, [[:save_graphics_state], [:restore_graphics_state]])
335
- end
336
-
337
- it "adds the needed entry to the /ExtGState resources dictionary" do
338
- @canvas.graphics_state.alpha_source = true
339
- @canvas.opacity(fill_alpha: 0.5, stroke_alpha: 0.7)
340
- assert_equal({Type: :ExtGState, CA: 0.7, ca: 0.5, AIS: false},
341
- @canvas.resources.ext_gstate(:GS1))
342
- end
343
-
344
- it "is serialized correctly when no block is used" do
345
- @canvas.opacity(fill_alpha: 0.5, stroke_alpha: 0.7)
346
- assert_operators(@page.contents, [[:set_graphics_state_parameters, [:GS1]]])
347
- end
348
-
349
- it "is serialized correctly when a block is used" do
350
- @canvas.opacity(fill_alpha: 0.5) do
351
- @canvas.opacity(stroke_alpha: 0.7)
352
- end
353
- assert_operators(@page.contents, [[:save_graphics_state],
354
- [:set_graphics_state_parameters, [:GS1]],
355
- [:set_graphics_state_parameters, [:GS2]],
356
- [:restore_graphics_state]])
357
- end
358
-
359
- it "fails if a block is given without an argument" do
360
- assert_raises(ArgumentError) { @canvas.opacity {} }
361
- end
362
-
363
- it "fails if invoked while in an unsupported graphics objects" do
364
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.opacity(fill_alpha: 1.0) }
365
- end
366
- end
367
-
368
- describe "private color_getter_setter" do
369
- def invoke(*params, &block)
370
- @canvas.send(:color_getter_setter, :stroke_color, params, :RG, :G, :K, :CS, :SCN, &block)
371
- end
372
-
373
- it "returns the current value when used with no argument" do
374
- color = @canvas.graphics_state.stroke_color
375
- assert_equal(color, invoke)
376
- end
377
-
378
- it "returns the canvas when used with a non-nil argument and no block" do
379
- assert_equal(@canvas, invoke(255))
380
- assert_equal(@canvas, invoke(255) {})
381
- end
382
-
383
- it "doesn't add an operator if the value is equal to the current one" do
384
- invoke(0.0)
385
- assert_operators(@page.contents, [])
386
- end
387
-
388
- it "always saves and restores the graphics state if a block is used" do
389
- invoke(0.0) {}
390
- assert_operators(@page.contents, [[:save_graphics_state], [:restore_graphics_state]])
391
- end
392
-
393
- it "adds an unknown color space to the resource dictionary" do
394
- invoke(HexaPDF::Content::ColorSpace::Universal.new([:Pattern, :DeviceRGB]).color(:Name))
395
- assert_equal([:Pattern, :DeviceRGB], @page.resources.color_space(:CS1).definition)
396
- end
397
-
398
- it "is serialized correctly when no block is used" do
399
- invoke(102)
400
- invoke([102])
401
- invoke("6600FF")
402
- invoke(102, 0, 255)
403
- invoke(0, 20, 40, 80)
404
- invoke(HexaPDF::Content::ColorSpace::Universal.new([:Pattern]).color(:Name))
405
- assert_operators(@page.contents, [[:set_device_gray_stroking_color, [0.4]],
406
- [:set_device_rgb_stroking_color, [0.4, 0, 1]],
407
- [:set_device_cmyk_stroking_color, [0, 0.2, 0.4, 0.8]],
408
- [:set_stroking_color_space, [:CS1]],
409
- [:set_stroking_color, [:Name]]])
410
- end
411
-
412
- it "is serialized correctly when a block is used" do
413
- invoke(102) { invoke(255) }
414
- assert_operators(@page.contents, [[:save_graphics_state],
415
- [:set_device_gray_stroking_color, [0.4]],
416
- [:set_device_gray_stroking_color, [1.0]],
417
- [:restore_graphics_state]])
418
- end
419
-
420
- it "fails if a block is given without an argument" do
421
- assert_raises(ArgumentError) { invoke {} }
422
- end
423
-
424
- it "fails if an unsupported number of component values is provided" do
425
- assert_raises(ArgumentError) { invoke(5, 5) }
426
- end
427
-
428
- it "fails if invoked while in an unsupported graphics objects" do
429
- assert_raises_in_graphics_object(:path, :clipping_path) { invoke(0.5) }
430
- end
431
- end
432
-
433
- # Asserts that the method +name+ invoked with +values+ invokes the #color_getter_setter helper
434
- # method with the +expected_values+ as arguments.
435
- def assert_color_getter_setter(name, expected_values, *values)
436
- assert_method_invoked(@canvas, :color_getter_setter, expected_values, check_block: true) do
437
- @canvas.send(name, *values) {}
438
- end
439
- end
440
-
441
- describe "stroke_color" do
442
- it "uses the color_getter_setter implementation" do
443
- assert_color_getter_setter(:stroke_color, [:stroke_color, [255], :RG, :G, :K, :CS, :SCN], 255)
444
- assert_color_getter_setter(:stroke_color, [:stroke_color, [], :RG, :G, :K, :CS, :SCN])
445
- end
446
- end
447
-
448
- describe "fill_color" do
449
- it "uses the color_getter_setter implementation" do
450
- assert_color_getter_setter(:fill_color, [:fill_color, [255], :rg, :g, :k, :cs, :scn], 255)
451
- assert_color_getter_setter(:fill_color, [:fill_color, [], :rg, :g, :k, :cs, :scn])
452
- end
453
- end
454
-
455
- describe "move_to" do
456
- it "invokes the operator implementation" do
457
- assert_operator_invoked(:m, 5, 6) { @canvas.move_to(5, 6) }
458
- end
459
-
460
- it "returns the canvas object" do
461
- assert_equal(@canvas, @canvas.move_to(5, 6))
462
- end
463
-
464
- it "sets the current point correctly" do
465
- @canvas.move_to(5, 6)
466
- assert_equal([5, 6], @canvas.current_point)
467
- end
468
-
469
- it "fails if invoked while in an unsupported graphics objects" do
470
- assert_raises_in_graphics_object(:clipping_path) { @canvas.move_to(5, 6) }
471
- end
472
- end
473
-
474
- describe "line_to" do
475
- before do
476
- @canvas.graphics_object = :path
477
- end
478
-
479
- it "invokes the operator implementation" do
480
- assert_operator_invoked(:l, 5, 6) { @canvas.line_to(5, 6) }
481
- end
482
-
483
- it "returns the canvas object" do
484
- assert_equal(@canvas, @canvas.line_to(5, 6))
485
- end
486
-
487
- it "sets the current point correctly" do
488
- @canvas.line_to(5, 6)
489
- assert_equal([5, 6], @canvas.current_point)
490
- end
491
-
492
- it "fails if invoked while in an unsupported graphics objects" do
493
- assert_raises_in_graphics_object(:none, :text, :clipping_path) { @canvas.line_to(5, 6) }
494
- end
495
- end
496
-
497
- describe "curve_to" do
498
- before do
499
- @canvas.graphics_object = :path
500
- end
501
-
502
- it "invokes the operator implementation" do
503
- assert_operator_invoked(:c, 5, 6, 7, 8, 9, 10) { @canvas.curve_to(9, 10, p1: [5, 6], p2: [7, 8]) }
504
- assert_operator_invoked(:v, 7, 8, 9, 10) { @canvas.curve_to(9, 10, p2: [7, 8]) }
505
- assert_operator_invoked(:y, 5, 6, 9, 10) { @canvas.curve_to(9, 10, p1: [5, 6]) }
506
- end
507
-
508
- it "returns the canvas object" do
509
- assert_equal(@canvas, @canvas.curve_to(5, 6, p1: [7, 8]))
510
- end
511
-
512
- it "sets the current point correctly" do
513
- @canvas.curve_to(5, 6, p1: [9, 10])
514
- assert_equal([5, 6], @canvas.current_point)
515
- end
516
-
517
- it "raises an error if both control points are omitted" do
518
- assert_raises(ArgumentError) { @canvas.curve_to(9, 10) }
519
- end
520
-
521
- it "fails if invoked while in an unsupported graphics objects" do
522
- assert_raises_in_graphics_object(:none, :text, :clipping_path) do
523
- @canvas.curve_to(5, 6, p1: [7, 8])
524
- end
525
- end
526
- end
527
-
528
- describe "rectangle" do
529
- it "invokes the operator implementation when radius == 0" do
530
- assert_operator_invoked(:re, 5, 10, 15, 20) { @canvas.rectangle(5, 10, 15, 20) }
531
- end
532
-
533
- it "invokes the polygon method when radius != 0" do
534
- args = [0, 0, 10, 0, 10, 10, 0, 10, {radius: 5}]
535
- assert_method_invoked(@canvas, :polygon, args) do
536
- @canvas.rectangle(0, 0, 10, 10, radius: 5)
537
- end
538
- end
539
-
540
- it "returns the canvas object" do
541
- assert_equal(@canvas, @canvas.rectangle(5, 6, 7, 8))
542
- end
543
-
544
- it "sets the current point correctly" do
545
- @canvas.rectangle(5, 6, 7, 8)
546
- assert_equal([5, 6], @canvas.current_point)
547
- end
548
-
549
- it "fails if invoked while in an unsupported graphics objects" do
550
- assert_raises_in_graphics_object(:clipping_path) { @canvas.rectangle(5, 6, 7, 8) }
551
- end
552
- end
553
-
554
- describe "close_subpath" do
555
- before do
556
- @canvas.graphics_object = :path
557
- end
558
-
559
- it "invokes the operator implementation" do
560
- assert_operator_invoked(:h) { @canvas.close_subpath }
561
- end
562
-
563
- it "returns the canvas object" do
564
- assert_equal(@canvas, @canvas.close_subpath)
565
- end
566
-
567
- it "sets the current point correctly" do
568
- @canvas.move_to(1, 1)
569
- @canvas.line_to(10, 10)
570
- @canvas.close_subpath
571
- assert_equal([1, 1], @canvas.current_point)
572
- end
573
-
574
- it "fails if invoked while in an unsupported graphics objects" do
575
- assert_raises_in_graphics_object(:none, :text) { @canvas.close_subpath }
576
- end
577
- end
578
-
579
- describe "line" do
580
- it "serializes correctly" do
581
- @canvas.line(1, 2, 3, 4)
582
- assert_operators(@canvas.contents, [[:move_to, [1, 2]], [:line_to, [3, 4]]])
583
- end
584
-
585
- it "returns the canvas object" do
586
- assert_equal(@canvas, @canvas.line(1, 2, 3, 4))
587
- end
588
- end
589
-
590
- describe "polyline" do
591
- it "serializes correctly" do
592
- @canvas.polyline(1, 2, 3, 4, 5, 6)
593
- assert_operators(@canvas.contents, [[:move_to, [1, 2]], [:line_to, [3, 4]], [:line_to, [5, 6]]])
594
- end
595
-
596
- it "returns the canvas object" do
597
- assert_equal(@canvas, @canvas.polyline(1, 2, 3, 4))
598
- end
599
-
600
- it "fails if not enought points are supplied" do
601
- assert_raises(ArgumentError) { @canvas.polyline(5, 6) }
602
- end
603
-
604
- it "fails if a y-coordinate is missing" do
605
- assert_raises(ArgumentError) { @canvas.polyline(5, 6, 7, 8, 9) }
606
- end
607
- end
608
-
609
- describe "polygon" do
610
- it "serializes correctly with no radius" do
611
- @canvas.polygon(1, 2, 3, 4, 5, 6)
612
- assert_operators(@canvas.contents, [[:move_to, [1, 2]], [:line_to, [3, 4]],
613
- [:line_to, [5, 6]], [:close_subpath]])
614
- end
615
-
616
- it "serializes correctly with a radius" do
617
- @canvas.polygon(-1, -1, -1, 1, 1, 1, 1, -1, radius: 1)
618
- k = @canvas.class::KAPPA.round(6)
619
- assert_operators(@canvas.contents, [[:move_to, [-1, 0]],
620
- [:line_to, [-1, 0]], [:curve_to, [-1, k, -k, 1, 0, 1]],
621
- [:line_to, [0, 1]], [:curve_to, [k, 1, 1, k, 1, 0]],
622
- [:line_to, [1, 0]], [:curve_to, [1, -k, k, -1, 0, -1]],
623
- [:line_to, [0, -1]], [:curve_to, [-k, -1, -1, -k, -1, 0]],
624
- [:close_subpath]])
625
- end
626
-
627
- it "returns the canvas object" do
628
- assert_equal(@canvas, @canvas.polyline(1, 2, 3, 4, 5, 6))
629
- end
630
- end
631
-
632
- describe "circle" do
633
- it "uses arc for the hard work" do
634
- assert_method_invoked(@canvas, :arc, [5, 6, {a: 7}]) do
635
- @canvas.graphics_object = :path
636
- @canvas.circle(5, 6, 7)
637
- end
638
- end
639
-
640
- it "serializes correctly" do
641
- @canvas.circle(0, 0, 1)
642
- assert_operators(@canvas.contents,
643
- [:move_to, :curve_to, :curve_to, :curve_to, :curve_to, :close_subpath],
644
- only_names: true)
645
- end
646
-
647
- it "returns the canvas object" do
648
- assert_equal(@canvas, @canvas.circle(1, 2, 3))
649
- end
650
- end
651
-
652
- describe "ellipse" do
653
- it "uses arc for the hard work" do
654
- assert_method_invoked(@canvas, :ellipse, [5, 6, {a: 7, b: 5, inclination: 10}]) do
655
- @canvas.ellipse(5, 6, a: 7, b: 5, inclination: 10)
656
- end
657
- end
658
-
659
- it "serializes correctly" do
660
- @canvas.ellipse(0, 0, a: 10, b: 5, inclination: 10)
661
- assert_operators(@canvas.contents,
662
- [:move_to, :curve_to, :curve_to, :curve_to, :curve_to, :close_subpath],
663
- only_names: true)
664
- end
665
-
666
- it "returns the canvas object" do
667
- assert_equal(@canvas, @canvas.circle(1, 2, 3))
668
- end
669
- end
670
-
671
- describe "arc" do
672
- it "serializes correctly" do
673
- @canvas.arc(0, 0, a: 1, b: 1, start_angle: 0, end_angle: 360, inclination: 0)
674
- @canvas.arc(0, 0, a: 1, b: 1, start_angle: 0, end_angle: 360, clockwise: true, inclination: 0)
675
- assert_operators(@canvas.contents, [[:move_to, [1, 0]],
676
- [:curve_to, [1, 0.548584, 0.548584, 1, 0, 1]],
677
- [:curve_to, [-0.548584, 1, -1, 0.548584, -1, 0]],
678
- [:curve_to, [-1, -0.548584, -0.548584, -1, 0, -1]],
679
- [:curve_to, [0.548584, -1, 1, -0.548584, 1, 0]],
680
- [:move_to, [1, 0]],
681
- [:curve_to, [1, -0.548584, 0.548584, -1, 0, -1]],
682
- [:curve_to, [-0.548584, -1, -1, -0.548584, -1, 0]],
683
- [:curve_to, [-1, 0.548584, -0.548584, 1, 0, 1]],
684
- [:curve_to, [0.548584, 1, 1, 0.548584, 1, 0]]])
685
- end
686
-
687
- it "returns the canvas object" do
688
- assert_equal(@canvas, @canvas.arc(1, 2, a: 3))
689
- end
690
- end
691
-
692
- describe "graphic_object" do
693
- it "returns a new graphic object given a name" do
694
- arc = @canvas.graphic_object(:arc)
695
- assert_respond_to(arc, :draw)
696
- arc1 = @canvas.graphic_object(:arc)
697
- refute_same(arc, arc1)
698
- end
699
-
700
- it "returns a configured graphic object given a name" do
701
- arc = @canvas.graphic_object(:arc, cx: 10)
702
- assert_equal(10, arc.cx)
703
- end
704
-
705
- it "reconfigures the given graphic object" do
706
- arc = @canvas.graphic_object(:arc)
707
- arc1 = @canvas.graphic_object(arc, cx: 10)
708
- assert_same(arc, arc1)
709
- assert_equal(10, arc.cx)
710
- end
711
- end
712
-
713
- describe "draw" do
714
- it "draws the, optionally configured, graphic object onto the canvas" do
715
- obj = Object.new
716
- obj.define_singleton_method(:options) { @options }
717
- obj.define_singleton_method(:configure) {|**kwargs| @options = kwargs; self }
718
- obj.define_singleton_method(:draw) {|canvas| canvas.move_to(@options[:x], @options[:y]) }
719
- @canvas.draw(obj, x: 5, y: 6)
720
- assert_operators(@canvas.contents, [[:move_to, [5, 6]]])
721
- end
722
-
723
- it "returns the canvas object" do
724
- assert_equal(@canvas, @canvas.draw(:arc))
725
- end
726
- end
727
-
728
- describe "path painting methods" do
729
- before do
730
- @canvas.graphics_object = :path
731
- end
732
-
733
- it "invokes the respective operator implementation" do
734
- assert_operator_invoked(:S) { @canvas.stroke }
735
- assert_operator_invoked(:s) { @canvas.close_stroke }
736
- assert_operator_invoked(:f) { @canvas.fill(:nonzero) }
737
- assert_operator_invoked(:'f*') { @canvas.fill(:even_odd) }
738
- assert_operator_invoked(:B) { @canvas.fill_stroke(:nonzero) }
739
- assert_operator_invoked(:'B*') { @canvas.fill_stroke(:even_odd) }
740
- assert_operator_invoked(:b) { @canvas.close_fill_stroke(:nonzero) }
741
- assert_operator_invoked(:'b*') { @canvas.close_fill_stroke(:even_odd) }
742
- assert_operator_invoked(:n) { @canvas.end_path }
743
- end
744
-
745
- it "returns the canvas object" do
746
- [:stroke, :close_stroke, :fill, :fill_stroke, :close_fill_stroke, :end_path].each do |m|
747
- @canvas.graphics_object = :path
748
- assert_equal(@canvas, @canvas.send(m))
749
- end
750
- end
751
-
752
- it "fails if invoked while in an unsupported graphics objects" do
753
- [:stroke, :close_stroke, :fill, :fill_stroke, :close_fill_stroke, :end_path].each do |m|
754
- assert_raises_in_graphics_object(:none, :text) { @canvas.send(m) }
755
- end
756
- end
757
- end
758
-
759
- describe "clip_path" do
760
- before do
761
- @canvas.graphics_object = :path
762
- end
763
-
764
- it "invokes the respective operator implementation" do
765
- assert_operator_invoked(:W) { @canvas.clip_path(:nonzero) }
766
- assert_operator_invoked(:'W*') { @canvas.clip_path(:even_odd) }
767
- end
768
-
769
- it "returns the canvas object" do
770
- assert_equal(@canvas, @canvas.clip_path)
771
- end
772
-
773
- it "fails if invoked while in an unsupported graphics objects" do
774
- assert_raises_in_graphics_object(:none, :text, :clipping_path) { @canvas.clip_path }
775
- end
776
- end
777
-
778
- describe "xobject" do
779
- before do
780
- @image = @doc.add({Type: :XObject, Subtype: :Image, Width: 10, Height: 5})
781
- @image.source_path = File.join(TEST_DATA_DIR, 'images', 'gray.jpg')
782
- @form = @doc.add({Type: :XObject, Subtype: :Form, BBox: [100, 50, 200, 100]})
783
- end
784
-
785
- it "can use any xobject specified via a filename" do
786
- xobject = @canvas.xobject(@image.source_path, at: [0, 0])
787
- assert_equal(xobject, @page.resources.xobject(:XO1))
788
- end
789
-
790
- it "can use any xobject specified via an IO object" do
791
- File.open(@image.source_path, 'rb') do |file|
792
- xobject = @canvas.xobject(file, at: [0, 0])
793
- assert_equal(xobject, @page.resources.xobject(:XO1))
794
- end
795
- end
796
-
797
- it "can use an already existing xobject" do
798
- xobject = @canvas.xobject(@image, at: [0, 0])
799
- assert_equal(xobject, @page.resources.xobject(:XO1))
800
- end
801
-
802
- it "correctly serializes the image with no options" do
803
- @canvas.xobject(@image, at: [1, 2])
804
- assert_operators(@page.contents, [[:save_graphics_state],
805
- [:concatenate_matrix, [10, 0, 0, 5, 1, 2]],
806
- [:paint_xobject, [:XO1]],
807
- [:restore_graphics_state]])
808
- end
809
-
810
- it "correctly serializes the image with just the width given" do
811
- @canvas.image(@image, at: [1, 2], width: 20)
812
- assert_operators(@page.contents, [[:save_graphics_state],
813
- [:concatenate_matrix, [20, 0, 0, 10, 1, 2]],
814
- [:paint_xobject, [:XO1]],
815
- [:restore_graphics_state]])
816
- end
817
-
818
- it "correctly serializes the image with just the height given" do
819
- @canvas.image(@image, at: [1, 2], height: 10)
820
- assert_operators(@page.contents, [[:save_graphics_state],
821
- [:concatenate_matrix, [20, 0, 0, 10, 1, 2]],
822
- [:paint_xobject, [:XO1]],
823
- [:restore_graphics_state]])
824
- end
825
-
826
- it "correctly serializes the image with both width and height given" do
827
- @canvas.image(@image, at: [1, 2], width: 10, height: 20)
828
- assert_operators(@page.contents, [[:save_graphics_state],
829
- [:concatenate_matrix, [10, 0, 0, 20, 1, 2]],
830
- [:paint_xobject, [:XO1]],
831
- [:restore_graphics_state]])
832
- end
833
-
834
- it "doesn't do anything if the image's width or height is zero" do
835
- @image[:Width] = 0
836
- @canvas.xobject(@image, at: [0, 0])
837
- assert_operators(@page.contents, [])
838
-
839
- @image[:Width] = 10
840
- @image[:Height] = 0
841
- @canvas.xobject(@image, at: [0, 0])
842
- assert_operators(@page.contents, [])
843
- end
844
-
845
- it "correctly serializes the form with no options" do
846
- @canvas.xobject(@form, at: [1, 2])
847
- assert_operators(@page.contents, [[:save_graphics_state],
848
- [:concatenate_matrix, [1, 0, 0, 1, -99, -48]],
849
- [:paint_xobject, [:XO1]],
850
- [:restore_graphics_state]])
851
- end
852
-
853
- it "correctly serializes the form with just the width given" do
854
- @canvas.image(@form, at: [1, 2], width: 50)
855
- assert_operators(@page.contents, [[:save_graphics_state],
856
- [:concatenate_matrix, [0.5, 0, 0, 0.5, -99, -48]],
857
- [:paint_xobject, [:XO1]],
858
- [:restore_graphics_state]])
859
- end
860
-
861
- it "correctly serializes the form with just the height given" do
862
- @canvas.image(@form, at: [1, 2], height: 10)
863
- assert_operators(@page.contents, [[:save_graphics_state],
864
- [:concatenate_matrix, [0.2, 0, 0, 0.2, -99, -48]],
865
- [:paint_xobject, [:XO1]],
866
- [:restore_graphics_state]])
867
- end
868
-
869
- it "correctly serializes the form with both width and height given" do
870
- @canvas.image(@form, at: [1, 2], width: 50, height: 10)
871
- assert_operators(@page.contents, [[:save_graphics_state],
872
- [:concatenate_matrix, [0.5, 0, 0, 0.2, -99, -48]],
873
- [:paint_xobject, [:XO1]],
874
- [:restore_graphics_state]])
875
- end
876
-
877
- it "doesn't do anything if the form's width or height is zero" do
878
- @form[:BBox] = [100, 50, 100, 200]
879
- @canvas.xobject(@form, at: [0, 0])
880
- assert_operators(@page.contents, [])
881
-
882
- @form[:BBox] = [100, 50, 150, 50]
883
- @canvas.xobject(@form, at: [0, 0])
884
- assert_operators(@page.contents, [])
885
- end
886
- end
887
-
888
- describe "character_spacing" do
889
- it "uses the gs_getter_setter implementation" do
890
- assert_gs_getter_setter(:character_spacing, :Tc, 0.25, 0.25)
891
- assert_gs_getter_setter(:character_spacing, :Tc, nil, nil)
892
- end
893
- end
894
-
895
- describe "word_spacing" do
896
- it "uses the gs_getter_setter implementation" do
897
- assert_gs_getter_setter(:word_spacing, :Tw, 0.25, 0.25)
898
- assert_gs_getter_setter(:word_spacing, :Tw, nil, nil)
899
- end
900
- end
901
-
902
- describe "horizontal_scaling" do
903
- it "uses the gs_getter_setter implementation" do
904
- assert_gs_getter_setter(:horizontal_scaling, :Tz, 50, 50)
905
- assert_gs_getter_setter(:horizontal_scaling, :Tz, nil, nil)
906
- end
907
- end
908
-
909
- describe "leading" do
910
- it "uses the gs_getter_setter implementation" do
911
- assert_gs_getter_setter(:leading, :TL, 15, 15)
912
- assert_gs_getter_setter(:leading, :TL, nil, nil)
913
- end
914
- end
915
-
916
- describe "text_rendering_mode" do
917
- it "uses the gs_getter_setter implementation" do
918
- assert_gs_getter_setter(:text_rendering_mode, :Tr, 0, :fill)
919
- assert_gs_getter_setter(:text_rendering_mode, :Tr, nil, nil)
920
- end
921
- end
922
-
923
- describe "text_rise" do
924
- it "uses the gs_getter_setter implementation" do
925
- assert_gs_getter_setter(:text_rise, :Ts, 15, 15)
926
- assert_gs_getter_setter(:text_rise, :Ts, nil, nil)
927
- end
928
- end
929
-
930
- describe "begin_text" do
931
- it "invokes the operator implementation" do
932
- assert_operator_invoked(:BT) { @canvas.begin_text }
933
- end
934
-
935
- it "serializes correctly" do
936
- @canvas.begin_text
937
- @canvas.begin_text
938
- @canvas.begin_text(force_new: true)
939
- assert_operators(@canvas.contents, [:begin_text, :end_text, :begin_text], only_names: true)
940
- end
941
-
942
- it "returns the canvas object" do
943
- assert_equal(@canvas, @canvas.begin_text)
944
- end
945
-
946
- it "fails if the current graphics object doesn't allow a new text object" do
947
- assert_raises(HexaPDF::Error) do
948
- @canvas.graphics_object = :path
949
- @canvas.begin_text
950
- end
951
- end
952
-
953
- it "fails if invoked while in an unsupported graphics objects" do
954
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.begin_text }
955
- end
956
- end
957
-
958
- describe "end_text" do
959
- it "invokes the operator implementation" do
960
- @canvas.graphics_object = :text
961
- assert_operator_invoked(:ET) { @canvas.end_text }
962
- end
963
-
964
- it "serializes correctly" do
965
- @canvas.end_text
966
- @canvas.begin_text
967
- @canvas.end_text
968
- @canvas.end_text
969
- assert_operators(@page.contents, [:begin_text, :end_text], only_names: true)
970
- end
971
-
972
- it "returns the canvas object" do
973
- assert_equal(@canvas, @canvas.begin_text)
974
- end
975
-
976
- it "fails if invoked while in an unsupported graphics objects" do
977
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.end_text }
978
- end
979
- end
980
-
981
- describe "text_matrix" do
982
- it "invokes the operator implementation" do
983
- @canvas.text_matrix(1, 2, 3, 4, 5, 6)
984
- assert_operators(@canvas.contents, [[:begin_text],
985
- [:set_text_matrix, [1, 2, 3, 4, 5, 6]]])
986
- end
987
-
988
- it "returns the canvas object" do
989
- assert_equal(@canvas, @canvas.text_matrix(1, 1, 1, 1, 1, 1))
990
- end
991
- end
992
-
993
- describe "move_text_cursor" do
994
- describe "invokes the operator implementation" do
995
- it "moves to the next line" do
996
- @canvas.move_text_cursor
997
- assert_operators(@canvas.contents, [[:begin_text],
998
- [:move_text_next_line]])
999
- end
1000
-
1001
- it "moves to the next line with an offset" do
1002
- @canvas.move_text_cursor(offset: [5, 10], absolute: false)
1003
- assert_operators(@canvas.contents, [[:begin_text],
1004
- [:move_text, [5, 10]]])
1005
- end
1006
-
1007
- it "moves to an absolute position" do
1008
- @canvas.move_text_cursor(offset: [5, 10], absolute: true)
1009
- assert_operators(@canvas.contents, [[:begin_text],
1010
- [:set_text_matrix, [1, 0, 0, 1, 5, 10]]])
1011
- end
1012
- end
1013
-
1014
- it "returns the canvas object" do
1015
- assert_equal(@canvas, @canvas.move_text_cursor)
1016
- end
1017
- end
1018
-
1019
- describe "text_cursor" do
1020
- it "returns the text cursor position" do
1021
- @canvas.move_text_cursor(offset: [5, 10])
1022
- assert_equal([5, 10], @canvas.text_cursor)
1023
- end
1024
-
1025
- it "fails if invoked outside a text object" do
1026
- assert_raises_in_graphics_object(:none, :path, :clipping_path) { @canvas.text_cursor }
1027
- end
1028
- end
1029
-
1030
- describe "font" do
1031
- it "returns the set font" do
1032
- assert_nil(@canvas.font)
1033
- @canvas.font("Times", size: 10)
1034
- assert_same(@doc.fonts.add("Times"), @canvas.font)
1035
- @canvas.font(@canvas.font)
1036
- assert_same(@doc.fonts.add("Times"), @canvas.font)
1037
- @canvas.font("Helvetica", size: 10)
1038
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
1039
- [:set_font_and_size, [:F2, 10]]])
1040
- end
1041
-
1042
- it "sets the font and optionally the font size" do
1043
- @canvas.font("Times", size: 12, variant: :italic)
1044
- assert_same(@doc.fonts.add("Times", variant: :italic), @canvas.font)
1045
- assert_equal(12, @canvas.font_size)
1046
- @canvas.font("Helvetica")
1047
- assert_equal(12, @canvas.font_size)
1048
- end
1049
- end
1050
-
1051
- describe "font_size" do
1052
- it "returns the set font size" do
1053
- assert_equal(0, @canvas.font_size)
1054
- @canvas.font("Times", size: 10) # calls #font_size
1055
- assert_equal(10, @canvas.font_size)
1056
- end
1057
-
1058
- it "sets the font size" do
1059
- @canvas.font("Times", size: 10)
1060
- assert_equal(10, @canvas.font_size)
1061
- end
1062
-
1063
- it "fails if no valid font is already set" do
1064
- assert_raises(HexaPDF::Error) { @canvas.font_size(10) }
1065
- end
1066
- end
1067
-
1068
- describe "show_glyphs" do
1069
- it "serializes correctly" do
1070
- @canvas.font("Times", size: 20)
1071
- @canvas.horizontal_scaling(200)
1072
- @canvas.character_spacing(1)
1073
- @canvas.word_spacing(2)
1074
-
1075
- font = @canvas.font
1076
- @canvas.show_glyphs(font.decode_utf8("Hal lo").insert(2, -35).insert(0, -10))
1077
- assert_in_delta(116.68, @canvas.text_cursor[0])
1078
- assert_equal(0, @canvas.text_cursor[1])
1079
- @canvas.font_size(10)
1080
- @canvas.show_glyphs(font.decode_utf8("Hal"))
1081
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
1082
- [:set_horizontal_scaling, [200]],
1083
- [:set_character_spacing, [1]],
1084
- [:set_word_spacing, [2]],
1085
- [:begin_text],
1086
- [:show_text_with_positioning, [['', -10, "Ha", -35, "l lo"]]],
1087
- [:set_font_and_size, [:F1, 10]],
1088
- [:show_text_with_positioning, [["Hal"]]]])
1089
- end
1090
-
1091
- it "does nothing if there are no glyphs" do
1092
- @canvas.show_glyphs_only([])
1093
- assert_operators(@canvas.contents, [])
1094
- end
1095
- end
1096
-
1097
- describe "show_glyphs_only" do
1098
- it "serializes positioned glyphs correctly" do
1099
- @canvas.font("Times", size: 20)
1100
- font = @canvas.font
1101
- @canvas.show_glyphs_only(font.decode_utf8("Hal lo").insert(2, -35))
1102
- assert_equal(0, @canvas.text_cursor[0])
1103
- assert_equal(0, @canvas.text_cursor[1])
1104
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
1105
- [:begin_text],
1106
- [:show_text_with_positioning, [["Ha", -35, "l lo"]]]])
1107
- end
1108
-
1109
- it "serializes unpositioned glyphs correctly" do
1110
- @canvas.font("Times", size: 20)
1111
- font = @canvas.font
1112
- @canvas.show_glyphs_only(font.decode_utf8("Hallo"))
1113
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 20]],
1114
- [:begin_text],
1115
- [:show_text, ["Hallo"]]])
1116
- end
1117
-
1118
- it "does nothing if there are no glyphs" do
1119
- @canvas.show_glyphs_only([])
1120
- assert_operators(@canvas.contents, [])
1121
- end
1122
- end
1123
-
1124
- describe "text" do
1125
- it "sets the text cursor position if instructed" do
1126
- @canvas.font("Times", size: 10)
1127
- @canvas.text("Hallo", at: [100, 100])
1128
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
1129
- [:begin_text],
1130
- [:set_text_matrix, [1, 0, 0, 1, 100, 100]],
1131
- [:show_text_with_positioning, [["Hallo"]]]])
1132
- end
1133
-
1134
- it "shows text, possibly split over multiple lines" do
1135
- @canvas.font("Times", size: 10)
1136
- @canvas.text("H\u{D A}H\u{A}H\u{B}H\u{c}H\u{D}H\u{85}H\u{2028}H\u{2029}H")
1137
- assert_operators(@canvas.contents, [[:set_font_and_size, [:F1, 10]],
1138
- [:begin_text],
1139
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1140
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1141
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1142
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1143
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1144
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1145
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1146
- [:show_text_with_positioning, [["H"]]], [:move_text_next_line],
1147
- [:show_text_with_positioning, [["H"]]]])
1148
- end
1149
-
1150
- it "fails if no valid font is set" do
1151
- error = assert_raises(HexaPDF::Error) { @canvas.text("test") }
1152
- assert_match(/if a font is set/, error.message)
1153
- end
1154
- end
1155
-
1156
- describe "marked_content_point" do
1157
- it "invokes the operator implementation" do
1158
- assert_operator_invoked(:MP, :tag) { @canvas.marked_content_point(:tag) }
1159
- assert_operator_invoked(:DP, :tag, :P1) do
1160
- @canvas.marked_content_point(:tag, property_list: {key: 5})
1161
- end
1162
- end
1163
-
1164
- it "is serialized correctly" do
1165
- @canvas.marked_content_point(:tag)
1166
- assert_operators(@canvas.contents, [[:designate_marked_content_point, [:tag]]])
1167
- end
1168
-
1169
- it "fails if invoked while in an unsupported graphics objects" do
1170
- assert_raises_in_graphics_object(:path, :clipping_path) { @canvas.marked_content_point(:tag) }
1171
- end
1172
- end
1173
-
1174
- describe "marked_content_sequence" do
1175
- it "invokes the operator implementation" do
1176
- assert_operator_invoked(:BMC, :tag) { @canvas.marked_content_sequence(:tag) }
1177
- assert_operator_invoked(:BDC, :tag, :P1) do
1178
- @canvas.marked_content_sequence(:tag, property_list: {key: 5})
1179
- end
1180
- end
1181
-
1182
- it "is serialized correctly when no block is used" do
1183
- @canvas.marked_content_sequence(:tag)
1184
- assert_operators(@canvas.contents, [[:begin_marked_content, [:tag]]])
1185
- end
1186
-
1187
- it "is serialized correctly when a block is used" do
1188
- @canvas.marked_content_sequence(:tag, property_list: {key: 5}) {}
1189
- assert_operators(@canvas.contents, [[:begin_marked_content_with_property_list, [:tag, :P1]],
1190
- [:end_marked_content]])
1191
- end
1192
-
1193
- it "fails if invoked while in an unsupported graphics objects" do
1194
- assert_raises_in_graphics_object(:path, :clipping_path) do
1195
- @canvas.marked_content_sequence(:tag)
1196
- end
1197
- end
1198
- end
1199
-
1200
- describe "end_marked_content_sequence" do
1201
- it "invokes the operator implementation" do
1202
- assert_operator_invoked(:EMC) { @canvas.end_marked_content_sequence }
1203
- end
1204
-
1205
- it "is serialized correctly" do
1206
- @canvas.end_marked_content_sequence
1207
- assert_operators(@page.contents, [[:end_marked_content]])
1208
- end
1209
-
1210
- it "fails if invoked while in an unsupported graphics objects" do
1211
- assert_raises_in_graphics_object(:path, :clipping_path) do
1212
- @canvas.end_marked_content_sequence
1213
- end
1214
- end
1215
- end
1216
- end