hexapdf 0.37.1 → 0.37.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/LICENSE +1 -1
- data/lib/hexapdf/cli/batch.rb +1 -1
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/cli/files.rb +1 -1
- data/lib/hexapdf/cli/fonts.rb +1 -1
- data/lib/hexapdf/cli/form.rb +1 -1
- data/lib/hexapdf/cli/image2pdf.rb +1 -1
- data/lib/hexapdf/cli/images.rb +1 -1
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +1 -1
- data/lib/hexapdf/cli/merge.rb +1 -1
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/split.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +1 -1
- data/lib/hexapdf/cli.rb +1 -1
- data/lib/hexapdf/composer.rb +1 -1
- data/lib/hexapdf/configuration.rb +3 -4
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/canvas_composer.rb +1 -1
- data/lib/hexapdf/content/color_space.rb +1 -1
- data/lib/hexapdf/content/graphic_object/arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/content/graphic_object.rb +1 -1
- data/lib/hexapdf/content/graphics_state.rb +1 -1
- data/lib/hexapdf/content/operator.rb +1 -1
- data/lib/hexapdf/content/parser.rb +1 -1
- data/lib/hexapdf/content/processor.rb +4 -4
- data/lib/hexapdf/content/transformation_matrix.rb +3 -3
- data/lib/hexapdf/content.rb +1 -1
- data/lib/hexapdf/data_dir.rb +1 -1
- data/lib/hexapdf/dictionary.rb +1 -1
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/digital_signature/cms_handler.rb +1 -2
- data/lib/hexapdf/digital_signature/handler.rb +1 -1
- data/lib/hexapdf/digital_signature/pkcs1_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signature.rb +2 -2
- data/lib/hexapdf/digital_signature/signatures.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/default_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/signed_data_creator.rb +1 -1
- data/lib/hexapdf/digital_signature/signing/timestamp_handler.rb +1 -1
- data/lib/hexapdf/digital_signature/signing.rb +1 -1
- data/lib/hexapdf/digital_signature/verification_result.rb +1 -1
- data/lib/hexapdf/digital_signature.rb +1 -1
- data/lib/hexapdf/document/destinations.rb +1 -1
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +1 -1
- data/lib/hexapdf/document/images.rb +1 -1
- data/lib/hexapdf/document/layout.rb +1 -1
- data/lib/hexapdf/document/metadata.rb +14 -13
- data/lib/hexapdf/document/pages.rb +1 -1
- data/lib/hexapdf/document.rb +1 -1
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/arc4.rb +1 -1
- data/lib/hexapdf/encryption/fast_aes.rb +1 -1
- data/lib/hexapdf/encryption/fast_arc4.rb +1 -1
- data/lib/hexapdf/encryption/identity.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_arc4.rb +1 -1
- data/lib/hexapdf/encryption/security_handler.rb +1 -1
- data/lib/hexapdf/encryption/standard_security_handler.rb +1 -1
- data/lib/hexapdf/encryption.rb +1 -1
- data/lib/hexapdf/error.rb +1 -1
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -1
- data/lib/hexapdf/filter/crypt.rb +1 -1
- data/lib/hexapdf/filter/encryption.rb +1 -1
- data/lib/hexapdf/filter/flate_decode.rb +1 -1
- data/lib/hexapdf/filter/lzw_decode.rb +1 -1
- data/lib/hexapdf/filter/pass_through.rb +1 -1
- data/lib/hexapdf/filter/predictor.rb +1 -1
- data/lib/hexapdf/filter/run_length_decode.rb +1 -1
- data/lib/hexapdf/filter.rb +1 -1
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/cmap/writer.rb +1 -1
- data/lib/hexapdf/font/cmap.rb +1 -1
- data/lib/hexapdf/font/encoding/base.rb +1 -1
- data/lib/hexapdf/font/encoding/difference_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/glyph_list.rb +2 -2
- data/lib/hexapdf/font/encoding/mac_expert_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/mac_roman_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/standard_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/symbol_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/win_ansi_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding/zapf_dingbats_encoding.rb +1 -1
- data/lib/hexapdf/font/encoding.rb +1 -1
- data/lib/hexapdf/font/invalid_glyph.rb +1 -1
- data/lib/hexapdf/font/true_type/builder.rb +2 -2
- data/lib/hexapdf/font/true_type/font.rb +1 -1
- data/lib/hexapdf/font/true_type/optimizer.rb +1 -1
- data/lib/hexapdf/font/true_type/subsetter.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap.rb +1 -1
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +1 -1
- data/lib/hexapdf/font/true_type/table/directory.rb +1 -1
- data/lib/hexapdf/font/true_type/table/glyf.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hhea.rb +1 -1
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -1
- data/lib/hexapdf/font/true_type/table/kern.rb +1 -1
- data/lib/hexapdf/font/true_type/table/loca.rb +1 -1
- data/lib/hexapdf/font/true_type/table/maxp.rb +1 -1
- data/lib/hexapdf/font/true_type/table/name.rb +1 -1
- data/lib/hexapdf/font/true_type/table/os2.rb +1 -1
- data/lib/hexapdf/font/true_type/table/post.rb +1 -1
- data/lib/hexapdf/font/true_type/table.rb +1 -1
- data/lib/hexapdf/font/true_type.rb +1 -1
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1/afm_parser.rb +1 -1
- data/lib/hexapdf/font/type1/character_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/font.rb +2 -2
- data/lib/hexapdf/font/type1/font_metrics.rb +1 -1
- data/lib/hexapdf/font/type1/pfb_parser.rb +1 -1
- data/lib/hexapdf/font/type1.rb +1 -1
- data/lib/hexapdf/font/type1_wrapper.rb +2 -2
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/from_file.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.rb +1 -1
- data/lib/hexapdf/font_loader.rb +1 -1
- data/lib/hexapdf/image_loader/jpeg.rb +1 -1
- data/lib/hexapdf/image_loader/pdf.rb +1 -1
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/image_loader.rb +1 -1
- data/lib/hexapdf/importer.rb +1 -1
- data/lib/hexapdf/layout/box.rb +4 -4
- data/lib/hexapdf/layout/box_fitter.rb +1 -1
- data/lib/hexapdf/layout/column_box.rb +1 -1
- data/lib/hexapdf/layout/container_box.rb +4 -4
- data/lib/hexapdf/layout/frame.rb +1 -1
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/inline_box.rb +1 -1
- data/lib/hexapdf/layout/line.rb +1 -1
- data/lib/hexapdf/layout/list_box.rb +4 -6
- data/lib/hexapdf/layout/numeric_refinements.rb +1 -1
- data/lib/hexapdf/layout/page_style.rb +1 -1
- data/lib/hexapdf/layout/style.rb +1 -1
- data/lib/hexapdf/layout/table_box.rb +4 -4
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +1 -1
- data/lib/hexapdf/layout/text_layouter.rb +1 -1
- data/lib/hexapdf/layout/text_shaper.rb +1 -1
- data/lib/hexapdf/layout/width_from_polygon.rb +1 -1
- data/lib/hexapdf/layout.rb +1 -1
- data/lib/hexapdf/name_tree_node.rb +1 -1
- data/lib/hexapdf/number_tree_node.rb +1 -1
- data/lib/hexapdf/object.rb +3 -3
- data/lib/hexapdf/parser.rb +1 -1
- data/lib/hexapdf/pdf_array.rb +1 -1
- data/lib/hexapdf/rectangle.rb +1 -1
- data/lib/hexapdf/reference.rb +1 -1
- data/lib/hexapdf/revision.rb +1 -1
- data/lib/hexapdf/revisions.rb +1 -1
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +1 -1
- data/lib/hexapdf/task/dereference.rb +1 -1
- data/lib/hexapdf/task/optimize.rb +1 -1
- data/lib/hexapdf/task.rb +1 -1
- data/lib/hexapdf/test_utils.rb +1 -1
- data/lib/hexapdf/tokenizer.rb +1 -1
- data/lib/hexapdf/type/acro_form/appearance_generator.rb +5 -5
- data/lib/hexapdf/type/acro_form/button_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/choice_field.rb +12 -2
- data/lib/hexapdf/type/acro_form/field.rb +1 -1
- data/lib/hexapdf/type/acro_form/form.rb +2 -1
- data/lib/hexapdf/type/acro_form/signature_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/text_field.rb +1 -1
- data/lib/hexapdf/type/acro_form/variable_text_field.rb +8 -5
- data/lib/hexapdf/type/acro_form.rb +1 -1
- data/lib/hexapdf/type/action.rb +1 -1
- data/lib/hexapdf/type/actions/go_to.rb +1 -1
- data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
- data/lib/hexapdf/type/actions/launch.rb +1 -1
- data/lib/hexapdf/type/actions/set_ocg_state.rb +1 -1
- data/lib/hexapdf/type/actions/uri.rb +1 -1
- data/lib/hexapdf/type/actions.rb +1 -1
- data/lib/hexapdf/type/annotation.rb +2 -2
- data/lib/hexapdf/type/annotations/link.rb +1 -1
- data/lib/hexapdf/type/annotations/markup_annotation.rb +1 -1
- data/lib/hexapdf/type/annotations/text.rb +1 -1
- data/lib/hexapdf/type/annotations/widget.rb +1 -1
- data/lib/hexapdf/type/annotations.rb +1 -1
- data/lib/hexapdf/type/catalog.rb +1 -1
- data/lib/hexapdf/type/cid_font.rb +1 -1
- data/lib/hexapdf/type/embedded_file.rb +1 -1
- data/lib/hexapdf/type/file_specification.rb +1 -1
- data/lib/hexapdf/type/font.rb +1 -1
- data/lib/hexapdf/type/font_descriptor.rb +1 -1
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_true_type.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +2 -2
- data/lib/hexapdf/type/font_type1.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +16 -16
- data/lib/hexapdf/type/graphics_state_parameter.rb +1 -1
- data/lib/hexapdf/type/icon_fit.rb +1 -1
- data/lib/hexapdf/type/image.rb +1 -1
- data/lib/hexapdf/type/info.rb +1 -1
- data/lib/hexapdf/type/mark_information.rb +1 -1
- data/lib/hexapdf/type/metadata.rb +1 -1
- data/lib/hexapdf/type/names.rb +1 -1
- data/lib/hexapdf/type/object_stream.rb +1 -1
- data/lib/hexapdf/type/optional_content_configuration.rb +5 -5
- data/lib/hexapdf/type/optional_content_group.rb +17 -1
- data/lib/hexapdf/type/optional_content_membership.rb +1 -1
- data/lib/hexapdf/type/optional_content_properties.rb +1 -2
- data/lib/hexapdf/type/outline.rb +1 -1
- data/lib/hexapdf/type/outline_item.rb +1 -1
- data/lib/hexapdf/type/page.rb +30 -15
- data/lib/hexapdf/type/page_label.rb +1 -1
- data/lib/hexapdf/type/page_tree_node.rb +1 -1
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +1 -1
- data/lib/hexapdf/type/viewer_preferences.rb +1 -1
- data/lib/hexapdf/type/xref_stream.rb +1 -1
- data/lib/hexapdf/type.rb +1 -1
- data/lib/hexapdf/utils/bit_field.rb +1 -1
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/graphics_helpers.rb +1 -1
- data/lib/hexapdf/utils/lru_cache.rb +1 -1
- data/lib/hexapdf/utils/math_helpers.rb +1 -1
- data/lib/hexapdf/utils/object_hash.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
- data/lib/hexapdf/utils.rb +3 -3
- data/lib/hexapdf/version.rb +2 -2
- data/lib/hexapdf/writer.rb +1 -1
- data/lib/hexapdf/xref_section.rb +1 -1
- data/lib/hexapdf.rb +1 -1
- data/test/hexapdf/content/test_canvas.rb +1 -1
- data/test/hexapdf/digital_signature/common.rb +1 -1
- data/test/hexapdf/document/test_layout.rb +2 -2
- data/test/hexapdf/document/test_metadata.rb +28 -28
- data/test/hexapdf/encryption/test_standard_security_handler.rb +9 -9
- data/test/hexapdf/font/true_type/table/test_cmap_subtable.rb +2 -2
- data/test/hexapdf/font/true_type/table/test_name.rb +5 -5
- data/test/hexapdf/layout/test_box.rb +2 -2
- data/test/hexapdf/layout/test_column_box.rb +5 -5
- data/test/hexapdf/layout/test_frame.rb +4 -5
- data/test/hexapdf/layout/test_text_fragment.rb +1 -1
- data/test/hexapdf/layout/test_text_shaper.rb +2 -2
- data/test/hexapdf/test_composer.rb +1 -1
- data/test/hexapdf/test_utils.rb +1 -1
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/acro_form/test_choice_field.rb +7 -0
- data/test/hexapdf/type/acro_form/test_form.rb +6 -0
- data/test/hexapdf/type/acro_form/test_variable_text_field.rb +12 -0
- data/test/hexapdf/type/test_annotation.rb +1 -1
- data/test/hexapdf/type/test_optional_content_group.rb +2 -2
- data/test/hexapdf/type/test_page.rb +67 -38
- 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
|
-
|
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 |
|
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 |
|
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
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
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)
|
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
|
-
|
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
|
-
|
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,
|
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) {|
|
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)
|
data/test/hexapdf/test_utils.rb
CHANGED
data/test/hexapdf/test_writer.rb
CHANGED
@@ -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.
|
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.
|
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)
|
@@ -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],
|
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] =
|
140
|
-
assert_equal(
|
141
|
-
@page[:CropBox] =
|
142
|
-
assert_equal(
|
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] =
|
147
|
-
assert_equal(
|
148
|
-
assert_equal(
|
149
|
-
assert_equal(
|
150
|
-
@page[:CropBox] =
|
151
|
-
assert_equal(
|
152
|
-
assert_equal(
|
153
|
-
assert_equal(
|
154
|
-
@page[:BleedBox] =
|
155
|
-
@page[:TrimBox] =
|
156
|
-
@page[:ArtBox] =
|
157
|
-
assert_equal(
|
158
|
-
assert_equal(
|
159
|
-
assert_equal(
|
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,
|
168
|
-
assert_equal(
|
169
|
-
|
170
|
-
|
171
|
-
@page.box(:
|
172
|
-
assert_equal(
|
173
|
-
@page.box(:
|
174
|
-
assert_equal(
|
175
|
-
@page.box(:
|
176
|
-
assert_equal(
|
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, [
|
254
|
-
@page.box(:bleed, [
|
255
|
-
@page.box(:trim, [
|
256
|
-
@page.box(:art, [
|
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([
|
260
|
-
assert_equal([0, 0,
|
261
|
-
assert_equal([
|
262
|
-
assert_equal([
|
263
|
-
assert_equal([
|
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.
|
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-
|
11
|
+
date: 2024-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdparse
|