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.
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