|
28 | 28 | Finally, legal html names for colors, like 'red', 'burlywood' and |
29 | 29 | 'chartreuse' are supported. |
30 | 30 | """ |
| 31 | +import re |
31 | 32 |
|
32 | 33 | from numerix import array, arange, take, put, Float, Int, where, \ |
33 | 34 | zeros, asarray, sort, searchsorted, sometrue, ravel, divide |
@@ -336,10 +337,14 @@ def rgb2hex(rgb): |
336 | 337 | 'Given a len 3 rgb tuple of 0-1 floats, return the hex string' |
337 | 338 | return '#%02x%02x%02x' % tuple([round(val*255) for val in rgb]) |
338 | 339 |
|
| 340 | +hexColorPattern = re.compile("\A#[a-fA-F0-9]{6}\Z") |
| 341 | + |
339 | 342 | def hex2color(s): |
340 | | - "Convert hex string (like html uses, eg, #efefef) to a r,g,b tuple" |
341 | | - if s[0]!='#' or len(s)!=7: |
342 | | - raise ValueError('s must be a hex string like "#efefef"') |
| 343 | + "Convert hex string 's' (like html uses, eg, #efefef) to a r,g,b tuple" |
| 344 | + if not isinstance(s, str): |
| 345 | + raise TypeError('hex2color requires a string argument') |
| 346 | + if not hexColorPattern.match(s): |
| 347 | + raise ValueError('invalid hex color string "%s"' % s) |
343 | 348 | return tuple([int(n, 16)/255.0 for n in (s[1:3], s[3:5], s[5:7])]) |
344 | 349 |
|
345 | 350 | class ColorConverter: |
@@ -368,28 +373,29 @@ def to_rgb(self, arg): |
368 | 373 | try: self.cache[arg] |
369 | 374 | except KeyError: pass |
370 | 375 |
|
371 | | - color = None |
372 | | - try: float(arg) |
373 | | - except: |
| 376 | + try: |
374 | 377 | if is_string_like(arg): |
375 | | - hex = cnames.get(arg) |
376 | | - if hex is not None: arg = hex |
377 | | - if len(arg)==7 and arg[0]=='#': |
378 | | - color = hex2color(arg) |
379 | | - if color is None: |
380 | | - # see if it looks like rgb. If so, just return arg |
381 | | - try: float(arg[2]) |
382 | | - except: color = self.colors.get(arg, (0.0, 0.0, 0.0)) |
383 | | - else: color = tuple(arg) |
384 | | - else: |
385 | | - if arg>=0 and arg<=1: |
386 | | - color = (arg,arg,arg) |
387 | | - else: |
388 | | - msg = 'Floating point color arg must be between 0 and 1\n' +\ |
389 | | - 'Found %1.2f' % arg |
390 | | - raise RuntimeError(msg) |
391 | | - |
392 | | - self.cache[arg] = color |
| 378 | + str1 = cnames.get(arg, arg) |
| 379 | + if str1.startswith('#'): |
| 380 | + color = hex2color(str1) |
| 381 | + else: |
| 382 | + color = self.colors[arg] |
| 383 | + elif isinstance(arg, float): |
| 384 | + if 0<=arg<=1: |
| 385 | + color = (arg,arg,arg) |
| 386 | + else: |
| 387 | + raise ValueError('Floating point color arg must be between 0 and 1') |
| 388 | + else: # assume tuple (or list) |
| 389 | + assert isinstance(arg[2], (float,int)) |
| 390 | + color = tuple(arg[:3]) |
| 391 | + |
| 392 | + self.cache[arg] = color # raise exception if color not set |
| 393 | + |
| 394 | + except KeyError: |
| 395 | + raise ValueError('to_rgb: Invalid rgb arg "%s"' % (str(arg))) |
| 396 | + except Exception, exc: |
| 397 | + raise ValueError('to_rgb: Invalid rgb arg "%s"\n%s' % (str(arg), exc)) |
| 398 | + |
393 | 399 | return color |
394 | 400 |
|
395 | 401 | def to_rgba(self, arg, alpha=1.0): |
|
0 commit comments