Posted to tcl by egavilan at Tue Feb 03 01:58:28 GMT 2026view pretty

Index: generic/tkButton.c
==================================================================
--- generic/tkButton.c
+++ generic/tkButton.c
@@ -58,10 +58,13 @@
  * Information used for parsing configuration options.  There is a
  * separate table for each of the four widget classes.
  */
 
 static const Tk_OptionSpec labelOptionSpecs[] = {
+    {TK_OPTION_DOUBLE, "-angle", "angle", "Angle",
+	"0.0", TCL_INDEX_NONE, offsetof(TkButton, angle),
+	0, 0, 0},
     {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
 	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
 	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
     {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
 	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),

Index: generic/tkButton.h
==================================================================
--- generic/tkButton.h
+++ generic/tkButton.h
@@ -62,10 +62,11 @@
 
     /*
      * Information about what's in the button.
      */
 
+    double angle;		/* Value of -angle option. */
     Tcl_Obj *textPtr;		/* Value of -text option: specifies text to
 				 * display in button. */
     int underline;		/* Value of -underline option: specifies index
 				 * of character to underline. INT_MIN means don't
 				 * underline anything. */

Index: unix/tkUnixButton.c
==================================================================
--- unix/tkUnixButton.c
+++ unix/tkUnixButton.c
@@ -649,16 +649,27 @@
 		    0, 0, (unsigned int) width, (unsigned int) height,
 		    imageXOffset, imageYOffset, 1);
 	    XSetClipOrigin(butPtr->display, gc, 0, 0);
 	}
 
+if (butPtr->angle == 0.0) {
 	Tk_DrawTextLayout(butPtr->display, pixmap, gc,
 		butPtr->textLayout, x + textXOffset, y + textYOffset, 0, -1);
 	Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
 		butPtr->textLayout, x + textXOffset, y + textYOffset,
 		butPtr->underline);
 	y += fullHeight/2;
+} else {
+/* angle != 0*/
+	TkDrawAngledTextLayout(butPtr->display, pixmap, gc,
+		butPtr->textLayout, x + textXOffset, y + textYOffset,
+		butPtr->angle, 0, -1);
+	TkUnderlineAngledTextLayout(butPtr->display, pixmap, gc,
+		butPtr->textLayout, x + textXOffset, y + textYOffset,
+		butPtr->angle, butPtr->underline);
+	y += fullHeight/2;
+}
     } else {
 	if (haveImage) {
 	    TkComputeAnchor(butPtr->anchor, tkwin, 0, 0,
 		    butPtr->indicatorSpace + width, height, &x, &y);
 	    x += butPtr->indicatorSpace;
@@ -714,15 +725,25 @@
 		    butPtr->indicatorSpace + butPtr->textWidth,
 		    butPtr->textHeight, &x, &y);
 
 	    x += butPtr->indicatorSpace;
 	    ShiftByOffset(butPtr, relief, &x, &y, width, height);
+if (butPtr->angle == 0.0) {
 	    Tk_DrawTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
 		    x, y, 0, -1);
 	    Tk_UnderlineTextLayout(butPtr->display, pixmap, gc,
 		    butPtr->textLayout, x, y, butPtr->underline);
 	    y += butPtr->textHeight/2;
+} else {
+/* angle != 0*/
+	    TkDrawAngledTextLayout(butPtr->display, pixmap, gc, butPtr->textLayout,
+		    x, y, butPtr->angle, 0, -1);
+	    TkUnderlineAngledTextLayout(butPtr->display, pixmap, gc,
+		    butPtr->textLayout, x, y,
+		    butPtr->angle, butPtr->underline);
+	    y += butPtr->textHeight/2;
+}
 	}
     }
 
     /*
      * Draw the indicator for check buttons and radio buttons. At this point,