hexapdf 0.21.0 → 0.23.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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +79 -1
  3. data/Rakefile +1 -1
  4. data/lib/hexapdf/cli/form.rb +30 -3
  5. data/lib/hexapdf/cli/inspect.rb +18 -5
  6. data/lib/hexapdf/cli/modify.rb +23 -3
  7. data/lib/hexapdf/composer.rb +24 -2
  8. data/lib/hexapdf/dictionary_fields.rb +1 -1
  9. data/lib/hexapdf/document/destinations.rb +396 -0
  10. data/lib/hexapdf/document.rb +38 -89
  11. data/lib/hexapdf/encryption/aes.rb +9 -5
  12. data/lib/hexapdf/layout/frame.rb +8 -9
  13. data/lib/hexapdf/layout/style.rb +280 -7
  14. data/lib/hexapdf/layout/text_box.rb +10 -2
  15. data/lib/hexapdf/layout/text_layouter.rb +6 -1
  16. data/lib/hexapdf/revision.rb +8 -1
  17. data/lib/hexapdf/revisions.rb +151 -50
  18. data/lib/hexapdf/task/optimize.rb +21 -11
  19. data/lib/hexapdf/type/acro_form/form.rb +11 -5
  20. data/lib/hexapdf/type/acro_form/text_field.rb +8 -0
  21. data/lib/hexapdf/type/catalog.rb +9 -1
  22. data/lib/hexapdf/type/image.rb +47 -3
  23. data/lib/hexapdf/type/names.rb +13 -0
  24. data/lib/hexapdf/type/xref_stream.rb +2 -1
  25. data/lib/hexapdf/utils/sorted_tree_node.rb +3 -1
  26. data/lib/hexapdf/version.rb +1 -1
  27. data/lib/hexapdf/writer.rb +15 -2
  28. data/test/hexapdf/document/test_destinations.rb +338 -0
  29. data/test/hexapdf/encryption/test_aes.rb +8 -0
  30. data/test/hexapdf/encryption/test_security_handler.rb +2 -2
  31. data/test/hexapdf/layout/test_frame.rb +15 -1
  32. data/test/hexapdf/layout/test_text_box.rb +16 -0
  33. data/test/hexapdf/layout/test_text_layouter.rb +7 -0
  34. data/test/hexapdf/task/test_optimize.rb +17 -4
  35. data/test/hexapdf/test_composer.rb +24 -1
  36. data/test/hexapdf/test_dictionary_fields.rb +1 -1
  37. data/test/hexapdf/test_document.rb +30 -133
  38. data/test/hexapdf/test_parser.rb +1 -1
  39. data/test/hexapdf/test_revision.rb +14 -0
  40. data/test/hexapdf/test_revisions.rb +137 -29
  41. data/test/hexapdf/test_writer.rb +43 -14
  42. data/test/hexapdf/type/acro_form/test_form.rb +2 -1
  43. data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
  44. data/test/hexapdf/type/test_catalog.rb +8 -0
  45. data/test/hexapdf/type/test_image.rb +45 -9
  46. data/test/hexapdf/type/test_names.rb +20 -0
  47. data/test/hexapdf/type/test_xref_stream.rb +2 -1
  48. data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
  49. metadata +6 -3
@@ -115,16 +115,42 @@ describe HexaPDF::Type::Image do
115
115
  assert(info.indexed)
116
116
  assert(info.writable)
117
117
 
118
- @image[:ColorSpace] = :ICCBased
118
+ @image[:ColorSpace] = [:ICCBased, {N: 3}]
119
119
  info = @image.info
120
- assert_equal(:other, info.color_space)
121
- assert_equal(-1, info.components)
120
+ assert_equal(:icc, info.color_space)
121
+ assert_equal(3, info.components)
122
+ assert(info.writable)
123
+ @image[:ColorSpace] = [:ICCBased, {N: 4}]
124
+ info = @image.info
125
+ refute(info.writable)
122
126
  end
123
127
 
124
128
  it "processes the SMask entry" do
125
- @image[:SMask] = :something
126
- info = @image.info
127
- refute(info.writable)
129
+ @image[:SMask] = {BitsPerComponent: 8, Width: 10, Height: 5}
130
+
131
+ @image[:BitsPerComponent] = 8
132
+ assert(@image.info.writable)
133
+
134
+ @image[:BitsPerComponent] = 16
135
+ refute(@image.info.writable)
136
+ @image[:SMask][:BitsPerComponent] = 16
137
+ assert(@image.info.writable)
138
+
139
+ @image[:BitsPerComponent] = 4
140
+ refute(@image.info.writable)
141
+ @image[:SMask][:BitsPerComponent] = 4
142
+ refute(@image.info.writable)
143
+
144
+ @image[:BitsPerComponent] = @image[:SMask][:BitsPerComponent] = 8
145
+ @image[:SMask][:Width] = 8
146
+ refute(@image.info.writable)
147
+
148
+ @image[:SMask][:Width] = 10
149
+ @image[:SMask][:Height] = 8
150
+ refute(@image.info.writable)
151
+
152
+ @image[:SMask][:Height] = 5
153
+ assert(@image.info.writable)
128
154
  end
129
155
  end
130
156
 
@@ -184,7 +210,7 @@ describe HexaPDF::Type::Image do
184
210
  end
185
211
 
186
212
  Dir.glob(File.join(TEST_DATA_DIR, 'images', '*.png')).each do |png_file|
187
- next if png_file =~ /alpha/
213
+ next if png_file =~ /indexed-alpha/
188
214
  it "writes #{File.basename(png_file)} correctly as PNG file" do
189
215
  image = @doc.images.add(png_file)
190
216
  if png_file =~ /greyscale-1bit.png/ # force use of arrays for one image
@@ -208,6 +234,7 @@ describe HexaPDF::Type::Image do
208
234
  else
209
235
  assert_nil(new_image[:Mask], "file: #{png_file}")
210
236
  end
237
+ assert(new_image[:SMask]) if png_file =~ /alpha/
211
238
  assert_equal(image.stream, new_image.stream, "file: #{png_file}")
212
239
 
213
240
  # ColorSpace is currently not always preserved, e.g. with CalRGB
@@ -236,6 +263,15 @@ describe HexaPDF::Type::Image do
236
263
  assert_equal(image.stream, new_image.stream)
237
264
  end
238
265
 
266
+ it "works for images with an ICCBased color space" do
267
+ image = @doc.add({Type: :XObject, Subtype: :Image, Width: 2, Height: 2, BitsPerComponent: 2,
268
+ ColorSpace: [:ICCBased, @doc.wrap({}, stream: 'abcd')]})
269
+ image.stream = HexaPDF::StreamData.new(filter: :ASCIIHexDecode) { "10 B0".b }
270
+ image.write(@file.path)
271
+ assert_valid_png(@file.path)
272
+ assert_match(/iCCPICCProfile\x00\x00/, File.binread(@file.path))
273
+ end
274
+
239
275
  it "fails if an unsupported stream filter is used" do
240
276
  image = @doc.images.add(@jpg)
241
277
  image.set_filter([:DCTDecode, :ASCIIHexDecode])
@@ -244,13 +280,13 @@ describe HexaPDF::Type::Image do
244
280
 
245
281
  it "fails if an unsupported colorspace is used" do
246
282
  image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
247
- ColorSpace: :ICCBased})
283
+ ColorSpace: :Unknown})
248
284
  assert_raises(HexaPDF::Error) { image.write(@file) }
249
285
  end
250
286
 
251
287
  it "fails if an indexed image with an unsupported colorspace is used" do
252
288
  image = @doc.add({Type: :XObject, Subtype: :Image, Width: 1, Height: 1, BitsPerComponent: 8,
253
- ColorSpace: [:Indexed, :ICCBased, 0, "0"]})
289
+ ColorSpace: [:Indexed, :Unknown, 0, "0"]})
254
290
  assert_raises(HexaPDF::Error) { image.write(@file) }
255
291
  end
256
292
  end
@@ -0,0 +1,20 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require 'test_helper'
4
+ require 'hexapdf/document'
5
+ require 'hexapdf/type/names'
6
+
7
+ describe HexaPDF::Type::Names do
8
+ before do
9
+ @doc = HexaPDF::Document.new
10
+ @names = @doc.add({}, type: :XXNames)
11
+ end
12
+
13
+ it "returns the name tree for the /Dests entry" do
14
+ refute(@names.key?(:Dests))
15
+ dests = @names.destinations
16
+ assert_kind_of(HexaPDF::NameTreeNode, dests)
17
+ assert_same(dests, @names[:Dests])
18
+ assert_same(dests, @names.destinations)
19
+ end
20
+ end
@@ -88,10 +88,11 @@ describe HexaPDF::Type::XRefStream do
88
88
  @obj[:Index] = [0, 5]
89
89
  @obj[:W] = [1, 2, 2]
90
90
  dict = @obj.trailer
91
- assert_equal(3, dict.length)
91
+ assert_equal(4, dict.length)
92
92
  assert_equal(5, dict[:Size])
93
93
  assert_equal(["a", "b"], dict[:ID])
94
94
  assert_equal('x', dict[:Root])
95
+ assert_equal(:XRef, dict[:Type])
95
96
  end
96
97
  end
97
98
 
@@ -135,7 +135,17 @@ describe HexaPDF::Utils::SortedTreeNode do
135
135
  assert_nil(@root.find_entry('non'))
136
136
  end
137
137
 
138
- it "works when no entry exists" do
138
+ it "works when no entry exists and neither /Names nor /Kids are set" do
139
+ assert_nil(@root.find_entry('non'))
140
+ end
141
+
142
+ it "works when no entry exists and /Names is set" do
143
+ @root[:Names] = []
144
+ assert_nil(@root.find_entry('non'))
145
+ end
146
+
147
+ it "works when no entry exists and /Kids is set" do
148
+ @root[:Kids] = []
139
149
  assert_nil(@root.find_entry('non'))
140
150
  end
141
151
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexapdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.0
4
+ version: 0.23.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Leitner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-04 00:00:00.000000000 Z
11
+ date: 2022-05-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse
@@ -255,6 +255,7 @@ files:
255
255
  - lib/hexapdf/dictionary.rb
256
256
  - lib/hexapdf/dictionary_fields.rb
257
257
  - lib/hexapdf/document.rb
258
+ - lib/hexapdf/document/destinations.rb
258
259
  - lib/hexapdf/document/files.rb
259
260
  - lib/hexapdf/document/fonts.rb
260
261
  - lib/hexapdf/document/images.rb
@@ -504,6 +505,7 @@ files:
504
505
  - test/hexapdf/content/test_parser.rb
505
506
  - test/hexapdf/content/test_processor.rb
506
507
  - test/hexapdf/content/test_transformation_matrix.rb
508
+ - test/hexapdf/document/test_destinations.rb
507
509
  - test/hexapdf/document/test_files.rb
508
510
  - test/hexapdf/document/test_fonts.rb
509
511
  - test/hexapdf/document/test_images.rb
@@ -636,6 +638,7 @@ files:
636
638
  - test/hexapdf/type/test_form.rb
637
639
  - test/hexapdf/type/test_image.rb
638
640
  - test/hexapdf/type/test_info.rb
641
+ - test/hexapdf/type/test_names.rb
639
642
  - test/hexapdf/type/test_object_stream.rb
640
643
  - test/hexapdf/type/test_page.rb
641
644
  - test/hexapdf/type/test_page_tree_node.rb
@@ -671,7 +674,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
671
674
  - !ruby/object:Gem::Version
672
675
  version: '0'
673
676
  requirements: []
674
- rubygems_version: 3.3.3
677
+ rubygems_version: 3.2.32
675
678
  signing_key:
676
679
  specification_version: 4
677
680
  summary: HexaPDF - A Versatile PDF Creation and Manipulation Library For Ruby