diff options
Diffstat (limited to 'generic/tkColor.c')
-rw-r--r-- | generic/tkColor.c | 110 |
1 files changed, 73 insertions, 37 deletions
diff --git a/generic/tkColor.c b/generic/tkColor.c index 76d0baa..9abb448 100644 --- a/generic/tkColor.c +++ b/generic/tkColor.c @@ -42,6 +42,7 @@ static Tcl_ThreadDataKey dataKey; static void ColorInit(TkDisplay *dispPtr); static void DupColorObjProc(Tcl_Obj *srcObjPtr,Tcl_Obj *dupObjPtr); +static void FreeColorObj(Tcl_Obj *objPtr); static void FreeColorObjProc(Tcl_Obj *objPtr); static void InitColorObj(Tcl_Obj *objPtr); @@ -51,7 +52,7 @@ static void InitColorObj(Tcl_Obj *objPtr); * of the Tcl_Obj points to a TkColor object. */ -Tcl_ObjType tkColorObjType = { +const Tcl_ObjType tkColorObjType = { "color", /* name */ FreeColorObjProc, /* freeIntRepProc */ DupColorObjProc, /* dupIntRepProc */ @@ -111,7 +112,7 @@ Tk_AllocColorFromObj( * longer in use. Clear the reference. */ - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); tkColPtr = NULL; } else if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { @@ -129,14 +130,14 @@ Tk_AllocColorFromObj( if (tkColPtr != NULL) { TkColor *firstColorPtr = Tcl_GetHashValue(tkColPtr->hashPtr); - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); for (tkColPtr = firstColorPtr; tkColPtr != NULL; tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { tkColPtr->resourceRefCount++; tkColPtr->objRefCount++; - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; return (XColor *) tkColPtr; } } @@ -147,7 +148,7 @@ Tk_AllocColorFromObj( */ tkColPtr = (TkColor *) Tk_GetColor(interp, tkwin, Tcl_GetString(objPtr)); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; if (tkColPtr != NULL) { tkColPtr->objRefCount++; } @@ -223,11 +224,13 @@ Tk_GetColor( if (tkColPtr == NULL) { if (interp != NULL) { if (*name == '#') { - Tcl_AppendResult(interp, "invalid color name \"", name, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid color name \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL); } else { - Tcl_AppendResult(interp, "unknown color name \"", name, - "\"", NULL); + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown color name \"%s\"", name)); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "COLOR", name, NULL); } } if (isNew) { @@ -356,7 +359,7 @@ Tk_GetColorByValue( *-------------------------------------------------------------- */ -CONST char * +const char * Tk_NameOfColor( XColor *colorPtr) /* Color whose name is desired. */ { @@ -365,11 +368,30 @@ Tk_NameOfColor( if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) { return tkColPtr->hashPtr->key.string; } else { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); 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; } } @@ -496,7 +518,7 @@ Tk_FreeColor( */ if (tkColPtr->objRefCount == 0) { - ckfree((char *) tkColPtr); + ckfree(tkColPtr); } } @@ -528,13 +550,13 @@ Tk_FreeColorFromObj( Tcl_Obj *objPtr) /* The Tcl_Obj * to be freed. */ { Tk_FreeColor(Tk_GetColorFromObj(tkwin, objPtr)); - FreeColorObjProc(objPtr); + FreeColorObj(objPtr); } /* *--------------------------------------------------------------------------- * - * FreeColorObjProc -- + * FreeColorObjProc, FreeColorObj -- * * This proc is called to release an object reference to a color. Called * when the object's internal rep is released or when the cached tkColPtr @@ -554,13 +576,21 @@ static void FreeColorObjProc( Tcl_Obj *objPtr) /* The object we are releasing. */ { - TkColor *tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + FreeColorObj(objPtr); + objPtr->typePtr = NULL; +} + +static void +FreeColorObj( + Tcl_Obj *objPtr) /* The object we are releasing. */ +{ + TkColor *tkColPtr = objPtr->internalRep.twoPtrValue.ptr1; if (tkColPtr != NULL) { tkColPtr->objRefCount--; if ((tkColPtr->objRefCount == 0) && (tkColPtr->resourceRefCount == 0)) { - ckfree((char *) tkColPtr); + ckfree(tkColPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -589,10 +619,10 @@ DupColorObjProc( Tcl_Obj *srcObjPtr, /* The object we are copying from. */ Tcl_Obj *dupObjPtr) /* The object we are copying to. */ { - TkColor *tkColPtr = (TkColor *) srcObjPtr->internalRep.twoPtrValue.ptr1; + TkColor *tkColPtr = srcObjPtr->internalRep.twoPtrValue.ptr1; dupObjPtr->typePtr = srcObjPtr->typePtr; - dupObjPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + dupObjPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; if (tkColPtr != NULL) { tkColPtr->objRefCount++; @@ -639,7 +669,7 @@ Tk_GetColorFromObj( * map. If it is, we are done. */ - tkColPtr = (TkColor *) objPtr->internalRep.twoPtrValue.ptr1; + tkColPtr = objPtr->internalRep.twoPtrValue.ptr1; if ((tkColPtr != NULL) && (tkColPtr->resourceRefCount > 0) && (Tk_Screen(tkwin) == tkColPtr->screen) @@ -669,8 +699,8 @@ Tk_GetColorFromObj( (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { if ((Tk_Screen(tkwin) == tkColPtr->screen) && (Tk_Colormap(tkwin) == tkColPtr->colormap)) { - FreeColorObjProc(objPtr); - objPtr->internalRep.twoPtrValue.ptr1 = (void *) tkColPtr; + FreeColorObj(objPtr); + objPtr->internalRep.twoPtrValue.ptr1 = tkColPtr; tkColPtr->objRefCount++; return (XColor *) tkColPtr; } @@ -715,7 +745,7 @@ InitColorObj( Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { - (*typePtr->freeIntRepProc)(objPtr); + typePtr->freeIntRepProc(objPtr); } objPtr->typePtr = &tkColorObjType; objPtr->internalRep.twoPtrValue.ptr1 = NULL; @@ -772,7 +802,7 @@ Tcl_Obj * TkDebugColor( Tk_Window tkwin, /* The window in which the color will be used * (not currently used). */ - char *name) /* Name of the desired color. */ + const char *name) /* Name of the desired color. */ { Tcl_HashEntry *hashPtr; Tcl_Obj *resultPtr; @@ -799,30 +829,30 @@ TkDebugColor( return resultPtr; } -#ifndef __WIN32__ +#ifndef _WIN32 /* This function is not necessary for Win32, * since XParseColor already does the right thing */ #undef XParseColor -CONST char *CONST tkWebColors[20] = { +const char *const tkWebColors[20] = { /* 'a' */ "qua\0#0000ffffffff", /* 'b' */ NULL, /* 'c' */ "rimson\0#dcdc14143c3c", /* 'd' */ NULL, /* 'e' */ NULL, /* 'f' */ "uchsia\0#ffff0000ffff", - /* 'g' */ NULL, + /* 'g' */ "reen\0#000080800000", /* 'h' */ NULL, /* 'i' */ "ndigo\0#4b4b00008282", /* 'j' */ NULL, /* 'k' */ NULL, /* 'l' */ "ime\0#0000ffff0000", - /* 'm' */ NULL, + /* 'm' */ "aroon\0#808000000000", /* 'n' */ NULL, /* 'o' */ "live\0#808080800000", - /* 'p' */ NULL, + /* 'p' */ "urple\0#808000008080", /* 'q' */ NULL, /* 'r' */ NULL, /* 's' */ "ilver\0#c0c0c0c0c0c0", @@ -883,25 +913,31 @@ TkParseColor( } goto done; } else if (((*name - 'A') & 0xdf) < sizeof(tkWebColors)/sizeof(tkWebColors[0])) { - const char *p = tkWebColors[((*name - 'A') & 0x1f)]; - if (p) { - const char *q = name; - while (!((*p - *(++q)) & 0xdf)) { - if (!*p++) { - name = p; - goto done; + if (!((name[0] - 'G') & 0xdf) && !((name[1] - 'R') & 0xdf) + && !((name[2] - 'A') & 0xdb) && !((name[3] - 'Y') & 0xdf) + && !name[4]) { + name = "#808080808080"; + goto done; + } else { + const char *p = tkWebColors[((*name - 'A') & 0x1f)]; + if (p) { + const char *q = name; + while (!((*p - *(++q)) & 0xdf)) { + if (!*p++) { + name = p; + goto done; + } } } } } if (strlen(name) > 99) { - /* Don't bother to parse this. [Bug 2809525]*/ return 0; } done: return XParseColor(display, map, name, color); } -#endif /* __WIN32__ */ +#endif /* _WIN32 */ /* * Local Variables: * mode: c |