hexapdf 0.15.6 → 0.16.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 +32 -0
- data/lib/hexapdf/cli/command.rb +1 -1
- data/lib/hexapdf/configuration.rb +1 -1
- data/lib/hexapdf/content/canvas.rb +5 -1
- data/lib/hexapdf/content/color_space.rb +167 -1
- data/lib/hexapdf/dictionary_fields.rb +22 -1
- data/lib/hexapdf/parser.rb +10 -1
- data/lib/hexapdf/tokenizer.rb +10 -2
- data/lib/hexapdf/version.rb +1 -1
- data/test/hexapdf/common_tokenizer_tests.rb +15 -0
- data/test/hexapdf/content/test_color_space.rb +13 -1
- data/test/hexapdf/test_dictionary_fields.rb +15 -0
- data/test/hexapdf/test_parser.rb +15 -2
- data/test/hexapdf/test_writer.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b2303787fd50c2407bb99336c3315643c4a9401a84a508462715d18a378788c
|
4
|
+
data.tar.gz: 675bb953973762670c598f93ed15fcaa4387f962c0cbdc9d27060bd06de4f5ae
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81715891b39fc35606baae317fc44a4be4d7710b2a1488f682425620771c2b563ecdfa8ba8ff0028a5226904d511c79b9507c1fed7170fdfd2c7a29aa4706127
|
7
|
+
data.tar.gz: f24fb2cdd07da0c2afde7511c40880e66fd65d87d2fd6035524202fbf8f1040d1e64576b3b080f6aa0d006d5938fc61c399c062d8687b33b3f3a5e9966b3917d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,35 @@
|
|
1
|
+
## 0.16.0 - 2021-09-28
|
2
|
+
|
3
|
+
## Added
|
4
|
+
|
5
|
+
* Support for RGB color values of the form "RGB" in addition to "RRGGBB" and for
|
6
|
+
CSS color module level 3 color names
|
7
|
+
* Conversion module for Integer fields to fix certain invalid PDF files
|
8
|
+
|
9
|
+
|
10
|
+
## 0.15.9 - 2021-09-04
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
* Handling of files that contain stream length values that are indirect objects
|
15
|
+
not referring to a number
|
16
|
+
|
17
|
+
|
18
|
+
## 0.15.8 - 2021-08-16
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
|
22
|
+
* Regression when using `-v` with the hexapdf command line tool
|
23
|
+
|
24
|
+
|
25
|
+
## 0.15.7 - 2021-07-17
|
26
|
+
|
27
|
+
### Fixed
|
28
|
+
|
29
|
+
* Infinite loop while parsing PDF array due to missing closing bracket
|
30
|
+
* Handling of invalid files with missing or corrupted trailer dictionary
|
31
|
+
|
32
|
+
|
1
33
|
## 0.15.6 - 2021-07-16
|
2
34
|
|
3
35
|
### Fixed
|
data/lib/hexapdf/cli/command.rb
CHANGED
@@ -119,7 +119,7 @@ module HexaPDF
|
|
119
119
|
# Writes the document to the given file or does nothing if +out_file+ is +nil+.
|
120
120
|
def write_document(doc, out_file, incremental: false)
|
121
121
|
if out_file
|
122
|
-
doc.validate(auto_correct: true) do |
|
122
|
+
doc.validate(auto_correct: true) do |msg, correctable, object|
|
123
123
|
if command_parser.strict && !correctable
|
124
124
|
raise "Validation error for object (#{object.oid},#{object.gen}): #{msg}"
|
125
125
|
elsif command_parser.verbosity_info?
|
@@ -245,7 +245,7 @@ module HexaPDF
|
|
245
245
|
# Defines a mapping from font names and variants to font files.
|
246
246
|
#
|
247
247
|
# The value needs to be a hash of the form:
|
248
|
-
# {"font_name"
|
248
|
+
# {"font_name" => {variant: file_name, variant2: file_name2, ...}, ...}
|
249
249
|
#
|
250
250
|
# Once a font is registered in this way, the font name together with a variant name can be used
|
251
251
|
# with the HexaPDF::Document::Fonts#add method to load the font.
|
@@ -675,6 +675,10 @@ module HexaPDF
|
|
675
675
|
# * Three numeric arguments specify an RGB color (see Content::ColorSpace::DeviceRGB::Color).
|
676
676
|
# * A string in the format "RRGGBB" where "RR" is the hexadecimal number for the red, "GG"
|
677
677
|
# for the green and "BB" for the blue color value also specifies an RGB color.
|
678
|
+
# * As does a string in the format "RGB" where "RR", "GG" and "BB" would be used as the
|
679
|
+
# hexadecimal numbers for the red, green and blue color values of an RGB color.
|
680
|
+
# * Any other string is treated as a CSS Color Module Level 3 color name, see
|
681
|
+
# https://www.w3.org/TR/css-color-3/#svg-color.
|
678
682
|
# * Four numeric arguments specify a CMYK color (see Content::ColorSpace::DeviceCMYK::Color).
|
679
683
|
# * A color object is used directly (normally used for color spaces other than DeviceRGB,
|
680
684
|
# DeviceCMYK and DeviceGray).
|
@@ -1852,7 +1856,7 @@ module HexaPDF
|
|
1852
1856
|
# on the possible color specifications.
|
1853
1857
|
def color_from_specification(spec)
|
1854
1858
|
if spec.length == 1 && spec[0].kind_of?(String)
|
1855
|
-
|
1859
|
+
ColorSpace.device_color_from_specification(spec)
|
1856
1860
|
elsif spec.length == 1 && spec[0].respond_to?(:color_space)
|
1857
1861
|
spec[0]
|
1858
1862
|
else
|
@@ -96,6 +96,157 @@ module HexaPDF
|
|
96
96
|
# See: PDF1.7 s8.6
|
97
97
|
module ColorSpace
|
98
98
|
|
99
|
+
# Mapping of CSS Color Module Level 3 names to RGB values.
|
100
|
+
CSS_COLOR_NAMES = {
|
101
|
+
"aliceblue" => [240, 248, 255],
|
102
|
+
"antiquewhite" => [250, 235, 215],
|
103
|
+
"aqua" => [0, 255, 255],
|
104
|
+
"aquamarine" => [127, 255, 212],
|
105
|
+
"azure" => [240, 255, 255],
|
106
|
+
"beige" => [245, 245, 220],
|
107
|
+
"bisque" => [255, 228, 196],
|
108
|
+
"black" => [0, 0, 0],
|
109
|
+
"blanchedalmond" => [255, 235, 205],
|
110
|
+
"blue" => [0, 0, 255],
|
111
|
+
"blueviolet" => [138, 43, 226],
|
112
|
+
"brown" => [165, 42, 42],
|
113
|
+
"burlywood" => [222, 184, 135],
|
114
|
+
"cadetblue" => [95, 158, 160],
|
115
|
+
"chartreuse" => [127, 255, 0],
|
116
|
+
"chocolate" => [210, 105, 30],
|
117
|
+
"coral" => [255, 127, 80],
|
118
|
+
"cornflowerblue" => [100, 149, 237],
|
119
|
+
"cornsilk" => [255, 248, 220],
|
120
|
+
"crimson" => [220, 20, 60],
|
121
|
+
"cyan" => [0, 255, 255],
|
122
|
+
"darkblue" => [0, 0, 139],
|
123
|
+
"darkcyan" => [0, 139, 139],
|
124
|
+
"darkgoldenrod" => [184, 134, 11],
|
125
|
+
"darkgray" => [169, 169, 169],
|
126
|
+
"darkgreen" => [0, 100, 0],
|
127
|
+
"darkgrey" => [169, 169, 169],
|
128
|
+
"darkkhaki" => [189, 183, 107],
|
129
|
+
"darkmagenta" => [139, 0, 139],
|
130
|
+
"darkolivegreen" => [85, 107, 47],
|
131
|
+
"darkorange" => [255, 140, 0],
|
132
|
+
"darkorchid" => [153, 50, 204],
|
133
|
+
"darkred" => [139, 0, 0],
|
134
|
+
"darksalmon" => [233, 150, 122],
|
135
|
+
"darkseagreen" => [143, 188, 143],
|
136
|
+
"darkslateblue" => [72, 61, 139],
|
137
|
+
"darkslategray" => [47, 79, 79],
|
138
|
+
"darkslategrey" => [47, 79, 79],
|
139
|
+
"darkturquoise" => [0, 206, 209],
|
140
|
+
"darkviolet" => [148, 0, 211],
|
141
|
+
"deeppink" => [255, 20, 147],
|
142
|
+
"deepskyblue" => [0, 191, 255],
|
143
|
+
"dimgray" => [105, 105, 105],
|
144
|
+
"dimgrey" => [105, 105, 105],
|
145
|
+
"dodgerblue" => [30, 144, 255],
|
146
|
+
"firebrick" => [178, 34, 34],
|
147
|
+
"floralwhite" => [255, 250, 240],
|
148
|
+
"forestgreen" => [34, 139, 34],
|
149
|
+
"fuchsia" => [255, 0, 255],
|
150
|
+
"gainsboro" => [220, 220, 220],
|
151
|
+
"ghostwhite" => [248, 248, 255],
|
152
|
+
"gold" => [255, 215, 0],
|
153
|
+
"goldenrod" => [218, 165, 32],
|
154
|
+
"gray" => [128, 128, 128],
|
155
|
+
"green" => [0, 128, 0],
|
156
|
+
"greenyellow" => [173, 255, 47],
|
157
|
+
"grey" => [128, 128, 128],
|
158
|
+
"honeydew" => [240, 255, 240],
|
159
|
+
"hotpink" => [255, 105, 180],
|
160
|
+
"indianred" => [205, 92, 92],
|
161
|
+
"indigo" => [75, 0, 130],
|
162
|
+
"ivory" => [255, 255, 240],
|
163
|
+
"khaki" => [240, 230, 140],
|
164
|
+
"lavender" => [230, 230, 250],
|
165
|
+
"lavenderblush" => [255, 240, 245],
|
166
|
+
"lawngreen" => [124, 252, 0],
|
167
|
+
"lemonchiffon" => [255, 250, 205],
|
168
|
+
"lightblue" => [173, 216, 230],
|
169
|
+
"lightcoral" => [240, 128, 128],
|
170
|
+
"lightcyan" => [224, 255, 255],
|
171
|
+
"lightgoldenrodyellow" => [250, 250, 210],
|
172
|
+
"lightgray" => [211, 211, 211],
|
173
|
+
"lightgreen" => [144, 238, 144],
|
174
|
+
"lightgrey" => [211, 211, 211],
|
175
|
+
"lightpink" => [255, 182, 193],
|
176
|
+
"lightsalmon" => [255, 160, 122],
|
177
|
+
"lightseagreen" => [32, 178, 170],
|
178
|
+
"lightskyblue" => [135, 206, 250],
|
179
|
+
"lightslategray" => [119, 136, 153],
|
180
|
+
"lightslategrey" => [119, 136, 153],
|
181
|
+
"lightsteelblue" => [176, 196, 222],
|
182
|
+
"lightyellow" => [255, 255, 224],
|
183
|
+
"lime" => [0, 255, 0],
|
184
|
+
"limegreen" => [50, 205, 50],
|
185
|
+
"linen" => [250, 240, 230],
|
186
|
+
"magenta" => [255, 0, 255],
|
187
|
+
"maroon" => [128, 0, 0],
|
188
|
+
"mediumaquamarine" => [102, 205, 170],
|
189
|
+
"mediumblue" => [0, 0, 205],
|
190
|
+
"mediumorchid" => [186, 85, 211],
|
191
|
+
"mediumpurple" => [147, 112, 219],
|
192
|
+
"mediumseagreen" => [60, 179, 113],
|
193
|
+
"mediumslateblue" => [123, 104, 238],
|
194
|
+
"mediumspringgreen" => [0, 250, 154],
|
195
|
+
"mediumturquoise" => [72, 209, 204],
|
196
|
+
"mediumvioletred" => [199, 21, 133],
|
197
|
+
"midnightblue" => [25, 25, 112],
|
198
|
+
"mintcream" => [245, 255, 250],
|
199
|
+
"mistyrose" => [255, 228, 225],
|
200
|
+
"moccasin" => [255, 228, 181],
|
201
|
+
"navajowhite" => [255, 222, 173],
|
202
|
+
"navy" => [0, 0, 128],
|
203
|
+
"oldlace" => [253, 245, 230],
|
204
|
+
"olive" => [128, 128, 0],
|
205
|
+
"olivedrab" => [107, 142, 35],
|
206
|
+
"orange" => [255, 165, 0],
|
207
|
+
"orangered" => [255, 69, 0],
|
208
|
+
"orchid" => [218, 112, 214],
|
209
|
+
"palegoldenrod" => [238, 232, 170],
|
210
|
+
"palegreen" => [152, 251, 152],
|
211
|
+
"paleturquoise" => [175, 238, 238],
|
212
|
+
"palevioletred" => [219, 112, 147],
|
213
|
+
"papayawhip" => [255, 239, 213],
|
214
|
+
"peachpuff" => [255, 218, 185],
|
215
|
+
"peru" => [205, 133, 63],
|
216
|
+
"pink" => [255, 192, 203],
|
217
|
+
"plum" => [221, 160, 221],
|
218
|
+
"powderblue" => [176, 224, 230],
|
219
|
+
"purple" => [128, 0, 128],
|
220
|
+
"red" => [255, 0, 0],
|
221
|
+
"rosybrown" => [188, 143, 143],
|
222
|
+
"royalblue" => [65, 105, 225],
|
223
|
+
"saddlebrown" => [139, 69, 19],
|
224
|
+
"salmon" => [250, 128, 114],
|
225
|
+
"sandybrown" => [244, 164, 96],
|
226
|
+
"seagreen" => [46, 139, 87],
|
227
|
+
"seashell" => [255, 245, 238],
|
228
|
+
"sienna" => [160, 82, 45],
|
229
|
+
"silver" => [192, 192, 192],
|
230
|
+
"skyblue" => [135, 206, 235],
|
231
|
+
"slateblue" => [106, 90, 205],
|
232
|
+
"slategray" => [112, 128, 144],
|
233
|
+
"slategrey" => [112, 128, 144],
|
234
|
+
"snow" => [255, 250, 250],
|
235
|
+
"springgreen" => [0, 255, 127],
|
236
|
+
"steelblue" => [70, 130, 180],
|
237
|
+
"tan" => [210, 180, 140],
|
238
|
+
"teal" => [0, 128, 128],
|
239
|
+
"thistle" => [216, 191, 216],
|
240
|
+
"tomato" => [255, 99, 71],
|
241
|
+
"turquoise" => [64, 224, 208],
|
242
|
+
"violet" => [238, 130, 238],
|
243
|
+
"wheat" => [245, 222, 179],
|
244
|
+
"white" => [255, 255, 255],
|
245
|
+
"whitesmoke" => [245, 245, 245],
|
246
|
+
"yellow" => [255, 255, 0],
|
247
|
+
"yellowgreen" => [154, 205, 50],
|
248
|
+
}.freeze
|
249
|
+
|
99
250
|
# :call-seq:
|
100
251
|
# ColorSpace.device_color_from_specification(gray) => color
|
101
252
|
# ColorSpace.device_color_from_specification(r, g, b) => color
|
@@ -111,6 +262,10 @@ module HexaPDF
|
|
111
262
|
# * Three numeric arguments specify an RGB color (see DeviceRGB::Color).
|
112
263
|
# * A string in the format "RRGGBB" where "RR" is the hexadecimal number for the red, "GG"
|
113
264
|
# for the green and "BB" for the blue color value also specifies an RGB color.
|
265
|
+
# * As does a string in the format "RGB" where "RR", "GG" and "BB" would be used as the
|
266
|
+
# hexadecimal numbers for the red, green and blue color values of an RGB color.
|
267
|
+
# * Any other string is treated as a CSS Color Module Level 3 color name, see
|
268
|
+
# https://www.w3.org/TR/css-color-3/#svg-color.
|
114
269
|
# * Four numeric arguments specify a CMYK color (see DeviceCMYK::Color).
|
115
270
|
# * An array is treated as if its items were specified separately as arguments.
|
116
271
|
#
|
@@ -118,7 +273,18 @@ module HexaPDF
|
|
118
273
|
# values are first normalized - see DeviceGray#color, DeviceRGB#color and DeviceCMYK#color.
|
119
274
|
def self.device_color_from_specification(*spec)
|
120
275
|
spec.flatten!
|
121
|
-
|
276
|
+
first_item = spec[0]
|
277
|
+
if spec.length == 1 && first_item.kind_of?(String)
|
278
|
+
spec = if first_item.match?(/\A\h{6}\z/)
|
279
|
+
first_item.scan(/../).map!(&:hex)
|
280
|
+
elsif first_item.match?(/\A\h{3}\z/)
|
281
|
+
first_item.each_char.map {|x| (x*2).hex}
|
282
|
+
elsif CSS_COLOR_NAMES.key?(first_item)
|
283
|
+
CSS_COLOR_NAMES[first_item]
|
284
|
+
else
|
285
|
+
raise ArgumentError, "Given string is neither a hex color nor a color name"
|
286
|
+
end
|
287
|
+
end
|
122
288
|
GlobalConfiguration.constantize('color_space.map', for_components(spec)).new.color(*spec)
|
123
289
|
end
|
124
290
|
|
@@ -349,9 +349,30 @@ module HexaPDF
|
|
349
349
|
|
350
350
|
end
|
351
351
|
|
352
|
+
# Converter module for fields of type Integer.
|
353
|
+
module IntegerConverter
|
354
|
+
|
355
|
+
# This converter is usable if the +type+ is Integer.
|
356
|
+
def self.usable_for?(type)
|
357
|
+
type == Integer
|
358
|
+
end
|
359
|
+
|
360
|
+
# :nodoc:
|
361
|
+
def self.additional_types
|
362
|
+
end
|
363
|
+
|
364
|
+
# Converts a Float value into an Integer if the float is equal to its integer value. Otherwise
|
365
|
+
# returns +nil+
|
366
|
+
def self.convert(data, _type, _document)
|
367
|
+
return unless data.kind_of?(Float) && data == data.to_i
|
368
|
+
data.to_i
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|
352
373
|
Field.converters.replace([FileSpecificationConverter, DictionaryConverter, ArrayConverter,
|
353
374
|
StringConverter, PDFByteStringConverter, DateConverter,
|
354
|
-
RectangleConverter])
|
375
|
+
RectangleConverter, IntegerConverter])
|
355
376
|
|
356
377
|
end
|
357
378
|
|
data/lib/hexapdf/parser.rb
CHANGED
@@ -165,7 +165,7 @@ module HexaPDF
|
|
165
165
|
else
|
166
166
|
0
|
167
167
|
end
|
168
|
-
@tokenizer.pos = pos + length
|
168
|
+
@tokenizer.pos = pos + length rescue pos
|
169
169
|
|
170
170
|
tok = @tokenizer.next_token
|
171
171
|
unless tok.kind_of?(Tokenizer::Token) && tok == 'endstream'
|
@@ -447,6 +447,15 @@ module HexaPDF
|
|
447
447
|
|
448
448
|
if !trailer || trailer.empty?
|
449
449
|
_, trailer = load_revision(startxref_offset) rescue nil
|
450
|
+
unless trailer
|
451
|
+
xref.each do |_oid, _gen, xref_entry|
|
452
|
+
obj, * = parse_indirect_object(xref_entry.pos) rescue nil
|
453
|
+
if obj.kind_of?(Hash) && obj[:Type] == :Catalog
|
454
|
+
trailer = {Root: HexaPDF::Reference.new(xref_entry.oid, xref_entry.gen)}
|
455
|
+
break
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
450
459
|
unless trailer
|
451
460
|
@in_reconstruct_revision = false
|
452
461
|
raise_malformed("Could not reconstruct malformed PDF because trailer was not found", pos: 0)
|
data/lib/hexapdf/tokenizer.rb
CHANGED
@@ -55,6 +55,9 @@ module HexaPDF
|
|
55
55
|
|
56
56
|
# This object is returned when there are no more tokens to read.
|
57
57
|
NO_MORE_TOKENS = ::Object.new
|
58
|
+
def NO_MORE_TOKENS.to_s
|
59
|
+
"EOS - no more tokens"
|
60
|
+
end
|
58
61
|
|
59
62
|
# Characters defined as whitespace.
|
60
63
|
#
|
@@ -384,7 +387,11 @@ module HexaPDF
|
|
384
387
|
result = []
|
385
388
|
while true
|
386
389
|
obj = next_object(allow_end_array_token: true)
|
387
|
-
|
390
|
+
if obj.equal?(TOKEN_ARRAY_END)
|
391
|
+
break
|
392
|
+
elsif obj.equal?(NO_MORE_TOKENS)
|
393
|
+
raise HexaPDF::MalformedPDFError.new("Unclosed array found", pos: pos)
|
394
|
+
end
|
388
395
|
result << obj
|
389
396
|
end
|
390
397
|
result
|
@@ -403,7 +410,8 @@ module HexaPDF
|
|
403
410
|
key = next_token
|
404
411
|
break if key.equal?(TOKEN_DICT_END)
|
405
412
|
unless key.kind_of?(Symbol)
|
406
|
-
raise HexaPDF::MalformedPDFError.new("Dictionary keys must be PDF name objects
|
413
|
+
raise HexaPDF::MalformedPDFError.new("Dictionary keys must be PDF name objects, " \
|
414
|
+
"found '#{key}'", pos: pos)
|
407
415
|
end
|
408
416
|
|
409
417
|
val = next_object
|
data/lib/hexapdf/version.rb
CHANGED
@@ -161,6 +161,21 @@ module CommonTokenizerTests
|
|
161
161
|
assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
|
162
162
|
end
|
163
163
|
|
164
|
+
it "next_object: fails for an array without closing bracket, encountering EOS" do
|
165
|
+
create_tokenizer("[1 2")
|
166
|
+
exception = assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
|
167
|
+
assert_match(/Unclosed array found/, exception.message)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "next_object: fails for a dictionary without closing bracket, encountering EOS" do
|
171
|
+
create_tokenizer("<</Name 5")
|
172
|
+
exception = assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
|
173
|
+
assert_match(/must be PDF name objects.*EOS/, exception.message)
|
174
|
+
create_tokenizer("<</Name 5 /Other")
|
175
|
+
exception = assert_raises(HexaPDF::MalformedPDFError) { @tokenizer.next_object }
|
176
|
+
assert_match(/must be PDF name objects.*EOS/, exception.message)
|
177
|
+
end
|
178
|
+
|
164
179
|
it "returns the correct position on operations" do
|
165
180
|
create_tokenizer("hallo du" << " " * 50000 << "hallo du")
|
166
181
|
@tokenizer.next_token
|
@@ -73,10 +73,18 @@ describe HexaPDF::Content::ColorSpace do
|
|
73
73
|
assert_equal([0.2, 1, 0], @class.device_color_from_specification(51, 255, 0).components)
|
74
74
|
end
|
75
75
|
|
76
|
-
it "works for RGB values given as string" do
|
76
|
+
it "works for RGB values given as full hex string" do
|
77
77
|
assert_equal([0.2, 1, 0], @class.device_color_from_specification("33FF00").components)
|
78
78
|
end
|
79
79
|
|
80
|
+
it "works for RGB values given as half hex string" do
|
81
|
+
assert_equal([0.2, 1, 0], @class.device_color_from_specification("3F0").components)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "works for RGB values given as color names" do
|
85
|
+
assert_equal([0, 0, 1], @class.device_color_from_specification("blue").components)
|
86
|
+
end
|
87
|
+
|
80
88
|
it "works for CMYK values" do
|
81
89
|
assert_equal([0.51, 0.9, 1, 0.5],
|
82
90
|
@class.device_color_from_specification(51, 90, 100, 50).components)
|
@@ -85,6 +93,10 @@ describe HexaPDF::Content::ColorSpace do
|
|
85
93
|
it "works when an array is given" do
|
86
94
|
assert_equal([0.2], @class.device_color_from_specification([51]).components)
|
87
95
|
end
|
96
|
+
|
97
|
+
it "raises an error if an invalid color string is given" do
|
98
|
+
assert_raises(ArgumentError) { @class.device_color_from_specification("unknown") }
|
99
|
+
end
|
88
100
|
end
|
89
101
|
|
90
102
|
it "returns a device color object for prenormalized color values" do
|
@@ -242,4 +242,19 @@ describe HexaPDF::DictionaryFields do
|
|
242
242
|
doc.verify
|
243
243
|
end
|
244
244
|
end
|
245
|
+
|
246
|
+
describe "IntegerConverter" do
|
247
|
+
before do
|
248
|
+
@field = self.class::Field.new(Integer)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "no additional field types allowed" do
|
252
|
+
assert_equal([Integer], @field.type)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "allows conversion to an Integer from an equivalent Float value" do
|
256
|
+
refute_same(3, @field.convert(3.1, nil))
|
257
|
+
assert_same(3, @field.convert(3.0, nil))
|
258
|
+
end
|
259
|
+
end
|
245
260
|
end
|
data/test/hexapdf/test_parser.rb
CHANGED
@@ -113,13 +113,21 @@ describe HexaPDF::Parser do
|
|
113
113
|
assert_nil(object)
|
114
114
|
end
|
115
115
|
|
116
|
-
it "recovers from
|
116
|
+
it "recovers from a stream length value that doesn't reflect the correct length" do
|
117
117
|
create_parser("1 0 obj<</Length 4>> stream\n12endstream endobj")
|
118
118
|
obj, _, _, stream = @parser.parse_indirect_object
|
119
119
|
assert_equal(2, obj[:Length])
|
120
120
|
assert_equal('12', TestHelper.collector(stream.fiber))
|
121
121
|
end
|
122
122
|
|
123
|
+
it "recovers from an invalid stream length value" do
|
124
|
+
create_parser("1 0 obj<</Length 2 0 R>> stream\n12endstream endobj")
|
125
|
+
@document.add([5], oid: 2)
|
126
|
+
obj, _, _, stream = @parser.parse_indirect_object
|
127
|
+
assert_equal(2, obj[:Length])
|
128
|
+
assert_equal('12', TestHelper.collector(stream.fiber))
|
129
|
+
end
|
130
|
+
|
123
131
|
it "works even if the keyword endobj is missing or mangled" do
|
124
132
|
create_parser("1 0 obj<</Length 4>>5")
|
125
133
|
object, * = @parser.parse_indirect_object
|
@@ -619,7 +627,12 @@ describe HexaPDF::Parser do
|
|
619
627
|
assert_equal({Size: 1}, @parser.reconstructed_revision.trailer.value)
|
620
628
|
end
|
621
629
|
|
622
|
-
it "
|
630
|
+
it "constructs a trailer with a /Root entry if no valid trailer was found" do
|
631
|
+
create_parser("1 0 obj\n<</Type /Catalog/Pages 2 0 R>>\nendobj\nxref trailer <</Size 1/Prev 5\n%%EOF")
|
632
|
+
assert_equal({Root: HexaPDF::Reference.new(1, 0)}, @parser.reconstructed_revision.trailer.value)
|
633
|
+
end
|
634
|
+
|
635
|
+
it "fails if no valid trailer is found and couldn't be constructed" do
|
623
636
|
create_parser("1 0 obj\n5\nendobj\nquack trailer <</Size 1>>\nstartxref\n22\n%%EOF")
|
624
637
|
assert_raises(HexaPDF::MalformedPDFError) { @parser.reconstructed_revision.trailer }
|
625
638
|
end
|
data/test/hexapdf/test_writer.rb
CHANGED
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
|
|
40
40
|
219
|
41
41
|
%%EOF
|
42
42
|
3 0 obj
|
43
|
-
<</Producer(HexaPDF version 0.
|
43
|
+
<</Producer(HexaPDF version 0.16.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.
|
75
|
+
<</Producer(HexaPDF version 0.16.0)>>
|
76
76
|
endobj
|
77
77
|
2 0 obj
|
78
78
|
<</Length 10>>stream
|
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.16.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: 2021-
|
11
|
+
date: 2021-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cmdparse
|