diff options
author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-01-23 12:10:20 (GMT) |
---|---|---|
committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-01-23 12:10:20 (GMT) |
commit | 2c1df2e9f4f50fb3d70656c278d42ca0da4401d4 (patch) | |
tree | 265011910e5e1e4ae1c3632a98af9f1a1423613b /generic | |
parent | 10c4db3640ed279cc5c507569efdfd2358e515f6 (diff) | |
parent | 725decf9a3e8cad6285a4942e69f3f19a0361a0a (diff) | |
download | tk-2c1df2e9f4f50fb3d70656c278d42ca0da4401d4.zip tk-2c1df2e9f4f50fb3d70656c278d42ca0da4401d4.tar.gz tk-2c1df2e9f4f50fb3d70656c278d42ca0da4401d4.tar.bz2 |
Fix [026e2bb685]: text tag sets bad relief, gets error, but bad relief is saved anyway. Continued fix
Diffstat (limited to 'generic')
-rw-r--r-- | generic/tkTextTag.c | 427 |
1 files changed, 221 insertions, 206 deletions
diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index 3f8ab80..400b2d1 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -38,6 +38,202 @@ static const char *const tabStyleStrings[] = { "tabular", "wordprocessor", "", NULL }; +/* This struct can be used for booleans, relief and pixels */ +typedef struct { + char *string; + int value; +} IntStruct; + +typedef struct { + char *string; + Tk_Justify value; +} JustifyStruct; + +static int +ObjectIsEmpty( + Tcl_Obj *objPtr) /* Object to test. May be NULL. */ +{ + if (objPtr == NULL) { + return 1; + } + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); + } + return (objPtr->length == 0); +} + +#define OPTION_NONNEG (1 << 10) + +static int +SetPixels(void *clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *oldInternalPtr, + int flags) +{ + IntStruct pixel = {NULL, INT_MIN}; + IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset); + + if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) { + if (Tk_GetPixelsFromObj(interp, tkwin, *value, &pixel.value) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & OPTION_NONNEG) && pixel.value < 0) { + pixel.value = 0; + } + pixel.string = ckalloc((*value)->length + 1); + strcpy(pixel.string, (*value)->bytes); + } + + *((char **)oldInternalPtr) = NULL; + *internalPtr = pixel; + return TCL_OK; +}; + +static int +SetBoolean(void *clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *oldInternalPtr, + int flags) +{ + IntStruct booleanVal = {NULL, -1}; + IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset); + + if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) { + if (Tcl_GetBooleanFromObj(interp, *value, &booleanVal.value) != TCL_OK) { + return TCL_ERROR; + } + booleanVal.string = ckalloc((*value)->length + 1); + strcpy(booleanVal.string, (*value)->bytes); + } + + *((char **)oldInternalPtr) = NULL; + *internalPtr = booleanVal; + return TCL_OK; +}; + +static int +SetRelief(void *clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *oldInternalPtr, + int flags) +{ + IntStruct relief = {NULL, TK_RELIEF_NULL}; + IntStruct *internalPtr = (IntStruct *)(recordPtr + internalOffset); + + if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) { + if (Tk_GetReliefFromObj(interp, *value, &relief.value) != TCL_OK) { + return TCL_ERROR; + } + relief.string = ckalloc((*value)->length + 1); + strcpy(relief.string, (*value)->bytes); + } + + *((char **)oldInternalPtr) = NULL; + *internalPtr = relief; + return TCL_OK; +}; + +static int +SetJustify(void *clientData, + Tcl_Interp *interp, + Tk_Window tkwin, + Tcl_Obj **value, + char *recordPtr, + int internalOffset, + char *oldInternalPtr, + int flags) +{ + JustifyStruct justify = {NULL, (Tk_Justify)-1}; + JustifyStruct *internalPtr = (JustifyStruct *)(recordPtr + internalOffset); + + if (!(flags & TK_OPTION_NULL_OK) || !ObjectIsEmpty(*value)) { + if (Tk_GetJustifyFromObj(interp, *value, &justify.value) != TCL_OK) { + return TCL_ERROR; + } + justify.string = ckalloc((*value)->length + 1); + strcpy(justify.string, (*value)->bytes); + } + + *((char **)oldInternalPtr) = NULL; + *internalPtr = justify; + return TCL_OK; +}; + +static Tcl_Obj *GetStruct( + void *clientData, + Tk_Window tkwin, + char *recordPtr, + int internalOffset) +{ + char **structPtr = (char **)(recordPtr + internalOffset); + + if (*structPtr == NULL || **structPtr == '\0') { + return Tcl_NewObj(); + } + return Tcl_NewStringObj(*structPtr, -1); +}; + + +static void +FreeStruct(void *clientData, + Tk_Window tkwin, + char *internalPtr) +{ + char **structPtr = (char **)internalPtr; + if (*structPtr) { + ckfree(*structPtr); + *structPtr = NULL; + } +}; + +static const Tk_ObjCustomOption pixelsOption = { + "pixels", /* name */ + SetPixels, /* setProc */ + GetStruct, /* getProc */ + NULL, /* restoreProc */ + FreeStruct, /* freeProc */ + 0 +}; + +static const Tk_ObjCustomOption booleanOption = { + "boolean", /* name */ + SetBoolean, /* setProc */ + GetStruct, /* getProc */ + NULL, /* restoreProc */ + FreeStruct, /* freeProc */ + 0 +}; + +static const Tk_ObjCustomOption justifyOption = { + "justify", /* name */ + SetJustify, /* setProc */ + GetStruct, /* getProc */ + NULL, /* restoreProc */ + FreeStruct, /* freeProc */ + 0 +}; + +static const Tk_ObjCustomOption reliefOption = { + "relief", /* name */ + SetRelief, /* setProc */ + GetStruct, /* getProc */ + NULL, /* restoreProc */ + FreeStruct, /* freeProc */ + 0 +}; + static const Tk_OptionSpec tagOptionSpecs[] = { {TK_OPTION_BORDER, "-background", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0}, @@ -46,55 +242,55 @@ static const Tk_OptionSpec tagOptionSpecs[] = { {TK_OPTION_PIXELS, "-borderwidth", NULL, NULL, NULL, Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-elide", NULL, NULL, + {TK_OPTION_CUSTOM, "-elide", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, elideString), - TK_OPTION_NULL_OK, 0, 0}, + TK_OPTION_NULL_OK, &booleanOption, 0}, {TK_OPTION_BITMAP, "-fgstipple", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_FONT, "-font", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_COLOR, "-foreground", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-justify", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0,0}, - {TK_OPTION_STRING, "-lmargin1", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0}, - {TK_OPTION_STRING, "-lmargin2", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0}, + {TK_OPTION_CUSTOM, "-justify", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, &justifyOption, 0}, + {TK_OPTION_CUSTOM, "-lmargin1", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK, &pixelsOption, 0}, + {TK_OPTION_CUSTOM, "-lmargin2", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK, &pixelsOption, 0}, {TK_OPTION_BORDER, "-lmargincolor", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, lMarginColor), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-offset", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-overstrike", NULL, NULL, + {TK_OPTION_CUSTOM, "-offset", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, &pixelsOption, 0}, + {TK_OPTION_CUSTOM, "-overstrike", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, overstrikeString), - TK_OPTION_NULL_OK, 0, 0}, + TK_OPTION_NULL_OK, &booleanOption, 0}, {TK_OPTION_COLOR, "-overstrikefg", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, overstrikeColor), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-relief", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-rmargin", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0}, + {TK_OPTION_CUSTOM, "-relief", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, &reliefOption, 0}, + {TK_OPTION_CUSTOM, "-rmargin", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, &pixelsOption, 0}, {TK_OPTION_BORDER, "-rmargincolor", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, rMarginColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, selBorder), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_COLOR, "-selectforeground", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, selFgColor), TK_OPTION_NULL_OK, 0, 0}, - {TK_OPTION_STRING, "-spacing1", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0}, - {TK_OPTION_STRING, "-spacing2", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK,0,0}, - {TK_OPTION_STRING, "-spacing3", NULL, NULL, - NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0}, + {TK_OPTION_CUSTOM, "-spacing1", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0}, + {TK_OPTION_CUSTOM, "-spacing2", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0}, + {TK_OPTION_CUSTOM, "-spacing3", NULL, NULL, + NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK|OPTION_NONNEG, &pixelsOption, 0}, {TK_OPTION_STRING, "-tabs", NULL, NULL, NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-tabstyle", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, tabStyle), TK_OPTION_NULL_OK, tabStyleStrings, 0}, - {TK_OPTION_STRING, "-underline", NULL, NULL, + {TK_OPTION_CUSTOM, "-underline", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, underlineString), - TK_OPTION_NULL_OK, 0, 0}, + TK_OPTION_NULL_OK, &booleanOption, 0}, {TK_OPTION_COLOR, "-underlinefg", NULL, NULL, NULL, -1, Tk_Offset(TkTextTag, underlineColor), TK_OPTION_NULL_OK, 0, 0}, @@ -183,7 +379,7 @@ TkTextTagCmd( return TCL_ERROR; } tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); - if (tagPtr->elide) { + if (tagPtr->elide > 0) { /* * Indices are potentially obsolete after adding or removing * elided character ranges, especially indices having "display" @@ -387,158 +583,6 @@ TkTextTagCmd( if (tagPtr->borderWidth < 0) { tagPtr->borderWidth = 0; } - if (tagPtr->reliefString != NULL) { - if (Tk_GetRelief(interp, tagPtr->reliefString, - &tagPtr->relief) != TCL_OK) { - ckfree(tagPtr->reliefString); - tagPtr->reliefString = NULL; - if ((unsigned)tagPtr->relief <= TK_RELIEF_SUNKEN) { - const char *reliefString = Tk_NameOfRelief(tagPtr->relief); - tagPtr->reliefString = ckalloc(strlen(reliefString)+1); - strcpy(tagPtr->reliefString, reliefString); - } - return TCL_ERROR; - } - } else { - tagPtr->relief = TK_RELIEF_NULL; - } - if (tagPtr->justifyString != NULL) { - if (Tk_GetJustify(interp, tagPtr->justifyString, - &tagPtr->justify) != TCL_OK) { - ckfree(tagPtr->justifyString); - tagPtr->justifyString = NULL; - if ((unsigned)tagPtr->justify <= (unsigned)TK_JUSTIFY_CENTER) { - const char *justifyString = Tk_NameOfJustify(tagPtr->justify); - tagPtr->justifyString = ckalloc(strlen(justifyString)+1); - strcpy(tagPtr->justifyString, justifyString); - } - return TCL_ERROR; - } - } else { - tagPtr->justify = (Tk_Justify)-1; - } - if (tagPtr->lMargin1String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { - ckfree(tagPtr->lMargin1String); - tagPtr->lMargin1String = NULL; - if (tagPtr->lMargin1 != INT_MIN) { - tagPtr->lMargin1String = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->lMargin1String, TCL_INTEGER_SPACE, "%d", tagPtr->lMargin1); - } - return TCL_ERROR; - } - } else { - tagPtr->lMargin1 = INT_MIN; - } - if (tagPtr->lMargin2String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { - ckfree(tagPtr->lMargin2String); - tagPtr->lMargin2String = NULL; - if (tagPtr->lMargin2 != INT_MIN) { - tagPtr->lMargin2String = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->lMargin2String, TCL_INTEGER_SPACE, "%d", tagPtr->lMargin2); - } - return TCL_ERROR; - } - } else { - tagPtr->lMargin2 = INT_MIN; - } - if (tagPtr->offsetString != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString, - &tagPtr->offset) != TCL_OK) { - ckfree(tagPtr->offsetString); - tagPtr->offsetString = NULL; - if (tagPtr->offset != INT_MIN) { - tagPtr->offsetString = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->offsetString, TCL_INTEGER_SPACE, "%d", tagPtr->offset); - } - return TCL_ERROR; - } - } else { - tagPtr->offset = INT_MIN; - } - if (tagPtr->overstrikeString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->overstrikeString, - &tagPtr->overstrike) != TCL_OK) { - ckfree(tagPtr->overstrikeString); - tagPtr->overstrikeString = NULL; - if ((unsigned)tagPtr->overstrike <= 1) { - tagPtr->overstrikeString = ckalloc(2); - tagPtr->overstrikeString[0] = '0' + tagPtr->overstrike; - tagPtr->overstrikeString[1] = 0; - } - return TCL_ERROR; - } - } else { - tagPtr->overstrike = -1; - } - if (tagPtr->rMarginString != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { - ckfree(tagPtr->rMarginString); - tagPtr->rMarginString = NULL; - if (tagPtr->rMargin != INT_MIN) { - tagPtr->rMarginString = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->rMarginString, TCL_INTEGER_SPACE, "%d", tagPtr->rMargin); - } - return TCL_ERROR; - } - } else { - tagPtr->rMargin = INT_MIN; - } - if (tagPtr->spacing1String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { - ckfree(tagPtr->spacing1String); - tagPtr->spacing1String = NULL; - if (tagPtr->spacing1 != INT_MIN) { - tagPtr->spacing1String = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->spacing1String, TCL_INTEGER_SPACE, "%d", tagPtr->spacing1); - } - return TCL_ERROR; - } - if (tagPtr->spacing1 < 0) { - tagPtr->spacing1 = 0; - } - } else { - tagPtr->spacing1 = INT_MIN; - } - if (tagPtr->spacing2String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { - ckfree(tagPtr->spacing2String); - tagPtr->spacing2String = NULL; - if (tagPtr->spacing2 != INT_MIN) { - tagPtr->spacing2String = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->spacing2String, TCL_INTEGER_SPACE, "%d", tagPtr->spacing2); - } - return TCL_ERROR; - } - if (tagPtr->spacing2 < 0) { - tagPtr->spacing2 = 0; - } - } else { - tagPtr->spacing2 = INT_MIN; - } - if (tagPtr->spacing3String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { - ckfree(tagPtr->spacing3String); - tagPtr->spacing3String = NULL; - if (tagPtr->spacing3 != INT_MIN) { - tagPtr->spacing3String = ckalloc(TCL_INTEGER_SPACE); - snprintf(tagPtr->spacing3String, TCL_INTEGER_SPACE, "%d", tagPtr->spacing3); - } - return TCL_ERROR; - } - if (tagPtr->spacing3 < 0) { - tagPtr->spacing3 = 0; - } - } else { - tagPtr->spacing3 = INT_MIN; - } if (tagPtr->tabArrayPtr != NULL) { ckfree(tagPtr->tabArrayPtr); tagPtr->tabArrayPtr = NULL; @@ -550,34 +594,7 @@ TkTextTagCmd( return TCL_ERROR; } } - if (tagPtr->underlineString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->underlineString, - &tagPtr->underline) != TCL_OK) { - ckfree(tagPtr->underlineString); - tagPtr->underlineString = NULL; - if ((unsigned)tagPtr->underline <= 1) { - tagPtr->underlineString = ckalloc(2); - tagPtr->underlineString[0] = '0' + tagPtr->underline; - tagPtr->underlineString[1] = 0; - } - return TCL_ERROR; - } - } else { - tagPtr->underline = -1; - } if (tagPtr->elideString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->elideString, - &tagPtr->elide) != TCL_OK) { - ckfree(tagPtr->elideString); - tagPtr->elideString = NULL; - if ((unsigned)tagPtr->elide <= 1) { - tagPtr->elideString = ckalloc(2); - tagPtr->elideString[0] = '0' + tagPtr->elide; - tagPtr->elideString[1] = 0; - } - return TCL_ERROR; - } - /* * Indices are potentially obsolete after changing -elide, * especially those computed with "display" or "any" @@ -585,8 +602,6 @@ TkTextTagCmd( */ textPtr->sharedTextPtr->stateEpoch++; - } else { - tagPtr->elide = -1; } /* |