diff options
Diffstat (limited to 'unix/tkUnixRFont.c')
-rw-r--r-- | unix/tkUnixRFont.c | 85 |
1 files changed, 62 insertions, 23 deletions
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index ccf77a3..4f7f6f3 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -14,6 +14,14 @@ #include <X11/Xft/Xft.h> #include <ctype.h> +/* needed for backport to 8.5 */ +#ifndef ROUND16 +# define ROUND16(x) ((short) floor((x) + 0.5)) +#endif +#ifndef PI +# define PI 3.14159265358979323846 +#endif + #define MAX_CACHED_COLORS 16 typedef struct { @@ -614,11 +622,24 @@ TkpGetSubFonts( *---------------------------------------------------------------------- */ +/* we need backward compatibility */ +#if TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 7 +# define UNICHAR Tcl_UniChar +# define TkUtfToUniChar Tcl_UtfToUniChar +#else /* if !(TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 7) */ +# define UNICHAR int +# if TCL_UTF_MAX > 4 +# define TkUtfToUniChar Tcl_UtfToUniChar +# else /* if TCL_UTF_MAX <= 4 */ +extern int TkUtfToUniChar(const char *src, int *chPtr); +# endif /* TCL_UTF_MAX > 4 */ +#endif /* TK_MAJOR_VERSION == 8 && TK_MINOR_VERSION < 7 */ + void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - int c, /* Character of interest */ + UNICHAR c, /* Character of interest */ TkFontAttributes *faPtr) /* Output: Font attributes */ { UnixFtFont *fontPtr = (UnixFtFont *) tkfont; @@ -671,7 +692,7 @@ Tk_MeasureChars( curByte = 0; sawNonSpace = 0; while (numBytes > 0) { - int unichar; + UNICHAR unichar; clen = TkUtfToUniChar(source, &unichar); c = (FcChar32) unichar; @@ -859,6 +880,10 @@ Tk_DrawChars( ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + if (maxCoord <= y) { + return; /* nothing to draw */ + } + if (fontPtr->ftDraw == 0) { #if DEBUG_FONTSEL printf("Switch to drawable 0x%x\n", drawable); @@ -879,7 +904,7 @@ Tk_DrawChars( XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); } nspec = 0; - while (numBytes > 0 && x <= maxCoord && y <= maxCoord) { + while (numBytes > 0) { XftFont *ftFont; FcChar32 c; @@ -896,19 +921,25 @@ Tk_DrawChars( ftFont = GetFont(fontPtr, c, 0.0); if (ftFont) { - specs[nspec].font = ftFont; + int cx = x; + int cy = y; + specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c); - specs[nspec].x = x; - specs[nspec].y = y; XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1, &metrics); - x += metrics.xOff; - y += metrics.yOff; - nspec++; - if (nspec == NUM_SPEC) { - XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, - specs, nspec); - nspec = 0; + if ((x += metrics.xOff) >= maxCoord + || (y += metrics.yOff) >= maxCoord) { + break; + } + if (metrics.xOff > 0 && cx >= 0 && cy >= 0) { + specs[nspec].font = ftFont; + specs[nspec].x = cx; + specs[nspec].y = cy; + if (++nspec == NUM_SPEC) { + XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, + specs, nspec); + nspec = 0; + } } } } @@ -1011,8 +1042,7 @@ TkDrawAngledChars( currentFtFont = NULL; originX = originY = 0; /* lint */ - while (numBytes > 0 && x <= maxCoord && x >= minCoord && y <= maxCoord - && y >= minCoord) { + while (numBytes > 0 && x >= minCoord && y >= minCoord) { XftFont *ftFont; FcChar32 c; @@ -1050,8 +1080,17 @@ TkDrawAngledChars( XftGlyphExtents(fontPtr->display, currentFtFont, glyphs, nglyph, &metrics); nglyph = 0; - x += metrics.xOff; - y += metrics.yOff; + /* + * Breaking at this place is sub-optimal, but the whole algorithm + * has a design problem, the choice of NUM_SPEC is arbitrary, and so + * the inter-glyph spacing will look arbitrary. This algorithm + * has to draw the whole string at once (or whole blocks with same + * font), this requires a dynamic 'glyphs' array. In case of overflow + * the array has to be divided until the maximal string will fit. (GC) + */ + if ((x += metrics.xOff) >= maxCoord || (y += metrics.yOff) >= maxCoord) { + break; + } } currentFtFont = ftFont; } @@ -1087,8 +1126,7 @@ TkDrawAngledChars( XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); } nspec = 0; - while (numBytes > 0 && x <= maxCoord && x >= minCoord - && y <= maxCoord && y >= minCoord) { + while (numBytes > 0 && x >= minCoord && y >= minCoord) { XftFont *ftFont, *ft0Font; FcChar32 c; @@ -1112,10 +1150,11 @@ TkDrawAngledChars( specs[nspec].y = ROUND16(y); XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1, &metrics); - x += metrics.xOff*cosA + metrics.yOff*sinA; - y += metrics.yOff*cosA - metrics.xOff*sinA; - nspec++; - if (nspec == NUM_SPEC) { + if ((x += metrics.xOff*cosA + metrics.yOff*sinA) > maxCoord + || (y += metrics.yOff*cosA - metrics.xOff*sinA) > maxCoord) { + break; + } + if (++nspec == NUM_SPEC) { XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec); nspec = 0; |