hexapdf 0.15.9 → 0.16.0

Sign up to get free protection for your applications and to get access to all the features.
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