hexapdf 0.10.0 → 0.11.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 (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