|
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