hexapdf 0.15.9 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 24d17dfd6c8dc9e3f7014e1ea769dede6f8cea81529bb201a8447f21873d3b25
4
- data.tar.gz: 7165a2e11983731ba2597d2e4a824415abc96936d2b58f3fb737a4fed94dcf16
3
+ metadata.gz: 5b2303787fd50c2407bb99336c3315643c4a9401a84a508462715d18a378788c
4
+ data.tar.gz: 675bb953973762670c598f93ed15fcaa4387f962c0cbdc9d27060bd06de4f5ae
5
5
  SHA512:
6
- metadata.gz: 244332a4f024c90cf6344b462ed422a5f73b32d3a4d04d0dcdadc6e7ede2cd0724f7a3329fa3aad68c99e47f49a9dff66806d9b8b152b9551eaecd7365c807d4
7
- data.tar.gz: 06c4b9fd5ecd8f045a37e85ce4a6539f52b48bb16fb685290bcc2a0210b5f2e66bcfa9b7efb1115c45dd1618de9421c479d7a66d84556d1b9c37b19b1f8b6075
6
+ metadata.gz: 81715891b39fc35606baae317fc44a4be4d7710b2a1488f682425620771c2b563ecdfa8ba8ff0028a5226904d511c79b9507c1fed7170fdfd2c7a29aa4706127
7
+ data.tar.gz: f24fb2cdd07da0c2afde7511c40880e66fd65d87d2fd6035524202fbf8f1040d1e64576b3b080f6aa0d006d5938fc61c399c062d8687b33b3f3a5e9966b3917d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
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
+
1
10
  ## 0.15.9 - 2021-09-04
2
11
 
3
12
  ### Fixed
@@ -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": {variant: file_name, variant2: file_name2, ...}, ...}
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
- resources.color_space(:DeviceRGB).color(*spec[0].scan(/../).map!(&:hex))
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
- spec = spec[0].scan(/../).map!(&:hex) if spec.length == 1 && spec[0].kind_of?(String)
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
 
@@ -37,6 +37,6 @@
37
37
  module HexaPDF
38
38
 
39
39
  # The version of HexaPDF.
40
- VERSION = '0.15.9'
40
+ VERSION = '0.16.0'
41
41
 
42
42
  end
@@ -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
@@ -40,7 +40,7 @@ describe HexaPDF::Writer do
40
40
  219
41
41
  %%EOF
42
42
  3 0 obj
43
- <</Producer(HexaPDF version 0.15.9)>>
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.15.9)>>
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.15.9
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-09-04 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cmdparse