diff options
author | fvogel <fvogelnew1@free.fr> | 2017-08-21 19:07:37 (GMT) |
---|---|---|
committer | fvogel <fvogelnew1@free.fr> | 2017-08-21 19:07:37 (GMT) |
commit | 7a5d33ce65d82c1f0e55cca84ee7f6304e994f3d (patch) | |
tree | b7168553ac10748b92d0bb4a2e8acde52a89c612 /unix/tkUnixRFont.c | |
parent | 53bd11aa50181ad6112b9a72fda543db9ec7a4ca (diff) | |
download | tk-7a5d33ce65d82c1f0e55cca84ee7f6304e994f3d.zip tk-7a5d33ce65d82c1f0e55cca84ee7f6304e994f3d.tar.gz tk-7a5d33ce65d82c1f0e55cca84ee7f6304e994f3d.tar.bz2 |
Fix [d9fdfa435d]: Long non-wrapped lines in text widget displayed malformed. Backported a fix from Gregor Cramer from the revised_text branch.
Diffstat (limited to 'unix/tkUnixRFont.c')
-rw-r--r-- | unix/tkUnixRFont.c | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c index cce59a8..d43ed24 100644 --- a/unix/tkUnixRFont.c +++ b/unix/tkUnixRFont.c @@ -859,6 +859,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 +883,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 +900,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 +1021,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 +1059,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 +1105,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 +1129,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; |