hexapdf 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +56 -0
  3. data/CONTRIBUTERS +1 -1
  4. data/Rakefile +3 -3
  5. data/VERSION +1 -1
  6. data/examples/arc.rb +1 -1
  7. data/examples/graphics.rb +1 -1
  8. data/examples/hello_world.rb +1 -1
  9. data/examples/merging.rb +1 -1
  10. data/examples/show_char_bboxes.rb +1 -1
  11. data/examples/standard_pdf_fonts.rb +1 -1
  12. data/examples/truetype.rb +1 -1
  13. data/lib/hexapdf/cli.rb +14 -7
  14. data/lib/hexapdf/cli/extract.rb +1 -1
  15. data/lib/hexapdf/cli/info.rb +2 -2
  16. data/lib/hexapdf/cli/inspect.rb +4 -4
  17. data/lib/hexapdf/cli/modify.rb +151 -51
  18. data/lib/hexapdf/configuration.rb +1 -1
  19. data/lib/hexapdf/content/canvas.rb +1 -1
  20. data/lib/hexapdf/content/processor.rb +1 -1
  21. data/lib/hexapdf/dictionary.rb +6 -19
  22. data/lib/hexapdf/dictionary_fields.rb +1 -1
  23. data/lib/hexapdf/document.rb +23 -16
  24. data/lib/hexapdf/document/files.rb +130 -0
  25. data/lib/hexapdf/{font_utils.rb → document/fonts.rb} +40 -38
  26. data/lib/hexapdf/document/images.rb +117 -0
  27. data/lib/hexapdf/document/pages.rb +125 -0
  28. data/lib/hexapdf/encryption/aes.rb +1 -1
  29. data/lib/hexapdf/encryption/ruby_aes.rb +10 -10
  30. data/lib/hexapdf/encryption/standard_security_handler.rb +11 -8
  31. data/lib/hexapdf/filter/ascii85_decode.rb +1 -1
  32. data/lib/hexapdf/filter/ascii_hex_decode.rb +1 -6
  33. data/lib/hexapdf/font/cmap/writer.rb +5 -7
  34. data/lib/hexapdf/font/true_type.rb +4 -1
  35. data/lib/hexapdf/font/true_type/font.rb +8 -16
  36. data/lib/hexapdf/font/true_type/table.rb +5 -16
  37. data/lib/hexapdf/font/true_type/table/cmap.rb +2 -7
  38. data/lib/hexapdf/font/true_type/table/cmap_subtable.rb +2 -6
  39. data/lib/hexapdf/font/true_type/table/directory.rb +0 -5
  40. data/lib/hexapdf/font/true_type/table/glyf.rb +3 -11
  41. data/lib/hexapdf/font/true_type/table/head.rb +0 -12
  42. data/lib/hexapdf/font/true_type/table/hhea.rb +0 -7
  43. data/lib/hexapdf/font/true_type/table/hmtx.rb +1 -5
  44. data/lib/hexapdf/font/true_type/table/loca.rb +0 -4
  45. data/lib/hexapdf/font/true_type/table/maxp.rb +0 -8
  46. data/lib/hexapdf/font/true_type/table/name.rb +3 -17
  47. data/lib/hexapdf/font/true_type/table/os2.rb +0 -14
  48. data/lib/hexapdf/font/true_type/table/post.rb +0 -8
  49. data/lib/hexapdf/font/true_type_wrapper.rb +1 -1
  50. data/lib/hexapdf/font/type1.rb +2 -2
  51. data/lib/hexapdf/font/type1/font.rb +2 -1
  52. data/lib/hexapdf/font/type1/font_metrics.rb +10 -1
  53. data/lib/hexapdf/font/type1_wrapper.rb +2 -1
  54. data/lib/hexapdf/font_loader/from_configuration.rb +1 -1
  55. data/lib/hexapdf/font_loader/standard14.rb +1 -1
  56. data/lib/hexapdf/image_loader/jpeg.rb +1 -1
  57. data/lib/hexapdf/image_loader/pdf.rb +1 -1
  58. data/lib/hexapdf/image_loader/png.rb +2 -2
  59. data/lib/hexapdf/object.rb +18 -5
  60. data/lib/hexapdf/rectangle.rb +8 -1
  61. data/lib/hexapdf/revisions.rb +4 -2
  62. data/lib/hexapdf/serializer.rb +3 -3
  63. data/lib/hexapdf/stream.rb +3 -2
  64. data/lib/hexapdf/task/dereference.rb +4 -5
  65. data/lib/hexapdf/task/optimize.rb +6 -3
  66. data/lib/hexapdf/tokenizer.rb +3 -3
  67. data/lib/hexapdf/type/file_specification.rb +2 -2
  68. data/lib/hexapdf/type/form.rb +19 -0
  69. data/lib/hexapdf/type/page.rb +21 -6
  70. data/lib/hexapdf/type/page_tree_node.rb +27 -34
  71. data/lib/hexapdf/utils/bit_stream.rb +1 -1
  72. data/lib/hexapdf/utils/pdf_doc_encoding.rb +1 -1
  73. data/lib/hexapdf/version.rb +1 -1
  74. data/man/man1/hexapdf.1 +259 -187
  75. data/test/hexapdf/content/graphic_object/test_arc.rb +1 -1
  76. data/test/hexapdf/content/graphic_object/test_endpoint_arc.rb +1 -1
  77. data/test/hexapdf/content/graphic_object/test_solid_arc.rb +1 -1
  78. data/test/hexapdf/content/test_canvas.rb +1 -1
  79. data/test/hexapdf/document/test_files.rb +71 -0
  80. data/test/hexapdf/{test_font_utils.rb → document/test_fonts.rb} +1 -2
  81. data/test/hexapdf/document/test_images.rb +78 -0
  82. data/test/hexapdf/document/test_pages.rb +114 -0
  83. data/test/hexapdf/encryption/test_standard_security_handler.rb +26 -5
  84. data/test/hexapdf/font/test_true_type_wrapper.rb +1 -1
  85. data/test/hexapdf/font/true_type/common.rb +0 -4
  86. data/test/hexapdf/font/true_type/table/test_cmap.rb +0 -6
  87. data/test/hexapdf/font/true_type/table/test_directory.rb +0 -5
  88. data/test/hexapdf/font/true_type/table/test_glyf.rb +5 -8
  89. data/test/hexapdf/font/true_type/table/test_head.rb +0 -20
  90. data/test/hexapdf/font/true_type/table/test_hhea.rb +0 -7
  91. data/test/hexapdf/font/true_type/table/test_hmtx.rb +2 -7
  92. data/test/hexapdf/font/true_type/table/test_loca.rb +4 -8
  93. data/test/hexapdf/font/true_type/table/test_maxp.rb +0 -7
  94. data/test/hexapdf/font/true_type/table/test_name.rb +0 -19
  95. data/test/hexapdf/font/true_type/table/test_os2.rb +0 -8
  96. data/test/hexapdf/font/true_type/table/test_post.rb +0 -13
  97. data/test/hexapdf/font/true_type/test_font.rb +14 -38
  98. data/test/hexapdf/font/true_type/test_table.rb +0 -9
  99. data/test/hexapdf/font/type1/test_font_metrics.rb +22 -0
  100. data/test/hexapdf/task/test_dereference.rb +5 -1
  101. data/test/hexapdf/task/test_optimize.rb +1 -1
  102. data/test/hexapdf/test_dictionary.rb +4 -0
  103. data/test/hexapdf/test_document.rb +0 -7
  104. data/test/hexapdf/test_importer.rb +4 -4
  105. data/test/hexapdf/test_object.rb +31 -9
  106. data/test/hexapdf/test_rectangle.rb +18 -0
  107. data/test/hexapdf/test_revisions.rb +7 -0
  108. data/test/hexapdf/test_serializer.rb +6 -0
  109. data/test/hexapdf/test_writer.rb +2 -2
  110. data/test/hexapdf/type/test_form.rb +12 -0
  111. data/test/hexapdf/type/test_page.rb +39 -20
  112. data/test/hexapdf/type/test_page_tree_node.rb +28 -21
  113. metadata +21 -9
  114. data/lib/hexapdf/document_utils.rb +0 -209
  115. 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.add_page
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.add_page
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
@@ -50,7 +50,7 @@ describe HexaPDF::Content::GraphicObject::SolidArc do
50
50
  before do
51
51
  @doc = HexaPDF::Document.new
52
52
  @doc.config['graphic_object.arc.max_curves'] = 4
53
- @page = @doc.pages.add_page
53
+ @page = @doc.pages.add
54
54
  @canvas = @page.canvas
55
55
  end
56
56
 
@@ -14,7 +14,7 @@ describe HexaPDF::Content::Canvas do
14
14
 
15
15
  @doc = HexaPDF::Document.new
16
16
  @doc.config['graphic_object.arc.max_curves'] = 4
17
- @page = @doc.pages.add_page
17
+ @page = @doc.pages.add
18
18
  @canvas = @page.canvas
19
19
  end
20
20
 
@@ -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::FontUtils do
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 | @handler.class::Permissions::MODIFY_ANNOTATION | @handler.class::Permissions::RESERVED,
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 for the user and owner passwords" do
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(io: File.open(font_file))
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
@@ -10,10 +10,6 @@ module TestHelper
10
10
  def parse_table
11
11
  @data = io.read(directory_entry.length)
12
12
  end
13
-
14
- def load_default
15
- @data = 'default'
16
- end
17
13
  end
18
14
 
19
15
  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 = HexaPDF::Font::TrueType::Table::Loca.new(@file)
11
- loca.offsets = [0, 0]
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