hexapdf 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +56 -0
- data/CONTRIBUTERS +1 -1
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/examples/arc.rb +1 -1
- data/examples/graphics.rb +1 -1
- data/examples/hello_world.rb +1 -1
- data/examples/merging.rb +1 -1
- data/examples/show_char_bboxes.rb +1 -1
- data/examples/standard_pdf_fonts.rb +1 -1
- data/examples/truetype.rb +1 -1
- data/lib/hexapdf/cli.rb +14 -7
- data/lib/hexapdf/cli/extract.rb +1 -1
- data/lib/hexapdf/cli/info.rb +2 -2
- data/lib/hexapdf/cli/inspect.rb +4 -4
- data/lib/hexapdf/cli/modify.rb +151 -51
- data/lib/hexapdf/configuration.rb +1 -1
- data/lib/hexapdf/content/canvas.rb +1 -1
- data/lib/hexapdf/content/processor.rb +1 -1
- data/lib/hexapdf/dictionary.rb +6 -19
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document.rb +23 -16
- data/lib/hexapdf/document/files.rb +130 -0
- data/lib/hexapdf/{font_utils.rb → document/fonts.rb} +40 -38
- data/lib/hexapdf/document/images.rb +117 -0
- data/lib/hexapdf/document/pages.rb +125 -0
- data/lib/hexapdf/encryption/aes.rb +1 -1
- data/lib/hexapdf/encryption/ruby_aes.rb +10 -10
- data/lib/hexapdf/encryption/standard_security_handler.rb +11 -8
- data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
- data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -6
- data/lib/hexapdf/font/cmap/writer.rb +5 -7
- data/lib/hexapdf/font/true_type.rb +4 -1
- data/lib/hexapdf/font/true_type/font.rb +8 -16
- data/lib/hexapdf/font/true_type/table.rb +5 -16
- data/lib/hexapdf/font/true_type/table/cmap.rb +2 -7
- data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +2 -6
- data/lib/hexapdf/font/true_type/table/directory.rb +0 -5
- data/lib/hexapdf/font/true_type/table/glyf.rb +3 -11
- data/lib/hexapdf/font/true_type/table/head.rb +0 -12
- data/lib/hexapdf/font/true_type/table/hhea.rb +0 -7
- data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -5
- data/lib/hexapdf/font/true_type/table/loca.rb +0 -4
- data/lib/hexapdf/font/true_type/table/maxp.rb +0 -8
- data/lib/hexapdf/font/true_type/table/name.rb +3 -17
- data/lib/hexapdf/font/true_type/table/os2.rb +0 -14
- data/lib/hexapdf/font/true_type/table/post.rb +0 -8
- data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
- data/lib/hexapdf/font/type1.rb +2 -2
- data/lib/hexapdf/font/type1/font.rb +2 -1
- data/lib/hexapdf/font/type1/font_metrics.rb +10 -1
- data/lib/hexapdf/font/type1_wrapper.rb +2 -1
- data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
- data/lib/hexapdf/font_loader/standard14.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 +2 -2
- data/lib/hexapdf/object.rb +18 -5
- data/lib/hexapdf/rectangle.rb +8 -1
- data/lib/hexapdf/revisions.rb +4 -2
- data/lib/hexapdf/serializer.rb +3 -3
- data/lib/hexapdf/stream.rb +3 -2
- data/lib/hexapdf/task/dereference.rb +4 -5
- data/lib/hexapdf/task/optimize.rb +6 -3
- data/lib/hexapdf/tokenizer.rb +3 -3
- data/lib/hexapdf/type/file_specification.rb +2 -2
- data/lib/hexapdf/type/form.rb +19 -0
- data/lib/hexapdf/type/page.rb +21 -6
- data/lib/hexapdf/type/page_tree_node.rb +27 -34
- data/lib/hexapdf/utils/bit_stream.rb +1 -1
- data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
- data/lib/hexapdf/version.rb +1 -1
- data/man/man1/hexapdf.1 +259 -187
- data/test/hexapdf/content/graphic_object/test_arc.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +1 -1
- data/test/hexapdf/content/graphic_object/test_solid_arc.rb +1 -1
- data/test/hexapdf/content/test_canvas.rb +1 -1
- data/test/hexapdf/document/test_files.rb +71 -0
- data/test/hexapdf/{test_font_utils.rb → document/test_fonts.rb} +1 -2
- data/test/hexapdf/document/test_images.rb +78 -0
- data/test/hexapdf/document/test_pages.rb +114 -0
- data/test/hexapdf/encryption/test_standard_security_handler.rb +26 -5
- data/test/hexapdf/font/test_true_type_wrapper.rb +1 -1
- data/test/hexapdf/font/true_type/common.rb +0 -4
- data/test/hexapdf/font/true_type/table/test_cmap.rb +0 -6
- data/test/hexapdf/font/true_type/table/test_directory.rb +0 -5
- data/test/hexapdf/font/true_type/table/test_glyf.rb +5 -8
- data/test/hexapdf/font/true_type/table/test_head.rb +0 -20
- data/test/hexapdf/font/true_type/table/test_hhea.rb +0 -7
- data/test/hexapdf/font/true_type/table/test_hmtx.rb +2 -7
- data/test/hexapdf/font/true_type/table/test_loca.rb +4 -8
- data/test/hexapdf/font/true_type/table/test_maxp.rb +0 -7
- data/test/hexapdf/font/true_type/table/test_name.rb +0 -19
- data/test/hexapdf/font/true_type/table/test_os2.rb +0 -8
- data/test/hexapdf/font/true_type/table/test_post.rb +0 -13
- data/test/hexapdf/font/true_type/test_font.rb +14 -38
- data/test/hexapdf/font/true_type/test_table.rb +0 -9
- data/test/hexapdf/font/type1/test_font_metrics.rb +22 -0
- data/test/hexapdf/task/test_dereference.rb +5 -1
- data/test/hexapdf/task/test_optimize.rb +1 -1
- data/test/hexapdf/test_dictionary.rb +4 -0
- data/test/hexapdf/test_document.rb +0 -7
- data/test/hexapdf/test_importer.rb +4 -4
- data/test/hexapdf/test_object.rb +31 -9
- data/test/hexapdf/test_rectangle.rb +18 -0
- data/test/hexapdf/test_revisions.rb +7 -0
- data/test/hexapdf/test_serializer.rb +6 -0
- data/test/hexapdf/test_writer.rb +2 -2
- data/test/hexapdf/type/test_form.rb +12 -0
- data/test/hexapdf/type/test_page.rb +39 -20
- data/test/hexapdf/type/test_page_tree_node.rb +28 -21
- metadata +21 -9
- data/lib/hexapdf/document_utils.rb +0 -209
- data/test/hexapdf/test_document_utils.rb +0 -144
@@ -82,7 +82,7 @@ describe HexaPDF::Content::GraphicObject::Arc do
|
|
82
82
|
describe "draw" do
|
83
83
|
it "draws the arc onto the canvas" do
|
84
84
|
doc = HexaPDF::Document.new
|
85
|
-
page = doc.pages.
|
85
|
+
page = doc.pages.add
|
86
86
|
canvas = page.canvas
|
87
87
|
@arc.max_curves = 4
|
88
88
|
@arc.draw(canvas)
|
@@ -37,7 +37,7 @@ describe HexaPDF::Content::GraphicObject::EndpointArc do
|
|
37
37
|
describe "draw" do
|
38
38
|
before do
|
39
39
|
@doc = HexaPDF::Document.new
|
40
|
-
@page = @doc.pages.
|
40
|
+
@page = @doc.pages.add
|
41
41
|
end
|
42
42
|
|
43
43
|
it "draws nothing if the endpoint is the same as the current point" do
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'tempfile'
|
6
|
+
require 'hexapdf/document'
|
7
|
+
|
8
|
+
describe HexaPDF::Document::Files do
|
9
|
+
before do
|
10
|
+
@doc = HexaPDF::Document.new
|
11
|
+
@data = "embed-test"
|
12
|
+
@file = Tempfile.new('file-embed-test')
|
13
|
+
@file.write(@data)
|
14
|
+
@file.close
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
@file.unlink
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "add" do
|
22
|
+
it "adds a file using a filename and embeds it" do
|
23
|
+
spec = @doc.files.add(@file.path)
|
24
|
+
assert_equal(File.basename(@file.path), spec.path)
|
25
|
+
assert_equal(@data, spec.embedded_file_stream.stream)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "adds a reference to a file" do
|
29
|
+
spec = @doc.files.add(@file.path, embed: false)
|
30
|
+
assert_equal(File.basename(@file.path), spec.path)
|
31
|
+
refute(spec.embedded_file?)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "adds a file using an IO" do
|
35
|
+
@file.open
|
36
|
+
spec = @doc.files.add(@file, name: 'test', embed: false)
|
37
|
+
assert_equal('test', spec.path)
|
38
|
+
assert_equal(@data, spec.embedded_file_stream.stream)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "optionally sets the description of the file" do
|
42
|
+
spec = @doc.files.add(@file.path, description: 'Some file')
|
43
|
+
assert_equal('Some file', spec[:Desc])
|
44
|
+
end
|
45
|
+
|
46
|
+
it "requires the name argument when given an IO object" do
|
47
|
+
assert_raises(ArgumentError) { @doc.files.add(StringIO.new) }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "each" do
|
52
|
+
it "iterates only over named embedded files and file annotations if search=false" do
|
53
|
+
@doc.add(Type: :Filespec)
|
54
|
+
spec1 = @doc.files.add(__FILE__)
|
55
|
+
spec2 = @doc.add(Type: :Filespec)
|
56
|
+
@doc.pages.add[:Annots] = [
|
57
|
+
{Subtype: :FileAttachment, FS: HexaPDF::Reference.new(spec1.oid, spec1.gen)},
|
58
|
+
{Subtype: :FileAttachment, FS: spec2},
|
59
|
+
{},
|
60
|
+
]
|
61
|
+
assert_equal([spec1, spec2], @doc.files.to_a)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "iterates over all file specifications of the document if search=true" do
|
65
|
+
specs = []
|
66
|
+
specs << @doc.add(Type: :Filespec)
|
67
|
+
specs << @doc.add(Type: :Filespec)
|
68
|
+
assert_equal(specs, @doc.files.each(search: true).to_a)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -1,10 +1,9 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
3
|
require 'test_helper'
|
4
|
-
require 'hexapdf/font_utils'
|
5
4
|
require 'hexapdf/document'
|
6
5
|
|
7
|
-
describe HexaPDF::
|
6
|
+
describe HexaPDF::Document::Fonts do
|
8
7
|
before do
|
9
8
|
@doc = HexaPDF::Document.new
|
10
9
|
@doc.config['font_loader'] = []
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'stringio'
|
5
|
+
require 'hexapdf/document'
|
6
|
+
|
7
|
+
describe HexaPDF::Document::Images do
|
8
|
+
before do
|
9
|
+
@doc = HexaPDF::Document.new
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "add" do
|
13
|
+
describe "using a custom image loader" do
|
14
|
+
before do
|
15
|
+
@loader = Object.new
|
16
|
+
@loader.define_singleton_method(:handles?) {|*| true}
|
17
|
+
@loader.define_singleton_method(:load) do |doc, s|
|
18
|
+
s = HexaPDF::StreamData.new(s) if s.kind_of?(IO)
|
19
|
+
doc.add({Subtype: :Image}, stream: s)
|
20
|
+
end
|
21
|
+
HexaPDF::GlobalConfiguration['image_loader'].unshift(@loader)
|
22
|
+
end
|
23
|
+
|
24
|
+
after do
|
25
|
+
HexaPDF::GlobalConfiguration['image_loader'].delete(@loader)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "adds an image using a filename" do
|
29
|
+
data = 'test'
|
30
|
+
image = @doc.images.add(data)
|
31
|
+
assert_equal(data, image.stream)
|
32
|
+
assert_equal(File.absolute_path(data), image.source_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "adds an image using an IO" do
|
36
|
+
File.open(__FILE__, 'rb') do |file|
|
37
|
+
image = @doc.images.add(file)
|
38
|
+
assert_equal(File.read(__FILE__), image.stream)
|
39
|
+
assert_equal(File.absolute_path(__FILE__), image.source_path)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "doesn't add an image twice" do
|
44
|
+
data = 'test'
|
45
|
+
image = @doc.images.add(data)
|
46
|
+
image1 = @doc.images.add(data)
|
47
|
+
assert_same(image, image1)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "fails if the needed image loader can't be resolved" do
|
52
|
+
begin
|
53
|
+
HexaPDF::GlobalConfiguration['image_loader'].unshift('SomeUnknownConstantHere')
|
54
|
+
exp = assert_raises(HexaPDF::Error) { @doc.images.add(StringIO.new('test')) }
|
55
|
+
assert_match(/image loader from configuration/, exp.message)
|
56
|
+
ensure
|
57
|
+
HexaPDF::GlobalConfiguration['image_loader'].shift
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
it "fails if no image loader is found" do
|
62
|
+
exp = assert_raises(HexaPDF::Error) { @doc.images.add(StringIO.new('test')) }
|
63
|
+
assert_match(/suitable image loader/, exp.message)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "each" do
|
68
|
+
it "iterates over all non-mask images" do
|
69
|
+
@doc.add(5)
|
70
|
+
images = []
|
71
|
+
images << @doc.add(Subtype: :Image)
|
72
|
+
images << @doc.add(Subtype: :Image, Mask: [5, 6])
|
73
|
+
images << @doc.add(Subtype: :Image, Mask: @doc.add(Subtype: :Image))
|
74
|
+
images << @doc.add(Subtype: :Image, SMask: @doc.add(Subtype: :Image))
|
75
|
+
assert_equal(images.sort, @doc.images.to_a.sort)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'hexapdf/document'
|
5
|
+
|
6
|
+
describe HexaPDF::Document::Pages do
|
7
|
+
before do
|
8
|
+
@doc = HexaPDF::Document.new
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "root" do
|
12
|
+
it "returns the root of the page tree" do
|
13
|
+
assert_same(@doc.catalog.pages, @doc.pages.root)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "add" do
|
18
|
+
it "adds a new empty page when no page is given" do
|
19
|
+
page = @doc.pages.add
|
20
|
+
assert_equal([page], @doc.pages.root[:Kids])
|
21
|
+
end
|
22
|
+
|
23
|
+
it "adds a given page to the end" do
|
24
|
+
page = @doc.pages.add
|
25
|
+
new_page = @doc.add(Type: :Page)
|
26
|
+
assert_same(new_page, @doc.pages.add(new_page))
|
27
|
+
assert_equal([page, new_page], @doc.pages.root[:Kids])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "<<" do
|
32
|
+
it "works like add but always needs a page returns self" do
|
33
|
+
page1 = @doc.add(Type: :Page)
|
34
|
+
page2 = @doc.add(Type: :Page)
|
35
|
+
@doc.pages << page1 << page2
|
36
|
+
assert_equal([page1, page2], @doc.pages.root[:Kids])
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "insert" do
|
41
|
+
before do
|
42
|
+
@doc.pages.add
|
43
|
+
@doc.pages.add
|
44
|
+
@doc.pages.add
|
45
|
+
end
|
46
|
+
|
47
|
+
it "insert a new page at a given index" do
|
48
|
+
page = @doc.pages.insert(2)
|
49
|
+
assert_equal(page, @doc.pages.root[:Kids][2])
|
50
|
+
end
|
51
|
+
|
52
|
+
it "insert a given page at a given index" do
|
53
|
+
new_page = @doc.add(Type: :Page)
|
54
|
+
assert_same(new_page, @doc.pages.insert(2, new_page))
|
55
|
+
assert_equal(new_page, @doc.pages.root[:Kids][2])
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "delete" do
|
60
|
+
it "deletes a given page" do
|
61
|
+
page = @doc.pages.add
|
62
|
+
@doc.pages.add
|
63
|
+
|
64
|
+
assert_same(page, @doc.pages.delete(page))
|
65
|
+
assert_nil(@doc.pages.delete(page))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "delete_at" do
|
70
|
+
it "deletes a page at a given index" do
|
71
|
+
page1 = @doc.pages.add
|
72
|
+
page2 = @doc.pages.add
|
73
|
+
page3 = @doc.pages.add
|
74
|
+
assert_same(page2, @doc.pages.delete_at(1))
|
75
|
+
assert_equal([page1, page3], @doc.pages.root[:Kids])
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "[]" do
|
80
|
+
it "returns the page at the given index" do
|
81
|
+
page1 = @doc.pages.add
|
82
|
+
page2 = @doc.pages.add
|
83
|
+
page3 = @doc.pages.add
|
84
|
+
|
85
|
+
assert_equal(page1, @doc.pages[0])
|
86
|
+
assert_equal(page2, @doc.pages[1])
|
87
|
+
assert_equal(page3, @doc.pages[2])
|
88
|
+
assert_nil(@doc.pages[3])
|
89
|
+
assert_equal(page3, @doc.pages[-1])
|
90
|
+
assert_equal(page2, @doc.pages[-2])
|
91
|
+
assert_equal(page1, @doc.pages[-3])
|
92
|
+
assert_nil(@doc.pages[-4])
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe "each" do
|
97
|
+
it "iterates over all pages" do
|
98
|
+
page1 = @doc.pages.add
|
99
|
+
page2 = @doc.pages.add
|
100
|
+
page3 = @doc.pages.add
|
101
|
+
assert_equal([page1, page2, page3], @doc.pages.to_a)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe "count" do
|
106
|
+
it "returns the number of pages in the page tree" do
|
107
|
+
assert_equal(0, @doc.pages.count)
|
108
|
+
@doc.pages.add
|
109
|
+
@doc.pages.add
|
110
|
+
@doc.pages.add
|
111
|
+
assert_equal(3, @doc.pages.count)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -95,6 +95,23 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
95
95
|
@handler = HexaPDF::Encryption::StandardSecurityHandler.new(@document)
|
96
96
|
end
|
97
97
|
|
98
|
+
it "can encrypt and then decrypt with all encryption variations" do
|
99
|
+
{arc4: [40, 48, 128], aes: [128, 256]}.each do |algorithm, key_lengths|
|
100
|
+
key_lengths.each do |key_length|
|
101
|
+
begin
|
102
|
+
doc = HexaPDF::Document.new
|
103
|
+
doc.encrypt(algorithm: algorithm, key_length: key_length)
|
104
|
+
sio = StringIO.new
|
105
|
+
doc.write(sio)
|
106
|
+
doc = HexaPDF::Document.new(io: sio)
|
107
|
+
assert_kind_of(Time, doc.trailer.info[:ModDate], "alg: #{algorithm} #{key_length} bits")
|
108
|
+
rescue HexaPDF::Error => e
|
109
|
+
flunk("Error using variation: #{algorithm} #{key_length} bits\n" << e.message)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
98
115
|
describe "prepare_encryption" do
|
99
116
|
it "returns the encryption dictionary wrapped with a custom class" do
|
100
117
|
dict = @handler.set_up_encryption
|
@@ -108,13 +125,15 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
108
125
|
|
109
126
|
it "sets the correct revision independent /P value" do
|
110
127
|
dict = @handler.set_up_encryption
|
111
|
-
assert_equal(@handler.class::Permissions::ALL | @handler.class::Permissions::RESERVED,
|
128
|
+
assert_equal(@handler.class::Permissions::ALL | @handler.class::Permissions::RESERVED - 2**32,
|
112
129
|
dict[:P])
|
113
130
|
dict = @handler.set_up_encryption(permissions: @handler.class::Permissions::COPY_CONTENT)
|
114
|
-
assert_equal(@handler.class::Permissions::COPY_CONTENT | @handler.class::Permissions::RESERVED,
|
131
|
+
assert_equal(@handler.class::Permissions::COPY_CONTENT | @handler.class::Permissions::RESERVED - 2**32,
|
115
132
|
dict[:P])
|
116
133
|
dict = @handler.set_up_encryption(permissions: [:modify_content, :modify_annotation])
|
117
|
-
assert_equal(@handler.class::Permissions::MODIFY_CONTENT |
|
134
|
+
assert_equal(@handler.class::Permissions::MODIFY_CONTENT | \
|
135
|
+
@handler.class::Permissions::MODIFY_ANNOTATION | \
|
136
|
+
@handler.class::Permissions::RESERVED - 2**32,
|
118
137
|
dict[:P])
|
119
138
|
end
|
120
139
|
|
@@ -150,7 +169,6 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
150
169
|
assert_equal({CFM: alg, Length: length, AuthEvent: :DocOpen}, d[:CF][:StdCF])
|
151
170
|
assert_equal(:StdCF, d[:StrF])
|
152
171
|
assert_equal(:StdCF, d[:StmF])
|
153
|
-
assert_equal(:StdCF, d[:EFF])
|
154
172
|
end
|
155
173
|
|
156
174
|
dict = @handler.set_up_encryption(key_length: 128, algorithm: :arc4, force_V4: true)
|
@@ -172,15 +190,18 @@ describe HexaPDF::Encryption::StandardSecurityHandler do
|
|
172
190
|
crypt_filter.call(dict, 6, :AESV3, 32)
|
173
191
|
end
|
174
192
|
|
175
|
-
it "uses the password keyword as fallback
|
193
|
+
it "uses the password keyword as fallback, the user password as owner password if the latter is not set" do
|
176
194
|
dict1 = @document.unwrap(@handler.set_up_encryption(password: 'user', owner_password: 'owner'))
|
177
195
|
dict2 = @document.unwrap(@handler.set_up_encryption(password: 'owner', user_password: 'user'))
|
178
196
|
dict3 = @document.unwrap(@handler.set_up_encryption(user_password: 'user', owner_password: 'owner'))
|
197
|
+
dict4 = @document.unwrap(@handler.set_up_encryption(user_password: 'test', owner_password: 'test'))
|
198
|
+
dict5 = @document.unwrap(@handler.set_up_encryption(user_password: 'test'))
|
179
199
|
|
180
200
|
assert_equal(dict1[:U], dict2[:U])
|
181
201
|
assert_equal(dict2[:U], dict3[:U])
|
182
202
|
assert_equal(dict1[:O], dict2[:O])
|
183
203
|
assert_equal(dict2[:O], dict3[:O])
|
204
|
+
assert_equal(dict4[:O], dict5[:O])
|
184
205
|
end
|
185
206
|
|
186
207
|
it "fails if the password contains invalid characters" do
|
@@ -8,7 +8,7 @@ describe HexaPDF::Font::TrueTypeWrapper do
|
|
8
8
|
before do
|
9
9
|
@doc = HexaPDF::Document.new
|
10
10
|
font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
|
11
|
-
@font = HexaPDF::Font::TrueType::Font.new(
|
11
|
+
@font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
|
12
12
|
@cmap = @font[:cmap].preferred_table
|
13
13
|
@font_wrapper = HexaPDF::Font::TrueTypeWrapper.new(@doc, @font)
|
14
14
|
end
|
@@ -39,12 +39,6 @@ describe HexaPDF::Font::TrueType::Table::Cmap do
|
|
39
39
|
assert_raises(HexaPDF::Error) { HexaPDF::Font::TrueType::Table::Cmap.new(@file, @entry) }
|
40
40
|
end
|
41
41
|
|
42
|
-
it "loads some default values if no entry is given" do
|
43
|
-
table = HexaPDF::Font::TrueType::Table::Cmap.new(@file)
|
44
|
-
assert_equal(0, table.version)
|
45
|
-
assert_equal([], table.tables)
|
46
|
-
end
|
47
|
-
|
48
42
|
it "loads data from subtables with identical offsets only once" do
|
49
43
|
table = HexaPDF::Font::TrueType::Table::Cmap.new(@file, @entry)
|
50
44
|
assert_same(table.tables[0].gid_map, table.tables[2].gid_map)
|
@@ -26,10 +26,5 @@ describe HexaPDF::Font::TrueType::Table::Directory do
|
|
26
26
|
assert_equal(28, entry.offset)
|
27
27
|
assert_equal(5, entry.length)
|
28
28
|
end
|
29
|
-
|
30
|
-
it "loads the default values if no entry is given" do
|
31
|
-
dir = HexaPDF::Font::TrueType::Table::Directory.new(@file)
|
32
|
-
assert_equal(0, dir.instance_eval { @tables }.length)
|
33
|
-
end
|
34
29
|
end
|
35
30
|
end
|
@@ -7,8 +7,11 @@ require 'hexapdf/font/true_type/table/glyf'
|
|
7
7
|
describe HexaPDF::Font::TrueType::Table::Glyf do
|
8
8
|
before do
|
9
9
|
@file = Object.new
|
10
|
-
loca =
|
11
|
-
loca.offsets
|
10
|
+
loca = Object.new
|
11
|
+
loca.define_singleton_method(:offsets) { @offsets ||= [] }
|
12
|
+
loca.define_singleton_method(:offset) {|i| @offsets[i]}
|
13
|
+
loca.define_singleton_method(:length) {|i| @offsets[i + 1] - @offsets[i]}
|
14
|
+
loca.offsets << 0 << 0
|
12
15
|
data = [1, -10, -20, 100, 150].pack('s>5')
|
13
16
|
loca.offsets << data.size
|
14
17
|
data << [-1, 10, 20, -100, -150].pack('s>5')
|
@@ -48,11 +51,5 @@ describe HexaPDF::Font::TrueType::Table::Glyf do
|
|
48
51
|
assert_equal(-150, glyph.y_max)
|
49
52
|
assert_equal([1, 2, 3, 4, 1], glyph.components)
|
50
53
|
end
|
51
|
-
|
52
|
-
it "loads some default values if no entry is given" do
|
53
|
-
table = HexaPDF::Font::TrueType::Table::Glyf.new(@file)
|
54
|
-
assert_equal({}, table.glyphs)
|
55
|
-
assert_nil(table[0])
|
56
|
-
end
|
57
54
|
end
|
58
55
|
end
|