Skip to content

Commit

Permalink
Fix [610a73a179]: Canvas widget handles pixel objects incorrectly in …
Browse files Browse the repository at this point in the history
…Tk 9.0

** Potential incopatibility ** because canvas -insertborderwidth/-insertwidth/-selectborderwidth can now return non-float values
  • Loading branch information
jan.nijtmans committed Oct 5, 2024
2 parents 562f881 + 15f413a commit 6f51c77
Show file tree
Hide file tree
Showing 14 changed files with 429 additions and 330 deletions.
92 changes: 47 additions & 45 deletions generic/tkButton.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ static const Tk_OptionSpec labelOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
tkDefButtonBorderWidth, offsetof(TkButton, borderWidthObj),
offsetof(TkButton, borderWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound),
0, tkCompoundStrings, 0},
Expand Down Expand Up @@ -109,18 +109,18 @@ static const Tk_OptionSpec labelOptionSpecs[] = {
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", tkDefLabelHighlightWidth,
offsetof(TkButton, highlightWidthObj),
offsetof(TkButton, highlightWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), TK_OPTION_ENUM_VAR, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
tkDefLabelPadx, offsetof(TkButton, padXObj),
offsetof(TkButton, padX), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
tkDefLabelPady, offsetof(TkButton, padYObj),
offsetof(TkButton, padY), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
{TK_OPTION_STRING_TABLE, "-state", "state", "State",
Expand All @@ -140,7 +140,7 @@ static const Tk_OptionSpec labelOptionSpecs[] = {
DEF_BUTTON_WIDTH, offsetof(TkButton, widthObj), TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthObj),
offsetof(TkButton, wrapLength), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

Expand All @@ -165,7 +165,7 @@ static const Tk_OptionSpec buttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
tkDefButtonBorderWidth, offsetof(TkButton, borderWidthObj),
offsetof(TkButton, borderWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand Down Expand Up @@ -200,7 +200,7 @@ static const Tk_OptionSpec buttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", tkDefButtonHighlightWidth,
offsetof(TkButton, highlightWidthObj),
offsetof(TkButton, highlightWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand All @@ -211,10 +211,10 @@ static const Tk_OptionSpec buttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
tkDefButtonPadx, offsetof(TkButton, padXObj),
offsetof(TkButton, padX), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
tkDefButtonPady, offsetof(TkButton, padYObj),
offsetof(TkButton, padY), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
0, 0, 0},
Expand All @@ -241,7 +241,7 @@ static const Tk_OptionSpec buttonOptionSpecs[] = {
DEF_BUTTON_WIDTH, offsetof(TkButton, widthObj), TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthObj),
offsetof(TkButton, wrapLength), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

Expand All @@ -266,7 +266,7 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
tkDefButtonBorderWidth, offsetof(TkButton, borderWidthObj),
offsetof(TkButton, borderWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand Down Expand Up @@ -298,7 +298,7 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", tkDefButtonHighlightWidth,
offsetof(TkButton, highlightWidthObj),
offsetof(TkButton, highlightWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand All @@ -317,10 +317,10 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
tkDefLabelPadx, offsetof(TkButton, padXObj),
offsetof(TkButton, padX), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
tkDefLabelPady, offsetof(TkButton, padYObj),
offsetof(TkButton, padY), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
Expand Down Expand Up @@ -354,7 +354,7 @@ static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
DEF_BUTTON_WIDTH, offsetof(TkButton, widthObj), TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthObj),
offsetof(TkButton, wrapLength), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

Expand All @@ -379,7 +379,7 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
tkDefButtonBorderWidth, offsetof(TkButton, borderWidthObj),
offsetof(TkButton, borderWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-command", "command", "Command",
DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand Down Expand Up @@ -411,7 +411,7 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
{TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
"HighlightThickness", tkDefButtonHighlightWidth,
offsetof(TkButton, highlightWidthObj),
offsetof(TkButton, highlightWidth), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_STRING, "-image", "image", "Image",
DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
TK_OPTION_NULL_OK, 0, 0},
Expand All @@ -427,10 +427,10 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
TK_OPTION_NULL_OK, 0, 0},
{TK_OPTION_PIXELS, "-padx", "padX", "Pad",
tkDefLabelPadx, offsetof(TkButton, padXObj),
offsetof(TkButton, padX), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-pady", "padY", "Pad",
tkDefLabelPady, offsetof(TkButton, padYObj),
offsetof(TkButton, padY), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_RELIEF, "-relief", "relief", "Relief",
DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
{TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
Expand Down Expand Up @@ -466,7 +466,7 @@ static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
DEF_BUTTON_WIDTH, offsetof(TkButton, widthObj), TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthObj),
offsetof(TkButton, wrapLength), 0, 0, 0},
TCL_INDEX_NONE, 0, 0, 0},
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

Expand Down Expand Up @@ -688,10 +688,8 @@ ButtonCreate(
butPtr->normalBorder = NULL;
butPtr->activeBorder = NULL;
butPtr->borderWidthObj = NULL;
butPtr->borderWidth = 0;
butPtr->relief = TK_RELIEF_FLAT;
butPtr->highlightWidthObj = NULL;
butPtr->highlightWidth = 0;
butPtr->highlightBorder = NULL;
butPtr->highlightColorPtr = NULL;
butPtr->inset = 0;
Expand All @@ -706,15 +704,10 @@ ButtonCreate(
butPtr->gray = None;
butPtr->copyGC = NULL;
butPtr->widthObj = NULL;
butPtr->width = 0;
butPtr->heightObj = NULL;
butPtr->height = 0;
butPtr->wrapLengthObj = NULL;
butPtr->wrapLength = 0;
butPtr->padXObj = NULL;
butPtr->padX = 0;
butPtr->padYObj = NULL;
butPtr->padY = 0;
butPtr->anchor = TK_ANCHOR_CENTER;
butPtr->justify = TK_JUSTIFY_CENTER;
butPtr->indicatorOn = 0;
Expand Down Expand Up @@ -1034,6 +1027,8 @@ ConfigureButton(
Tcl_Obj *errorResult = NULL;
int error, haveImage;
Tk_Image image;
int wrapLength, borderWidth, highlightWidth, padX, padY;
int butPtrWidth, butPtrHeight;

/*
* Eliminate any existing trace on variables monitored by the button.
Expand Down Expand Up @@ -1097,32 +1092,37 @@ ConfigureButton(
} else {
Tk_SetBackgroundFromBorder(butPtr->tkwin, butPtr->normalBorder);
}
if (butPtr->wrapLength < 0) {
butPtr->wrapLength = 0;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->wrapLengthObj, &wrapLength);
if (wrapLength < 0) {
wrapLength = 0;
Tcl_DecrRefCount(butPtr->wrapLengthObj);
butPtr->wrapLengthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(butPtr->wrapLengthObj);
}
if (butPtr->borderWidth < 0) {
butPtr->borderWidth = 0;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->borderWidthObj, &borderWidth);
if (borderWidth < 0) {
borderWidth = 0;
Tcl_DecrRefCount(butPtr->borderWidthObj);
butPtr->borderWidthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(butPtr->borderWidthObj);
}
if (butPtr->highlightWidth < 0) {
butPtr->highlightWidth = 0;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth < 0) {
highlightWidth = 0;
Tcl_DecrRefCount(butPtr->highlightWidthObj);
butPtr->highlightWidthObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(butPtr->highlightWidthObj);
}
if (butPtr->padX < 0) {
butPtr->padX = 0;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->padXObj, &padX);
if (padX < 0) {
padX = 0;
Tcl_DecrRefCount(butPtr->padXObj);
butPtr->padXObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(butPtr->padXObj);
}
if (butPtr->padY < 0) {
butPtr->padY = 0;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->padYObj, &padY);
if (padY < 0) {
padY = 0;
Tcl_DecrRefCount(butPtr->padYObj);
butPtr->padYObj = Tcl_NewIntObj(0);
Tcl_IncrRefCount(butPtr->padYObj);
Expand Down Expand Up @@ -1274,13 +1274,13 @@ ConfigureButton(
*/

if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->widthObj,
&butPtr->width) != TCL_OK) {
&butPtrWidth) != TCL_OK) {
widthError:
Tcl_AddErrorInfo(interp, "\n (processing \"-width\" option)");
continue;
}
if (Tk_GetPixelsFromObj(interp, butPtr->tkwin, butPtr->heightObj,
&butPtr->height) != TCL_OK) {
&butPtrHeight) != TCL_OK) {
heightError:
Tcl_AddErrorInfo(interp, "\n (processing \"-height\" option)");
continue;
Expand All @@ -1290,11 +1290,11 @@ ConfigureButton(
* The button displays an ordinary text string.
*/

if (Tcl_GetIntFromObj(interp, butPtr->widthObj, &butPtr->width)
if (Tcl_GetIntFromObj(interp, butPtr->widthObj, &butPtrWidth)
!= TCL_OK) {
goto widthError;
}
if (Tcl_GetIntFromObj(interp, butPtr->heightObj, &butPtr->height)
if (Tcl_GetIntFromObj(interp, butPtr->heightObj, &butPtrHeight)
!= TCL_OK) {
goto heightError;
}
Expand Down Expand Up @@ -1467,6 +1467,8 @@ ButtonEventProc(
XEvent *eventPtr) /* Information about event. */
{
TkButton *butPtr = (TkButton *)clientData;
int highlightWidth;

if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
goto redraw;
} else if (eventPtr->type == ConfigureNotify) {
Expand All @@ -1481,16 +1483,16 @@ ButtonEventProc(
} else if (eventPtr->type == FocusIn) {
if (eventPtr->xfocus.detail != NotifyInferior) {
butPtr->flags |= GOT_FOCUS;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthObj, &butPtr->highlightWidth);
if (butPtr->highlightWidth > 0) {
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth > 0) {
goto redraw;
}
}
} else if (eventPtr->type == FocusOut) {
if (eventPtr->xfocus.detail != NotifyInferior) {
butPtr->flags &= ~GOT_FOCUS;
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthObj, &butPtr->highlightWidth);
if (butPtr->highlightWidth > 0) {
Tk_GetPixelsFromObj(NULL, butPtr->tkwin, butPtr->highlightWidthObj, &highlightWidth);
if (highlightWidth > 0) {
goto redraw;
}
}
Expand Down
6 changes: 0 additions & 6 deletions generic/tkButton.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,6 @@ typedef struct {
* invocataions of the button command. */
int flags; /* Various flags; see below for
* definitions. */
#ifdef BUILD_tk
int padX, padY;
int borderWidth;
int highlightWidth;
int width, height, wrapLength;
#endif
} TkButton;

/*
Expand Down
17 changes: 13 additions & 4 deletions generic/tkCanvText.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ typedef struct TextItem {
Pixmap activeStipple; /* Stipple bitmap for text, or None. */
Pixmap disabledStipple; /* Stipple bitmap for text, or None. */
char *text; /* Text for item (malloc-ed). */
int width; /* Width of lines for word-wrap, pixels. Zero
Tcl_Obj *widthObj; /* Width of lines for word-wrap, pixels. Zero
* means no word-wrap. */
int underline; /* Index of character to put underline beneath
* or INT_MIN for no underlining. */
Expand Down Expand Up @@ -209,7 +209,7 @@ static const Tk_ConfigSpec configSpecs[] = {
{TK_CONFIG_CUSTOM, "-underline", NULL, NULL, NULL,
offsetof(TextItem, underline), TK_CONFIG_NULL_OK, &underlineOption},
{TK_CONFIG_PIXELS, "-width", NULL, NULL,
"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
"0", offsetof(TextItem, widthObj), TK_CONFIG_OBJS, NULL},
{TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

Expand Down Expand Up @@ -346,7 +346,7 @@ CreateText(
textPtr->activeStipple = None;
textPtr->disabledStipple = None;
textPtr->text = NULL;
textPtr->width = 0;
textPtr->widthObj = NULL;
textPtr->underline = INT_MIN;
textPtr->angle = 0.0;

Expand Down Expand Up @@ -724,8 +724,12 @@ ComputeTextBbox(
}

Tk_FreeTextLayout(textPtr->textLayout);
width = 0;
if (textPtr->widthObj) {
Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), textPtr->widthObj, &width);
}
textPtr->textLayout = Tk_ComputeTextLayout(textPtr->tkfont,
textPtr->text, textPtr->numChars, textPtr->width,
textPtr->text, textPtr->numChars, width,
textPtr->justify, 0, &width, &height);

if (state == TK_STATE_HIDDEN || textPtr->color == NULL) {
Expand Down Expand Up @@ -795,6 +799,8 @@ ComputeTextBbox(
*/

textInfoPtr = textPtr->textInfoPtr;
Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), (Tcl_Obj *)textInfoPtr->reserved2, &textInfoPtr->insertWidth);
Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), (Tcl_Obj *)textInfoPtr->reserved3, &textInfoPtr->selBorderWidth);
fudge = (textInfoPtr->insertWidth + 1) / 2;
if (textInfoPtr->selBorderWidth > fudge) {
fudge = textInfoPtr->selBorderWidth;
Expand Down Expand Up @@ -943,6 +949,7 @@ DisplayCanvText(

x = xFirst;
height = hFirst;
Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), (Tcl_Obj *)textInfoPtr->reserved3, &textInfoPtr->selBorderWidth);
for (y = yFirst ; y <= yLast; y += height) {
int dx1, dy1, dx2, dy2;
double s = textPtr->sine, c = textPtr->cosine;
Expand Down Expand Up @@ -989,6 +996,7 @@ DisplayCanvText(
double s = textPtr->sine, c = textPtr->cosine;
XPoint points[4];

Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), (Tcl_Obj *)textInfoPtr->reserved2, &textInfoPtr->insertWidth);
dx1 = x - (textInfoPtr->insertWidth / 2);
dy1 = y;
dx2 = textInfoPtr->insertWidth;
Expand All @@ -1005,6 +1013,7 @@ DisplayCanvText(
Tk_SetCaretPos(Tk_CanvasTkwin(canvas), points[0].x, points[0].y,
height);
if (textInfoPtr->cursorOn) {
Tk_GetPixelsFromObj(NULL, Tk_CanvasTkwin(canvas), (Tcl_Obj *)textInfoPtr->reserved1, &textInfoPtr->insertBorderWidth);
Tk_Fill3DPolygon(Tk_CanvasTkwin(canvas), drawable,
textInfoPtr->insertBorder, points, 4,
textInfoPtr->insertBorderWidth, TK_RELIEF_RAISED);
Expand Down
Loading

0 comments on commit 6f51c77

Please sign in to comment.