diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-02-15 21:09:27 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2012-02-15 21:09:27 (GMT) |
commit | 41cc9023c9d8ba470b41666d54cfe4db9bbb5020 (patch) | |
tree | c95bfcb0f17783a66f7d2613c8962ecbd1a63748 | |
parent | da13c5e294143c51bdee3d5d9f42c72b1843dc51 (diff) | |
parent | 3db9fce4a20b8969cd5c73671c76dd4918d048f9 (diff) | |
download | tk-41cc9023c9d8ba470b41666d54cfe4db9bbb5020.zip tk-41cc9023c9d8ba470b41666d54cfe4db9bbb5020.tar.gz tk-41cc9023c9d8ba470b41666d54cfe4db9bbb5020.tar.bz2 |
[Bug 3486474]: Inconsistent color scaling
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | carbon/tkMacOSXColor.c | 2 | ||||
-rw-r--r-- | doc/GetColor.3 | 5 | ||||
-rw-r--r-- | generic/tkColor.c | 73 | ||||
-rw-r--r-- | generic/tkCursor.c | 4 | ||||
-rw-r--r-- | generic/tkImgBmap.c | 4 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 2 | ||||
-rw-r--r-- | generic/tkInt.h | 8 | ||||
-rw-r--r-- | generic/tkStubInit.c | 6 | ||||
-rw-r--r-- | macosx/tkMacOSXColor.c | 2 | ||||
-rw-r--r-- | unix/tkUnixColor.c | 2 | ||||
-rw-r--r-- | unix/tkUnixCursor.c | 10 | ||||
-rw-r--r-- | win/tkWinColor.c | 2 | ||||
-rw-r--r-- | xlib/xcolors.c | 39 |
14 files changed, 134 insertions, 32 deletions
@@ -1,3 +1,10 @@ +2012-02-15 Jan Nijtmans <nijtmans@users.sf.net> + + * xlib/xcolors.c: [Bug 3486474]: Inconsistent color scaling + * generic/tkColor.c: new internal function TkParseColor + * generic/tkInt.h: + * generic/tk*.c: Change XParseColor() to TkParseColor() everywhere. + 2012-02-10 Donal K. Fellows <dkf@users.sf.net> * win/tkWinDialog.c (GetFileName): Ensure that we do not convert a diff --git a/carbon/tkMacOSXColor.c b/carbon/tkMacOSXColor.c index 3217c69..2c9100d 100644 --- a/carbon/tkMacOSXColor.c +++ b/carbon/tkMacOSXColor.c @@ -591,7 +591,7 @@ TkpGetColor( } } - if (XParseColor(display, colormap, name, &color) == 0) { + if (TkParseColor(display, colormap, name, &color) == 0) { return NULL; } diff --git a/doc/GetColor.3 b/doc/GetColor.3 index f41a87a..5b7a553 100644 --- a/doc/GetColor.3 +++ b/doc/GetColor.3 @@ -86,8 +86,9 @@ to use to display the color. Each \fIR\fR, \fIG\fR, or \fIB\fR represents a single hexadecimal digit. The four forms permit colors to be specified with 4-bit, 8-bit, 12-bit or 16-bit values. When fewer than 16 bits are provided for each color, they represent -the most significant bits of the color. For example, #3a7 is the -same as #3000a0007000. +the most significant bits of the color, while the lower unfilled +bits will be repeatedly replicated from the available higher bits. +For example, #3a7 is the same as #3333aaaa7777. .PP \fBTk_AllocColorFromObj\fR returns a pointer to an XColor structure; the structure indicates the exact intensities of diff --git a/generic/tkColor.c b/generic/tkColor.c index 168664c..db649d3 100644 --- a/generic/tkColor.c +++ b/generic/tkColor.c @@ -371,6 +371,23 @@ Tk_NameOfColor( sprintf(tsdPtr->rgbString, "#%04x%04x%04x", colorPtr->red, colorPtr->green, colorPtr->blue); + + /* If the string has the form #RSRSTUTUVWVW (where equal + * letters denote equal hexdigits) then this is + * equivalent to #RSTUVW. Then output the shorter form. + */ + if ((tsdPtr->rgbString[1] == tsdPtr->rgbString[3]) + && (tsdPtr->rgbString[2] == tsdPtr->rgbString[4]) + && (tsdPtr->rgbString[5] == tsdPtr->rgbString[7]) + && (tsdPtr->rgbString[6] == tsdPtr->rgbString[8]) + && (tsdPtr->rgbString[9] == tsdPtr->rgbString[11]) + && (tsdPtr->rgbString[10] == tsdPtr->rgbString[12])) { + tsdPtr->rgbString[3] = tsdPtr->rgbString[5]; + tsdPtr->rgbString[4] = tsdPtr->rgbString[6]; + tsdPtr->rgbString[5] = tsdPtr->rgbString[9]; + tsdPtr->rgbString[6] = tsdPtr->rgbString[10]; + tsdPtr->rgbString[7] = '\0'; + } return tsdPtr->rgbString; } } @@ -807,7 +824,61 @@ TkDebugColor( } return resultPtr; } - + +#ifndef __WIN32__ +/* This function is not necessary for Win32, + * since XParseColor already does the right thing */ +Status +TkParseColor( + Display * display, /* The display */ + Colormap map, /* Color map */ + _Xconst char* spec, /* String to be parsed */ + XColor * colorPtr) +{ + if (*spec == '#') { + char buf[14]; + buf[0] = '#'; buf[13] = '\0'; + if (!*(++spec) || !*(++spec) || !*(++spec)) { + /* Not at least 3 hex digits, so invalid */ + return 0; + } else if (!*(++spec)) { + /* Exactly 3 hex digits */ + buf[9] = buf[10] = buf[11] = buf[12] = *(--spec); + buf[5] = buf[6] = buf[7] = buf[8] = *(--spec); + buf[1] = buf[2] = buf[3] = buf[4] = *(--spec); + spec = buf; + } else if (!*(++spec) || !*(++spec)) { + /* Not at least 6 hex digits, so invalid */ + return 0; + } else if (!*(++spec)) { + /* Exactly 6 hex digits */ + buf[10] = buf[12] = *(--spec); + buf[9] = buf[11] = *(--spec); + buf[6] = buf[8] = *(--spec); + buf[5] = buf[7] = *(--spec); + buf[2] = buf[4] = *(--spec); + buf[1] = buf[3] = *(--spec); + spec = buf; + } else if (!*(++spec) || !*(++spec)) { + /* Not at least 9 hex digits, so invalid */ + return 0; + } else if (!*(++spec)) { + /* Exactly 9 hex digits */ + buf[11] = *(--spec); + buf[10] = *(--spec); + buf[9] = buf[12] = *(--spec); + buf[7] = *(--spec); + buf[6] = *(--spec); + buf[5] = buf[8] = *(--spec); + buf[3] = *(--spec); + buf[2] = *(--spec); + buf[1] = buf[4] = *(--spec); + spec = buf; + } + } + return XParseColor(display, map, spec, colorPtr); +} +#endif /* __WIN32__ */ /* * Local Variables: * mode: c diff --git a/generic/tkCursor.c b/generic/tkCursor.c index 54184b3..2bbf861 100644 --- a/generic/tkCursor.c +++ b/generic/tkCursor.c @@ -351,11 +351,11 @@ Tk_GetCursorFromData( * add it to the database. */ - if (XParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) { + if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), fg, &fgColor) == 0) { Tcl_AppendResult(interp, "invalid color name \"", fg, "\"", NULL); goto error; } - if (XParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) { + if (TkParseColor(dataKey.display, Tk_Colormap(tkwin), bg, &bgColor) == 0) { Tcl_AppendResult(interp, "invalid color name \"", bg, "\"", NULL); goto error; } diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index 87c6283..82374cb 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -1247,7 +1247,7 @@ ImgBmapPostscript( if ((masterPtr->bgUid != NULL) && (masterPtr->bgUid[0] != '\000')) { XColor color; - XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid, + TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->bgUid, &color); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { return TCL_ERROR; @@ -1269,7 +1269,7 @@ ImgBmapPostscript( if ((masterPtr->fgUid != NULL) && (masterPtr->data != NULL)) { XColor color; - XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid, + TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), masterPtr->fgUid, &color); if (Tk_PostscriptColor(interp, psinfo, &color) != TCL_OK) { return TCL_ERROR; diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 7d8bf0d..5b172f1 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -918,7 +918,7 @@ ImgPhotoCmd( } } - if (!XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), + if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), colorString, &color)) { Tcl_AppendResult(interp, "can't parse color \"", colorString, "\"", NULL); diff --git a/generic/tkInt.h b/generic/tkInt.h index 51bc896..4faf908 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1211,6 +1211,14 @@ MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +#ifdef __WIN32__ +#define TkParseColor XParseColor +#else +MODULE_SCOPE Status TkParseColor (Display * display, + Colormap map, _Xconst char* spec, + XColor * colorPtr); +#endif + /* * Unsupported commands. */ diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 2b87360..c62d143 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -44,6 +44,12 @@ MODULE_SCOPE const TkStubs tkStubs; #undef Tk_MainEx +#ifndef __WIN32__ +/* Make sure that extensions which call XParseColor through + * the stub table, call TkParseColor in stead. See bug #3486474 */ +# define XParseColor TkParseColor +#endif + /* !BEGIN!: Do not edit below this line. */ static const TkIntStubs tkIntStubs = { diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c index 3cd7c66..ebbaec2 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -606,7 +606,7 @@ TkpGetColor( } } - if (XParseColor(display, colormap, name, &color) == 0) { + if (TkParseColor(display, colormap, name, &color) == 0) { return NULL; } diff --git a/unix/tkUnixColor.c b/unix/tkUnixColor.c index afa9d24..df754bd 100644 --- a/unix/tkUnixColor.c +++ b/unix/tkUnixColor.c @@ -166,7 +166,7 @@ TkpGetColor( FindClosestColor(tkwin, &screen, &color); } } else { - if (XParseColor(display, colormap, buf, &color) == 0) { + if (TkParseColor(display, colormap, buf, &color) == 0) { return NULL; } if (XAllocColor(display, colormap, &color) != 0) { diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c index 1603ee3..bbf5206 100644 --- a/unix/tkUnixCursor.c +++ b/unix/tkUnixCursor.c @@ -274,7 +274,7 @@ TkGetCursorByName( fg.red = fg.green = fg.blue = 0; bg.red = bg.green = bg.blue = 65535; } else { - if (XParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) { + if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[1], "\"", NULL); goto cleanup; @@ -282,7 +282,7 @@ TkGetCursorByName( if (argc == 2) { bg.red = bg.green = bg.blue = 0; maskIndex = namePtr->shape; - } else if (XParseColor(display, Tk_Colormap(tkwin), argv[2], + } else if (TkParseColor(display, Tk_Colormap(tkwin), argv[2], &bg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[2], "\"", NULL); @@ -456,7 +456,7 @@ CreateCursorFromTableOrFile( bg.red = bg.green = bg.blue = 65535; } else if (argc == 2) { fgColor = argv[1]; - if (XParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { + if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", fgColor, "\"", NULL); goto cleanup; @@ -475,12 +475,12 @@ CreateCursorFromTableOrFile( fgColor = argv[2]; bgColor = argv[3]; } - if (XParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { + if (TkParseColor(display, Tk_Colormap(tkwin), fgColor, &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", fgColor, "\"", NULL); goto cleanup; } - if (XParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) { + if (TkParseColor(display, Tk_Colormap(tkwin), bgColor, &bg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", bgColor, "\"", NULL); goto cleanup; diff --git a/win/tkWinColor.c b/win/tkWinColor.c index 0057573..d93143d 100644 --- a/win/tkWinColor.c +++ b/win/tkWinColor.c @@ -180,7 +180,7 @@ TkpGetColor( if (((strncasecmp(name, "system", 6) == 0) && FindSystemColor(name+6, &color, &index)) - || XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name, + || TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), name, &color)) { winColPtr = ckalloc(sizeof(WinColor)); winColPtr->info.color = color; diff --git a/xlib/xcolors.c b/xlib/xcolors.c index be9e479..0f3085c 100644 --- a/xlib/xcolors.c +++ b/xlib/xcolors.c @@ -879,24 +879,33 @@ XParseColor( XColor *colorPtr) { if (spec[0] == '#') { - char fmt[16]; - int i, red, green, blue; + char *p; + Tcl_WideInt value = _strtoi64(++spec, &p, 16); - if ((i = (int) strlen(spec+1))%3) { - return 0; - } - i /= 3; - - sprintf(fmt, "%%%dx%%%dx%%%dx", i, i, i); - if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) { + 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; } - colorPtr->red = (((unsigned short) red) << (4 * (4 - i))) - | ((unsigned short) red); - colorPtr->green = (((unsigned short) green) << (4 * (4 - i))) - | ((unsigned short) green); - colorPtr->blue = (((unsigned short) blue) << (4 * (4 - i))) - | ((unsigned short) blue); } else { if (!FindColor(spec, colorPtr)) { return 0; |