hexapdf 0.1.0 → 0.2.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 +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
|