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
@@ -33,22 +33,6 @@ describe HexaPDF::Font::TrueType::Table::Head do
33
33
  assert_equal(0, table.index_to_loc_format)
34
34
  end
35
35
 
36
- it "loads some default values if no entry is given" do
37
- table = HexaPDF::Font::TrueType::Table::Head.new(@file)
38
- assert_equal(1.0, table.version.to_f)
39
- assert_equal(1.0, table.font_revision.to_f)
40
- assert_equal(0, table.checksum_adjustment)
41
- assert_equal(0, table.flags)
42
- assert_equal(64, table.units_per_em)
43
- assert(Time.now - table.created < 2)
44
- assert(Time.now - table.created < 2)
45
- assert_equal([0, 0, 0, 0], table.bbox)
46
- assert_equal(0, table.mac_style)
47
- assert_equal(0, table.smallest_readable_size)
48
- assert_equal(0, table.font_direction_hint)
49
- assert_equal(0, table.index_to_loc_format)
50
- end
51
-
52
36
  it "raises an error if the magic number is false when reading from a file" do
53
37
  @file.io.string[12, 1] = '\x5e'
54
38
  assert_raises(HexaPDF::Error) { HexaPDF::Font::TrueType::Table::Head.new(@file, @entry) }
@@ -68,9 +52,5 @@ describe HexaPDF::Font::TrueType::Table::Head do
68
52
  table = HexaPDF::Font::TrueType::Table::Head.new(@file, @entry)
69
53
  assert(table.checksum_valid?)
70
54
  end
71
-
72
- it "raises an error if the checksum can't be verified because none is available" do
73
- assert_raises(HexaPDF::Error) { HexaPDF::Font::TrueType::Table::Head.new(@file).checksum_valid? }
74
- end
75
55
  end
76
56
  end
@@ -29,12 +29,5 @@ describe HexaPDF::Font::TrueType::Table::Hhea do
29
29
  assert_equal(0, table.caret_offset)
30
30
  assert_equal(10, table.num_of_long_hor_metrics)
31
31
  end
32
-
33
- it "loads some default values if no entry is given" do
34
- table = HexaPDF::Font::TrueType::Table::Hhea.new(@file)
35
- assert_equal(1, table.version)
36
- assert_equal(0, table.ascent)
37
- assert_equal(0, table.descent)
38
- end
39
32
  end
40
33
  end
@@ -11,8 +11,8 @@ describe HexaPDF::Font::TrueType::Table::Hhea do
11
11
  io = StringIO.new(data)
12
12
  @file = Object.new
13
13
  @file.define_singleton_method(:io) { io }
14
- hhea = HexaPDF::Font::TrueType::Table::Hhea.new(@file)
15
- hhea.num_of_long_hor_metrics = 2
14
+ hhea = Object.new
15
+ hhea.define_singleton_method(:num_of_long_hor_metrics) { 2 }
16
16
  @file.define_singleton_method(:[]) {|_arg| hhea }
17
17
  @entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('hmtx', 0, 0, io.length)
18
18
  end
@@ -29,10 +29,5 @@ describe HexaPDF::Font::TrueType::Table::Hhea do
29
29
  assert_equal(3, table[3].advance_width)
30
30
  assert_equal(-6, table[3].left_side_bearing)
31
31
  end
32
-
33
- it "loads some default values if no entry is given" do
34
- table = HexaPDF::Font::TrueType::Table::Hmtx.new(@file)
35
- assert_equal([], table.horizontal_metrics)
36
- end
37
32
  end
38
33
  end
@@ -9,8 +9,8 @@ describe HexaPDF::Font::TrueType::Table::Loca do
9
9
  before do
10
10
  @file = Object.new
11
11
  @file.define_singleton_method(:io) { @io ||= StringIO.new('') }
12
- head = HexaPDF::Font::TrueType::Table::Head.new(@file)
13
- head.index_to_loc_format = 0
12
+ head = Object.new
13
+ head.define_singleton_method(:index_to_loc_format) { 0 }
14
14
  @file.define_singleton_method(:[]) {|_arg| head }
15
15
  @entry = HexaPDF::Font::TrueType::Table::Directory::Entry.new('loca', 0, 0, @file.io.length)
16
16
  end
@@ -29,15 +29,11 @@ describe HexaPDF::Font::TrueType::Table::Loca do
29
29
 
30
30
  it "reads the data in long format from the associated file" do
31
31
  @file.io.string = [0, 10, 30, 50, 90].pack('N*')
32
- @file[:head].index_to_loc_format = 1
32
+ @file[:head].singleton_class.send(:remove_method, :index_to_loc_format)
33
+ @file[:head].define_singleton_method(:index_to_loc_format) { 1 }
33
34
  @entry.length = @file.io.length
34
35
  table = HexaPDF::Font::TrueType::Table::Loca.new(@file, @entry)
35
36
  assert_equal([0, 10, 30, 50, 90], table.offsets)
36
37
  end
37
-
38
- it "loads some default values if no entry is given" do
39
- table = HexaPDF::Font::TrueType::Table::Loca.new(@file)
40
- assert_equal([], table.offsets)
41
- end
42
38
  end
43
39
  end
@@ -51,12 +51,5 @@ describe HexaPDF::Font::TrueType::Table::Maxp do
51
51
  assert_nil(table.max_component_elements)
52
52
  assert_nil(table.max_component_depth)
53
53
  end
54
-
55
- it "loads some default values if no entry is given" do
56
- table = HexaPDF::Font::TrueType::Table::Maxp.new(@file)
57
- assert_equal(1, table.version)
58
- assert_equal(0, table.num_glyphs)
59
- assert_equal(0, table.max_points)
60
- end
61
54
  end
62
55
  end
@@ -47,25 +47,6 @@ describe HexaPDF::Font::TrueType::Table::Name do
47
47
  assert_equal(1, table.format)
48
48
  assert_equal({0x8000 => 'en', 0x8001 => 'de'}, table.language_tags)
49
49
  end
50
-
51
- it "loads some default values if no entry is given" do
52
- table = HexaPDF::Font::TrueType::Table::Name.new(@file)
53
- assert_equal(0, table.format)
54
- assert_equal({}, table.records)
55
- assert_equal({}, table.language_tags)
56
- end
57
- end
58
-
59
- describe "add" do
60
- it "adds a new record for a name" do
61
- table = HexaPDF::Font::TrueType::Table::Name.new(@file)
62
- table.add(:postscript_name, "test")
63
- record = table[:postscript_name][0]
64
- assert_equal("test", record)
65
- assert_equal(HexaPDF::Font::TrueType::Table::Name::Record::PLATFORM_MACINTOSH, record.platform_id)
66
- assert_equal(0, record.encoding_id)
67
- assert_equal(0, record.language_id)
68
- end
69
50
  end
70
51
 
71
52
  describe "NameRecord" do
@@ -53,13 +53,5 @@ describe HexaPDF::Font::TrueType::Table::OS2 do
53
53
  assert_equal(30, table.lower_point_size)
54
54
  assert_equal(31, table.upper_point_size)
55
55
  end
56
-
57
- it "loads some default values if no entry is given" do
58
- table = HexaPDF::Font::TrueType::Table::OS2.new(@file)
59
- assert_equal(5, table.version)
60
- assert_equal(''.b, table.panose)
61
- assert_equal(' '.b, table.vendor_id)
62
- assert_equal(0, table.default_char)
63
- end
64
56
  end
65
57
  end
@@ -68,19 +68,6 @@ describe HexaPDF::Font::TrueType::Table::Post do
68
68
  assert_equal(0xFFFF, table[1_000_000])
69
69
  end
70
70
 
71
- it "loads some default values if no entry is given" do
72
- table = HexaPDF::Font::TrueType::Table::Post.new(@file)
73
- assert_equal(1, table.format)
74
- assert_equal(0, table.italic_angle)
75
- assert_equal(0, table.underline_position)
76
- assert_equal(0, table.underline_thickness)
77
- assert_equal(0, table.is_fixed_pitch)
78
- assert_equal(0, table.min_mem_type42)
79
- assert_equal(0, table.max_mem_type42)
80
- assert_equal(0, table.min_mem_type1)
81
- assert_equal(0, table.max_mem_type1)
82
- end
83
-
84
71
  it "raises an error if an unsupported format is given" do
85
72
  @file.io.string[0, 2] = [5].pack('n')
86
73
  assert_raises(HexaPDF::Error) { HexaPDF::Font::TrueType::Table::Post.new(@file, @entry) }
@@ -9,7 +9,7 @@ describe HexaPDF::Font::TrueType::Font do
9
9
  before do
10
10
  @io = StringIO.new("TEST\x00\x01\x00\x00\x00\x00\x00\x00" \
11
11
  "TEST----\x00\x00\x00\x1C\x00\x00\x00\x05ENTRY".b)
12
- @font = HexaPDF::Font::TrueType::Font.new(io: @io)
12
+ @font = HexaPDF::Font::TrueType::Font.new(@io)
13
13
  @font.config['font.true_type.table_mapping'][:TEST] = TestHelper::TrueTypeTestTable.name
14
14
  end
15
15
 
@@ -33,83 +33,59 @@ describe HexaPDF::Font::TrueType::Font do
33
33
  end
34
34
  end
35
35
 
36
- describe "add_table" do
37
- it "returns the existing table if one exists" do
38
- assert_same(@font[:TEST], @font.add_table(:TEST))
39
- end
40
-
41
- it "creates a new table instance if needed" do
42
- assert_kind_of(HexaPDF::Font::TrueType::Table::Head, @font.add_table(:head))
43
- end
44
- end
45
-
46
36
  describe "getter methods" do
47
37
  before do
48
- @font.add_table(:name)
49
- @font.add_table(:post)
50
- @font.add_table(:head)
51
- @font.add_table(:hhea)
52
- @font.add_table(:"OS/2")
38
+ font_file = File.join(TEST_DATA_DIR, "fonts", "Ubuntu-Title.ttf")
39
+ @font = HexaPDF::Font::TrueType::Font.new(File.open(font_file))
53
40
  end
54
41
 
55
42
  it "returns the postscript name" do
56
- @font[:name].add(:postscript_name, "name")
57
- assert_equal("name", @font.font_name)
43
+ assert_equal("Ubuntu-Title", @font.font_name)
58
44
  end
59
45
 
60
46
  it "returns the full name" do
61
- @font[:name].add(:font_name, "name")
62
- assert_equal("name", @font.full_name)
47
+ assert_equal("Ubuntu-Title", @font.full_name)
63
48
  end
64
49
 
65
50
  it "returns the family name" do
66
- @font[:name].add(:font_family, "name")
67
- assert_equal("name", @font.family_name)
51
+ assert_equal("Ubuntu-Title", @font.family_name)
68
52
  end
69
53
 
70
54
  it "returns the font's weight" do
71
- @font[:"OS/2"].weight_class = 400
72
55
  assert_equal(400, @font.weight)
73
56
  end
74
57
 
75
58
  it "returns the font's bounding box" do
76
- @font[:head].bbox = [0, 1, 2, 3]
77
- assert_equal([0, 1, 2, 3], @font.bounding_box)
59
+ assert_equal([-35, -187, 876, 801], @font.bounding_box)
78
60
  end
79
61
 
80
62
  it "returns the font's cap height" do
81
- @font[:"OS/2"].cap_height = 832
63
+ @font[:'OS/2'].cap_height = 832
82
64
  assert_equal(832, @font.cap_height)
83
65
  end
84
66
 
85
67
  it "returns the font's x height" do
86
- @font[:"OS/2"].x_height = 642
68
+ @font[:'OS/2'].x_height = 642
87
69
  assert_equal(642, @font.x_height)
88
70
  end
89
71
 
90
72
  it "returns the font's ascender" do
91
- @font[:"OS/2"].typo_ascender = 800
92
- @font[:hhea].ascent = 790
93
73
  assert_equal(800, @font.ascender)
94
- @font.instance_eval { @tables.delete(:"OS/2") }
95
- assert_equal(790, @font.ascender)
74
+ @font[:'OS/2'].typo_ascender = nil
75
+ assert_equal(801, @font.ascender)
96
76
  end
97
77
 
98
78
  it "returns the font's descender" do
99
- @font[:"OS/2"].typo_descender = -200
100
- @font[:hhea].descent = -180
101
79
  assert_equal(-200, @font.descender)
102
- @font.instance_eval { @tables.delete(:"OS/2") }
103
- assert_equal(-180, @font.descender)
80
+ @font[:'OS/2'].typo_descender = nil
81
+ assert_equal(-187, @font.descender)
104
82
  end
105
83
 
106
84
  it "returns the font's italic angle" do
107
- @font[:post].italic_angle = Rational(325, 10)
108
- assert_equal(32.5, @font.italic_angle)
85
+ assert_equal(0.0, @font.italic_angle)
109
86
  end
110
87
 
111
88
  it "returns the font's dominant vertical stem width" do
112
- @font[:"OS/2"].weight_class = 400
113
89
  assert_equal(80, @font.dominant_vertical_stem_width)
114
90
  end
115
91
  end
@@ -18,11 +18,6 @@ describe HexaPDF::Font::TrueType::Table do
18
18
  table = TestHelper::TrueTypeTestTable.new(@file, @entry)
19
19
  assert_equal(@file.io.string, table.data)
20
20
  end
21
-
22
- it "loads some default values if no entry is given" do
23
- table = TestHelper::TrueTypeTestTable.new(@file)
24
- assert_equal('default', table.data)
25
- end
26
21
  end
27
22
 
28
23
  describe "checksum_valid?" do
@@ -33,9 +28,5 @@ describe HexaPDF::Font::TrueType::Table do
33
28
  table = TestHelper::TrueTypeTestTable.new(@file, @entry)
34
29
  assert(table.checksum_valid?)
35
30
  end
36
-
37
- it "raises an error if the checksum can't be verified because none is available" do
38
- assert_raises(HexaPDF::Error) { TestHelper::TrueTypeTestTable.new(@file).checksum_valid? }
39
- end
40
31
  end
41
32
  end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/font/type1'
5
+
6
+ describe HexaPDF::Font::Type1::FontMetrics do
7
+ before do
8
+ @metrics = HexaPDF::Font::Type1::FontMetrics.new
9
+ end
10
+
11
+ describe "weight_class" do
12
+ it "converts known weight names" do
13
+ @metrics.weight = 'Bold'
14
+ assert_equal(700, @metrics.weight_class)
15
+ end
16
+
17
+ it "returns 0 for unknown weight names" do
18
+ @metrics.weight = 'Unknown'
19
+ assert_equal(0, @metrics.weight_class)
20
+ end
21
+ end
22
+ end
@@ -14,6 +14,10 @@ describe HexaPDF::Task::Dereference do
14
14
  len = @doc.add(5)
15
15
  str = @doc.add(@doc.wrap({Length: len}, stream: ''))
16
16
  @doc.trailer[:Test] = str
17
+ pages = @doc.wrap(Type: :Pages)
18
+ pages.add_page(@doc.wrap(Type: :Page))
19
+ @doc.trailer[:Test2] = pages
20
+
17
21
  checker = lambda do |val, done = {}|
18
22
  case val
19
23
  when Array then val.all? {|v| checker.call(v, done)}
@@ -24,7 +28,7 @@ describe HexaPDF::Task::Dereference do
24
28
  if done.key?(val)
25
29
  true
26
30
  else
27
- done[val] = true if val.oid != 0
31
+ done[val] = true
28
32
  checker.call(val.value, done)
29
33
  end
30
34
  else
@@ -128,7 +128,7 @@ describe HexaPDF::Task::Optimize do
128
128
 
129
129
  describe "compress_pages" do
130
130
  it "compresses pages streams" do
131
- page = @doc.pages.add_page
131
+ page = @doc.pages.add
132
132
  page.contents = " 10 10 m q Q BI /Name 5 ID dataEI "
133
133
  @doc.task(:optimize, compress_pages: true)
134
134
  assert_equal("10 10 m\nq\nQ\nBI\n/Name 5 ID\ndataEI\n", page.contents)
@@ -123,6 +123,10 @@ describe HexaPDF::Dictionary do
123
123
  assert_equal(Encoding::BINARY, result.encoding)
124
124
  assert_kind_of(HexaPDF::Object, @dict.value[:Binary])
125
125
  assert_same(result, @dict.value[:Binary].value)
126
+
127
+ @dict[:Test] = HexaPDF::Dictionary.new({})
128
+ @dict[:Test].data.value = nil
129
+ assert_nil(@dict[:Test])
126
130
  end
127
131
  end
128
132
 
@@ -554,13 +554,6 @@ EOF
554
554
  end
555
555
  end
556
556
 
557
- describe "pages" do
558
- it "returns the root node of the page tree" do
559
- pages = @doc.pages
560
- assert_equal(:Pages, pages.type)
561
- end
562
- end
563
-
564
557
  describe "listener interface" do
565
558
  it "allows registering and dispatching messages" do
566
559
  args = []
@@ -11,8 +11,8 @@ describe HexaPDF::Importer do
11
11
  @obj = @source.add(hash: {key: "value"}, array: ["one", "two"],
12
12
  ref: HexaPDF::Reference.new(obj.oid, obj.gen),
13
13
  others: [:symbol, 5, 5.5, nil, true, false])
14
- @source.pages.add_page
15
- @source.pages[:Rotate] = 90
14
+ @source.pages.add
15
+ @source.pages.root[:Rotate] = 90
16
16
  @dest = HexaPDF::Document.new
17
17
  @importer = HexaPDF::Importer.for(source: @source, destination: @dest)
18
18
  end
@@ -57,7 +57,7 @@ describe HexaPDF::Importer do
57
57
 
58
58
  it "does not import objects of type Catalog or Pages" do
59
59
  @obj[:catalog] = @source.catalog
60
- @obj[:pages] = @source.pages
60
+ @obj[:pages] = @source.catalog.pages
61
61
  obj = @importer.import(@obj)
62
62
 
63
63
  assert_nil(obj[:catalog])
@@ -65,7 +65,7 @@ describe HexaPDF::Importer do
65
65
  end
66
66
 
67
67
  it "imports Page objects correctly by copying the inherited values" do
68
- page = @importer.import(@source.pages.page(0))
68
+ page = @importer.import(@source.pages[0])
69
69
  assert_equal(90, page[:Rotate])
70
70
  end
71
71
 
@@ -43,6 +43,11 @@ describe HexaPDF::Object do
43
43
  it "handles PDF objects" do
44
44
  x = HexaPDF::Object.new("test")
45
45
  assert_equal("test", HexaPDF::Object.deep_copy(x))
46
+
47
+ x.must_be_indirect = true
48
+ assert_same(x, HexaPDF::Object.deep_copy(x))
49
+
50
+ x.must_be_indirect = false
46
51
  x.oid = 1
47
52
  assert_same(x, HexaPDF::Object.deep_copy(x))
48
53
  end
@@ -162,16 +167,33 @@ describe HexaPDF::Object do
162
167
  end
163
168
  end
164
169
 
165
- it "validates that the object is indirect if it must be indirect" do
166
- doc = Object.new
167
- def doc.add(obj) obj.oid = 1 end
168
- obj = HexaPDF::Object.new(6, document: doc)
170
+ describe "validation" do
171
+ before do
172
+ @doc = Object.new
173
+ @doc.define_singleton_method(:add) {|obj| obj.oid = 1}
174
+ end
175
+
176
+ it "validates that the object is indirect if it must be indirect" do
177
+ obj = HexaPDF::Object.new(6, document: @doc)
178
+
179
+ obj.validate
180
+ assert_equal(0, obj.oid)
169
181
 
170
- obj.validate
171
- assert_equal(0, obj.oid)
182
+ obj.must_be_indirect = true
183
+ obj.validate
184
+ assert_equal(1, obj.oid)
185
+ end
172
186
 
173
- obj.must_be_indirect = true
174
- obj.validate
175
- assert_equal(1, obj.oid)
187
+ it "validates collection values" do
188
+ x = HexaPDF::Object.new(:x, document: @doc)
189
+ x.must_be_indirect = true
190
+ y = HexaPDF::Object.new(:y, document: @doc)
191
+ y.must_be_indirect = true
192
+
193
+ obj = HexaPDF::Object.new([1, 2, 3, [4, x], {X: [y, 5]}])
194
+ obj.validate
195
+ assert_equal(1, x.oid)
196
+ assert_equal(1, y.oid)
197
+ end
176
198
  end
177
199
  end