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,779 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- require 'test_helper'
4
- require_relative '../content/common'
5
- require 'hexapdf/document'
6
- require 'hexapdf/layout/style'
7
- require 'hexapdf/layout/text_layouter'
8
- require 'hexapdf/layout/box'
9
-
10
- describe HexaPDF::Layout::Style::LineSpacing do
11
- before do
12
- @line1 = Object.new
13
- @line1.define_singleton_method(:y_min) { - 1 }
14
- @line1.define_singleton_method(:y_max) { 2 }
15
- @line2 = Object.new
16
- @line2.define_singleton_method(:y_min) { -3 }
17
- @line2.define_singleton_method(:y_max) { 4 }
18
- end
19
-
20
- def line_spacing(type, value = nil)
21
- HexaPDF::Layout::Style::LineSpacing.new(type: type, value: value)
22
- end
23
-
24
- it "allows single line spacing" do
25
- obj = line_spacing(:single)
26
- assert_equal(:proportional, obj.type)
27
- assert_equal(1, obj.value)
28
- assert_equal(1 + 4, obj.baseline_distance(@line1, @line2))
29
- assert_equal(0, obj.gap(@line1, @line2))
30
- end
31
-
32
- it "allows double line spacing" do
33
- obj = line_spacing(:double)
34
- assert_equal(:proportional, obj.type)
35
- assert_equal(2, obj.value)
36
- assert_equal((1 + 4) * 2, obj.baseline_distance(@line1, @line2))
37
- assert_equal(1 + 4, obj.gap(@line1, @line2))
38
- end
39
-
40
- it "allows proportional line spacing" do
41
- obj = line_spacing(:proportional, 1.5)
42
- assert_equal(:proportional, obj.type)
43
- assert_equal(1.5, obj.value)
44
- assert_equal((1 + 4) * 1.5, obj.baseline_distance(@line1, @line2))
45
- assert_equal((1 + 4) * 0.5, obj.gap(@line1, @line2))
46
- end
47
-
48
- it "allows fixed line spacing" do
49
- obj = line_spacing(:fixed, 7)
50
- assert_equal(:fixed, obj.type)
51
- assert_equal(7, obj.value)
52
- assert_equal(7, obj.baseline_distance(@line1, @line2))
53
- assert_equal(7 - 1 - 4, obj.gap(@line1, @line2))
54
- end
55
-
56
- it "allows line spacing using a leading value" do
57
- obj = line_spacing(:leading, 3)
58
- assert_equal(:leading, obj.type)
59
- assert_equal(3, obj.value)
60
- assert_equal(1 + 4 + 3, obj.baseline_distance(@line1, @line2))
61
- assert_equal(3, obj.gap(@line1, @line2))
62
- end
63
-
64
- it "allows using a LineSpacing object as type" do
65
- obj = line_spacing(line_spacing(:single))
66
- assert_equal(:proportional, obj.type)
67
- end
68
-
69
- it "raises an error if a value is needed and none is provided" do
70
- assert_raises(ArgumentError) { line_spacing(:proportional) }
71
- end
72
-
73
- it "raises an error if an invalid type is provided" do
74
- assert_raises(ArgumentError) { line_spacing(:invalid) }
75
- end
76
- end
77
-
78
- describe HexaPDF::Layout::Style::Quad do
79
- def create_quad(val)
80
- HexaPDF::Layout::Style::Quad.new(val)
81
- end
82
-
83
- describe "initialize" do
84
- it "works with a single value" do
85
- quad = create_quad(5)
86
- assert_equal(5, quad.top)
87
- assert_equal(5, quad.right)
88
- assert_equal(5, quad.bottom)
89
- assert_equal(5, quad.left)
90
-
91
- quad = create_quad([5])
92
- assert_equal(5, quad.top)
93
- assert_equal(5, quad.right)
94
- assert_equal(5, quad.bottom)
95
- assert_equal(5, quad.left)
96
- end
97
-
98
- it "works with two values" do
99
- quad = create_quad([5, 2])
100
- assert_equal(5, quad.top)
101
- assert_equal(2, quad.right)
102
- assert_equal(5, quad.bottom)
103
- assert_equal(2, quad.left)
104
- end
105
-
106
- it "works with three values" do
107
- quad = create_quad([5, 2, 7])
108
- assert_equal(5, quad.top)
109
- assert_equal(2, quad.right)
110
- assert_equal(7, quad.bottom)
111
- assert_equal(2, quad.left)
112
- end
113
-
114
- it "works with four or more values" do
115
- quad = create_quad([5, 2, 7, 1, 9])
116
- assert_equal(5, quad.top)
117
- assert_equal(2, quad.right)
118
- assert_equal(7, quad.bottom)
119
- assert_equal(1, quad.left)
120
- end
121
-
122
- it "works with a Quad as value" do
123
- quad = create_quad([5, 2, 7, 1])
124
- new_quad = create_quad(quad)
125
- assert_equal(new_quad.top, quad.top)
126
- assert_equal(new_quad.right, quad.right)
127
- assert_equal(new_quad.bottom, quad.bottom)
128
- assert_equal(new_quad.left, quad.left)
129
- end
130
- end
131
-
132
- it "can be asked if it contains only a single value" do
133
- assert(create_quad(5).simple?)
134
- refute(create_quad([5, 2]).simple?)
135
- end
136
- end
137
-
138
- describe HexaPDF::Layout::Style::Border do
139
- def create_border(**args)
140
- HexaPDF::Layout::Style::Border.new(**args)
141
- end
142
-
143
- it "has accessors for with, color and style that return Quads" do
144
- border = create_border
145
- assert_kind_of(HexaPDF::Layout::Style::Quad, border.width)
146
- assert_kind_of(HexaPDF::Layout::Style::Quad, border.color)
147
- assert_kind_of(HexaPDF::Layout::Style::Quad, border.style)
148
- end
149
-
150
- it "can be duplicated" do
151
- border = create_border
152
- copy = border.dup
153
- border.width.top = 10
154
- border.color.top = :red
155
- border.style.top = :dotted
156
- assert_equal(0, copy.width.top)
157
- assert_equal(0, copy.color.top)
158
- assert_equal(:solid, copy.style.top)
159
- end
160
-
161
- it "can be asked whether a border is defined" do
162
- assert(create_border.none?)
163
- refute(create_border(width: 5).none?)
164
- end
165
-
166
- describe "draw" do
167
- before do
168
- @canvas = HexaPDF::Document.new.pages.add.canvas
169
- end
170
-
171
- it "draws nothing if no border is defined" do
172
- border = create_border
173
- border.draw(@canvas, 0, 0, 100, 100)
174
- assert_operators(@canvas.contents, [])
175
- end
176
-
177
- describe "simple - same width, color and style on all sides" do
178
- it "works with style solid" do
179
- border = create_border(width: 10, color: 0.5, style: :solid)
180
- border.draw(@canvas, 0, 0, 100, 100)
181
- assert_operators(@canvas.contents, [[:save_graphics_state],
182
- [:set_device_gray_stroking_color, [0.5]],
183
- [:set_line_width, [10]],
184
- [:append_rectangle, [0, 0, 100, 100]],
185
- [:clip_path_non_zero], [:end_path],
186
- [:append_rectangle, [5, 5, 90, 90]],
187
- [:stroke_path],
188
- [:restore_graphics_state]])
189
- end
190
-
191
- it "works with style dashed" do
192
- border = create_border(width: 10, color: 0.5, style: :dashed)
193
- border.draw(@canvas, 0, 0, 200, 300)
194
- ops = [[:save_graphics_state],
195
- [:set_device_gray_stroking_color, [0.5]],
196
- [:set_line_width, [10]],
197
- [:set_line_cap_style, [2]],
198
- [:append_rectangle, [0, 0, 200, 300]],
199
- [:clip_path_non_zero], [:end_path],
200
- [:set_line_dash_pattern, [[10, 20], 25]],
201
- [:move_to, [0, 295]], [:line_to, [200, 295]],
202
- [:move_to, [200, 5]], [:line_to, [0, 5]],
203
- [:stroke_path],
204
- [:set_line_dash_pattern, [[10, 18], 23]],
205
- [:move_to, [195, 300]], [:line_to, [195, 0]],
206
- [:move_to, [5, 0]], [:line_to, [5, 300]],
207
- [:stroke_path],
208
- [:restore_graphics_state]]
209
- assert_operators(@canvas.contents, ops)
210
- end
211
-
212
- it "works with style dashed_round" do
213
- border = create_border(width: 10, color: 0.5, style: :dashed_round)
214
- border.draw(@canvas, 0, 0, 200, 300)
215
- ops = [[:save_graphics_state],
216
- [:set_device_gray_stroking_color, [0.5]],
217
- [:set_line_width, [10]],
218
- [:set_line_cap_style, [1]],
219
- [:append_rectangle, [0, 0, 200, 300]],
220
- [:clip_path_non_zero], [:end_path],
221
- [:set_line_dash_pattern, [[10, 20], 25]],
222
- [:move_to, [0, 295]], [:line_to, [200, 295]],
223
- [:move_to, [200, 5]], [:line_to, [0, 5]],
224
- [:stroke_path],
225
- [:set_line_dash_pattern, [[10, 18], 23]],
226
- [:move_to, [195, 300]], [:line_to, [195, 0]],
227
- [:move_to, [5, 0]], [:line_to, [5, 300]],
228
- [:stroke_path],
229
- [:restore_graphics_state]]
230
- assert_operators(@canvas.contents, ops)
231
- end
232
-
233
- it "works with style dotted" do
234
- border = create_border(width: 10, color: 0.5, style: :dotted)
235
- border.draw(@canvas, 0, 0, 100, 200)
236
- ops = [[:save_graphics_state],
237
- [:set_device_gray_stroking_color, [0.5]],
238
- [:set_line_width, [10]],
239
- [:set_line_cap_style, [1]],
240
- [:append_rectangle, [0, 0, 100, 200]],
241
- [:clip_path_non_zero], [:end_path],
242
- [:set_line_dash_pattern, [[0, 18], 13]],
243
- [:move_to, [0, 195]], [:line_to, [100, 195]],
244
- [:move_to, [100, 5]], [:line_to, [0, 5]],
245
- [:stroke_path],
246
- [:set_line_dash_pattern, [[0, 19], 14]],
247
- [:move_to, [95, 200]], [:line_to, [95, 0]],
248
- [:move_to, [5, 0]], [:line_to, [5, 200]],
249
- [:stroke_path],
250
- [:restore_graphics_state]]
251
- assert_operators(@canvas.contents, ops)
252
- end
253
- end
254
-
255
- describe "complex borders where edges have different width/color/style values" do
256
- it "works correctly for the top border" do
257
- border = create_border(width: [10, 0, 0, 0], color: 0.5, style: :dashed)
258
- border.draw(@canvas, 0, 0, 200, 300)
259
- ops = [[:save_graphics_state],
260
- [:save_graphics_state],
261
- [:move_to, [0, 300]], [:line_to, [200, 300]],
262
- [:line_to, [200, 290]], [:line_to, [0, 290]],
263
- [:clip_path_non_zero], [:end_path],
264
- [:set_device_gray_stroking_color, [0.5]],
265
- [:set_line_width, [10]],
266
- [:set_line_cap_style, [2]],
267
- [:set_line_dash_pattern, [[10, 20], 25]],
268
- [:move_to, [0, 295]], [:line_to, [200, 295]],
269
- [:stroke_path],
270
- [:restore_graphics_state],
271
- [:restore_graphics_state]]
272
- assert_operators(@canvas.contents, ops)
273
- end
274
-
275
- it "works correctly for the right border" do
276
- border = create_border(width: [0, 10, 0, 0], color: 0.5, style: :dashed)
277
- border.draw(@canvas, 0, 0, 200, 300)
278
- ops = [[:save_graphics_state],
279
- [:save_graphics_state],
280
- [:move_to, [200, 300]], [:line_to, [200, 0]],
281
- [:line_to, [190, 0]], [:line_to, [190, 300]],
282
- [:clip_path_non_zero], [:end_path],
283
- [:set_device_gray_stroking_color, [0.5]],
284
- [:set_line_width, [10]],
285
- [:set_line_cap_style, [2]],
286
- [:set_line_dash_pattern, [[10, 18], 23]],
287
- [:move_to, [195, 300]], [:line_to, [195, 0]],
288
- [:stroke_path],
289
- [:restore_graphics_state],
290
- [:restore_graphics_state]]
291
- assert_operators(@canvas.contents, ops)
292
- end
293
-
294
- it "works correctly for the bottom border" do
295
- border = create_border(width: [0, 0, 10, 0], color: 0.5, style: :dashed)
296
- border.draw(@canvas, 0, 0, 200, 300)
297
- ops = [[:save_graphics_state],
298
- [:save_graphics_state],
299
- [:move_to, [200, 0]], [:line_to, [0, 0]],
300
- [:line_to, [0, 10]], [:line_to, [200, 10]],
301
- [:clip_path_non_zero], [:end_path],
302
- [:set_device_gray_stroking_color, [0.5]],
303
- [:set_line_width, [10]],
304
- [:set_line_cap_style, [2]],
305
- [:set_line_dash_pattern, [[10, 20], 25]],
306
- [:move_to, [200, 5]], [:line_to, [0, 5]],
307
- [:stroke_path],
308
- [:restore_graphics_state],
309
- [:restore_graphics_state]]
310
- assert_operators(@canvas.contents, ops)
311
- end
312
-
313
- it "works correctly for the left border" do
314
- border = create_border(width: [0, 0, 0, 10], color: 0.5, style: :dashed)
315
- border.draw(@canvas, 0, 0, 200, 300)
316
- ops = [[:save_graphics_state],
317
- [:save_graphics_state],
318
- [:move_to, [0, 0]], [:line_to, [0, 300]],
319
- [:line_to, [10, 300]], [:line_to, [10, 0]],
320
- [:clip_path_non_zero], [:end_path],
321
- [:set_device_gray_stroking_color, [0.5]],
322
- [:set_line_width, [10]],
323
- [:set_line_cap_style, [2]],
324
- [:set_line_dash_pattern, [[10, 18], 23]],
325
- [:move_to, [5, 0]], [:line_to, [5, 300]],
326
- [:stroke_path],
327
- [:restore_graphics_state],
328
- [:restore_graphics_state]]
329
- assert_operators(@canvas.contents, ops)
330
- end
331
-
332
- it "works with all values combined" do
333
- border = create_border(width: [20, 10, 40, 30], color: [0, 0.25, 0.5, 0.75],
334
- style: [:solid, :dashed, :dashed_round, :dotted])
335
- border.draw(@canvas, 0, 0, 100, 200)
336
- ops = [[:save_graphics_state],
337
- [:save_graphics_state],
338
- [:move_to, [0, 200]], [:line_to, [100, 200]],
339
- [:line_to, [90, 180]], [:line_to, [30, 180]], [:clip_path_non_zero], [:end_path],
340
- [:set_line_width, [20]],
341
- [:move_to, [0, 190]], [:line_to, [100, 190]], [:stroke_path],
342
- [:restore_graphics_state], [:save_graphics_state],
343
- [:move_to, [100, 200]], [:line_to, [100, 0]],
344
- [:line_to, [90, 40]], [:line_to, [90, 180]], [:clip_path_non_zero], [:end_path],
345
- [:set_device_gray_stroking_color, [0.25]], [:set_line_width, [10]],
346
- [:set_line_cap_style, [2]], [:set_line_dash_pattern, [[10, 20], 25]],
347
- [:move_to, [95, 200]], [:line_to, [95, 0]], [:stroke_path],
348
- [:restore_graphics_state], [:save_graphics_state],
349
- [:move_to, [100, 0]], [:line_to, [0, 0]],
350
- [:line_to, [30, 40]], [:line_to, [90, 40]], [:clip_path_non_zero], [:end_path],
351
- [:set_device_gray_stroking_color, [0.5]], [:set_line_width, [40]],
352
- [:set_line_cap_style, [1]], [:set_line_dash_pattern, [[40, 0], 20]],
353
- [:move_to, [100, 20]], [:line_to, [0, 20]], [:stroke_path],
354
- [:restore_graphics_state], [:save_graphics_state],
355
- [:move_to, [0, 0]], [:line_to, [0, 200]],
356
- [:line_to, [30, 180]], [:line_to, [30, 40]], [:clip_path_non_zero], [:end_path],
357
- [:set_device_gray_stroking_color, [0.75]], [:set_line_width, [30]],
358
- [:set_line_cap_style, [1]], [:set_line_dash_pattern, [[0, 42.5], 27.5]],
359
- [:move_to, [15, 0]], [:line_to, [15, 200]], [:stroke_path],
360
- [:restore_graphics_state], [:restore_graphics_state]]
361
- assert_operators(@canvas.contents, ops)
362
- end
363
- end
364
-
365
- describe "border width greater than edge length" do
366
- it "works for solid borders" do
367
- border = create_border(width: 100, style: :solid)
368
- border.draw(@canvas, 0, 0, 10, 10)
369
- assert_operators(@canvas.contents, [[:save_graphics_state],
370
- [:set_line_width, [100]],
371
- [:append_rectangle, [0, 0, 10, 10]],
372
- [:clip_path_non_zero], [:end_path],
373
- [:append_rectangle, [50, 50, -90, -90]],
374
- [:stroke_path],
375
- [:restore_graphics_state]])
376
- end
377
-
378
- it "works for dashed borders" do
379
- border = create_border(width: 100, style: :dashed)
380
- border.draw(@canvas, 0, 0, 10, 10)
381
- assert_operators(@canvas.contents, [[:save_graphics_state],
382
- [:set_line_width, [100]],
383
- [:set_line_cap_style, [2]],
384
- [:append_rectangle, [0, 0, 10, 10]],
385
- [:clip_path_non_zero], [:end_path],
386
- [:set_line_dash_pattern, [[100, 0], 50]],
387
- [:move_to, [0, -40]], [:line_to, [10, -40]],
388
- [:move_to, [10, 50]], [:line_to, [0, 50]],
389
- [:stroke_path],
390
- [:move_to, [-40, 10]], [:line_to, [-40, 0]],
391
- [:move_to, [50, 0]], [:line_to, [50, 10]],
392
- [:stroke_path],
393
- [:restore_graphics_state]])
394
- end
395
- it "works for dashed-round borders" do
396
- border = create_border(width: 100, style: :dashed_round)
397
- border.draw(@canvas, 0, 0, 10, 10)
398
- assert_operators(@canvas.contents, [[:save_graphics_state],
399
- [:set_line_width, [100]],
400
- [:set_line_cap_style, [1]],
401
- [:append_rectangle, [0, 0, 10, 10]],
402
- [:clip_path_non_zero], [:end_path],
403
- [:set_line_dash_pattern, [[100, 0], 50]],
404
- [:move_to, [0, -40]], [:line_to, [10, -40]],
405
- [:move_to, [10, 50]], [:line_to, [0, 50]],
406
- [:stroke_path],
407
- [:move_to, [-40, 10]], [:line_to, [-40, 0]],
408
- [:move_to, [50, 0]], [:line_to, [50, 10]],
409
- [:stroke_path],
410
- [:restore_graphics_state]])
411
- end
412
- it "works for dotted borders" do
413
- border = create_border(width: 100, style: :dotted)
414
- border.draw(@canvas, 0, 0, 10, 10)
415
- assert_operators(@canvas.contents, [[:save_graphics_state],
416
- [:set_line_width, [100]],
417
- [:set_line_cap_style, [1]],
418
- [:append_rectangle, [0, 0, 10, 10]],
419
- [:clip_path_non_zero], [:end_path],
420
- [:set_line_dash_pattern, [[0, 1], 0]],
421
- [:move_to, [0, -40]], [:line_to, [10, -40]],
422
- [:move_to, [10, 50]], [:line_to, [0, 50]],
423
- [:stroke_path],
424
- [:move_to, [-40, 10]], [:line_to, [-40, 0]],
425
- [:move_to, [50, 0]], [:line_to, [50, 10]],
426
- [:stroke_path],
427
- [:restore_graphics_state]])
428
- end
429
- end
430
-
431
- it "raises an error if an invalid style is provided" do
432
- assert_raises(ArgumentError) do
433
- create_border(width: 1, color: 0, style: :unknown).draw(@canvas, 0, 0, 10, 10)
434
- end
435
- end
436
- end
437
- end
438
-
439
- describe HexaPDF::Layout::Style::Layers do
440
- before do
441
- @layers = HexaPDF::Layout::Style::Layers.new
442
- end
443
-
444
- it "can be initialized with an array of layers" do
445
- data = [lambda {}]
446
- layers = HexaPDF::Layout::Style::Layers.new(data)
447
- assert_equal(data, layers.enum_for(:each, {}).to_a)
448
- end
449
-
450
- it "can be duplicated" do
451
- copy = @layers.dup
452
- @layers.add(lambda {})
453
- assert(copy.none?)
454
- end
455
-
456
- describe "add and each" do
457
- it "can use a given block" do
458
- block = proc { true }
459
- @layers.add(&block)
460
- assert_equal([block], @layers.enum_for(:each, {}).to_a)
461
- end
462
-
463
- it "can store a reference" do
464
- @layers.add(:link, option: :value)
465
- value = Object.new
466
- value.define_singleton_method(:new) {|*| :new }
467
- config = Object.new
468
- config.define_singleton_method(:constantize) {|*| value }
469
- assert_equal([:new], @layers.enum_for(:each, config).to_a)
470
- end
471
-
472
- it "fails if neither a block nor a name is given when adding a layer" do
473
- assert_raises(ArgumentError) { @layers.add }
474
- end
475
- end
476
-
477
- it "can determine whether layers are defined" do
478
- assert(@layers.none?)
479
- @layers.add {}
480
- refute(@layers.none?)
481
- end
482
-
483
- it "draws the layers onto a canvas" do
484
- box = Object.new
485
- value = nil
486
- klass = Class.new
487
- klass.send(:define_method, :initialize) {|**args| @args = args }
488
- klass.send(:define_method, :call) do |canvas, _|
489
- value = @args
490
- canvas.line_width(5)
491
- end
492
- canvas = HexaPDF::Document.new.pages.add.canvas
493
- canvas.context.document.config['style.layers_map'][:test] = klass
494
-
495
- @layers.draw(canvas, 10, 15, box)
496
- @layers.add {|canv, ibox| assert_equal(box, ibox); canv.line_width(10) }
497
- @layers.add(:test, option: :value)
498
- @layers.draw(canvas, 10, 15, box)
499
- ops = [[:save_graphics_state],
500
- [:concatenate_matrix, [1, 0, 0, 1, 10, 15]],
501
- [:save_graphics_state],
502
- [:set_line_width, [10]],
503
- [:restore_graphics_state],
504
- [:save_graphics_state],
505
- [:set_line_width, [5]],
506
- [:restore_graphics_state],
507
- [:restore_graphics_state]]
508
- assert_operators(canvas.contents, ops)
509
- assert_equal({option: :value}, value)
510
- end
511
- end
512
-
513
- describe HexaPDF::Layout::Style::LinkLayer do
514
- describe "initialize" do
515
- it "fails if more than one possible target is chosen" do
516
- assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(dest: true, uri: true) }
517
- assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(dest: true, file: true) }
518
- assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(uri: true, file: true) }
519
- end
520
-
521
- it "fails if an invalid border is provided" do
522
- assert_raises(ArgumentError) { HexaPDF::Layout::Style::LinkLayer.new(border: 5) }
523
- end
524
- end
525
-
526
- describe "call" do
527
- before do
528
- @canvas = HexaPDF::Document.new.pages.add.canvas
529
- @canvas.translate(10, 10)
530
- @box = HexaPDF::Layout::Box.new(width: 15, height: 10)
531
- end
532
-
533
- def call_link(hash)
534
- link = HexaPDF::Layout::Style::LinkLayer.new(**hash)
535
- link.call(@canvas, @box)
536
- @canvas.context[:Annots]&.first
537
- end
538
-
539
- it "does nothing if the context is not a page object" do
540
- @canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form, BBox: [0, 0, 1, 1]}).canvas
541
- assert_nil(call_link(dest: true))
542
- end
543
-
544
- it "sets general values like /Rect and /QuadPoints" do
545
- annot = call_link(dest: true)
546
- assert_equal(:Link, annot[:Subtype])
547
- assert_equal([10, 10, 25, 20], annot[:Rect].value)
548
- assert_equal([10, 10, 25, 10, 25, 20, 10, 20], annot[:QuadPoints].value)
549
- end
550
-
551
- it "removes the border by default" do
552
- annot = call_link(dest: true)
553
- assert_equal([0, 0, 0], annot[:Border].value)
554
- end
555
-
556
- it "uses a default border if no specific border style is specified" do
557
- annot = call_link(dest: true, border: true)
558
- assert_equal([0, 0, 1], annot[:Border].value)
559
- end
560
-
561
- it "uses the specified border and border color" do
562
- annot = call_link(dest: true, border: [10, 10, 2], border_color: [255])
563
- assert_equal([10, 10, 2], annot[:Border].value)
564
- assert_equal([1.0], annot[:C].value)
565
- end
566
-
567
- it "works for simple destinations" do
568
- annot = call_link(dest: [@canvas.context, :FitH])
569
- assert_equal([@canvas.context, :FitH], annot[:Dest].value)
570
- assert_nil(annot[:A])
571
- end
572
-
573
- it "works for URIs" do
574
- annot = call_link(uri: "test.html")
575
- assert_equal({S: :URI, URI: "test.html"}, annot[:A].value)
576
- assert_nil(annot[:Dest])
577
- end
578
-
579
- it "works for files" do
580
- annot = call_link(file: "local-file.pdf")
581
- assert_equal({S: :Launch, F: "local-file.pdf", NewWindow: true}, annot[:A].value)
582
- assert_nil(annot[:Dest])
583
- end
584
- end
585
- end
586
-
587
- describe HexaPDF::Layout::Style do
588
- before do
589
- @style = HexaPDF::Layout::Style.new
590
- end
591
-
592
- it "can assign values on initialization" do
593
- style = HexaPDF::Layout::Style.new(font_size: 10)
594
- assert_equal(10, style.font_size)
595
- end
596
-
597
- describe "initialize_copy" do
598
- it "can be duplicated" do
599
- @style.font_features[:kerning] = true
600
- @style.padding.top = 10
601
- @style.margin.top = 10
602
- @style.border.width.top = 10
603
- @style.overlays.add(lambda {})
604
- @style.underlays.add(lambda {})
605
-
606
- copy = @style.dup
607
- @style.font_features[:kerning] = false
608
- @style.padding.top = 5
609
- @style.margin.top = 5
610
- @style.border.width.top = 5
611
- @style.overlays.add(lambda {})
612
- @style.underlays.add(lambda {})
613
-
614
- assert_equal({kerning: true}, copy.font_features)
615
- assert_equal(10, copy.padding.top)
616
- assert_equal(10, copy.margin.top)
617
- assert_equal(10, copy.border.width.top)
618
- assert_equal(1, copy.underlays.instance_variable_get(:@layers).size)
619
- assert_equal(1, copy.overlays.instance_variable_get(:@layers).size)
620
- end
621
-
622
- it "resets the cache" do
623
- @style.horizontal_scaling(200)
624
- assert_equal(2.0, @style.scaled_horizontal_scaling)
625
- assert_equal(-1.06, @style.scaled_item_width(53))
626
-
627
- style = @style.dup
628
- style.horizontal_scaling(100)
629
- assert_equal(2.0, @style.scaled_horizontal_scaling)
630
- assert_equal(-1.06, @style.scaled_item_width(53))
631
- assert_equal(1.0, style.scaled_horizontal_scaling)
632
- assert_equal(-0.53, style.scaled_item_width(53))
633
- end
634
- end
635
-
636
- it "has several simple and dynamically generated properties with default values" do
637
- assert_raises(HexaPDF::Error) { @style.font }
638
- assert_equal(10, @style.font_size)
639
- assert_equal(0, @style.character_spacing)
640
- assert_equal(0, @style.word_spacing)
641
- assert_equal(100, @style.horizontal_scaling)
642
- assert_equal(0, @style.text_rise)
643
- assert_equal({}, @style.font_features)
644
- assert_equal(HexaPDF::Content::TextRenderingMode::FILL, @style.text_rendering_mode)
645
- assert_equal([0], @style.fill_color.components)
646
- assert_equal(1, @style.fill_alpha)
647
- assert_equal([0], @style.stroke_color.components)
648
- assert_equal(1, @style.stroke_alpha)
649
- assert_equal(1, @style.stroke_width)
650
- assert_equal(HexaPDF::Content::LineCapStyle::BUTT_CAP, @style.stroke_cap_style)
651
- assert_equal(HexaPDF::Content::LineJoinStyle::MITER_JOIN, @style.stroke_join_style)
652
- assert_equal(10.0, @style.stroke_miter_limit)
653
- assert_equal(:left, @style.align)
654
- assert_equal(:top, @style.valign)
655
- assert_equal(0, @style.text_indent)
656
- assert_nil(@style.background_color)
657
- assert(@style.padding.simple?)
658
- assert_equal(0, @style.padding.top)
659
- assert(@style.margin.simple?)
660
- assert_equal(0, @style.margin.top)
661
- assert(@style.border.none?)
662
- assert_equal([[], 0], @style.stroke_dash_pattern.to_operands)
663
- assert_equal([:proportional, 1], [@style.line_spacing.type, @style.line_spacing.value])
664
- refute(@style.subscript)
665
- refute(@style.superscript)
666
- refute(@style.last_line_gap)
667
- assert_kind_of(HexaPDF::Layout::Style::Layers, @style.underlays)
668
- assert_kind_of(HexaPDF::Layout::Style::Layers, @style.overlays)
669
- end
670
-
671
- it "allows using a non-standard setter for generated properties" do
672
- @style.padding = [5, 3]
673
- assert_equal(5, @style.padding.top)
674
- assert_equal(3, @style.padding.left)
675
-
676
- @style.stroke_dash_pattern(5, 2)
677
- assert_equal([[5], 2], @style.stroke_dash_pattern.to_operands)
678
- end
679
-
680
- it "allows checking for valid values" do
681
- error = assert_raises(ArgumentError) { @style.align = :none }
682
- assert_match(/not a valid align value \(:left, :center, :right, :justify\)/, error.message)
683
- end
684
-
685
- it "allows checking whether a property has been set or accessed" do
686
- refute(@style.align?)
687
- assert_equal(:left, @style.align)
688
- assert(@style.align?)
689
-
690
- refute(@style.valign?)
691
- @style.valign = :bottom
692
- assert(@style.valign?)
693
- end
694
-
695
- it "has several dynamically generated properties with default values that take blocks" do
696
- assert_equal(HexaPDF::Layout::TextLayouter::SimpleTextSegmentation,
697
- @style.text_segmentation_algorithm)
698
- assert_equal(HexaPDF::Layout::TextLayouter::SimpleLineWrapping,
699
- @style.text_line_wrapping_algorithm)
700
-
701
- block = proc { :y }
702
- @style.text_segmentation_algorithm(&block)
703
- assert_equal(block, @style.text_segmentation_algorithm)
704
-
705
- @style.text_segmentation_algorithm(:callable)
706
- assert_equal(:callable, @style.text_segmentation_algorithm)
707
- end
708
-
709
- describe "methods for some derived and cached values" do
710
- before do
711
- wrapped_font = Object.new
712
- wrapped_font.define_singleton_method(:ascender) { 600 }
713
- wrapped_font.define_singleton_method(:descender) { -100 }
714
- font = Object.new
715
- font.define_singleton_method(:scaling_factor) { 1 }
716
- font.define_singleton_method(:wrapped_font) { wrapped_font }
717
- @style.font = font
718
- end
719
-
720
- it "computes them correctly" do
721
- @style.horizontal_scaling(200).character_spacing(1).word_spacing(2)
722
- assert_equal(0.02, @style.scaled_font_size)
723
- assert_equal(2, @style.scaled_character_spacing)
724
- assert_equal(4, @style.scaled_word_spacing)
725
- assert_equal(2, @style.scaled_horizontal_scaling)
726
-
727
- assert_equal(6, @style.scaled_font_ascender)
728
- assert_equal(-1, @style.scaled_font_descender)
729
- end
730
-
731
- it "computes item widths correctly" do
732
- @style.horizontal_scaling(200).character_spacing(1).word_spacing(2)
733
-
734
- assert_equal(-1.0, @style.scaled_item_width(50))
735
-
736
- obj = Object.new
737
- obj.define_singleton_method(:width) { 100 }
738
- obj.define_singleton_method(:apply_word_spacing?) { true }
739
- assert_equal(8, @style.scaled_item_width(obj))
740
- end
741
-
742
- it "handles subscript" do
743
- @style.subscript = true
744
- assert_in_delta(5.83, @style.calculated_font_size)
745
- assert_in_delta(0.00583, @style.scaled_font_size, 0.000001)
746
- assert_in_delta(-2.00, @style.calculated_text_rise)
747
- end
748
-
749
- it "handles superscript" do
750
- @style.superscript = true
751
- assert_in_delta(5.83, @style.calculated_font_size)
752
- assert_in_delta(3.30, @style.calculated_text_rise)
753
- end
754
-
755
- it "handles underline" do
756
- @style.font.wrapped_font.define_singleton_method(:underline_position) { -100 }
757
- @style.font.wrapped_font.define_singleton_method(:underline_thickness) { 10 }
758
- @style.text_rise = 10
759
- assert_in_delta(-1.05 + 10, @style.calculated_underline_position)
760
- assert_equal(0.1, @style.calculated_underline_thickness)
761
- end
762
-
763
- it "handles strikeout" do
764
- @style.font.wrapped_font.define_singleton_method(:strikeout_position) { 300 }
765
- @style.font.wrapped_font.define_singleton_method(:strikeout_thickness) { 10 }
766
- @style.text_rise = 10
767
- assert_in_delta(2.95 + 10, @style.calculated_strikeout_position)
768
- assert_equal(0.1, @style.calculated_strikeout_thickness)
769
- end
770
- end
771
-
772
- it "can clear cached values" do
773
- assert_equal(0.01, @style.scaled_font_size)
774
- @style.font_size = 20
775
- assert_equal(0.01, @style.scaled_font_size)
776
- @style.clear_cache
777
- assert_equal(0.02, @style.scaled_font_size)
778
- end
779
- end