summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixRFont.c
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2017-08-21 19:07:37 (GMT)
committerfvogel <fvogelnew1@free.fr>2017-08-21 19:07:37 (GMT)
commit7a5d33ce65d82c1f0e55cca84ee7f6304e994f3d (patch)
treeb7168553ac10748b92d0bb4a2e8acde52a89c612 /unix/tkUnixRFont.c
parent53bd11aa50181ad6112b9a72fda543db9ec7a4ca (diff)
downloadtk-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.c60
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;