hexapdf 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +33 -0
  3. data/CONTRIBUTERS +1 -1
  4. data/Rakefile +35 -50
  5. data/VERSION +1 -1
  6. data/lib/hexapdf/cli.rb +4 -0
  7. data/lib/hexapdf/cli/command.rb +6 -2
  8. data/lib/hexapdf/cli/image2pdf.rb +141 -0
  9. data/lib/hexapdf/cli/info.rb +1 -1
  10. data/lib/hexapdf/cli/inspect.rb +32 -2
  11. data/lib/hexapdf/cli/modify.rb +1 -1
  12. data/lib/hexapdf/cli/optimize.rb +1 -1
  13. data/lib/hexapdf/cli/watermark.rb +130 -0
  14. data/lib/hexapdf/composer.rb +2 -2
  15. data/lib/hexapdf/configuration.rb +7 -1
  16. data/lib/hexapdf/content/canvas.rb +2 -2
  17. data/lib/hexapdf/content/graphic_object/arc.rb +2 -2
  18. data/lib/hexapdf/content/graphic_object/endpoint_arc.rb +2 -2
  19. data/lib/hexapdf/content/graphic_object/geom2d.rb +1 -1
  20. data/lib/hexapdf/content/graphic_object/solid_arc.rb +1 -1
  21. data/lib/hexapdf/dictionary.rb +11 -3
  22. data/lib/hexapdf/dictionary_fields.rb +32 -3
  23. data/lib/hexapdf/document.rb +7 -3
  24. data/lib/hexapdf/document/files.rb +1 -1
  25. data/lib/hexapdf/document/fonts.rb +21 -1
  26. data/lib/hexapdf/document/pages.rb +2 -2
  27. data/lib/hexapdf/encryption/standard_security_handler.rb +2 -2
  28. data/lib/hexapdf/font/cmap/parser.rb +1 -1
  29. data/lib/hexapdf/font/true_type/table/head.rb +2 -2
  30. data/lib/hexapdf/font/true_type/table/os2.rb +4 -4
  31. data/lib/hexapdf/font/true_type_wrapper.rb +16 -16
  32. data/lib/hexapdf/font/type1_wrapper.rb +16 -16
  33. data/lib/hexapdf/font_loader.rb +2 -0
  34. data/lib/hexapdf/font_loader/from_configuration.rb +5 -0
  35. data/lib/hexapdf/font_loader/standard14.rb +5 -0
  36. data/lib/hexapdf/image_loader/png.rb +1 -1
  37. data/lib/hexapdf/layout/box.rb +2 -2
  38. data/lib/hexapdf/layout/image_box.rb +1 -1
  39. data/lib/hexapdf/layout/style.rb +50 -24
  40. data/lib/hexapdf/layout/text_box.rb +1 -1
  41. data/lib/hexapdf/layout/text_fragment.rb +2 -2
  42. data/lib/hexapdf/layout/text_layouter.rb +14 -10
  43. data/lib/hexapdf/name_tree_node.rb +3 -3
  44. data/lib/hexapdf/number_tree_node.rb +3 -3
  45. data/lib/hexapdf/pdf_array.rb +207 -0
  46. data/lib/hexapdf/rectangle.rb +12 -12
  47. data/lib/hexapdf/serializer.rb +1 -1
  48. data/lib/hexapdf/stream.rb +6 -4
  49. data/lib/hexapdf/task/optimize.rb +3 -3
  50. data/lib/hexapdf/type.rb +2 -0
  51. data/lib/hexapdf/type/acro_form.rb +51 -0
  52. data/lib/hexapdf/type/acro_form/field.rb +129 -0
  53. data/lib/hexapdf/type/acro_form/form.rb +124 -0
  54. data/lib/hexapdf/type/action.rb +1 -1
  55. data/lib/hexapdf/type/actions/go_to.rb +1 -1
  56. data/lib/hexapdf/type/actions/go_to_r.rb +1 -1
  57. data/lib/hexapdf/type/actions/launch.rb +1 -1
  58. data/lib/hexapdf/type/annotation.rb +2 -2
  59. data/lib/hexapdf/type/annotations.rb +1 -0
  60. data/lib/hexapdf/type/annotations/link.rb +4 -15
  61. data/lib/hexapdf/type/annotations/markup_annotation.rb +2 -1
  62. data/lib/hexapdf/type/annotations/text.rb +3 -6
  63. data/lib/hexapdf/type/annotations/widget.rb +90 -0
  64. data/lib/hexapdf/type/catalog.rb +12 -9
  65. data/lib/hexapdf/type/cid_font.rb +3 -3
  66. data/lib/hexapdf/type/file_specification.rb +2 -2
  67. data/lib/hexapdf/type/font_descriptor.rb +5 -2
  68. data/lib/hexapdf/type/font_simple.rb +1 -1
  69. data/lib/hexapdf/type/font_type0.rb +1 -1
  70. data/lib/hexapdf/type/font_type3.rb +1 -1
  71. data/lib/hexapdf/type/form.rb +2 -2
  72. data/lib/hexapdf/type/graphics_state_parameter.rb +11 -6
  73. data/lib/hexapdf/type/icon_fit.rb +58 -0
  74. data/lib/hexapdf/type/image.rb +14 -8
  75. data/lib/hexapdf/type/info.rb +2 -1
  76. data/lib/hexapdf/type/page.rb +4 -4
  77. data/lib/hexapdf/type/page_tree_node.rb +3 -7
  78. data/lib/hexapdf/type/resources.rb +1 -1
  79. data/lib/hexapdf/type/trailer.rb +4 -4
  80. data/lib/hexapdf/type/viewer_preferences.rb +7 -4
  81. data/lib/hexapdf/type/xref_stream.rb +2 -2
  82. data/lib/hexapdf/utils/sorted_tree_node.rb +1 -1
  83. data/lib/hexapdf/version.rb +1 -1
  84. data/man/man1/hexapdf.1 +77 -8
  85. data/test/hexapdf/content/test_canvas.rb +2 -2
  86. data/test/hexapdf/content/test_processor.rb +3 -3
  87. data/test/hexapdf/document/test_files.rb +4 -4
  88. data/test/hexapdf/document/test_fonts.rb +13 -1
  89. data/test/hexapdf/document/test_images.rb +6 -6
  90. data/test/hexapdf/document/test_pages.rb +8 -8
  91. data/test/hexapdf/encryption/test_security_handler.rb +7 -7
  92. data/test/hexapdf/encryption/test_standard_security_handler.rb +5 -5
  93. data/test/hexapdf/font/test_true_type_wrapper.rb +2 -2
  94. data/test/hexapdf/font_loader/test_from_configuration.rb +4 -0
  95. data/test/hexapdf/font_loader/test_standard14.rb +10 -0
  96. data/test/hexapdf/image_loader/test_jpeg.rb +1 -1
  97. data/test/hexapdf/image_loader/test_png.rb +3 -3
  98. data/test/hexapdf/layout/test_box.rb +2 -2
  99. data/test/hexapdf/layout/test_frame.rb +1 -1
  100. data/test/hexapdf/layout/test_image_box.rb +1 -1
  101. data/test/hexapdf/layout/test_style.rb +18 -13
  102. data/test/hexapdf/layout/test_text_box.rb +1 -1
  103. data/test/hexapdf/layout/test_text_layouter.rb +11 -6
  104. data/test/hexapdf/task/test_dereference.rb +2 -2
  105. data/test/hexapdf/task/test_optimize.rb +11 -11
  106. data/test/hexapdf/test_composer.rb +1 -1
  107. data/test/hexapdf/test_dictionary.rb +10 -2
  108. data/test/hexapdf/test_dictionary_fields.rb +27 -3
  109. data/test/hexapdf/test_document.rb +16 -15
  110. data/test/hexapdf/test_importer.rb +4 -4
  111. data/test/hexapdf/test_object.rb +1 -1
  112. data/test/hexapdf/test_pdf_array.rb +162 -0
  113. data/test/hexapdf/test_rectangle.rb +3 -5
  114. data/test/hexapdf/test_serializer.rb +1 -1
  115. data/test/hexapdf/test_stream.rb +1 -0
  116. data/test/hexapdf/test_writer.rb +3 -3
  117. data/test/hexapdf/type/acro_form/test_field.rb +85 -0
  118. data/test/hexapdf/type/acro_form/test_form.rb +69 -0
  119. data/test/hexapdf/type/annotations/test_text.rb +2 -6
  120. data/test/hexapdf/type/annotations/test_widget.rb +24 -0
  121. data/test/hexapdf/type/test_annotation.rb +1 -1
  122. data/test/hexapdf/type/test_catalog.rb +1 -1
  123. data/test/hexapdf/type/test_cid_font.rb +3 -3
  124. data/test/hexapdf/type/test_font.rb +2 -2
  125. data/test/hexapdf/type/test_font_descriptor.rb +2 -1
  126. data/test/hexapdf/type/test_font_simple.rb +3 -3
  127. data/test/hexapdf/type/test_font_true_type.rb +6 -6
  128. data/test/hexapdf/type/test_font_type0.rb +5 -5
  129. data/test/hexapdf/type/test_font_type1.rb +8 -8
  130. data/test/hexapdf/type/test_font_type3.rb +4 -4
  131. data/test/hexapdf/type/test_image.rb +16 -12
  132. data/test/hexapdf/type/test_page.rb +11 -11
  133. data/test/hexapdf/type/test_page_tree_node.rb +20 -20
  134. data/test/hexapdf/type/test_resources.rb +6 -6
  135. data/test/hexapdf/type/test_trailer.rb +5 -2
  136. data/test/hexapdf/type/test_xref_stream.rb +1 -0
  137. data/test/hexapdf/utils/test_sorted_tree_node.rb +35 -35
  138. metadata +23 -7
  139. data/test/hexapdf/type/annotations/test_link.rb +0 -19
@@ -6,8 +6,9 @@ require 'hexapdf/document'
6
6
 
7
7
  describe HexaPDF::Rectangle do
8
8
  describe "after_data_change" do
9
- it "fails if the value is not a array" do
10
- assert_raises(ArgumentError) { HexaPDF::Rectangle.new(:Name) }
9
+ it "fails if the rectangle doesn't contain four numbers" do
10
+ assert_raises(ArgumentError) { HexaPDF::Rectangle.new([1, 2, 3]) }
11
+ assert_raises(ArgumentError) { HexaPDF::Rectangle.new([1, 2, 3, :a]) }
11
12
  end
12
13
 
13
14
  it "normalizes the array values" do
@@ -53,9 +54,6 @@ describe HexaPDF::Rectangle do
53
54
 
54
55
  rect.value.unshift(:A)
55
56
  refute(rect.validate)
56
-
57
- rect.data.value = :A
58
- refute(rect.validate)
59
57
  end
60
58
  end
61
59
  end
@@ -137,7 +137,7 @@ describe HexaPDF::Serializer do
137
137
  it "serializes streams" do
138
138
  @stream.stream = "somedata"
139
139
  assert_serialized("<</Key(value)/Length 8>>stream\nsomedata\nendstream", @stream)
140
- assert_serialized("<</Name 2 0 R>>", HexaPDF::Object.new(Name: @stream))
140
+ assert_serialized("<</Name 2 0 R>>", HexaPDF::Object.new({Name: @stream}))
141
141
  end
142
142
 
143
143
  it "handles self-referencing streams" do
@@ -81,6 +81,7 @@ describe HexaPDF::Stream do
81
81
  @document.config = HexaPDF::Configuration.with_defaults
82
82
  @document.instance_variable_set(:@version, '1.2')
83
83
  def (@document).unwrap(obj); obj; end
84
+ def (@document).wrap(obj, *); obj; end
84
85
  def (@document).deref(obj); obj; end
85
86
 
86
87
  @stm = HexaPDF::Stream.new({}, oid: 1, document: @document)
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.10.0)>>
43
+ <</Producer(HexaPDF version 0.11.0)>>
44
44
  endobj
45
45
  xref
46
46
  3 1
@@ -72,7 +72,7 @@ describe HexaPDF::Writer do
72
72
  141
73
73
  %%EOF
74
74
  6 0 obj
75
- <</Producer(HexaPDF version 0.10.0)>>
75
+ <</Producer(HexaPDF version 0.11.0)>>
76
76
  endobj
77
77
  2 0 obj
78
78
  <</Length 10>>stream
@@ -116,7 +116,7 @@ describe HexaPDF::Writer do
116
116
 
117
117
  it "raises an error if no xref stream is in a revision but object streams are" do
118
118
  document = HexaPDF::Document.new
119
- document.add(Type: :ObjStm)
119
+ document.add({Type: :ObjStm})
120
120
  assert_raises(HexaPDF::Error) { HexaPDF::Writer.new(document, StringIO.new).write }
121
121
  end
122
122
 
@@ -0,0 +1,85 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/acro_form/field'
6
+
7
+ describe HexaPDF::Type::AcroForm::Field do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @field = @doc.add({}, type: :XXAcroFormField)
11
+ end
12
+
13
+ it "must always be an indirect object" do
14
+ assert(@field.must_be_indirect?)
15
+ end
16
+
17
+ it "resolves inherited field values" do
18
+ assert_nil(@field[:FT])
19
+
20
+ @field[:Parent] = {FT: :Tx}
21
+ assert_equal(:Tx, @field[:FT])
22
+
23
+ @field[:FT] = :Ch
24
+ assert_equal(:Ch, @field[:FT])
25
+ end
26
+
27
+ it "returns the field type" do
28
+ assert_nil(@field.field_type)
29
+
30
+ @field[:FT] = :Tx
31
+ assert_equal(:Tx, @field.field_type)
32
+ end
33
+
34
+ it "returns the full name of the field" do
35
+ assert_nil(@field.full_name)
36
+
37
+ @field[:T] = "Test"
38
+ assert_equal("Test", @field.full_name)
39
+
40
+ @field[:Parent] = {}
41
+ assert_equal("Test", @field.full_name)
42
+
43
+ @field[:Parent] = {T: 'Parent'}
44
+ assert_equal("Parent.Test", @field.full_name)
45
+ end
46
+
47
+ it "returns whether the field is a terminal field" do
48
+ assert(@field.terminal_field?)
49
+
50
+ @field[:Kids] = []
51
+ assert(@field.terminal_field?)
52
+
53
+ @field[:Kids] = [{Subtype: :Widget}]
54
+ assert(@field.terminal_field?)
55
+
56
+ @field[:Kids] = [{FT: :Tx}]
57
+ refute(@field.terminal_field?)
58
+ end
59
+
60
+ describe "perform_validation" do
61
+ before do
62
+ @field[:FT] = :Tx
63
+ end
64
+
65
+ it "requires the /FT key to be present for terminal fields" do
66
+ assert(@field.validate)
67
+
68
+ @field.delete(:FT)
69
+ refute(@field.validate)
70
+
71
+ @field[:Kids] = [{}]
72
+ assert(@field.validate)
73
+ end
74
+
75
+ it "doesn't allow periods in partial field names" do
76
+ assert(@field.validate)
77
+
78
+ @field[:T] = "Test"
79
+ assert(@field.validate)
80
+
81
+ @field[:T] = "Te.st"
82
+ refute(@field.validate)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,69 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/acro_form/form'
6
+
7
+ describe HexaPDF::Type::AcroForm::Form do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @acroform = @doc.add({}, type: :XXAcroForm)
11
+ end
12
+
13
+ describe "signature flags" do
14
+ before do
15
+ @acroform[:SigFlags] = 3
16
+ end
17
+
18
+ it "returns all signature flags" do
19
+ assert_equal([:signatures_exist, :append_only], @acroform.signature_flags)
20
+ end
21
+
22
+ it "returns true if the given flag is set" do
23
+ assert(@acroform.signature_flag?(:signatures_exist))
24
+ end
25
+
26
+ it "raises an error if an unknown flag name is provided" do
27
+ assert_raises(ArgumentError) { @acroform.signature_flag?(:non_exist) }
28
+ end
29
+
30
+ it "sets the given flag bits" do
31
+ @acroform[:SigFlags] = 0
32
+ @acroform.signature_flag(:append_only)
33
+ assert_equal([:append_only], @acroform.signature_flags)
34
+ @acroform.signature_flag(:signatures_exist, clear_existing: true)
35
+ assert_equal([:signatures_exist], @acroform.signature_flags)
36
+ end
37
+ end
38
+
39
+ it "finds the root fields" do
40
+ @doc.pages.add[:Annots] = [{FT: :Tx1}, {FT: :Tx2, Parent: {FT: :Tx3}}]
41
+ @doc.pages.add[:Annots] = [{Subtype: :Widget}]
42
+
43
+ result = [{FT: :Tx1}, {FT: :Tx3}]
44
+ assert_equal(result, @acroform.find_root_fields.map(&:value))
45
+ refute(@acroform.key?(:Fields))
46
+
47
+ @acroform.find_root_fields!
48
+ assert_equal(result, @acroform[:Fields].value.map(&:value))
49
+ end
50
+
51
+ describe "each_field" do
52
+ before do
53
+ @acroform[:Fields] = [
54
+ {FT: :Tx1},
55
+ {FT: :Tx2, Kids: [{Subtype: :Widget}]},
56
+ {FT: :Tx3, Kids: [{FT: :Tx4}, {FT: :Tx5, Kids: [{FT: :Tx6}]}]},
57
+ ]
58
+ end
59
+
60
+ it "iterates over all terminal fields" do
61
+ assert_equal([:Tx1, :Tx2, :Tx4, :Tx6], @acroform.each_field.map {|h| h[:FT] })
62
+ end
63
+
64
+ it "iterates over all fields" do
65
+ assert_equal([:Tx1, :Tx2, :Tx3, :Tx4, :Tx5, :Tx6],
66
+ @acroform.each_field(terminal_only: false).map {|h| h[:FT] })
67
+ end
68
+ end
69
+ end
@@ -14,17 +14,13 @@ describe HexaPDF::Type::Annotations::Text do
14
14
  describe "validation" do
15
15
  it "checks for correct /StateModel values" do
16
16
  @annot[:StateModel] = 'Invalid'
17
- refute(@annot.validate {|msg| assert_match(/contains invalid value/, msg) })
17
+ refute(@annot.validate {|msg| assert_match(/does not contain an allowed value/, msg) })
18
18
  end
19
19
 
20
- it "automatically sets /StateModel based on the /State entry if possible" do
20
+ it "automatically sets /StateModel based on the /State entry" do
21
21
  @annot[:State] = 'Marked'
22
22
  assert(@annot.validate)
23
23
  assert_equal('Marked', @annot[:StateModel])
24
-
25
- @annot.delete(:StateModel)
26
- @annot[:State] = 'Unknown'
27
- refute(@annot.validate {|msg| assert_match(/StateModel required/, msg) })
28
24
  end
29
25
 
30
26
  it "checks whether /State and /StateModel match" do
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/annotations/widget'
6
+
7
+ describe HexaPDF::Type::Annotations::Widget::AppearanceCharacteristics do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @annot = @doc.wrap({}, type: :XXAppearanceCharacteristics)
11
+ end
12
+
13
+ describe "validation" do
14
+ it "needs /R to be a multiple of 90" do
15
+ assert(@annot.validate)
16
+
17
+ @annot[:R] = 45
18
+ refute(@annot.validate)
19
+
20
+ @annot[:R] = 90
21
+ assert(@annot.validate)
22
+ end
23
+ end
24
+ end
@@ -7,7 +7,7 @@ require 'hexapdf/type/annotation'
7
7
  describe HexaPDF::Type::Annotation do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- @annot = @doc.add(Type: :Annot, F: 0b100011)
10
+ @annot = @doc.add({Type: :Annot, F: 0b100011})
11
11
  end
12
12
 
13
13
  describe "flags" do
@@ -7,7 +7,7 @@ require 'hexapdf/type/catalog'
7
7
  describe HexaPDF::Type::Catalog do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- @catalog = @doc.add(Type: :Catalog)
10
+ @catalog = @doc.add({Type: :Catalog})
11
11
  end
12
12
 
13
13
  it "must always be indirect" do
@@ -7,8 +7,8 @@ require 'hexapdf/type/cid_font'
7
7
  describe HexaPDF::Type::CIDFont do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- @font = @doc.wrap(Type: :Font, Subtype: :CIDFontType2, W: [1, 2, 3], DW: 100,
11
- CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1})
10
+ @font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [1, 2, 3], DW: 100,
11
+ CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1}})
12
12
  end
13
13
 
14
14
  describe "width" do
@@ -39,7 +39,7 @@ describe HexaPDF::Type::CIDFont do
39
39
  it "allows setting the widths" do
40
40
  @font.set_widths([[1, 1], [2, 2], [4, 4], [5, 5], [7, 7.1]], default_width: 5.1)
41
41
  assert_equal(5, @font[:DW])
42
- assert_equal([1, [1, 2], 4, [4, 5], 7, [7]], @font[:W])
42
+ assert_equal([1, [1, 2], 4, [4, 5], 7, [7]], @font[:W].value)
43
43
  end
44
44
 
45
45
  it "handles an empty widths array correctly" do
@@ -13,8 +13,8 @@ describe HexaPDF::Type::Font do
13
13
  <22> <0042>
14
14
  endbfchar
15
15
  EOF
16
- fd = @doc.add(Type: :FontDescriptor, FontBBox: [0, 1, 2, 3])
17
- @font = @doc.add(Type: :Font, BaseFont: :TestFont, FontDescriptor: fd, ToUnicode: cmap)
16
+ fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
17
+ @font = @doc.add({Type: :Font, BaseFont: :TestFont, FontDescriptor: fd, ToUnicode: cmap})
18
18
  end
19
19
 
20
20
  it "must always be an indirect" do
@@ -7,7 +7,8 @@ require 'hexapdf/type/font_descriptor'
7
7
  describe HexaPDF::Type::FontDescriptor do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- @font_desc = @doc.add(Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001, ItalicAngle: 10)
10
+ @font_desc = @doc.add({Type: :FontDescriptor, FontName: :Test, Flags: 0b1001001,
11
+ ItalicAngle: 10})
11
12
  end
12
13
 
13
14
  describe "flags" do
@@ -13,9 +13,9 @@ describe HexaPDF::Type::FontSimple do
13
13
  <22> <0042>
14
14
  endbfchar
15
15
  EOF
16
- font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
- FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
- Descent: -100, CapHeight: 800, StemV: 20)
16
+ font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
17
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
18
+ Descent: -100, CapHeight: 800, StemV: 20})
19
19
  @font = @doc.add({Type: :Font, Encoding: :WinAnsiEncoding,
20
20
  BaseFont: :Embedded, FontDescriptor: font_descriptor, ToUnicode: cmap,
21
21
  FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]},
@@ -7,12 +7,12 @@ require 'hexapdf/type/font_true_type'
7
7
  describe HexaPDF::Type::FontTrueType do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Something, Flags: 0b100,
11
- FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
12
- Descent: -100, CapHeight: 800, StemV: 20)
13
- @font = @doc.add(Type: :Font, Subtype: :TrueType, Encoding: :WinAnsiEncoding,
14
- FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
15
- BaseFont: :Something, FontDescriptor: font_descriptor)
10
+ font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Something, Flags: 0b100,
11
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
12
+ Descent: -100, CapHeight: 800, StemV: 20})
13
+ @font = @doc.add({Type: :Font, Subtype: :TrueType, Encoding: :WinAnsiEncoding,
14
+ FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
15
+ BaseFont: :Something, FontDescriptor: font_descriptor})
16
16
  end
17
17
 
18
18
  describe "validation" do
@@ -7,15 +7,15 @@ require 'hexapdf/type/font_type0'
7
7
  describe HexaPDF::Type::FontType0 do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- fd = @doc.add(Type: :FontDescriptor, FontBBox: [0, 1, 2, 3])
11
- @cid_font = @doc.wrap(Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: fd,
12
- CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1})
13
- @font = @doc.wrap(Type: :Font, Subtype: :Type0, Encoding: :H, DescendantFonts: [@cid_font])
10
+ fd = @doc.add({Type: :FontDescriptor, FontBBox: [0, 1, 2, 3]})
11
+ @cid_font = @doc.wrap({Type: :Font, Subtype: :CIDFontType2, W: [633, [100]], FontDescriptor: fd,
12
+ CIDSystemInfo: {Registry: 'Adobe', Ordering: 'Japan1', Supplement: 1}})
13
+ @font = @doc.wrap({Type: :Font, Subtype: :Type0, Encoding: :H, DescendantFonts: [@cid_font]})
14
14
  end
15
15
 
16
16
  it "returns the correct writing mode" do
17
17
  assert_equal(:horizontal, @font.writing_mode)
18
- font = @doc.wrap(Type: :Font, Subtype: :Type0, Encoding: :V)
18
+ font = @doc.wrap({Type: :Font, Subtype: :Type0, Encoding: :V})
19
19
  assert_equal(:vertical, font.writing_mode)
20
20
  end
21
21
 
@@ -39,8 +39,8 @@ end
39
39
  describe HexaPDF::Type::FontType1 do
40
40
  before do
41
41
  @doc = HexaPDF::Document.new
42
- @font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
43
- BaseFont: :"Times-Roman")
42
+ @font = @doc.add({Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
43
+ BaseFont: :"Times-Roman"})
44
44
 
45
45
  font_file = @doc.add({}, stream: <<-EOF)
46
46
  /Encoding 256 array
@@ -49,12 +49,12 @@ describe HexaPDF::Type::FontType1 do
49
49
  dup 34 /B put
50
50
  readonly def
51
51
  EOF
52
- font_descriptor = @doc.add(Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
53
- FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
54
- Descent: -100, CapHeight: 800, StemV: 20, FontFile: font_file)
55
- @embedded_font = @doc.add(Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
56
- BaseFont: :Embedded, FontDescriptor: font_descriptor,
57
- FirstChar: 32, LastChar: 34, Widths: [600, 0, 700])
52
+ font_descriptor = @doc.add({Type: :FontDescriptor, FontName: :Embedded, Flags: 0b100,
53
+ FontBBox: [0, 1, 2, 3], ItalicAngle: 0, Ascent: 900,
54
+ Descent: -100, CapHeight: 800, StemV: 20, FontFile: font_file})
55
+ @embedded_font = @doc.add({Type: :Font, Subtype: :Type1, Encoding: :WinAnsiEncoding,
56
+ BaseFont: :Embedded, FontDescriptor: font_descriptor,
57
+ FirstChar: 32, LastChar: 34, Widths: [600, 0, 700]})
58
58
  end
59
59
 
60
60
  describe "encoding" do
@@ -7,10 +7,10 @@ require 'hexapdf/type/font_type3'
7
7
  describe HexaPDF::Type::FontType3 do
8
8
  before do
9
9
  @doc = HexaPDF::Document.new
10
- @font = @doc.add(Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
11
- FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
12
- FontBBox: [0, 0, 100, 100], FontMatrix: [1, 0, 0, 1, 0, 0],
13
- CharProcs: {})
10
+ @font = @doc.add({Type: :Font, Subtype: :Type3, Encoding: :WinAnsiEncoding,
11
+ FirstChar: 32, LastChar: 34, Widths: [600, 0, 700],
12
+ FontBBox: [0, 0, 100, 100], FontMatrix: [1, 0, 0, 1, 0, 0],
13
+ CharProcs: {}})
14
14
  end
15
15
 
16
16
  describe "validation" do
@@ -12,19 +12,19 @@ describe HexaPDF::Type::Image do
12
12
  end
13
13
 
14
14
  it "returns the width of the image" do
15
- @image = @doc.wrap(Type: :XObject, Subtype: :Image, Width: 10)
15
+ @image = @doc.wrap({Type: :XObject, Subtype: :Image, Width: 10})
16
16
  assert_equal(10, @image.width)
17
17
  end
18
18
 
19
19
  it "returns the height of the image" do
20
- @image = @doc.wrap(Type: :XObject, Subtype: :Image, Height: 10)
20
+ @image = @doc.wrap({Type: :XObject, Subtype: :Image, Height: 10})
21
21
  assert_equal(10, @image.height)
22
22
  end
23
23
 
24
24
  describe "info" do
25
25
  before do
26
- @image = @doc.wrap(Type: :XObject, Subtype: :Image, Width: 10, Height: 5,
27
- ColorSpace: :DeviceRGB, BitsPerComponent: 4)
26
+ @image = @doc.wrap({Type: :XObject, Subtype: :Image, Width: 10, Height: 5,
27
+ ColorSpace: :DeviceRGB, BitsPerComponent: 4})
28
28
  end
29
29
 
30
30
  it "uses the Width, Height and BitsPerComponent values" do
@@ -184,6 +184,10 @@ describe HexaPDF::Type::Image do
184
184
  Dir.glob(File.join(TEST_DATA_DIR, 'images', '*.png')).each do |png_file|
185
185
  it "writes #{File.basename(png_file)} correctly as PNG file" do
186
186
  image = @doc.images.add(png_file)
187
+ if png_file =~ /greyscale-1bit.png/ # force use of arrays for one image
188
+ image[:DecodeParms] = [image[:DecodeParms]]
189
+ image[:Filter] = [image[:Filter]]
190
+ end
187
191
  image.write(@file.path)
188
192
  assert_valid_png(@file.path, png_file)
189
193
 
@@ -197,7 +201,7 @@ describe HexaPDF::Type::Image do
197
201
  assert_equal(image[:Height], new_image[:Height], "file: #{png_file}")
198
202
  assert_equal(image[:BitsPerComponent], new_image[:BitsPerComponent], "file: #{png_file}")
199
203
  if image[:Mask]
200
- assert_equal(image[:Mask], new_image[:Mask], "file: #{png_file}")
204
+ assert_equal(image[:Mask].value, new_image[:Mask].value, "file: #{png_file}")
201
205
  else
202
206
  assert_nil(new_image[:Mask], "file: #{png_file}")
203
207
  end
@@ -217,15 +221,15 @@ describe HexaPDF::Type::Image do
217
221
  end
218
222
 
219
223
  it "works for greyscale indexed images" do
220
- image = @doc.add(Type: :XObject, Subtype: :Image, Width: 2, Height: 2, BitsPerComponent: 2,
221
- ColorSpace: [:Indexed, :DeviceGray, 3, "\x00\x40\x80\xFF".b])
224
+ image = @doc.add({Type: :XObject, Subtype: :Image, Width: 2, Height: 2, BitsPerComponent: 2,
225
+ ColorSpace: [:Indexed, :DeviceGray, 3, "\x00\x40\x80\xFF".b]})
222
226
  image.stream = HexaPDF::StreamData.new(filter: :ASCIIHexDecode) { "10 B0".b }
223
227
  image.write(@file.path)
224
228
  assert_valid_png(@file.path)
225
229
 
226
230
  new_image = @doc.images.add(@file.path)
227
231
  assert_equal([:Indexed, :DeviceRGB, 3, "\x00\x00\x00\x40\x40\x40\x80\x80\x80\xFF\xFF\xFF".b],
228
- new_image[:ColorSpace])
232
+ new_image[:ColorSpace].value)
229
233
  assert_equal(image.stream, new_image.stream)
230
234
  end
231
235
 
@@ -236,14 +240,14 @@ describe HexaPDF::Type::Image do
236
240
  end
237
241
 
238
242
  it "fails if an unsupported colorspace is used" do
239
- image = @doc.add(Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
240
- ColorSpace: :ICCBased)
243
+ image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
244
+ ColorSpace: :ICCBased})
241
245
  assert_raises(HexaPDF::Error) { image.write(@file) }
242
246
  end
243
247
 
244
248
  it "fails if an indexed image with an unsupported colorspace is used" do
245
- image = @doc.add(Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
246
- ColorSpace: [:Indexed, :ICCBased, 0, "0"])
249
+ image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
250
+ ColorSpace: [:Indexed, :ICCBased, 0, "0"]})
247
251
  assert_raises(HexaPDF::Error) { image.write(@file) }
248
252
  end
249
253
  end