diff options
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | doc/GetColor.3 | 5 | ||||
-rw-r--r-- | generic/tkColor.c | 55 | ||||
-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 | 7 | ||||
-rw-r--r-- | generic/tkStubInit.c | 6 | ||||
-rw-r--r-- | mac/tkMacColor.c | 2 | ||||
-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, 116 insertions, 31 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-01-25 Jan Nijtmans <nijtmans@users.sf.net> * generic/tkImgPhoto.c: [Bug 2433260]: non-critical error in diff --git a/doc/GetColor.3 b/doc/GetColor.3 index 201edab..abd1620 100644 --- a/doc/GetColor.3 +++ b/doc/GetColor.3 @@ -95,8 +95,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 .VS 8.1 \fBTk_AllocColorFromObj\fR returns a pointer to diff --git a/generic/tkColor.c b/generic/tkColor.c index f06c43f..8893dfe 100644 --- a/generic/tkColor.c +++ b/generic/tkColor.c @@ -809,3 +809,58 @@ TkDebugColor(tkwin, name) } return resultPtr; } + +#ifndef __WIN32__ +/* This function is not necessary for Win32, + * since XParseColor already does the right thing */ +Status +TkParseColor(display, map, spec, colorPtr) + 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__ */ diff --git a/generic/tkCursor.c b/generic/tkCursor.c index 466d0ef..f599083 100644 --- a/generic/tkCursor.c +++ b/generic/tkCursor.c @@ -357,12 +357,12 @@ Tk_GetCursorFromData(interp, tkwin, source, mask, width, height, * available and 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, "\"", (char *) 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, "\"", (char *) NULL); goto error; diff --git a/generic/tkImgBmap.c b/generic/tkImgBmap.c index 99ae050..e1ccecb 100644 --- a/generic/tkImgBmap.c +++ b/generic/tkImgBmap.c @@ -1266,7 +1266,7 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height, */ 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; @@ -1286,7 +1286,7 @@ ImgBmapPostscript(clientData, interp, tkwin, psinfo, x, y, width, height, */ 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 80b44d7..ffbb47c 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -1150,7 +1150,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) break; } for (x = 0; x < dataWidth; ++x) { - if (!XParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), + if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), listArgv[x], &color)) { Tcl_AppendResult(interp, "can't parse color \"", listArgv[x], "\"", (char *) NULL); diff --git a/generic/tkInt.h b/generic/tkInt.h index 777201e..c274236 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1213,6 +1213,13 @@ EXTERN int TkParsePadAmount _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *pad1Ptr, int *pad2Ptr)); EXTERN int TkpAlwaysShowSelection _ANSI_ARGS_((Tk_Window tkwin)); +#ifdef __WIN32__ +#define TkParseColor XParseColor +#else +EXTERN Status TkParseColor _ANSI_ARGS_((Display * display, + Colormap map, _Xconst char* spec, + XColor * colorPtr)); +#endif /* * Unsupported commands. diff --git a/generic/tkStubInit.c b/generic/tkStubInit.c index 6df1f2d..a82e044 100644 --- a/generic/tkStubInit.c +++ b/generic/tkStubInit.c @@ -46,6 +46,12 @@ #define Tk_GetCanvasVisitor ((VOID * (*) _ANSI_ARGS_((Tcl_Interp * interp, \ CONST char * name))) NULL) +#ifndef __WIN32__ +/* Make sure that extensions which call XParseColor through + * the stub table, call TkParseColor in stead. See bug #3486474 */ +# define XParseColor TkParseColor +#endif + /* * WARNING: The contents of this file is automatically generated by the * tools/genStubs.tcl script. Any modifications to the function declarations diff --git a/mac/tkMacColor.c b/mac/tkMacColor.c index 6fd0263..6c3c230 100644 --- a/mac/tkMacColor.c +++ b/mac/tkMacColor.c @@ -274,7 +274,7 @@ TkpGetColor( } } - if (XParseColor(display, colormap, name, &color) == 0) { + if (TkParseColor(display, colormap, name, &color) == 0) { return (TkColor *) NULL; } diff --git a/macosx/tkMacOSXColor.c b/macosx/tkMacOSXColor.c index 6ddb95e..9520a77 100644 --- a/macosx/tkMacOSXColor.c +++ b/macosx/tkMacOSXColor.c @@ -591,7 +591,7 @@ TkpGetColor( } } - if (XParseColor(display, colormap, name, &color) == 0) { + if (TkParseColor(display, colormap, name, &color) == 0) { return (TkColor *) NULL; } diff --git a/unix/tkUnixColor.c b/unix/tkUnixColor.c index d001be5..aebbbca 100644 --- a/unix/tkUnixColor.c +++ b/unix/tkUnixColor.c @@ -168,7 +168,7 @@ TkpGetColor(tkwin, name) FindClosestColor(tkwin, &screen, &color); } } else { - if (XParseColor(display, colormap, buf, &color) == 0) { + if (TkParseColor(display, colormap, buf, &color) == 0) { return (TkColor *) NULL; } if (XAllocColor(display, colormap, &color) != 0) { diff --git a/unix/tkUnixCursor.c b/unix/tkUnixCursor.c index 70e8b93..a4ee0cb 100644 --- a/unix/tkUnixCursor.c +++ b/unix/tkUnixCursor.c @@ -194,7 +194,7 @@ TkGetCursorByName(interp, tkwin, string) fg.red = fg.green = fg.blue = 0; bg.red = bg.green = bg.blue = 65535; } else { - if (XParseColor(display, Tk_Colormap(tkwin), argv[1], + if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[1], "\"", (char *) NULL); @@ -204,7 +204,7 @@ TkGetCursorByName(interp, tkwin, string) bg.red = bg.green = bg.blue = 0; maskIndex = namePtr->shape; } else { - if (XParseColor(display, Tk_Colormap(tkwin), argv[2], + if (TkParseColor(display, Tk_Colormap(tkwin), argv[2], &bg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[2], "\"", (char *) NULL); @@ -262,7 +262,7 @@ TkGetCursorByName(interp, tkwin, string) goto cleanup; } if (argc == 2) { - if (XParseColor(display, Tk_Colormap(tkwin), argv[1], + if (TkParseColor(display, Tk_Colormap(tkwin), argv[1], &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[1], "\"", (char *) NULL); @@ -285,13 +285,13 @@ TkGetCursorByName(interp, tkwin, string) TCL_STATIC); goto cleanup; } - if (XParseColor(display, Tk_Colormap(tkwin), argv[2], + if (TkParseColor(display, Tk_Colormap(tkwin), argv[2], &fg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[2], "\"", (char *) NULL); goto cleanup; } - if (XParseColor(display, Tk_Colormap(tkwin), argv[3], + if (TkParseColor(display, Tk_Colormap(tkwin), argv[3], &bg) == 0) { Tcl_AppendResult(interp, "invalid color name \"", argv[3], "\"", (char *) NULL); diff --git a/win/tkWinColor.c b/win/tkWinColor.c index d3b3cad..088c216 100644 --- a/win/tkWinColor.c +++ b/win/tkWinColor.c @@ -201,7 +201,7 @@ TkpGetColor(tkwin, name) 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 = (WinColor *) ckalloc(sizeof(WinColor)); winColPtr->info.color = color; diff --git a/xlib/xcolors.c b/xlib/xcolors.c index 32c53bd..7e88b2a 100644 --- a/xlib/xcolors.c +++ b/xlib/xcolors.c @@ -882,24 +882,33 @@ XParseColor(display, map, spec, colorPtr) 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; |