diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-02-12 17:46:18 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-02-12 17:46:18 (GMT) |
commit | 505d8dc8bc999b995961dbd32c518620d843bdfe (patch) | |
tree | 675f802aa0010722ed2fbc3f0bacb0c804c37bfc /xlib | |
parent | 9ec06c1450bc3f4984cbee812e30d3c9bfc202b8 (diff) | |
download | tk-505d8dc8bc999b995961dbd32c518620d843bdfe.zip tk-505d8dc8bc999b995961dbd32c518620d843bdfe.tar.gz tk-505d8dc8bc999b995961dbd32c518620d843bdfe.tar.bz2 |
improved, faster implementations of XParseColor and TkParseColorbug_3486474
Diffstat (limited to 'xlib')
-rw-r--r-- | xlib/xcolors.c | 90 |
1 files changed, 26 insertions, 64 deletions
diff --git a/xlib/xcolors.c b/xlib/xcolors.c index 598f27b..7e88b2a 100644 --- a/xlib/xcolors.c +++ b/xlib/xcolors.c @@ -882,71 +882,33 @@ XParseColor(display, map, spec, colorPtr) XColor *colorPtr; { if (spec[0] == '#') { - char rstr[5], gstr[5], bstr[5]; + char *p; + Tcl_WideInt value = _strtoi64(++spec, &p, 16); - if (!isxdigit((unsigned char) spec[1]) - || !isxdigit((unsigned char) spec[2]) - || !isxdigit((unsigned char) spec[3])) { - /* Not at least 3 hex digits, so invalid */ - return 0; - } else if (!spec[4]) { - /* Exactly 3 hex digits */ - rstr[0] = rstr[1] = rstr[2] = rstr[3] = spec[1]; - gstr[0] = gstr[1] = gstr[2] = gstr[3] = spec[2]; - bstr[0] = bstr[1] = bstr[2] = bstr[3] = spec[3]; - } else if (!isxdigit((unsigned char) spec[4]) - || !isxdigit((unsigned char) spec[5]) - || !isxdigit((unsigned char) spec[6])) { - /* Not at least 6 hex digits, so invalid */ - return 0; - } else if (!spec[7]) { - /* Exactly 6 hex digits */ - rstr[0] = rstr[2] = spec[1]; - rstr[1] = rstr[3] = spec[2]; - gstr[0] = gstr[2] = spec[3]; - gstr[1] = gstr[3] = spec[4]; - bstr[0] = bstr[2] = spec[5]; - bstr[1] = bstr[3] = spec[6]; - } else if (!isxdigit((unsigned char) spec[7]) - || !isxdigit((unsigned char) spec[8]) - || !isxdigit((unsigned char) spec[9])) { - /* Not at least 9 hex digits, so invalid */ - return 0; - } else if (!spec[10]) { - /* Exactly 9 hex digits */ - rstr[0] = rstr[3] = spec[1]; - rstr[1] = spec[2]; - rstr[2] = spec[3]; - gstr[0] = gstr[3] = spec[4]; - gstr[1] = spec[5]; - gstr[2] = spec[6]; - bstr[0] = bstr[3] = spec[7]; - bstr[1] = spec[8]; - bstr[2] = spec[9]; - } else if (!isxdigit((unsigned char) spec[10]) - || !isxdigit((unsigned char) spec[11]) - || !isxdigit((unsigned char) spec[12]) || spec[13]) { - /* Not exactly 12 hex digits, so invalid */ - return 0; - } else { - /* Exactly 12 hex digits */ - rstr[0] = spec[1]; - rstr[1] = spec[2]; - rstr[2] = spec[3]; - rstr[3] = spec[4]; - gstr[0] = spec[5]; - gstr[1] = spec[6]; - gstr[2] = spec[7]; - gstr[3] = spec[8]; - bstr[0] = spec[9]; - bstr[1] = spec[10]; - bstr[2] = spec[11]; - bstr[3] = spec[12]; - } - rstr[4] = gstr[4] = bstr[4] = '\0'; - colorPtr->red = strtol(rstr, NULL, 16); - colorPtr->green = strtol(gstr, NULL, 16); - colorPtr->blue = strtol(bstr, NULL, 16); + switch ((int)(p-spec)) { + case 3: + colorPtr->red = (unsigned short) (((value >> 8) & 0xf) * 0x1111); + colorPtr->green = (unsigned short) (((value >> 4) & 0xf) * 0x1111); + colorPtr->blue = (unsigned short) ((value & 0xf) * 0x1111); + break; + case 6: + colorPtr->red = (unsigned short) (((value >> 16) & 0xff) | ((value >> 8) & 0xff00)); + colorPtr->green = (unsigned short) (((value >> 8) & 0xff) | (value & 0xff00)); + colorPtr->blue = (unsigned short) ((value & 0xff) | (value << 8)); + break; + case 9: + colorPtr->red = (unsigned short) (((value >> 32) & 0xf) | ((value >> 20) & 0xfff0)); + colorPtr->green = (unsigned short) (((value >> 20) & 0xf) | ((value >> 8) & 0xfff0)); + colorPtr->blue = (unsigned short) (((value >> 8) & 0xf) | (value << 4)); + break; + case 12: + colorPtr->red = (unsigned short) (value >> 32); + colorPtr->green = (unsigned short) (value >> 16); + colorPtr->blue = (unsigned short) value; + break; + default: + return 0; + } } else { if (!FindColor(spec, colorPtr)) { return 0; |