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