hexapdf 0.37.1 → 0.37.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (253) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/LICENSE +1 -1
  4. data/lib/hexapdf/cli/batch.rb +1 -1
  5. data/lib/hexapdf/cli/command.rb +1 -1
  6. data/lib/hexapdf/cli/files.rb +1 -1
  7. data/lib/hexapdf/cli/fonts.rb +1 -1
  8. data/lib/hexapdf/cli/form.rb +1 -1
  9. data/lib/hexapdf/cli/image2pdf.rb +1 -1
  10. data/lib/hexapdf/cli/images.rb +1 -1
  11. data/lib/hexapdf/cli/info.rb +1 -1
  12. data/lib/hexapdf/cli/inspect.rb +1 -1
  13. data/lib/hexapdf/cli/merge.rb +1 -1
  14. data/lib/hexapdf/cli/modify.rb +1 -1
  15. data/lib/hexapdf/cli/optimize.rb +1 -1
  16. data/lib/hexapdf/cli/split.rb +1 -1
  17. data/lib/hexapdf/cli/watermark.rb +1 -1
  18. data/lib/hexapdf/cli.rb +1 -1
  19. data/lib/hexapdf/composer.rb +1 -1
  20. data/lib/hexapdf/configuration.rb +3 -4
  21. data/lib/hexapdf/content/canvas.rb +2 -2
  22. data/lib/hexapdf/content/canvas_composer.rb +1 -1
  23. data/lib/hexapdf/content/color_space.rb +1 -1
  24. data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
  25. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
  26. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  27. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  28. data/lib/hexapdf/content/graphic_object.rb +1 -1
  29. data/lib/hexapdf/content/graphics_state.rb +1 -1
  30. data/lib/hexapdf/content/operator.rb +1 -1
  31. data/lib/hexapdf/content/parser.rb +1 -1
  32. data/lib/hexapdf/content/processor.rb +4 -4
  33. data/lib/hexapdf/content/transformation_matrix.rb +3 -3
  34. data/lib/hexapdf/content.rb +1 -1
  35. data/lib/hexapdf/data_dir.rb +1 -1
  36. data/lib/hexapdf/dictionary.rb +1 -1
  37. data/lib/hexapdf/dictionary_fields.rb +1 -1
  38. data/lib/hexapdf/digital_signature/cms_handler.rb +1 -2
  39. data/lib/hexapdf/digital_signature/handler.rb +1 -1
  40. data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
  41. data/lib/hexapdf/digital_signature/signature.rb +2 -2
  42. data/lib/hexapdf/digital_signature/signatures.rb +1 -1
  43. data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -1
  44. data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +1 -1
  45. data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
  46. data/lib/hexapdf/digital_signature/signing.rb +1 -1
  47. data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
  48. data/lib/hexapdf/digital_signature.rb +1 -1
  49. data/lib/hexapdf/document/destinations.rb +1 -1
  50. data/lib/hexapdf/document/files.rb +1 -1
  51. data/lib/hexapdf/document/fonts.rb +1 -1
  52. data/lib/hexapdf/document/images.rb +1 -1
  53. data/lib/hexapdf/document/layout.rb +1 -1
  54. data/lib/hexapdf/document/metadata.rb +14 -13
  55. data/lib/hexapdf/document/pages.rb +1 -1
  56. data/lib/hexapdf/document.rb +1 -1
  57. data/lib/hexapdf/encryption/aes.rb +1 -1
  58. data/lib/hexapdf/encryption/arc4.rb +1 -1
  59. data/lib/hexapdf/encryption/fast_aes.rb +1 -1
  60. data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
  61. data/lib/hexapdf/encryption/identity.rb +1 -1
  62. data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
  63. data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
  64. data/lib/hexapdf/encryption/security_handler.rb +1 -1
  65. data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
  66. data/lib/hexapdf/encryption.rb +1 -1
  67. data/lib/hexapdf/error.rb +1 -1
  68. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  69. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
  70. data/lib/hexapdf/filter/crypt.rb +1 -1
  71. data/lib/hexapdf/filter/encryption.rb +1 -1
  72. data/lib/hexapdf/filter/flate_decode.rb +1 -1
  73. data/lib/hexapdf/filter/lzw_decode.rb +1 -1
  74. data/lib/hexapdf/filter/pass_through.rb +1 -1
  75. data/lib/hexapdf/filter/predictor.rb +1 -1
  76. data/lib/hexapdf/filter/run_length_decode.rb +1 -1
  77. data/lib/hexapdf/filter.rb +1 -1
  78. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  79. data/lib/hexapdf/font/cmap/writer.rb +1 -1
  80. data/lib/hexapdf/font/cmap.rb +1 -1
  81. data/lib/hexapdf/font/encoding/base.rb +1 -1
  82. data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
  83. data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
  84. data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
  85. data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
  86. data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
  87. data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
  88. data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
  89. data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
  90. data/lib/hexapdf/font/encoding.rb +1 -1
  91. data/lib/hexapdf/font/invalid_glyph.rb +1 -1
  92. data/lib/hexapdf/font/true_type/builder.rb +2 -2
  93. data/lib/hexapdf/font/true_type/font.rb +1 -1
  94. data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
  95. data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
  96. data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
  97. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
  98. data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
  99. data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
  100. data/lib/hexapdf/font/true_type/table/head.rb +1 -1
  101. data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
  102. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
  103. data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
  104. data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
  105. data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
  106. data/lib/hexapdf/font/true_type/table/name.rb +1 -1
  107. data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
  108. data/lib/hexapdf/font/true_type/table/post.rb +1 -1
  109. data/lib/hexapdf/font/true_type/table.rb +1 -1
  110. data/lib/hexapdf/font/true_type.rb +1 -1
  111. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  112. data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
  113. data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
  114. data/lib/hexapdf/font/type1/font.rb +2 -2
  115. data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
  116. data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
  117. data/lib/hexapdf/font/type1.rb +1 -1
  118. data/lib/hexapdf/font/type1_wrapper.rb +2 -2
  119. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  120. data/lib/hexapdf/font_loader/from_file.rb +1 -1
  121. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  122. data/lib/hexapdf/font_loader.rb +1 -1
  123. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  124. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  125. data/lib/hexapdf/image_loader/png.rb +1 -1
  126. data/lib/hexapdf/image_loader.rb +1 -1
  127. data/lib/hexapdf/importer.rb +1 -1
  128. data/lib/hexapdf/layout/box.rb +4 -4
  129. data/lib/hexapdf/layout/box_fitter.rb +1 -1
  130. data/lib/hexapdf/layout/column_box.rb +1 -1
  131. data/lib/hexapdf/layout/container_box.rb +4 -4
  132. data/lib/hexapdf/layout/frame.rb +1 -1
  133. data/lib/hexapdf/layout/image_box.rb +1 -1
  134. data/lib/hexapdf/layout/inline_box.rb +1 -1
  135. data/lib/hexapdf/layout/line.rb +1 -1
  136. data/lib/hexapdf/layout/list_box.rb +4 -6
  137. data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
  138. data/lib/hexapdf/layout/page_style.rb +1 -1
  139. data/lib/hexapdf/layout/style.rb +1 -1
  140. data/lib/hexapdf/layout/table_box.rb +4 -4
  141. data/lib/hexapdf/layout/text_box.rb +1 -1
  142. data/lib/hexapdf/layout/text_fragment.rb +1 -1
  143. data/lib/hexapdf/layout/text_layouter.rb +1 -1
  144. data/lib/hexapdf/layout/text_shaper.rb +1 -1
  145. data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
  146. data/lib/hexapdf/layout.rb +1 -1
  147. data/lib/hexapdf/name_tree_node.rb +1 -1
  148. data/lib/hexapdf/number_tree_node.rb +1 -1
  149. data/lib/hexapdf/object.rb +3 -3
  150. data/lib/hexapdf/parser.rb +1 -1
  151. data/lib/hexapdf/pdf_array.rb +1 -1
  152. data/lib/hexapdf/rectangle.rb +1 -1
  153. data/lib/hexapdf/reference.rb +1 -1
  154. data/lib/hexapdf/revision.rb +1 -1
  155. data/lib/hexapdf/revisions.rb +1 -1
  156. data/lib/hexapdf/serializer.rb +1 -1
  157. data/lib/hexapdf/stream.rb +1 -1
  158. data/lib/hexapdf/task/dereference.rb +1 -1
  159. data/lib/hexapdf/task/optimize.rb +1 -1
  160. data/lib/hexapdf/task.rb +1 -1
  161. data/lib/hexapdf/test_utils.rb +1 -1
  162. data/lib/hexapdf/tokenizer.rb +1 -1
  163. data/lib/hexapdf/type/acro_form/appearance_generator.rb +5 -5
  164. data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
  165. data/lib/hexapdf/type/acro_form/choice_field.rb +12 -2
  166. data/lib/hexapdf/type/acro_form/field.rb +1 -1
  167. data/lib/hexapdf/type/acro_form/form.rb +2 -1
  168. data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
  169. data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
  170. data/lib/hexapdf/type/acro_form/variable_text_field.rb +8 -5
  171. data/lib/hexapdf/type/acro_form.rb +1 -1
  172. data/lib/hexapdf/type/action.rb +1 -1
  173. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  174. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  175. data/lib/hexapdf/type/actions/launch.rb +1 -1
  176. data/lib/hexapdf/type/actions/set_ocg_state.rb +1 -1
  177. data/lib/hexapdf/type/actions/uri.rb +1 -1
  178. data/lib/hexapdf/type/actions.rb +1 -1
  179. data/lib/hexapdf/type/annotation.rb +2 -2
  180. data/lib/hexapdf/type/annotations/link.rb +1 -1
  181. data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
  182. data/lib/hexapdf/type/annotations/text.rb +1 -1
  183. data/lib/hexapdf/type/annotations/widget.rb +1 -1
  184. data/lib/hexapdf/type/annotations.rb +1 -1
  185. data/lib/hexapdf/type/catalog.rb +1 -1
  186. data/lib/hexapdf/type/cid_font.rb +1 -1
  187. data/lib/hexapdf/type/embedded_file.rb +1 -1
  188. data/lib/hexapdf/type/file_specification.rb +1 -1
  189. data/lib/hexapdf/type/font.rb +1 -1
  190. data/lib/hexapdf/type/font_descriptor.rb +1 -1
  191. data/lib/hexapdf/type/font_simple.rb +1 -1
  192. data/lib/hexapdf/type/font_true_type.rb +1 -1
  193. data/lib/hexapdf/type/font_type0.rb +2 -2
  194. data/lib/hexapdf/type/font_type1.rb +1 -1
  195. data/lib/hexapdf/type/font_type3.rb +1 -1
  196. data/lib/hexapdf/type/form.rb +16 -16
  197. data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
  198. data/lib/hexapdf/type/icon_fit.rb +1 -1
  199. data/lib/hexapdf/type/image.rb +1 -1
  200. data/lib/hexapdf/type/info.rb +1 -1
  201. data/lib/hexapdf/type/mark_information.rb +1 -1
  202. data/lib/hexapdf/type/metadata.rb +1 -1
  203. data/lib/hexapdf/type/names.rb +1 -1
  204. data/lib/hexapdf/type/object_stream.rb +1 -1
  205. data/lib/hexapdf/type/optional_content_configuration.rb +5 -5
  206. data/lib/hexapdf/type/optional_content_group.rb +17 -1
  207. data/lib/hexapdf/type/optional_content_membership.rb +1 -1
  208. data/lib/hexapdf/type/optional_content_properties.rb +1 -2
  209. data/lib/hexapdf/type/outline.rb +1 -1
  210. data/lib/hexapdf/type/outline_item.rb +1 -1
  211. data/lib/hexapdf/type/page.rb +30 -15
  212. data/lib/hexapdf/type/page_label.rb +1 -1
  213. data/lib/hexapdf/type/page_tree_node.rb +1 -1
  214. data/lib/hexapdf/type/resources.rb +1 -1
  215. data/lib/hexapdf/type/trailer.rb +1 -1
  216. data/lib/hexapdf/type/viewer_preferences.rb +1 -1
  217. data/lib/hexapdf/type/xref_stream.rb +1 -1
  218. data/lib/hexapdf/type.rb +1 -1
  219. data/lib/hexapdf/utils/bit_field.rb +1 -1
  220. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  221. data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
  222. data/lib/hexapdf/utils/lru_cache.rb +1 -1
  223. data/lib/hexapdf/utils/math_helpers.rb +1 -1
  224. data/lib/hexapdf/utils/object_hash.rb +1 -1
  225. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  226. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  227. data/lib/hexapdf/utils.rb +3 -3
  228. data/lib/hexapdf/version.rb +2 -2
  229. data/lib/hexapdf/writer.rb +1 -1
  230. data/lib/hexapdf/xref_section.rb +1 -1
  231. data/lib/hexapdf.rb +1 -1
  232. data/test/hexapdf/content/test_canvas.rb +1 -1
  233. data/test/hexapdf/digital_signature/common.rb +1 -1
  234. data/test/hexapdf/document/test_layout.rb +2 -2
  235. data/test/hexapdf/document/test_metadata.rb +28 -28
  236. data/test/hexapdf/encryption/test_standard_security_handler.rb +9 -9
  237. data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +2 -2
  238. data/test/hexapdf/font/true_type/table/test_name.rb +5 -5
  239. data/test/hexapdf/layout/test_box.rb +2 -2
  240. data/test/hexapdf/layout/test_column_box.rb +5 -5
  241. data/test/hexapdf/layout/test_frame.rb +4 -5
  242. data/test/hexapdf/layout/test_text_fragment.rb +1 -1
  243. data/test/hexapdf/layout/test_text_shaper.rb +2 -2
  244. data/test/hexapdf/test_composer.rb +1 -1
  245. data/test/hexapdf/test_utils.rb +1 -1
  246. data/test/hexapdf/test_writer.rb +2 -2
  247. data/test/hexapdf/type/acro_form/test_choice_field.rb +7 -0
  248. data/test/hexapdf/type/acro_form/test_form.rb +6 -0
  249. data/test/hexapdf/type/acro_form/test_variable_text_field.rb +12 -0
  250. data/test/hexapdf/type/test_annotation.rb +1 -1
  251. data/test/hexapdf/type/test_optional_content_group.rb +2 -2
  252. data/test/hexapdf/type/test_page.rb +67 -38
  253. metadata +2 -2
@@ -128,16 +128,16 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
128
128
 
129
129
  it "sets the correct revision independent /P value" do
130
130
  dict = @handler.set_up_encryption
131
- assert_equal(@handler.class::Permissions::ALL | \
131
+ assert_equal(@handler.class::Permissions::ALL |
132
132
  @handler.class::Permissions::RESERVED - 2**32,
133
133
  dict[:P])
134
134
  dict = @handler.set_up_encryption(permissions: @handler.class::Permissions::COPY_CONTENT)
135
- assert_equal(@handler.class::Permissions::COPY_CONTENT | \
135
+ assert_equal(@handler.class::Permissions::COPY_CONTENT |
136
136
  @handler.class::Permissions::RESERVED - 2**32,
137
137
  dict[:P])
138
138
  dict = @handler.set_up_encryption(permissions: [:modify_content, :modify_annotation])
139
- assert_equal(@handler.class::Permissions::MODIFY_CONTENT | \
140
- @handler.class::Permissions::MODIFY_ANNOTATION | \
139
+ assert_equal(@handler.class::Permissions::MODIFY_CONTENT |
140
+ @handler.class::Permissions::MODIFY_ANNOTATION |
141
141
  @handler.class::Permissions::RESERVED - 2**32,
142
142
  dict[:P])
143
143
  end
@@ -222,7 +222,7 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
222
222
  it "fails if the /Filter value is incorrect" do
223
223
  exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
224
224
  @handler.set_up_decryption({Filter: :NonStandard, V: 2, R: 4, O: 't' * 32, U: 't' * 32, P: 0,
225
- Length: 128})
225
+ Length: 128})
226
226
  end
227
227
  assert_match(/Invalid \/Filter value NonStandard/i, exp.message)
228
228
  end
@@ -307,28 +307,28 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
307
307
 
308
308
  describe "decryption_password_type" do
309
309
  it "doesn't need a password for encrypted files without a password" do
310
- file = test_files.find {|name| name =~ /nopwd-aes-256bit-V5.pdf/}
310
+ file = test_files.find {|name| name =~ /nopwd-aes-256bit-V5.pdf/ }
311
311
  HexaPDF::Document.open(file) do |doc|
312
312
  assert_equal(:none, doc.security_handler.decryption_password_type)
313
313
  end
314
314
  end
315
315
 
316
316
  it "doesn't need a password for owner encrypted files" do
317
- file = test_files.find {|name| name =~ /ownerpwd-aes-256bit-V5.pdf/}
317
+ file = test_files.find {|name| name =~ /ownerpwd-aes-256bit-V5.pdf/ }
318
318
  HexaPDF::Document.open(file) do |doc|
319
319
  assert_equal(:none, doc.security_handler.decryption_password_type)
320
320
  end
321
321
  end
322
322
 
323
323
  it "needs the user password for user encrypted files" do
324
- file = test_files.find {|name| name =~ /userpwd-aes-256bit-V5.pdf/}
324
+ file = test_files.find {|name| name =~ /userpwd-aes-256bit-V5.pdf/ }
325
325
  HexaPDF::Document.open(file, decryption_opts: {password: user_password}) do |doc|
326
326
  assert_equal(:user, doc.security_handler.decryption_password_type)
327
327
  end
328
328
  end
329
329
 
330
330
  it "can user either the user or owner password for user+owner encrypted files" do
331
- file = test_files.find {|name| name =~ /bothpwd-aes-256bit-V5.pdf/}
331
+ file = test_files.find {|name| name =~ /bothpwd-aes-256bit-V5.pdf/ }
332
332
  HexaPDF::Document.open(file, decryption_opts: {password: user_password}) do |doc|
333
333
  assert_equal(:user, doc.security_handler.decryption_password_type)
334
334
  end
@@ -54,8 +54,8 @@ describe HexaPDF::Font::TrueType::Table::CmapSubtable do
54
54
  end
55
55
 
56
56
  it "works for format 2" do
57
- f2 = ([0, 8] + [0] * 254).pack('n*') + \
58
- [[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n') }.join + \
57
+ f2 = ([0, 8] + [0] * 254).pack('n*') +
58
+ [[0, 256, 0, 2 + 8], [0x33, 3, 5, 2 + 256 * 2]].map {|a| a.pack('n2s>n') }.join +
59
59
  ((0..255).to_a + [35, 65534, 0]).pack('n*')
60
60
  t = table([2, f2.length + 6, 0].pack('n3') << f2)
61
61
  assert_nil(t[0x0132])
@@ -6,11 +6,11 @@ require 'hexapdf/font/true_type/table/name'
6
6
 
7
7
  describe HexaPDF::Font::TrueType::Table::Name do
8
8
  before do
9
- data = [0, 3, 42].pack('n3') << \
10
- [1, 0, 0, 0, 4, 0].pack('n6') << \
11
- [0, 3, 1, 0, 8, 4].pack('n6') << \
12
- [3, 1, 1033, 1, 14, 12].pack('n6') << \
13
- 'hexa'.encode('MACROMAN').b << \
9
+ data = [0, 3, 42].pack('n3') <<
10
+ [1, 0, 0, 0, 4, 0].pack('n6') <<
11
+ [0, 3, 1, 0, 8, 4].pack('n6') <<
12
+ [3, 1, 1033, 1, 14, 12].pack('n6') <<
13
+ 'hexa'.encode('MACROMAN').b <<
14
14
  'hexa'.encode('UTF-16BE').b <<
15
15
  'hexapdf'.encode('UTF-16BE').b
16
16
  set_up_stub_true_type_font(data)
@@ -113,7 +113,7 @@ describe HexaPDF::Layout::Box do
113
113
 
114
114
  it "can use the #content_width/#content_height helper methods" do
115
115
  box = create_box
116
- box.define_singleton_method(:fit_content) do |aw, ah, frame|
116
+ box.define_singleton_method(:fit_content) do |_aw, _ah, _frame|
117
117
  update_content_width { 10 }
118
118
  update_content_height { 20 }
119
119
  true
@@ -123,7 +123,7 @@ describe HexaPDF::Layout::Box do
123
123
  assert_equal(20, box.height)
124
124
 
125
125
  box = create_box(width: 30, height: 50)
126
- box.define_singleton_method(:fit_content) do |aw, ah, frame|
126
+ box.define_singleton_method(:fit_content) do |_aw, _ah, _frame|
127
127
  update_content_width { 10 }
128
128
  update_content_height { 20 }
129
129
  true
@@ -181,11 +181,11 @@ describe HexaPDF::Layout::ColumnBox do
181
181
  [:restore_graphics_state]]
182
182
  end
183
183
  operators.concat(90.step(to: 30, by: -10).map do |y|
184
- [[:save_graphics_state],
185
- [:concatenate_matrix, [1, 0, 0, 1, 55, y]],
186
- [:move_to, [0, 0]],
187
- [:end_path],
188
- [:restore_graphics_state]]
184
+ [[:save_graphics_state],
185
+ [:concatenate_matrix, [1, 0, 0, 1, 55, y]],
186
+ [:move_to, [0, 0]],
187
+ [:end_path],
188
+ [:restore_graphics_state]]
189
189
  end)
190
190
  operators.flatten!(1)
191
191
  assert_operators(@canvas.contents, operators)
@@ -123,7 +123,7 @@ describe HexaPDF::Layout::Frame do
123
123
 
124
124
  it "fails if an unkown position value is provided" do
125
125
  box = HexaPDF::Layout::Box.create(position: :unknown)
126
- exception = assert_raises(HexaPDF::Error) { @frame.fit(box) }
126
+ exception = assert_raises(HexaPDF::Error) { @frame.fit(box) }
127
127
  assert_match(/Invalid value 'unknown'/, exception.message)
128
128
  end
129
129
 
@@ -338,8 +338,7 @@ describe HexaPDF::Layout::Frame do
338
338
  check_box({width: 50, height: 50, mask_mode: :none},
339
339
  [10, 60],
340
340
  [10, 60, 10, 60],
341
- [[[10, 10], [110, 10], [110, 110], [10, 110]]]
342
- )
341
+ [[[10, 10], [110, 10], [110, 110], [10, 110]]])
343
342
  end
344
343
  end
345
344
 
@@ -401,7 +400,7 @@ describe HexaPDF::Layout::Frame do
401
400
  [35, 60],
402
401
  [35, 10, 85, 110],
403
402
  [[[10, 10], [35, 10], [35, 110], [10, 110]],
404
- [[85, 10], [110, 10], [110, 110], [85, 110]]])
403
+ [[85, 10], [110, 10], [110, 110], [85, 110]]])
405
404
  end
406
405
 
407
406
  it "respects the left and right margins for the mask" do
@@ -409,7 +408,7 @@ describe HexaPDF::Layout::Frame do
409
408
  [35, 60],
410
409
  [25, 10, 95, 110],
411
410
  [[[10, 10], [25, 10], [25, 110], [10, 110]],
412
- [[95, 10], [110, 10], [110, 110], [95, 110]]])
411
+ [[95, 10], [110, 10], [110, 110], [95, 110]]])
413
412
  end
414
413
  end
415
414
 
@@ -50,7 +50,7 @@ describe HexaPDF::Layout::TextFragment do
50
50
  it "replaces invalid glyphs with the result of the block" do
51
51
  zapf_dingbats = @doc.fonts.add('ZapfDingbats')
52
52
  i = 0
53
- fallback = lambda do |codepoint, invalid_glyph|
53
+ fallback = lambda do |codepoint, _invalid_glyph|
54
54
  case (i += 1) % 3
55
55
  when 0 then []
56
56
  when 1 then [zapf_dingbats.decode_codepoint(codepoint)]
@@ -48,8 +48,8 @@ describe HexaPDF::Layout::TextShaper do
48
48
  end
49
49
 
50
50
  it "handles kerning" do
51
- data = [0, 1].pack('n2') << \
52
- [0, 6 + 8 + 12, 0x1].pack('n3') << \
51
+ data = [0, 1].pack('n2') <<
52
+ [0, 6 + 8 + 12, 0x1].pack('n3') <<
53
53
  [2, 0, 0, 0, 53, 80, -20, 80, 81, -10].pack('n4n2s>n2s>')
54
54
  table = create_table(:Kern, data, standalone: true)
55
55
  @wrapped_font.instance_eval { @tables[:kern] = table }
@@ -132,7 +132,7 @@ describe HexaPDF::Composer do
132
132
  end
133
133
 
134
134
  it "sets a page style using default attributes but with a block" do
135
- @composer.page_style(:other) {|canvas, style| style.frame = :hallo }
135
+ @composer.page_style(:other) {|_canvas, style| style.frame = :hallo }
136
136
  style = @composer.page_style(:other)
137
137
  style.create_page(@composer.document)
138
138
  assert_equal(:hallo, style.frame)
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  require 'test_helper'
4
- require 'hexapdf/utils.rb'
4
+ require 'hexapdf/utils'
5
5
 
6
6
  describe HexaPDF::Utils do
7
7
  include HexaPDF::Utils
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.37.1)>>
43
+ <</Producer(HexaPDF version 0.37.2)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.37.1)>>
75
+ <</Producer(HexaPDF version 0.37.2)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -145,6 +145,13 @@ describe HexaPDF::Type::AcroForm::ChoiceField do
145
145
  @field[:Opt] = @items
146
146
  assert_equal(["a", "Töne", "Hällo"], @field.export_values)
147
147
  end
148
+
149
+ it "can retrieve the option items/export values if they are set on a widget and not on the field" do
150
+ @field.create_widget(@doc.pages.add, allow_embedded: false, Rect: [0, 0, 0, 0], Opt: @items)
151
+ @field.create_widget(@doc.pages.add, Rect: [0, 0, 0, 0], Opt: ['other'])
152
+ assert_equal(["Zx", "Töne", "Hällo"], @field.option_items)
153
+ assert_equal(["a", "Töne", "Hällo"], @field.export_values)
154
+ end
148
155
  end
149
156
 
150
157
  it "returns the correct concrete field type" do
@@ -81,6 +81,12 @@ describe HexaPDF::Type::AcroForm::Form do
81
81
  it "converts the fields into their proper types if possible" do
82
82
  assert_kind_of(HexaPDF::Type::AcroForm::TextField, @acro_form.each_field.to_a.last)
83
83
  end
84
+
85
+ it "gracefully handles null entries" do
86
+ @acro_form[:Fields].insert(1, HexaPDF::Reference.new(100, 0))
87
+ @acro_form[:Fields][-1][:Kids].insert(1, nil)
88
+ assert_equal([:Tx1, :Tx2, :Tx4, :Tx6], @acro_form.each_field.map {|h| h[:T] })
89
+ end
84
90
  end
85
91
 
86
92
  describe "field_by_name" do
@@ -79,6 +79,18 @@ describe HexaPDF::Type::AcroForm::VariableTextField do
79
79
  assert_equal([:F2, 10, @color], @field.parse_default_appearance_string)
80
80
  end
81
81
 
82
+ it "parses the default appearance string of the given widget" do
83
+ widget = @field.create_widget(@doc.pages.add, allow_embedded: false, Rect: [0, 0, 1, 1],
84
+ DA: "/F1 10 Tf 1 g")
85
+ assert_equal([:F1, 10, @color], @field.parse_default_appearance_string(widget))
86
+ end
87
+
88
+ it "falls back to the field if the widget has no appearance string set" do
89
+ @field[:DA] = "/F2 5 Tf"
90
+ widget = @field.create_widget(@doc.pages.add, allow_embedded: false, Rect: [0, 0, 1, 1])
91
+ assert_equal([:F2, 5, nil], @field.parse_default_appearance_string(widget))
92
+ end
93
+
82
94
  it "uses the default appearance string of a parent field" do
83
95
  parent = @doc.add({DA: "/F1 15 Tf"}, type: :XXAcroFormField)
84
96
  @field[:Parent] = parent
@@ -142,7 +142,7 @@ describe HexaPDF::Type::Annotation do
142
142
  describe "validation" do
143
143
  it "makes sure that empty appearance stream dictionaries don't cause validation errors" do
144
144
  assert(@annot.validate)
145
- @annot[:AP] = {}
145
+ @annot[:AP] = HexaPDF::Reference.new(@doc.add({}).oid)
146
146
  msg = nil
147
147
  assert(@annot.validate {|imsg| msg = imsg })
148
148
  assert_match(/appearance.*must not be empty/, msg)
@@ -20,8 +20,8 @@ describe HexaPDF::Type::OptionalContentGroup do
20
20
  Print: {},
21
21
  View: {},
22
22
  User: {},
23
- PageElement: {}
24
- }
23
+ PageElement: {},
24
+ },
25
25
  }
26
26
  ocg = @doc.add(hash, type: :OCG)
27
27
  assert_kind_of(HexaPDF::Type::OptionalContentGroup, ocg)
@@ -16,7 +16,8 @@ describe HexaPDF::Type::Page do
16
16
  end
17
17
 
18
18
  it "respects the orientation key" do
19
- assert_equal([0, 0, 841.889764, 595.275591], HexaPDF::Type::Page.media_box(:A4, orientation: :landscape))
19
+ assert_equal([0, 0, 841.889764, 595.275591],
20
+ HexaPDF::Type::Page.media_box(:A4, orientation: :landscape))
20
21
  end
21
22
 
22
23
  it "works with a paper size array" do
@@ -136,27 +137,46 @@ describe HexaPDF::Type::Page do
136
137
  end
137
138
 
138
139
  it "returns the correct crop box" do
139
- @page[:MediaBox] = :media
140
- assert_equal(:media, @page.box(:crop))
141
- @page[:CropBox] = :crop
142
- assert_equal(:crop, @page.box(:crop))
140
+ @page[:MediaBox] = [0, 0, 10, 10]
141
+ assert_equal([0, 0, 10, 10], @page.box(:crop))
142
+ @page[:CropBox] = [0, 0, 5, 5]
143
+ assert_equal([0, 0, 5, 5], @page.box(:crop))
143
144
  end
144
145
 
145
146
  it "returns the correct bleed, trim and art boxes" do
146
- @page[:MediaBox] = :media
147
- assert_equal(:media, @page.box(:bleed))
148
- assert_equal(:media, @page.box(:trim))
149
- assert_equal(:media, @page.box(:art))
150
- @page[:CropBox] = :crop
151
- assert_equal(:crop, @page.box(:bleed))
152
- assert_equal(:crop, @page.box(:trim))
153
- assert_equal(:crop, @page.box(:art))
154
- @page[:BleedBox] = :bleed
155
- @page[:TrimBox] = :trim
156
- @page[:ArtBox] = :art
157
- assert_equal(:bleed, @page.box(:bleed))
158
- assert_equal(:trim, @page.box(:trim))
159
- assert_equal(:art, @page.box(:art))
147
+ @page[:MediaBox] = mb = [0, 0, 10, 10]
148
+ assert_equal(mb, @page.box(:bleed))
149
+ assert_equal(mb, @page.box(:trim))
150
+ assert_equal(mb, @page.box(:art))
151
+ @page[:CropBox] = cb = [0, 0, 8, 8]
152
+ assert_equal(cb, @page.box(:bleed))
153
+ assert_equal(cb, @page.box(:trim))
154
+ assert_equal(cb, @page.box(:art))
155
+ @page[:BleedBox] = [0, 0, 0, 5]
156
+ @page[:TrimBox] = [0, 0, 0, 7]
157
+ @page[:ArtBox] = [0, 0, 0, 1]
158
+ assert_equal([0, 0, 0, 5], @page.box(:bleed))
159
+ assert_equal([0, 0, 0, 7], @page.box(:trim))
160
+ assert_equal([0, 0, 0, 1], @page.box(:art))
161
+ end
162
+
163
+ it "restricts all boxes to the bounds of the media box" do
164
+ @page[:MediaBox] = [10, 20, 100, 200]
165
+ @page[:CropBox] = [0, 0, 200, 300]
166
+ assert_equal([10, 20, 100, 200], @page.box.value)
167
+ end
168
+
169
+ it "returns a zero-sized box if requested box doesn't overlap with the media box" do
170
+ @page[:MediaBox] = [0, 0, 100, 100]
171
+
172
+ @page[:CropBox] = [-20, 0, -10, 100]
173
+ assert_equal([0, 0, 0, 0], @page.box)
174
+ @page[:CropBox] = [200, 0, 250, 100]
175
+ assert_equal([0, 0, 0, 0], @page.box)
176
+ @page[:CropBox] = [0, 110, 100, 150]
177
+ assert_equal([0, 0, 0, 0], @page.box)
178
+ @page[:CropBox] = [0, -100, 100, -10]
179
+ assert_equal([0, 0, 0, 0], @page.box)
160
180
  end
161
181
 
162
182
  it "fails if an unknown box type is supplied" do
@@ -164,16 +184,18 @@ describe HexaPDF::Type::Page do
164
184
  end
165
185
 
166
186
  it "sets the correct box" do
167
- @page.box(:media, :media)
168
- assert_equal(:media, @page.box(:media))
169
- @page.box(:crop, :crop)
170
- assert_equal(:crop, @page.box(:crop))
171
- @page.box(:bleed, :bleed)
172
- assert_equal(:bleed, @page.box(:bleed))
173
- @page.box(:trim, :trim)
174
- assert_equal(:trim, @page.box(:trim))
175
- @page.box(:art, :art)
176
- assert_equal(:art, @page.box(:art))
187
+ @page.box(:media, [0, 0, 1, 1])
188
+ assert_equal([0, 0, 1, 1], @page.box(:media).value)
189
+
190
+ @page.box(:media, [0, 0, 1, 10])
191
+ @page.box(:crop, [0, 0, 1, 2])
192
+ assert_equal([0, 0, 1, 2], @page.box(:crop).value)
193
+ @page.box(:bleed, [0, 0, 1, 3])
194
+ assert_equal([0, 0, 1, 3], @page.box(:bleed))
195
+ @page.box(:trim, [0, 0, 1, 4])
196
+ assert_equal([0, 0, 1, 4], @page.box(:trim))
197
+ @page.box(:art, [0, 0, 1, 5])
198
+ assert_equal([0, 0, 1, 5], @page.box(:art))
177
199
  end
178
200
 
179
201
  it "fails if an unknown box type is supplied when setting a box" do
@@ -250,17 +272,17 @@ describe HexaPDF::Type::Page do
250
272
 
251
273
  describe "flatten" do
252
274
  it "adjust all page boxes" do
253
- @page.box(:crop, [0, 0, 1, 2])
254
- @page.box(:bleed, [0, 0, 2, 3])
255
- @page.box(:trim, [0, 0, 3, 4])
256
- @page.box(:art, [0, 0, 4, 5])
275
+ @page.box(:crop, [50, 100, 200, 300])
276
+ @page.box(:bleed, [60, 110, 190, 290])
277
+ @page.box(:trim, [70, 120, 180, 280])
278
+ @page.box(:art, [80, 130, 170, 270])
257
279
 
258
280
  @page.rotate(90, flatten: true)
259
- assert_equal([-298, 50, -98, 200], @page.box(:media).value)
260
- assert_equal([0, 0, 2, 1], @page.box(:crop).value)
261
- assert_equal([-1, 0, 2, 2], @page.box(:bleed).value)
262
- assert_equal([-2, 0, 2, 3], @page.box(:trim).value)
263
- assert_equal([-3, 0, 2, 4], @page.box(:art).value)
281
+ assert_equal([0, 0, 200, 150], @page.box(:media).value)
282
+ assert_equal([0, 0, 200, 150], @page.box(:crop).value)
283
+ assert_equal([10, 10, 190, 140], @page.box(:bleed).value)
284
+ assert_equal([20, 20, 180, 130], @page.box(:trim).value)
285
+ assert_equal([30, 30, 170, 120], @page.box(:art).value)
264
286
  end
265
287
 
266
288
  it "works correctly for 90 degrees" do
@@ -488,6 +510,7 @@ describe HexaPDF::Type::Page do
488
510
  end
489
511
 
490
512
  it "works correctly if the page has its crop box origin not at (0,0)" do
513
+ @page.box(:media, [-20, -20, 100, 300])
491
514
  @page.box(:crop, [-10, -5, 100, 300])
492
515
  @page.canvas(type: :underlay).line_width = 2
493
516
  @page.canvas(type: :page).line_width = 2
@@ -591,6 +614,12 @@ describe HexaPDF::Type::Page do
591
614
  assert(@annot2.null?)
592
615
  end
593
616
 
617
+ it "gracefully handles duplicate annotations that should be flattened" do
618
+ @page[:Annots] << @annot1
619
+ result = @page.flatten_annotations
620
+ assert(result.empty?)
621
+ end
622
+
594
623
  it "gracefully handles invalid /Annot key values" do
595
624
  @page[:Annots] << nil << @doc.add({}, stream: '') << 543
596
625
  result = @page.flatten_annotations
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.37.1
4
+ version: 0.37.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-05 00:00:00.000000000 Z
11
+ date: 2024-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse