summaryrefslogtreecommitdiffstats
path: root/xlib/xcolors.c
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-12 17:46:18 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2012-02-12 17:46:18 (GMT)
commit505d8dc8bc999b995961dbd32c518620d843bdfe (patch)
tree675f802aa0010722ed2fbc3f0bacb0c804c37bfc /xlib/xcolors.c
parent9ec06c1450bc3f4984cbee812e30d3c9bfc202b8 (diff)
downloadtk-505d8dc8bc999b995961dbd32c518620d843bdfe.zip
tk-505d8dc8bc999b995961dbd32c518620d843bdfe.tar.gz
tk-505d8dc8bc999b995961dbd32c518620d843bdfe.tar.bz2
improved, faster implementations of XParseColor and TkParseColorbug_3486474
Diffstat (limited to 'xlib/xcolors.c')
-rw-r--r--xlib/xcolors.c90
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;