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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +79 -1
- data/Rakefile +1 -1
- data/lib/hexapdf/cli/form.rb +30 -3
- data/lib/hexapdf/cli/inspect.rb +18 -5
- data/lib/hexapdf/cli/modify.rb +23 -3
- data/lib/hexapdf/composer.rb +24 -2
- data/lib/hexapdf/dictionary_fields.rb +1 -1
- data/lib/hexapdf/document/destinations.rb +396 -0
- data/lib/hexapdf/document.rb +38 -89
- data/lib/hexapdf/encryption/aes.rb +9 -5
- data/lib/hexapdf/layout/frame.rb +8 -9
- data/lib/hexapdf/layout/style.rb +280 -7
- data/lib/hexapdf/layout/text_box.rb +10 -2
- data/lib/hexapdf/layout/text_layouter.rb +6 -1
- data/lib/hexapdf/revision.rb +8 -1
- data/lib/hexapdf/revisions.rb +151 -50
- data/lib/hexapdf/task/optimize.rb +21 -11
- data/lib/hexapdf/type/acro_form/form.rb +11 -5
- data/lib/hexapdf/type/acro_form/text_field.rb +8 -0
- data/lib/hexapdf/type/catalog.rb +9 -1
- data/lib/hexapdf/type/image.rb +47 -3
- data/lib/hexapdf/type/names.rb +13 -0
- data/lib/hexapdf/type/xref_stream.rb +2 -1
- data/lib/hexapdf/utils/sorted_tree_node.rb +3 -1
- data/lib/hexapdf/version.rb +1 -1
- data/lib/hexapdf/writer.rb +15 -2
- data/test/hexapdf/document/test_destinations.rb +338 -0
- data/test/hexapdf/encryption/test_aes.rb +8 -0
- data/test/hexapdf/encryption/test_security_handler.rb +2 -2
- data/test/hexapdf/layout/test_frame.rb +15 -1
- data/test/hexapdf/layout/test_text_box.rb +16 -0
- data/test/hexapdf/layout/test_text_layouter.rb +7 -0
- data/test/hexapdf/task/test_optimize.rb +17 -4
- data/test/hexapdf/test_composer.rb +24 -1
- data/test/hexapdf/test_dictionary_fields.rb +1 -1
- data/test/hexapdf/test_document.rb +30 -133
- data/test/hexapdf/test_parser.rb +1 -1
- data/test/hexapdf/test_revision.rb +14 -0
- data/test/hexapdf/test_revisions.rb +137 -29
- data/test/hexapdf/test_writer.rb +43 -14
- data/test/hexapdf/type/acro_form/test_form.rb +2 -1
- data/test/hexapdf/type/acro_form/test_text_field.rb +17 -0
- data/test/hexapdf/type/test_catalog.rb +8 -0
- data/test/hexapdf/type/test_image.rb +45 -9
- data/test/hexapdf/type/test_names.rb +20 -0
- data/test/hexapdf/type/test_xref_stream.rb +2 -1
- data/test/hexapdf/utils/test_sorted_tree_node.rb +11 -1
- 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(:
|
121
|
-
assert_equal(
|
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] = :
|
126
|
-
|
127
|
-
|
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: :
|
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, :
|
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(
|
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.
|
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-
|
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.
|
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
|