diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2012-12-06 10:49:51 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2012-12-06 10:49:51 (GMT) |
commit | f5d2d3ec431795a33448cb6c1b16bfd3dce8703e (patch) | |
tree | 4383630aee6a63b6d705aae37afef300c8f948e0 /xlib | |
parent | da50f34ecbf4db62aacd90cbd9a7f9788d72110b (diff) | |
download | tk-f5d2d3ec431795a33448cb6c1b16bfd3dce8703e.zip tk-f5d2d3ec431795a33448cb6c1b16bfd3dce8703e.tar.gz tk-f5d2d3ec431795a33448cb6c1b16bfd3dce8703e.tar.bz2 |
Force the use of the correct internal function for parsing hex colors rather
than leaving it to the vagaries of the system library (buggy on some versions
of MinGW apparently).
Diffstat (limited to 'xlib')
-rwxr-xr-x | xlib/xcolors.c | 149 |
1 files changed, 64 insertions, 85 deletions
diff --git a/xlib/xcolors.c b/xlib/xcolors.c index 70ab3cb..2c99c5d 100755 --- a/xlib/xcolors.c +++ b/xlib/xcolors.c @@ -14,11 +14,14 @@ #include "tkInt.h" /* - * Index array. For each of the characters 'a'-'y', this table gives the first color - * starting with that character in the xColors table. + * Index array. For each of the characters 'a'-'y', this table gives the first + * color starting with that character in the xColors table. */ -static const unsigned char az[] = {0, 5, 13, 21, 45, 46, 50, 60, 62, 65, 66, - 67, 91, 106, 109, 115, 126, 127, 130, 144, 149, 150, 152, 155, 156, 158}; + +static const unsigned char az[] = { + 0, 5, 13, 21, 45, 46, 50, 60, 62, 65, 66, + 67, 91, 106, 109, 115, 126, 127, 130, 144, 149, 150, 152, 155, 156, 158 +}; /* * Define an array that defines the mapping from color names to RGB values. @@ -241,15 +244,18 @@ static const elem xColors[] = { * None. * *---------------------------------------------------------------------- + * + * This only handles hex-strings without 0x prefix. Luckily, that's just what + * we need. */ -#if defined(__WIN32__) && !defined(__CYGWIN__) -# ifdef NO_STRTOI64 -/* This version only handles hex-strings without 0x prefix */ -static __int64 -_strtoi64(const char *spec, char **p, int base) +static Tcl_WideInt +parseHex64bit( + const char *spec, + char **p, + int base) { - __int64 result = 0; + Tcl_WideInt result = 0; char c; while ((c = *spec)) { if ((c >= '0') && (c <= '9')) { @@ -267,16 +273,18 @@ _strtoi64(const char *spec, char **p, int base) *p = (char *) spec; return result; } -# endif -#else -# define _strtoi64 strtoll -#endif -static int colorcmp(const char *spec, const char *pname, int *special) { +static int +colorcmp( + const char *spec, + const char *pname, + int *special) +{ int r; int c, d; int notequal = 0; int num = 0; + do { d = *pname++; c = (*spec == ' '); @@ -286,9 +294,12 @@ static int colorcmp(const char *spec, const char *pname, int *special) { if ((unsigned)(d - 'A') <= (unsigned)('Z' - 'A')) { d += 'a' - 'A'; } else if (c) { - /* A space doesn't match a lowercase, but we don't know - * yet whether we should return a negative or positive - * number. That depends on what follows. */ + /* + * A space doesn't match a lowercase, but we don't know yet + * whether we should return a negative or positive number. That + * depends on what follows. + */ + notequal = 1; } c = *spec++; @@ -305,19 +316,24 @@ static int colorcmp(const char *spec, const char *pname, int *special) { } } r = c - d; - } while(!r && d); + } while (!r && d); + if (!r && notequal) { - /* Strings are equal, but difference in spacings only. We should still - * report not-equal, so "burly wood" is not a valid color */ + /* + * Strings are equal, but difference in spacings only. We should still + * report not-equal, so "burly wood" is not a valid color. + */ + r = 1; } *special = num; return r; } -#define RED(p) ((unsigned char)(p)[0]) -#define GREEN(p) ((unsigned char)(p)[1]) -#define BLUE(p) ((unsigned char)(p)[2]) +#define RED(p) ((unsigned char) (p)[0]) +#define GREEN(p) ((unsigned char) (p)[1]) +#define BLUE(p) ((unsigned char) (p)[2]) +#define US(expr) ((unsigned short) (expr)) Status XParseColor( @@ -328,42 +344,44 @@ XParseColor( { if (spec[0] == '#') { char *p; - Tcl_WideInt value = _strtoi64(++spec, &p, 16); + Tcl_WideInt value = parseHex64bit(++spec, &p, 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); + colorPtr->red = US(((value >> 8) & 0xf) * 0x1111); + colorPtr->green = US(((value >> 4) & 0xf) * 0x1111); + colorPtr->blue = US((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)); + colorPtr->red = US(((value >> 16) & 0xff) | ((value >> 8) & 0xff00)); + colorPtr->green = US(((value >> 8) & 0xff) | (value & 0xff00)); + colorPtr->blue = US((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)); + colorPtr->red = US(((value >> 32) & 0xf) | ((value >> 20) & 0xfff0)); + colorPtr->green = US(((value >> 20) & 0xf) | ((value >> 8) & 0xfff0)); + colorPtr->blue = US(((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; + colorPtr->red = US(value >> 32); + colorPtr->green = US(value >> 16); + colorPtr->blue = US(value); break; default: return 0; } } else { - int size, num; - const elem *p; - const char *q; /* * Perform a binary search on the sorted array of colors. * size = current size of search range * p = pointer to current element being considered. */ + + int size, num; + const elem *p; + const char *q; int r = (spec[0] - 'A') & 0xdf; + if (r >= (int) sizeof(az) - 1) { return 0; } @@ -386,11 +404,15 @@ XParseColor( r = colorcmp(spec + 1, *p, &num); } if (num > (*p)[31]) { - if (((*p)[31] != 8) || num > 100) + if (((*p)[31] != 8) || num > 100) { return 0; + } num = (num * 255 + 50) / 100; if ((num == 230) || (num == 128)) { - /* Those two entries have a deviation i.r.t the table */ + /* + * Those two entries have a deviation i.r.t the table. + */ + num--; } num |= (num << 8); @@ -408,49 +430,6 @@ XParseColor( return 1; } - -#if 0 -int main() { - XColor color; - char buf[32]; - int charindex; - int i, result; - int repeat = 1; - int num, maxnum; - char *end; - - while (repeat--) { - buf[0] = 'a'; - charindex = 1; - for (i = 0; i < sizeof(xColors)/sizeof(xColors[0]); ++i) { - while (i >= az[charindex]) { - ++charindex; - ++(buf[0]); - } - strcpy(buf + 1, xColors[i]); - end = buf + strlen(buf); - num = 0; - result = XParseColor(0, 0, buf, &color); - printf("%3d %3d %3d\t\t%s\n", color.red >> 8, color.green >> 8, color.blue >> 8, buf); - maxnum = xColors[i][31]; - if (maxnum == 8) maxnum = 100; - while (result && ++num <= maxnum) { - sprintf(end, "%d", num); - result = XParseColor(0, 0, buf, &color); - printf("%3d %3d %3d\t\t%s\n", color.red >> 8, color.green >> 8, color.blue >> 8, buf); - } - if (!result) { - break; - } - } - } - if (!result) { - printf("NOT OK: %s\n", buf); - } else { - printf("OK\n"); - } -} -#endif /* * Local Variables: * mode: c |