hexapdf 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/CONTRIBUTERS +1 -1
- data/Rakefile +35 -50
- data/VERSION +1 -1
- data/lib/hexapdf/cli.rb +4 -0
- data/lib/hexapdf/cli/command.rb +6 -2
- data/lib/hexapdf/cli/image2pdf.rb +141 -0
- data/lib/hexapdf/cli/info.rb +1 -1
- data/lib/hexapdf/cli/inspect.rb +32 -2
- data/lib/hexapdf/cli/modify.rb +1 -1
- data/lib/hexapdf/cli/optimize.rb +1 -1
- data/lib/hexapdf/cli/watermark.rb +130 -0
- data/lib/hexapdf/composer.rb +2 -2
- data/lib/hexapdf/configuration.rb +7 -1
- data/lib/hexapdf/content/canvas.rb +2 -2
- data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
- data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
- data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
- data/lib/hexapdf/dictionary.rb +11 -3
- data/lib/hexapdf/dictionary_fields.rb +32 -3
- data/lib/hexapdf/document.rb +7 -3
- data/lib/hexapdf/document/files.rb +1 -1
- data/lib/hexapdf/document/fonts.rb +21 -1
- data/lib/hexapdf/document/pages.rb +2 -2
- data/lib/hexapdf/encryption/standard_security_handler.rb +2 -2
- data/lib/hexapdf/font/cmap/parser.rb +1 -1
- data/lib/hexapdf/font/true_type/table/head.rb +2 -2
- data/lib/hexapdf/font/true_type/table/os2.rb +4 -4
- data/lib/hexapdf/font/true_type_wrapper.rb +16 -16
- data/lib/hexapdf/font/type1_wrapper.rb +16 -16
- data/lib/hexapdf/font_loader.rb +2 -0
- data/lib/hexapdf/font_loader/from_configuration.rb +5 -0
- data/lib/hexapdf/font_loader/standard14.rb +5 -0
- data/lib/hexapdf/image_loader/png.rb +1 -1
- data/lib/hexapdf/layout/box.rb +2 -2
- data/lib/hexapdf/layout/image_box.rb +1 -1
- data/lib/hexapdf/layout/style.rb +50 -24
- data/lib/hexapdf/layout/text_box.rb +1 -1
- data/lib/hexapdf/layout/text_fragment.rb +2 -2
- data/lib/hexapdf/layout/text_layouter.rb +14 -10
- data/lib/hexapdf/name_tree_node.rb +3 -3
- data/lib/hexapdf/number_tree_node.rb +3 -3
- data/lib/hexapdf/pdf_array.rb +207 -0
- data/lib/hexapdf/rectangle.rb +12 -12
- data/lib/hexapdf/serializer.rb +1 -1
- data/lib/hexapdf/stream.rb +6 -4
- data/lib/hexapdf/task/optimize.rb +3 -3
- data/lib/hexapdf/type.rb +2 -0
- data/lib/hexapdf/type/acro_form.rb +51 -0
- data/lib/hexapdf/type/acro_form/field.rb +129 -0
- data/lib/hexapdf/type/acro_form/form.rb +124 -0
- 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/annotation.rb +2 -2
- data/lib/hexapdf/type/annotations.rb +1 -0
- data/lib/hexapdf/type/annotations/link.rb +4 -15
- data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -1
- data/lib/hexapdf/type/annotations/text.rb +3 -6
- data/lib/hexapdf/type/annotations/widget.rb +90 -0
- data/lib/hexapdf/type/catalog.rb +12 -9
- data/lib/hexapdf/type/cid_font.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/font_descriptor.rb +5 -2
- data/lib/hexapdf/type/font_simple.rb +1 -1
- data/lib/hexapdf/type/font_type0.rb +1 -1
- data/lib/hexapdf/type/font_type3.rb +1 -1
- data/lib/hexapdf/type/form.rb +2 -2
- data/lib/hexapdf/type/graphics_state_parameter.rb +11 -6
- data/lib/hexapdf/type/icon_fit.rb +58 -0
- data/lib/hexapdf/type/image.rb +14 -8
- data/lib/hexapdf/type/info.rb +2 -1
- data/lib/hexapdf/type/page.rb +4 -4
- data/lib/hexapdf/type/page_tree_node.rb +3 -7
- data/lib/hexapdf/type/resources.rb +1 -1
- data/lib/hexapdf/type/trailer.rb +4 -4
- data/lib/hexapdf/type/viewer_preferences.rb +7 -4
- data/lib/hexapdf/type/xref_stream.rb +2 -2
- data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/man/man1/hexapdf.1 +77 -8
- data/test/hexapdf/content/test_canvas.rb +2 -2
- data/test/hexapdf/content/test_processor.rb +3 -3
- data/test/hexapdf/document/test_files.rb +4 -4
- data/test/hexapdf/document/test_fonts.rb +13 -1
- data/test/hexapdf/document/test_images.rb +6 -6
- data/test/hexapdf/document/test_pages.rb +8 -8
- data/test/hexapdf/encryption/test_security_handler.rb +7 -7
- data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -5
- data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
- data/test/hexapdf/font_loader/test_from_configuration.rb +4 -0
- data/test/hexapdf/font_loader/test_standard14.rb +10 -0
- data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
- data/test/hexapdf/image_loader/test_png.rb +3 -3
- data/test/hexapdf/layout/test_box.rb +2 -2
- data/test/hexapdf/layout/test_frame.rb +1 -1
- data/test/hexapdf/layout/test_image_box.rb +1 -1
- data/test/hexapdf/layout/test_style.rb +18 -13
- data/test/hexapdf/layout/test_text_box.rb +1 -1
- data/test/hexapdf/layout/test_text_layouter.rb +11 -6
- data/test/hexapdf/task/test_dereference.rb +2 -2
- data/test/hexapdf/task/test_optimize.rb +11 -11
- data/test/hexapdf/test_composer.rb +1 -1
- data/test/hexapdf/test_dictionary.rb +10 -2
- data/test/hexapdf/test_dictionary_fields.rb +27 -3
- data/test/hexapdf/test_document.rb +16 -15
- data/test/hexapdf/test_importer.rb +4 -4
- data/test/hexapdf/test_object.rb +1 -1
- data/test/hexapdf/test_pdf_array.rb +162 -0
- data/test/hexapdf/test_rectangle.rb +3 -5
- data/test/hexapdf/test_serializer.rb +1 -1
- data/test/hexapdf/test_stream.rb +1 -0
- data/test/hexapdf/test_writer.rb +3 -3
- data/test/hexapdf/type/acro_form/test_field.rb +85 -0
- data/test/hexapdf/type/acro_form/test_form.rb +69 -0
- data/test/hexapdf/type/annotations/test_text.rb +2 -6
- data/test/hexapdf/type/annotations/test_widget.rb +24 -0
- data/test/hexapdf/type/test_annotation.rb +1 -1
- data/test/hexapdf/type/test_catalog.rb +1 -1
- data/test/hexapdf/type/test_cid_font.rb +3 -3
- data/test/hexapdf/type/test_font.rb +2 -2
- data/test/hexapdf/type/test_font_descriptor.rb +2 -1
- data/test/hexapdf/type/test_font_simple.rb +3 -3
- data/test/hexapdf/type/test_font_true_type.rb +6 -6
- data/test/hexapdf/type/test_font_type0.rb +5 -5
- data/test/hexapdf/type/test_font_type1.rb +8 -8
- data/test/hexapdf/type/test_font_type3.rb +4 -4
- data/test/hexapdf/type/test_image.rb +16 -12
- data/test/hexapdf/type/test_page.rb +11 -11
- data/test/hexapdf/type/test_page_tree_node.rb +20 -20
- data/test/hexapdf/type/test_resources.rb +6 -6
- data/test/hexapdf/type/test_trailer.rb +5 -2
- data/test/hexapdf/type/test_xref_stream.rb +1 -0
- data/test/hexapdf/utils/test_sorted_tree_node.rb +35 -35
- metadata +23 -7
- data/test/hexapdf/type/annotations/test_link.rb +0 -19
|
@@ -777,9 +777,9 @@ describe HexaPDF::Content::Canvas do
|
|
|
777
777
|
|
|
778
778
|
describe "xobject" do
|
|
779
779
|
before do
|
|
780
|
-
@image = @doc.add(Type: :XObject, Subtype: :Image, Width: 10, Height: 5)
|
|
780
|
+
@image = @doc.add({Type: :XObject, Subtype: :Image, Width: 10, Height: 5})
|
|
781
781
|
@image.source_path = File.join(TEST_DATA_DIR, 'images', 'gray.jpg')
|
|
782
|
-
@form = @doc.add(Type: :XObject, Subtype: :Form, BBox: [100, 50, 200, 100])
|
|
782
|
+
@form = @doc.add({Type: :XObject, Subtype: :Form, BBox: [100, 50, 200, 100]})
|
|
783
783
|
end
|
|
784
784
|
|
|
785
785
|
it "can use any xobject specified via a filename" do
|
|
@@ -117,9 +117,9 @@ describe HexaPDF::Content::Processor do
|
|
|
117
117
|
before do
|
|
118
118
|
@doc = HexaPDF::Document.new
|
|
119
119
|
@processor.process(:BT)
|
|
120
|
-
@processor.graphics_state.font = @font = @doc.add(Type: :Font, Subtype: :Type1,
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
@processor.graphics_state.font = @font = @doc.add({Type: :Font, Subtype: :Type1,
|
|
121
|
+
Encoding: :WinAnsiEncoding,
|
|
122
|
+
BaseFont: :"Times-Roman"})
|
|
123
123
|
@processor.graphics_state.font_size = 10
|
|
124
124
|
@processor.graphics_state.text_rise = 10
|
|
125
125
|
@processor.graphics_state.character_spacing = 1
|
|
@@ -50,9 +50,9 @@ describe HexaPDF::Document::Files do
|
|
|
50
50
|
|
|
51
51
|
describe "each" do
|
|
52
52
|
it "iterates only over named embedded files and file annotations if search=false" do
|
|
53
|
-
@doc.add(Type: :Filespec)
|
|
53
|
+
@doc.add({Type: :Filespec})
|
|
54
54
|
spec1 = @doc.files.add(__FILE__)
|
|
55
|
-
spec2 = @doc.add(Type: :Filespec)
|
|
55
|
+
spec2 = @doc.add({Type: :Filespec})
|
|
56
56
|
@doc.pages.add # page without annot
|
|
57
57
|
@doc.pages.add[:Annots] = [
|
|
58
58
|
{Subtype: :FileAttachment, FS: HexaPDF::Reference.new(spec1.oid, spec1.gen)},
|
|
@@ -64,8 +64,8 @@ describe HexaPDF::Document::Files do
|
|
|
64
64
|
|
|
65
65
|
it "iterates over all file specifications of the document if search=true" do
|
|
66
66
|
specs = []
|
|
67
|
-
specs << @doc.add(Type: :Filespec)
|
|
68
|
-
specs << @doc.add(Type: :Filespec)
|
|
67
|
+
specs << @doc.add({Type: :Filespec})
|
|
68
|
+
specs << @doc.add({Type: :Filespec})
|
|
69
69
|
assert_equal(specs, @doc.files.each(search: true).to_a)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -37,7 +37,9 @@ describe HexaPDF::Document::Fonts do
|
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
it "fails if the requested font is not found" do
|
|
40
|
-
|
|
40
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::Standard14'
|
|
41
|
+
error = assert_raises(HexaPDF::Error) { @doc.fonts.add("Unknown") }
|
|
42
|
+
assert_match(/Times \(none/, error.message)
|
|
41
43
|
end
|
|
42
44
|
|
|
43
45
|
it "raises an error if a font loader cannot be correctly retrieved" do
|
|
@@ -45,4 +47,14 @@ describe HexaPDF::Document::Fonts do
|
|
|
45
47
|
assert_raises(HexaPDF::Error) { @doc.fonts.add(:Other) }
|
|
46
48
|
end
|
|
47
49
|
end
|
|
50
|
+
|
|
51
|
+
it "returns the configured fonts" do
|
|
52
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::Standard14'
|
|
53
|
+
@doc.config['font_loader'] << 'HexaPDF::FontLoader::FromConfiguration'
|
|
54
|
+
@doc.config['font.map'] = {'Times' => {heavy: 'none', none: 'none'}, 'Other' => {none: 'none'}}
|
|
55
|
+
fonts = @doc.fonts.configured_fonts
|
|
56
|
+
assert_equal([:none], fonts['Symbol'])
|
|
57
|
+
assert_equal([:none, :bold, :italic, :bold_italic, :heavy], fonts['Times'])
|
|
58
|
+
assert_equal([:none], fonts['Other'])
|
|
59
|
+
end
|
|
48
60
|
end
|
|
@@ -60,12 +60,12 @@ describe HexaPDF::Document::Images do
|
|
|
60
60
|
it "iterates over all non-mask images" do
|
|
61
61
|
@doc.add(5)
|
|
62
62
|
images = []
|
|
63
|
-
images << @doc.add(Type: :XObject, Subtype: :Image)
|
|
64
|
-
images << @doc.add(Type: :XObject, Subtype: :Image, Mask: [5, 6])
|
|
65
|
-
images << @doc.add(Type: :XObject, Subtype: :Image,
|
|
66
|
-
|
|
67
|
-
images << @doc.add(Type: :XObject, Subtype: :Image,
|
|
68
|
-
|
|
63
|
+
images << @doc.add({Type: :XObject, Subtype: :Image})
|
|
64
|
+
images << @doc.add({Type: :XObject, Subtype: :Image, Mask: [5, 6]})
|
|
65
|
+
images << @doc.add({Type: :XObject, Subtype: :Image,
|
|
66
|
+
Mask: @doc.add({Type: :XObject, Subtype: :Image})})
|
|
67
|
+
images << @doc.add({Type: :XObject, Subtype: :Image,
|
|
68
|
+
SMask: @doc.add({Type: :XObject, Subtype: :Image})})
|
|
69
69
|
assert_equal(images.sort, @doc.images.to_a.sort)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
@@ -17,7 +17,7 @@ describe HexaPDF::Document::Pages do
|
|
|
17
17
|
describe "add" do
|
|
18
18
|
it "adds a new empty page when no page is given" do
|
|
19
19
|
page = @doc.pages.add
|
|
20
|
-
assert_equal([page], @doc.pages.root[:Kids])
|
|
20
|
+
assert_equal([page], @doc.pages.root[:Kids].value)
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
it "adds a new empty page with the given dimensions" do
|
|
@@ -34,9 +34,9 @@ describe HexaPDF::Document::Pages do
|
|
|
34
34
|
|
|
35
35
|
it "adds the given page to the end" do
|
|
36
36
|
page = @doc.pages.add
|
|
37
|
-
new_page = @doc.add(Type: :Page)
|
|
37
|
+
new_page = @doc.add({Type: :Page})
|
|
38
38
|
assert_same(new_page, @doc.pages.add(new_page))
|
|
39
|
-
assert_equal([page, new_page], @doc.pages.root[:Kids])
|
|
39
|
+
assert_equal([page, new_page], @doc.pages.root[:Kids].value)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it "fails if an unknown page format is given" do
|
|
@@ -46,10 +46,10 @@ describe HexaPDF::Document::Pages do
|
|
|
46
46
|
|
|
47
47
|
describe "<<" do
|
|
48
48
|
it "works like add but always needs a page returns self" do
|
|
49
|
-
page1 = @doc.add(Type: :Page)
|
|
50
|
-
page2 = @doc.add(Type: :Page)
|
|
49
|
+
page1 = @doc.add({Type: :Page})
|
|
50
|
+
page2 = @doc.add({Type: :Page})
|
|
51
51
|
@doc.pages << page1 << page2
|
|
52
|
-
assert_equal([page1, page2], @doc.pages.root[:Kids])
|
|
52
|
+
assert_equal([page1, page2], @doc.pages.root[:Kids].value)
|
|
53
53
|
end
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -66,7 +66,7 @@ describe HexaPDF::Document::Pages do
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
it "insert a given page at a given index" do
|
|
69
|
-
new_page = @doc.add(Type: :Page)
|
|
69
|
+
new_page = @doc.add({Type: :Page})
|
|
70
70
|
assert_same(new_page, @doc.pages.insert(2, new_page))
|
|
71
71
|
assert_equal(new_page, @doc.pages.root[:Kids][2])
|
|
72
72
|
end
|
|
@@ -88,7 +88,7 @@ describe HexaPDF::Document::Pages do
|
|
|
88
88
|
page2 = @doc.pages.add
|
|
89
89
|
page3 = @doc.pages.add
|
|
90
90
|
assert_same(page2, @doc.pages.delete_at(1))
|
|
91
|
-
assert_equal([page1, page3], @doc.pages.root[:Kids])
|
|
91
|
+
assert_equal([page1, page3], @doc.pages.root[:Kids].value)
|
|
92
92
|
end
|
|
93
93
|
end
|
|
94
94
|
|
|
@@ -201,14 +201,14 @@ describe HexaPDF::Encryption::SecurityHandler do
|
|
|
201
201
|
|
|
202
202
|
describe "set_up_decryption" do
|
|
203
203
|
it "wraps the given hash in an encryption dictionary class, uses it for its dict, returns it" do
|
|
204
|
-
dict = @handler.set_up_decryption(Filter: :test, V: 1)
|
|
204
|
+
dict = @handler.set_up_decryption({Filter: :test, V: 1})
|
|
205
205
|
assert_equal(dict, @handler.dict)
|
|
206
206
|
assert_kind_of(HexaPDF::Encryption::EncryptionDictionary, @handler.dict)
|
|
207
207
|
assert_equal({Filter: :test, V: 1}, @handler.dict.value)
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
it "doesn't modify the trailer's /Encrypt dictionary" do
|
|
211
|
-
@handler.set_up_decryption(Filter: :test, V: 4, Length: 128)
|
|
211
|
+
@handler.set_up_decryption({Filter: :test, V: 4, Length: 128})
|
|
212
212
|
assert_nil(@document.trailer[:Encrypt])
|
|
213
213
|
end
|
|
214
214
|
|
|
@@ -238,8 +238,8 @@ describe HexaPDF::Encryption::SecurityHandler do
|
|
|
238
238
|
end
|
|
239
239
|
|
|
240
240
|
it "selects the correct algorithm for string, stream and embedded file decryption" do
|
|
241
|
-
@handler.set_up_decryption(V: 4, StrF: :Mine, StmF: :Mine, EFF: :Mine,
|
|
242
|
-
|
|
241
|
+
@handler.set_up_decryption({V: 4, StrF: :Mine, StmF: :Mine, EFF: :Mine,
|
|
242
|
+
CF: {Mine: {CFM: :V2}}})
|
|
243
243
|
assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:embedded_file_algorithm))
|
|
244
244
|
assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:string_algorithm))
|
|
245
245
|
assert_equal(HexaPDF::Encryption::FastARC4, @handler.send(:stream_algorithm))
|
|
@@ -254,14 +254,14 @@ describe HexaPDF::Encryption::SecurityHandler do
|
|
|
254
254
|
|
|
255
255
|
it "fails for unsupported /V values in the dict" do
|
|
256
256
|
exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
|
|
257
|
-
@handler.set_up_decryption(V: 3)
|
|
257
|
+
@handler.set_up_decryption({V: 3})
|
|
258
258
|
end
|
|
259
259
|
assert_match(/Unsupported encryption version/i, exp.message)
|
|
260
260
|
end
|
|
261
261
|
|
|
262
262
|
it "fails for unsupported crypt filter encryption methods" do
|
|
263
263
|
exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
|
|
264
|
-
@handler.set_up_decryption(V: 4, StrF: :Mine, CF: {Mine: {CFM: :Unknown}})
|
|
264
|
+
@handler.set_up_decryption({V: 4, StrF: :Mine, CF: {Mine: {CFM: :Unknown}}})
|
|
265
265
|
end
|
|
266
266
|
assert_match(/Unsupported encryption method/i, exp.message)
|
|
267
267
|
end
|
|
@@ -269,7 +269,7 @@ describe HexaPDF::Encryption::SecurityHandler do
|
|
|
269
269
|
|
|
270
270
|
describe "decrypt" do
|
|
271
271
|
before do
|
|
272
|
-
@handler.set_up_decryption(V: 1)
|
|
272
|
+
@handler.set_up_decryption({V: 1})
|
|
273
273
|
@encrypted = @handler.encrypt_string('string', @obj)
|
|
274
274
|
@obj.value = {Key: @encrypted.dup, Array: [@encrypted.dup], Hash: {Another: @encrypted.dup}}
|
|
275
275
|
end
|
|
@@ -217,29 +217,29 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
|
217
217
|
describe "prepare_decryption" do
|
|
218
218
|
it "fails if the /Filter value is incorrect" do
|
|
219
219
|
exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
|
|
220
|
-
@handler.set_up_decryption(Filter: :NonStandard, V: 2)
|
|
220
|
+
@handler.set_up_decryption({Filter: :NonStandard, V: 2})
|
|
221
221
|
end
|
|
222
222
|
assert_match(/Invalid \/Filter/i, exp.message)
|
|
223
223
|
end
|
|
224
224
|
|
|
225
225
|
it "fails if the /R value is incorrect" do
|
|
226
226
|
exp = assert_raises(HexaPDF::UnsupportedEncryptionError) do
|
|
227
|
-
@handler.set_up_decryption(Filter: :Standard, V: 2, R: 5)
|
|
227
|
+
@handler.set_up_decryption({Filter: :Standard, V: 2, R: 5})
|
|
228
228
|
end
|
|
229
229
|
assert_match(/Invalid \/R/i, exp.message)
|
|
230
230
|
end
|
|
231
231
|
|
|
232
232
|
it "fails if the ID in the document's trailer is missing although it is needed" do
|
|
233
233
|
exp = assert_raises(HexaPDF::EncryptionError) do
|
|
234
|
-
@handler.set_up_decryption(Filter: :Standard, V: 2, R: 2)
|
|
234
|
+
@handler.set_up_decryption({Filter: :Standard, V: 2, R: 2})
|
|
235
235
|
end
|
|
236
236
|
assert_match(/Document ID/i, exp.message)
|
|
237
237
|
end
|
|
238
238
|
|
|
239
239
|
it "fails if the supplied password is invalid" do
|
|
240
240
|
exp = assert_raises(HexaPDF::EncryptionError) do
|
|
241
|
-
@handler.set_up_decryption(Filter: :Standard, V: 2, R: 6, U: 'a' * 48, O: 'a' * 48,
|
|
242
|
-
|
|
241
|
+
@handler.set_up_decryption({Filter: :Standard, V: 2, R: 6, U: 'a' * 48, O: 'a' * 48,
|
|
242
|
+
UE: 'a' * 32, OE: 'a' * 32})
|
|
243
243
|
end
|
|
244
244
|
assert_match(/Invalid password/i, exp.message)
|
|
245
245
|
end
|
|
@@ -114,7 +114,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
114
114
|
cidfont[:CIDSystemInfo].value)
|
|
115
115
|
assert_equal(:Identity, cidfont[:CIDToGIDMap])
|
|
116
116
|
assert_equal(@font_wrapper.glyph(3).width, cidfont[:DW])
|
|
117
|
-
assert_equal([2, [glyph.width]], cidfont[:W])
|
|
117
|
+
assert_equal([2, [glyph.width]], cidfont[:W].value)
|
|
118
118
|
assert(cidfont.validate)
|
|
119
119
|
|
|
120
120
|
# Checking font descriptor
|
|
@@ -155,7 +155,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
|
155
155
|
|
|
156
156
|
assert_equal(HexaPDF::Font::CMap.create_to_unicode_cmap([[3, ' '.ord], [glyph.id, 'H'.ord]]),
|
|
157
157
|
dict[:ToUnicode].stream)
|
|
158
|
-
assert_equal([glyph.id, [glyph.width]], dict[:DescendantFonts][0][:W])
|
|
158
|
+
assert_equal([glyph.id, [glyph.width]], dict[:DescendantFonts][0][:W].value)
|
|
159
159
|
end
|
|
160
160
|
end
|
|
161
161
|
|
|
@@ -32,4 +32,8 @@ describe HexaPDF::FontLoader::FromConfiguration do
|
|
|
32
32
|
it "returns nil for unknown fonts" do
|
|
33
33
|
assert_nil(@klass.call(@doc, "Unknown"))
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
it "returns a hash with all configured fonts" do
|
|
37
|
+
assert_equal({'font' => [:none]}, @klass.available_fonts(@doc))
|
|
38
|
+
end
|
|
35
39
|
end
|
|
@@ -20,4 +20,14 @@ describe HexaPDF::FontLoader::Standard14 do
|
|
|
20
20
|
it "returns nil for unknown fonts" do
|
|
21
21
|
assert_nil(@obj.call(@doc, "Unknown"))
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
it "returns a hash with all standard PDF fonts" do
|
|
25
|
+
assert_equal({
|
|
26
|
+
'Times' => [:none, :bold, :italic, :bold_italic],
|
|
27
|
+
'Helvetica' => [:none, :bold, :italic, :bold_italic],
|
|
28
|
+
'Courier' => [:none, :bold, :italic, :bold_italic],
|
|
29
|
+
'Symbol' => [:none], 'ZapfDingbats' => [:none]
|
|
30
|
+
},
|
|
31
|
+
@obj.available_fonts(@doc))
|
|
32
|
+
end
|
|
23
33
|
end
|
|
@@ -62,7 +62,7 @@ describe HexaPDF::ImageLoader::JPEG do
|
|
|
62
62
|
assert_equal(5, image[:Width])
|
|
63
63
|
assert_equal(5, image[:Height])
|
|
64
64
|
assert_equal(:DeviceCMYK, image[:ColorSpace])
|
|
65
|
-
assert_equal([1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0], image[:Decode])
|
|
65
|
+
assert_equal([1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0], image[:Decode].value)
|
|
66
66
|
assert_equal(File.binread(jpeg), image.stream)
|
|
67
67
|
end
|
|
68
68
|
|
|
@@ -29,7 +29,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
|
29
29
|
assert_equal(width, image[:Width])
|
|
30
30
|
assert_equal(height, image[:Height])
|
|
31
31
|
assert_equal(bpc, image[:BitsPerComponent])
|
|
32
|
-
assert_equal(color_space, image[:ColorSpace]) if color_space
|
|
32
|
+
assert_equal(color_space, @doc.unwrap(image[:ColorSpace])) if color_space
|
|
33
33
|
data = stream.map {|row| [row.map {|i| i.to_s(2).rjust(bpc, '0') }.join("")].pack('B*') }.join("")
|
|
34
34
|
assert_equal(data, image.stream)
|
|
35
35
|
end
|
|
@@ -111,7 +111,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
|
111
111
|
[253, 202, 151, 100, 50],
|
|
112
112
|
[253, 202, 151, 100, 49]]
|
|
113
113
|
assert_image(image, 5, 5, 8, :DeviceGray, data)
|
|
114
|
-
assert_equal([203, 203], image[:Mask])
|
|
114
|
+
assert_equal([203, 203], image[:Mask].value)
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
it "works for a greyscale png with a gamma value of 1" do
|
|
@@ -123,7 +123,7 @@ describe HexaPDF::ImageLoader::PNG do
|
|
|
123
123
|
it "works for a greyscale png with a gamma value of 1/1.5" do
|
|
124
124
|
png = @images.grep(/greyscale-with-gamma1\.5\.png/).first
|
|
125
125
|
image = @loader.load(@doc, png)
|
|
126
|
-
assert_equal([:CalGray, {WhitePoint: [1.0, 1.0, 1.0], Gamma: 1 / 1.5}], image[:ColorSpace])
|
|
126
|
+
assert_equal([:CalGray, {WhitePoint: [1.0, 1.0, 1.0], Gamma: 1 / 1.5}], image[:ColorSpace].value)
|
|
127
127
|
end
|
|
128
128
|
|
|
129
129
|
it "works for an indexed 1-bit png" do
|
|
@@ -6,8 +6,8 @@ require 'hexapdf/document'
|
|
|
6
6
|
require 'hexapdf/layout/box'
|
|
7
7
|
|
|
8
8
|
describe HexaPDF::Layout::Box do
|
|
9
|
-
def create_box(
|
|
10
|
-
HexaPDF::Layout::Box.new(
|
|
9
|
+
def create_box(**args, &block)
|
|
10
|
+
HexaPDF::Layout::Box.new(**args, &block)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
describe "::create" do
|
|
@@ -50,7 +50,7 @@ describe HexaPDF::Layout::Frame do
|
|
|
50
50
|
# checked whether the box coordinates are pos and whether the frame has the shape given by
|
|
51
51
|
# points.
|
|
52
52
|
def check_box(box_opts, pos, points)
|
|
53
|
-
@box = HexaPDF::Layout::Box.create(box_opts) {}
|
|
53
|
+
@box = HexaPDF::Layout::Box.create(**box_opts) {}
|
|
54
54
|
@canvas.expect(:translate, nil, pos)
|
|
55
55
|
assert(@frame.draw(@canvas, @box))
|
|
56
56
|
assert_equal(points, @frame.shape.polygons.map(&:to_a))
|
|
@@ -136,8 +136,8 @@ describe HexaPDF::Layout::Style::Quad do
|
|
|
136
136
|
end
|
|
137
137
|
|
|
138
138
|
describe HexaPDF::Layout::Style::Border do
|
|
139
|
-
def create_border(
|
|
140
|
-
HexaPDF::Layout::Style::Border.new(
|
|
139
|
+
def create_border(**args)
|
|
140
|
+
HexaPDF::Layout::Style::Border.new(**args)
|
|
141
141
|
end
|
|
142
142
|
|
|
143
143
|
it "has accessors for with, color and style that return Quads" do
|
|
@@ -531,13 +531,13 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
|
531
531
|
end
|
|
532
532
|
|
|
533
533
|
def call_link(hash)
|
|
534
|
-
link = HexaPDF::Layout::Style::LinkLayer.new(hash)
|
|
534
|
+
link = HexaPDF::Layout::Style::LinkLayer.new(**hash)
|
|
535
535
|
link.call(@canvas, @box)
|
|
536
536
|
@canvas.context[:Annots]&.first
|
|
537
537
|
end
|
|
538
538
|
|
|
539
539
|
it "does nothing if the context is not a page object" do
|
|
540
|
-
@canvas = HexaPDF::Document.new.add(Type: :XObject, Subtype: :Form).canvas
|
|
540
|
+
@canvas = HexaPDF::Document.new.add({Type: :XObject, Subtype: :Form}).canvas
|
|
541
541
|
assert_nil(call_link(dest: true))
|
|
542
542
|
end
|
|
543
543
|
|
|
@@ -545,28 +545,28 @@ describe HexaPDF::Layout::Style::LinkLayer do
|
|
|
545
545
|
annot = call_link(dest: true)
|
|
546
546
|
assert_equal(:Link, annot[:Subtype])
|
|
547
547
|
assert_equal([10, 10, 25, 20], annot[:Rect].value)
|
|
548
|
-
assert_equal([10, 10, 25, 10, 25, 20, 10, 20], annot[:QuadPoints])
|
|
548
|
+
assert_equal([10, 10, 25, 10, 25, 20, 10, 20], annot[:QuadPoints].value)
|
|
549
549
|
end
|
|
550
550
|
|
|
551
551
|
it "removes the border by default" do
|
|
552
552
|
annot = call_link(dest: true)
|
|
553
|
-
assert_equal([0, 0, 0], annot[:Border])
|
|
553
|
+
assert_equal([0, 0, 0], annot[:Border].value)
|
|
554
554
|
end
|
|
555
555
|
|
|
556
556
|
it "uses a default border if no specific border style is specified" do
|
|
557
557
|
annot = call_link(dest: true, border: true)
|
|
558
|
-
assert_equal([0, 0, 1], annot[:Border])
|
|
558
|
+
assert_equal([0, 0, 1], annot[:Border].value)
|
|
559
559
|
end
|
|
560
560
|
|
|
561
561
|
it "uses the specified border and border color" do
|
|
562
562
|
annot = call_link(dest: true, border: [10, 10, 2], border_color: [255])
|
|
563
|
-
assert_equal([10, 10, 2], annot[:Border])
|
|
564
|
-
assert_equal([1.0], annot[:C])
|
|
563
|
+
assert_equal([10, 10, 2], annot[:Border].value)
|
|
564
|
+
assert_equal([1.0], annot[:C].value)
|
|
565
565
|
end
|
|
566
566
|
|
|
567
567
|
it "works for simple destinations" do
|
|
568
568
|
annot = call_link(dest: [@canvas.context, :FitH])
|
|
569
|
-
assert_equal([@canvas.context, :FitH], annot[:Dest])
|
|
569
|
+
assert_equal([@canvas.context, :FitH], annot[:Dest].value)
|
|
570
570
|
assert_nil(annot[:A])
|
|
571
571
|
end
|
|
572
572
|
|
|
@@ -641,14 +641,14 @@ describe HexaPDF::Layout::Style do
|
|
|
641
641
|
assert_equal(100, @style.horizontal_scaling)
|
|
642
642
|
assert_equal(0, @style.text_rise)
|
|
643
643
|
assert_equal({}, @style.font_features)
|
|
644
|
-
assert_equal(
|
|
644
|
+
assert_equal(HexaPDF::Content::TextRenderingMode::FILL, @style.text_rendering_mode)
|
|
645
645
|
assert_equal([0], @style.fill_color.components)
|
|
646
646
|
assert_equal(1, @style.fill_alpha)
|
|
647
647
|
assert_equal([0], @style.stroke_color.components)
|
|
648
648
|
assert_equal(1, @style.stroke_alpha)
|
|
649
649
|
assert_equal(1, @style.stroke_width)
|
|
650
|
-
assert_equal(
|
|
651
|
-
assert_equal(
|
|
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
652
|
assert_equal(10.0, @style.stroke_miter_limit)
|
|
653
653
|
assert_equal(:left, @style.align)
|
|
654
654
|
assert_equal(:top, @style.valign)
|
|
@@ -677,6 +677,11 @@ describe HexaPDF::Layout::Style do
|
|
|
677
677
|
assert_equal([[5], 2], @style.stroke_dash_pattern.to_operands)
|
|
678
678
|
end
|
|
679
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
|
+
|
|
680
685
|
it "allows checking whether a property has been set or accessed" do
|
|
681
686
|
refute(@style.align?)
|
|
682
687
|
assert_equal(:left, @style.align)
|