diff -r -u -B ../Tk800-orig/Tk/prolog.ps ./Tk/prolog.ps --- ../Tk800-orig/Tk/prolog.ps Sat Dec 30 11:12:37 2000 +++ ./Tk/prolog.ps Sat Sep 22 21:17:25 2001 @@ -207,11 +207,13 @@ % drawn in stippled fashion. If text is stippled, % procedure StippleText must have been defined to call % StippleFill in the right way. +% angle - Rotation angle in degrees, positive CCW % % Also, when this procedure is invoked, the color and font must already % have been set for the text. /DrawText { + /angle exch def /stipple exch def /justify exch def /yoffset exch def @@ -235,19 +237,47 @@ exch pop exch sub /height exch def pop newpath - % Translate coordinates first so that the origin is at the upper-left - % corner of the text's bounding box. Remember that x and y for - % positioning are still on the stack. - + % Use x and y for positioning currently on stack translate - lineLength xoffset mul - strings length 1 sub spacing mul height add yoffset mul translate + + % We now need to know the actual width and height of the box, including + % any rotations. + /basex lineLength def + /basey strings length 1 sub spacing mul height add def + + /rx basex angle cos mul abs basey angle sin mul abs add def + /ry basex angle sin mul abs basey angle cos mul abs add def + + % Then we need to know how to move the box so that the lower-left-most + % part is back to being in the upper-left corner. + angle 0 gt angle 90 gt not and { + 0 + basex angle sin mul neg + translate } if + angle 90 gt angle 180 gt not and { + basex angle cos mul neg + ry neg + translate } if + angle 180 gt angle 270 gt not and { + rx + basey angle cos mul + translate } if + angle 270 gt angle 360 gt not and { + basey angle sin mul neg + 0 + translate } if + + % Now move based on the anchor + rx xoffset mul + ry yoffset mul translate % Now use the baseline and justification information to translate so % that the origin is at the baseline and positioning point for the % first line of text. - justify lineLength mul baseline neg translate + justify lineLength mul angle cos mul baseline angle sin mul add + justify lineLength mul angle sin mul baseline angle cos mul add neg + translate % Iterate over each of the lines to output it. For each line, % compute its width again so it can be properly justified, then @@ -276,7 +306,7 @@ moveto } forall grestore - } {show} ifelse + } {show} angle rotate ifelse 0 spacing neg translate } forall } bind def diff -r -u -B ../Tk800-orig/pTk/mTk/generic/tk.h ./pTk/mTk/generic/tk.h --- ../Tk800-orig/pTk/mTk/generic/tk.h Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/generic/tk.h Sat Sep 22 15:49:11 2001 @@ -1934,6 +1934,8 @@ ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)); +EXTERN Tk_Font Tk_RotateFont _ANSI_ARGS_((Tk_Font oldfnt, double angle)); + EXTERN Tcl_Command Lang_CreateWidget _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window, Tcl_CmdProc *proc, diff -r -u -B ../Tk800-orig/pTk/mTk/generic/tkCanvPs.c ./pTk/mTk/generic/tkCanvPs.c --- ../Tk800-orig/pTk/mTk/generic/tkCanvPs.c Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/generic/tkCanvPs.c Sat Sep 22 21:16:00 2001 @@ -290,7 +290,7 @@ % acr", /* End of part 3 */ - /* Start of part 4 (2000 characters) */ + /* Start of part 4 (many characters) */ "oss rows, blasting out a stipple-pattern-sized rectangle at\n\ % each position\n\ \n\ @@ -341,11 +341,13 @@ % drawn in stippled fashion. If text is stippled,\n\ % procedure StippleText must have been defined to call\n\ % StippleFill in the right way.\n\ +% angle - Rotation angle in degrees, positive ccw \n\ %\n\ % Also, when this procedure is invoked, the color and font must already\n\ % have been set for the text.\n\ \n\ /DrawText {\n\ + /angle exch def\n\ /stipple exch def\n\ /justify exch def\n\ /yoffset exch def\n\ @@ -358,11 +360,7 @@ /lineLength 0 def\n\ strings {\n\ stringwidth pop\n\ - dup lineLength gt {/lineLength exch def}", - /* End of part 4 */ - - /* Start of part 5 (1546 characters) */ - " {pop} ifelse\n\ + dup lineLength gt {/lineLength exch def} {pop} ifelse\n\ newpath\n\ } forall\n\ \n\ @@ -373,19 +371,47 @@ exch pop exch sub /height exch def pop\n\ newpath\n\ \n\ - % Translate coordinates first so that the origin is at the upper-left\n\ - % corner of the text's bounding box. Remember that x and y for\n\ - % positioning are still on the stack.\n\ -\n\ + % Use x and y for positioning currently on stack\n\ translate\n\ - lineLength xoffset mul\n\ - strings length 1 sub spacing mul height add yoffset mul translate\n\ +\n\ + % We now need to know the actual width and height of the box, including\n\ + % any rotations.\n\ + /basex lineLength def\n\ + /basey strings length 1 sub spacing mul height add def\n\ +\n\ + /rx basex angle cos mul abs basey angle sin mul abs add def\n\ + /ry basex angle sin mul abs basey angle cos mul abs add def\n\ +\n\ + % Then we need to know how to move the box so that the lower-left-most\n\ + % part is back to being in the upper-left corner.\n\ + angle 0 gt angle 90 gt not and {\n\ + 0\n\ + basex angle sin mul neg\n\ + translate } if\n\ + angle 90 gt angle 180 gt not and {\n\ + basex angle cos mul neg\n\ + ry neg\n\ + translate } if\n\ + angle 180 gt angle 270 gt not and {\n\ + rx\n\ + basey angle cos mul\n\ + translate } if\n\ + angle 270 gt angle 360 gt not and {\n\ + basey angle sin mul neg\n\ + 0\n\ + translate } if\n\ +\n\ + % Now move based on the anchor\n\ + rx xoffset mul\n\ + ry yoffset mul translate\n\ \n\ % Now use the baseline and justification information to translate so\n\ % that the origin is at the baseline and positioning point for the\n\ % first line of text.\n\ \n\ - justify lineLength mul baseline neg translate\n\ + justify lineLength mul angle cos mul baseline angle sin mul add\n\ + justify lineLength mul angle sin mul baseline angle cos mul add neg\n\ + translate\n\ \n\ % Iterate over each of the lines to output it. For each line,\n\ % compute its width again so it can be properly justified, then\n\ @@ -414,7 +440,7 @@ moveto\n\ } forall\n\ grestore\n\ - } {show} ifelse\n\ + } {show} angle rotate ifelse\n\ 0 spacing neg translate\n\ } forall\n\ } bind def\n\ diff -r -u -B ../Tk800-orig/pTk/mTk/generic/tkCanvText.c ./pTk/mTk/generic/tkCanvText.c --- ../Tk800-orig/pTk/mTk/generic/tkCanvText.c Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/generic/tkCanvText.c Sun Sep 23 02:52:12 2001 @@ -72,12 +72,16 @@ int rightEdge; /* Pixel just to right of right edge of * area of text item. Used for selecting up * to end of line. */ + int insertionx, insertiony; /* Insertion point, which is not necessarily + in the corner anymore now that we rotate */ GC gc; /* Graphics context for drawing text. */ GC selTextGC; /* Graphics context for selected text. */ GC cursorOffGC; /* If not None, this gives a graphics context * to use to draw the insertion cursor when * it's off. Used if the selection and * insertion cursor colors are the same. */ + double angle; /* rotation angle, degrees; positive ccw */ + } TextItem; /* @@ -145,6 +149,8 @@ (char *) NULL, Tk_Offset(Tk_Item, updateCmd), TK_CONFIG_NULL_OK}, {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT}, + {TK_CONFIG_DOUBLE, "-angle", (char *) NULL, (char *) NULL, + 0, Tk_Offset(TextItem, angle), 0}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, (char *) NULL, 0, 0} }; @@ -302,6 +308,7 @@ textPtr->disabledStipple = None; textPtr->text = NULL; textPtr->width = 0; + textPtr->angle = 0; textPtr->numChars = 0; textPtr->textLayout = NULL; @@ -322,6 +329,16 @@ return TCL_OK; } + /* If we have a nonzero angle, we must rotate the font accordingly */ + if (textPtr->angle) + { + while(textPtr->angle >= 360) + textPtr->angle -= 360; + while(textPtr->angle < 0) + textPtr->angle += 360; + textPtr->tkfont=Tk_RotateFont(textPtr->tkfont, textPtr->angle); + } + error: DeleteText(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); return TCL_ERROR; @@ -444,6 +461,15 @@ * graphics contexts. */ + if (textPtr->angle) + { + while(textPtr->angle >= 360) + textPtr->angle -= 360; + while(textPtr->angle < 0) + textPtr->angle += 360; + textPtr->tkfont=Tk_RotateFont(textPtr->tkfont, textPtr->angle); + } + state = Tk_GetItemState(canvas, itemPtr); if (textPtr->activeColor != NULL || @@ -680,8 +706,47 @@ * of the bounding box for the text item. */ - leftX = (int) (textPtr->x + 0.5); - topY = (int) (textPtr->y + 0.5); + /*ROTATEDEBUG*/ +/* printf ("angle: %g width: %d height %d\n", textPtr->angle, width, height); + */ + + if (textPtr->angle == 0) + { + leftX = (int) (textPtr->x + 0.5); + topY = (int) (textPtr->y + 0.5); + + textPtr->insertionx=leftX; + textPtr->insertiony=topY; + } + else + /* Now rotate. We rotate around x,y. insertion[xy] just move, + * as desired. leftx, lefty, width, and height change to + * describe an imaginary box bounding the new rotated shape */ + + { + double cs=cos(textPtr->angle*M_PI/180); + double sn=sin(textPtr->angle*M_PI/180); + int cenx=textPtr->x+width/2; + int ceny=textPtr->y+height/2; + int delix=textPtr->x-cenx; + int deliy=-(textPtr->y-ceny); /* positive towards *top* */ + int origw=width; + int origh=height; + + leftX = (int) (textPtr->x + 0.5); + topY = (int) (textPtr->y + 0.5); + + /* width and height are easy */ + width=abs(cs*origw)+abs(sn*origh); + height=abs(sn*origw)+abs(cs*origh); + + /* this has to adjust to be relative to the new center */ + textPtr->insertionx=cenx+(delix*cs-deliy*sn); + textPtr->insertionx+=(width-origw)/2; + textPtr->insertiony=ceny+(-delix*sn-deliy*cs); + textPtr->insertiony+=(height-origh)/2; + + } switch (textPtr->anchor) { case TK_ANCHOR_NW: case TK_ANCHOR_N: @@ -692,12 +757,14 @@ case TK_ANCHOR_CENTER: case TK_ANCHOR_E: topY -= height / 2; + textPtr->insertiony -= height/2; break; case TK_ANCHOR_SW: case TK_ANCHOR_S: case TK_ANCHOR_SE: topY -= height; + textPtr->insertiony -= height; break; } switch (textPtr->anchor) { @@ -710,14 +777,23 @@ case TK_ANCHOR_CENTER: case TK_ANCHOR_S: leftX -= width / 2; + textPtr->insertionx -= width/2; break; case TK_ANCHOR_NE: case TK_ANCHOR_E: case TK_ANCHOR_SE: leftX -= width; + textPtr->insertionx -= width; break; } + /*ROTATEDEBUG */ +/* + printf ("%g: %d %d %d %d %d %d\n", textPtr->angle, leftX, topY, + width, height, textPtr->insertionx, textPtr->insertiony); +*/ + + textPtr->leftEdge = leftX; textPtr->rightEdge = leftX + width; @@ -909,8 +985,11 @@ * as foreground color) than regular text. */ - Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge, +/* Tk_CanvasDrawableCoords(canvas, (double) textPtr->leftEdge, (double) textPtr->header.y1, &drawableX, &drawableY); +*/ + Tk_CanvasDrawableCoords(canvas, (double) textPtr->insertionx, + (double) textPtr->insertiony, &drawableX, &drawableY); Tk_DrawTextLayout(display, drawable, textPtr->gc, textPtr->textLayout, drawableX, drawableY, 0, -1); @@ -1526,9 +1605,9 @@ } Tk_GetFontMetrics(textPtr->tkfont, &fm); - sprintf(buffer, "] %d %g %g %s %s DrawText\n", + sprintf(buffer, "] %d %g %g %s %s %g DrawText\n", fm.linespace, x / -2.0, y / 2.0, justify, - ((stipple == None) ? "false" : "true")); + ((stipple == None) ? "false" : "true"), textPtr->angle); Tcl_AppendResult(interp, buffer, (char *) NULL); return TCL_OK; diff -r -u -B ../Tk800-orig/pTk/mTk/generic/tkFont.c ./pTk/mTk/generic/tkFont.c --- ../Tk800-orig/pTk/mTk/generic/tkFont.c Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/generic/tkFont.c Sun Sep 23 02:26:09 2001 @@ -14,6 +14,7 @@ * RCS: @(#) $Id: tkFont.c,v 1.2 1998/09/14 18:23:10 stanton Exp $ */ +#include #include "tkInt.h" #include "tkFont.h" @@ -818,6 +819,69 @@ /* *--------------------------------------------------------------------------- * + * Tk_RotateFont -- + * + * Given a Tk_Font and an angle, generate a new font which is rotated. + * Angle is absolute, not relative to any current rotation. + * + * Results: + * If possible, a new Tk_Font which is rotated is generated. + * + * Side effects: + * Tk_FreeFont() is called on the font passed in. + * + *--------------------------------------------------------------------------- + */ +Tk_Font +Tk_RotateFont(oldfnt, angle) + Tk_Font oldfnt; + double angle; +{ + TkFont *newfont; + TkFont *oldfont=(TkFont *)oldfnt; + Tcl_HashEntry *cacheHashPtr; + char *oldkey, newkey[100]; + int new; + TkFontAttributes fa; + Tcl_HashTable *cacheTable = + &(((TkWindow *)(oldfont->tkwin))->mainPtr->fontInfoPtr->fontCache); + + oldkey=Tcl_GetHashKey(cacheTable, oldfont->cacheHashPtr); + + /* Generate a new key from the old one and the rotation angle */ + sprintf(newkey, "%g:", angle); + strncat(newkey, oldkey, 100); + + /* Insert the new entry into the hash */ + cacheHashPtr = Tcl_CreateHashEntry(cacheTable, newkey, &new); + if (!new) + { + newfont=(TkFont *)Tcl_GetHashValue(cacheHashPtr); + Tk_FreeFont((Tk_Font)oldfont); + return (Tk_Font)newfont; + } + + fa=oldfont->fa; + fa.angle=angle; + + /* GetFontFromAttributes for Unix has been modified to DTRT with the + * angle field. Other platforms will silently fail. */ + newfont= TkpGetFontFromAttributes(NULL, oldfont->tkwin, &fa); + + Tcl_SetHashValue(cacheHashPtr, newfont); + newfont->namedHashPtr=0; + newfont->cacheHashPtr=cacheHashPtr; + newfont->tkwin=oldfont->tkwin; + newfont->refCount=1; + + Tk_FreeFont((Tk_Font)oldfont); + return (Tk_Font)newfont; +} + + +/* + *--------------------------------------------------------------------------- + * * Tk_GetFontFromObj -- * * Given a string description of a font, map the description to a @@ -907,6 +971,7 @@ Tcl_SetHashValue(cacheHashPtr, fontPtr); fontPtr->refCount = 1; + fontPtr->tkwin = tkwin; fontPtr->cacheHashPtr = cacheHashPtr; fontPtr->namedHashPtr = namedHashPtr; @@ -1496,7 +1561,10 @@ flags &= ~TK_AT_LEAST_ONE; if (charsThisChunk > 0) { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, - charsThisChunk, curX, newX, baseline); + charsThisChunk, + curX+baseline*sin(fontPtr->fa.angle*M_PI/180), + newX+baseline*sin(fontPtr->fa.angle*M_PI/180), + baseline*cos(fontPtr->fa.angle*M_PI/180)); start += charsThisChunk; curX = newX; @@ -1512,8 +1580,11 @@ if (*special == '\t') { newX = curX + fontPtr->tabWidth; newX -= newX % fontPtr->tabWidth; - NewChunk(&layoutPtr, &maxChunks, start, 1, curX, newX, - baseline)->numDisplayChars = -1; + NewChunk(&layoutPtr, &maxChunks, start, 1, + curX+baseline*sin(fontPtr->fa.angle*M_PI/180), + newX+baseline*sin(fontPtr->fa.angle*M_PI/180), + baseline*cos(fontPtr->fa.angle*M_PI/180)) + ->numDisplayChars = -1; start++; if ((start < end) && ((wrapLength <= 0) || (newX <= wrapLength))) { @@ -2507,6 +2578,7 @@ break; } } + faPtr->angle=0; return TCL_OK; } @@ -2685,6 +2757,7 @@ result = TkParseXLFD(string, &xa); if (result == TCL_OK) { *faPtr = xa.fa; + faPtr->angle=0; return result; } } @@ -2750,6 +2823,8 @@ (char *) NULL); return TCL_ERROR; } + faPtr->angle=0; + return TCL_OK; } @@ -2785,6 +2860,8 @@ Tcl_DString ds; memset(field, '\0', sizeof(field)); + /* ROTATEDEBUG */ +/* printf("String: %s\n", string); */ str = string; if (*str == '-') { @@ -2870,19 +2947,33 @@ * Pointsize in tenths of a point, but treat it as tenths of a pixel. */ + /* Default to 0; set later if necessary */ + xaPtr->fa.angle=0; + if (FieldSpecified(field[XLFD_POINT_SIZE])) { if (field[XLFD_POINT_SIZE][0] == '[') { + double a,b,c,d; + int i; /* * Some X fonts have the point size specified as follows: * * [ N1 N2 N3 N4 ] * - * where N1 is the point size (in points, not decipoints!), and - * N2, N3, and N4 are some additional numbers that I don't know - * the purpose of, so I ignore them. + * These are coordinate transforms, wherein the point size + * of the font will be sqrt(N1*N1 + N2*N2). If this is not + * equal to sqrt(N3*N3 + N4*N4), the font is stretched, but + * we ignore that possibility for now and assume it's not. + * See XFLD doc for more information. */ - xaPtr->fa.pointsize = atoi(field[XLFD_POINT_SIZE] + 1); + /* Undo the translation hack so we can scan */ + for (i=1; field[XLFD_POINT_SIZE][i] != ']'; i++) + if( field[XLFD_POINT_SIZE][i] == '~') + field[XLFD_POINT_SIZE][i] = '-'; + sscanf(field[XLFD_POINT_SIZE]+1, "%lg %lg %lg %lg", + &a, &b, &c, &d); + xaPtr->fa.pointsize = pow(c*c+d*d, 0.5)+.5; + xaPtr->fa.angle = atan2(b,a)/M_PI*180; } else if (Lang_GetStrInt(NULL, field[XLFD_POINT_SIZE], &xaPtr->fa.pointsize) == TCL_OK) { xaPtr->fa.pointsize /= 10; @@ -2897,24 +2988,29 @@ if (FieldSpecified(field[XLFD_PIXEL_SIZE])) { if (field[XLFD_PIXEL_SIZE][0] == '[') { - /* - * Some X fonts have the pixel size specified as follows: - * - * [ N1 N2 N3 N4 ] - * - * where N1 is the pixel size, and where N2, N3, and N4 - * are some additional numbers that I don't know - * the purpose of, so I ignore them. - */ + /* See point size for explanation */ + + double a,b,c,d; + int i; + + for (i=1; field[XLFD_PIXEL_SIZE][i] != ']'; i++) + if( field[XLFD_PIXEL_SIZE][i] == '~') + field[XLFD_PIXEL_SIZE][i] = '-'; + sscanf(field[XLFD_PIXEL_SIZE]+1, "%lg %lg %lg %lg", + &a, &b, &c, &d); + /* ROTATEDEBUG */ +/* printf ("From %s, pixelsize %d\n", field[XLFD_PIXEL_SIZE], + xaPtr->fa.pointsize); */ - xaPtr->fa.pointsize = atoi(field[XLFD_PIXEL_SIZE] + 1); + xaPtr->fa.pointsize = pow(c*c+d*d, 0.5)+.5; + xaPtr->fa.angle = atan2(b,a)/M_PI*180; } else if (Lang_GetStrInt(NULL, field[XLFD_PIXEL_SIZE], &xaPtr->fa.pointsize) != TCL_OK) { return TCL_ERROR; } - } - xaPtr->fa.pointsize = -xaPtr->fa.pointsize; + xaPtr->fa.pointsize = -xaPtr->fa.pointsize; + } /* XLFD_RESOLUTION_X ignored. */ diff -r -u -B ../Tk800-orig/pTk/mTk/generic/tkFont.h ./pTk/mTk/generic/tkFont.h --- ../Tk800-orig/pTk/mTk/generic/tkFont.h Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/generic/tkFont.h Sun Sep 23 01:55:11 2001 @@ -35,6 +35,7 @@ int slant; /* Slant flag; see below for def'n. */ int underline; /* Non-zero for underline font. */ int overstrike; /* Non-zero for overstrike font. */ + double angle; /* in degrees, ccw positive */ } TkFontAttributes; /* @@ -92,6 +93,8 @@ */ int refCount; /* Number of users of the TkFont. */ + Tk_Window tkwin; /* needed to fork the font - you cant get + from a cachePtr back to the table */ Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure, * used when deleting it. */ Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that @@ -105,6 +108,9 @@ int underlineHeight; /* Height of underline bar (used for drawing * underlines on a non-underlined font). */ + struct TkFont *nonrotated; /* Used to point to the nonrotated version + of a rotated font */ + /* * Fields in the generic font structure that are filled in by * platform-specific code. diff -r -u -B ../Tk800-orig/pTk/mTk/unix/tkUnixFont.c ./pTk/mTk/unix/tkUnixFont.c --- ../Tk800-orig/pTk/mTk/unix/tkUnixFont.c Sat Dec 30 11:12:37 2000 +++ ./pTk/mTk/unix/tkUnixFont.c Sun Sep 23 02:51:20 2001 @@ -11,6 +11,7 @@ * * RCS: @(#) $Id: tkUnixFont.c,v 1.4 1998/11/25 01:48:54 stanton Exp $ */ +#include #include "tkPort.h" #include "tkInt.h" @@ -227,7 +228,7 @@ d += 0.5; pixelsize = (int) d; } - + /* * Replace the standard Windows and Mac family names with the names that * X likes. @@ -337,6 +339,10 @@ } else { score += (pixelsize - xaPixelsize) * 100; } + + /* If the font is to be rotated, bitmapped won't do at all. */ + if (faPtr->angle) + score+=5000; } score += ABS(xa.fa.weight - faPtr->weight) * 30; @@ -412,8 +418,43 @@ rest = strchr(rest + 1, '-'); } *str = '\0'; - sprintf(buf, "%.240s-*-%d-*-*-*-*-*%s", nameList[bestScaleableIdx], + + /* We fill in rotated fonts using the transformation matrix. + * See the XLFD documentation for details. */ + if (faPtr->angle==0) + sprintf(buf, "%.240s-*-%d-*-*-*-*-*%s", nameList[bestScaleableIdx], pixelsize, rest); + else + { + char val[4][50]; + double x,y; + int i; + + /* We want to round off to low precision here, so we don't get + * 23434e-16 where we want 0 */ + x=rint(pixelsize*cos(faPtr->angle/180*M_PI)*1000)/1000; + y=rint(pixelsize*sin(faPtr->angle/180*M_PI)*1000)/1000; + + sprintf(val[0], "%g",x); + sprintf(val[1], "%g",y); + sprintf(val[2], "%g",-y); + sprintf(val[3], "%g",x); + + /* X uses this horrible hack because the meaning of - is taken */ + /* We know there is no - in the exponent because the rounding + * above guarantees there is no exponent at all */ + for (i=0; i<4; i++) + if (val[i][0]=='-') + val[i][0]='~'; + + sprintf(buf, "%.240s-*-[%s %s %s %s]-0-*-*-*-*%s", + nameList[bestScaleableIdx], val[0], val[1], val[2], val[3], + rest); + } + + /* ROTATEDEBUG */ +/* printf ("Using scalable font %s\n", buf); */ + *str = '-'; fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), buf); bestScaleableScore = INT_MAX; @@ -771,7 +812,27 @@ 0x7fff - x, 0, &length); } - XDrawString(display, drawable, gc, x, y, source, numChars); + if (!fontPtr->font.fa.angle) + XDrawString(display, drawable, gc, x, y, source, numChars); + else + { + int i; + int rx,ry; + rx=x; + ry=y; + + /* ROTATEDEBUG */ +/* printf ("Drawing at angle %g\n", fontPtr->font.fa.angle); */ + + for (i=0; iwidths[UCHAR(source[i])]* + cos(fontPtr->font.fa.angle*M_PI/180); + ry-=fontPtr->widths[UCHAR(source[i])]* + sin(fontPtr->font.fa.angle*M_PI/180); + } + } if (fontPtr->font.fa.underline != 0) { XFillRectangle(display, drawable, gc, x, @@ -874,6 +935,12 @@ fontPtr->display = Tk_Display(tkwin); fontPtr->fontStructPtr = fontStructPtr; + if (fontPtr->font.fa.angle) + { + /* and now we have to kluge the ascent and descent too */ + fontPtr->font.fm.ascent = fontPtr->font.fa.pointsize; + fontPtr->font.fm.descent = fontPtr->font.fa.pointsize/6; + } /* * Classify the characters. */ @@ -902,7 +969,22 @@ } else if (fontStructPtr->per_char == NULL) { n = fontStructPtr->max_bounds.width; } else { - n = fontStructPtr->per_char[i - firstChar].width; + if (fontPtr->font.fa.angle) + { + fontPtr->font.fm.fixed = 0; + + /* This is a horrible kluge because I can't find any way to + * get the proper width! */ + if (fontStructPtr->per_char[i - firstChar].width == 0) + n=(fontStructPtr->per_char[i-firstChar].ascent+ + fontStructPtr->per_char[i-firstChar].descent+1); +// *sin(fontPtr->font.fa.angle/180*M_PI); + else + n=fontStructPtr->per_char[i - firstChar].width + /cos(fontPtr->font.fa.angle/180*M_PI)+.5; + } + else + n = fontStructPtr->per_char[i - firstChar].width; } fontPtr->widths[i] = n; if (n != 0) { diff -r -u -B ../Tk800-orig/pTk/tk.m ./pTk/tk.m --- ../Tk800-orig/pTk/tk.m Sat Dec 30 11:12:37 2000 +++ ./pTk/tk.m Sun Sep 23 00:47:51 2001 @@ -658,6 +658,10 @@ # define Tk_RestrictEvents (*TkVptr->V_Tk_RestrictEvents) #endif +#ifndef Tk_RotateFont +# define Tk_RotateFont (*TkVptr->V_Tk_RotateFont) +#endif + #ifndef Tk_SetAppName # define Tk_SetAppName (*TkVptr->V_Tk_SetAppName) #endif diff -r -u -B ../Tk800-orig/pTk/tk.t ./pTk/tk.t --- ../Tk800-orig/pTk/tk.t Sat Dec 30 11:12:37 2000 +++ ./pTk/tk.t Sun Sep 23 00:47:51 2001 @@ -870,6 +870,10 @@ ClientData arg, ClientData *prevArgPtr))) #endif +#ifndef Tk_RotateFont +VFUNC(Tk_Font,Tk_RotateFont,V_Tk_RotateFont,_ANSI_ARGS_((Tk_Font oldfnt, double angle))) +#endif + #ifndef Tk_SetAppName VFUNC(char *,Tk_SetAppName,V_Tk_SetAppName,_ANSI_ARGS_((Tk_Window tkwin, char *name)))