summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixRFont.c
diff options
context:
space:
mode:
authorfvogel <fvogelnew1@free.fr>2018-01-29 07:16:44 (GMT)
committerfvogel <fvogelnew1@free.fr>2018-01-29 07:16:44 (GMT)
commitce768c117f9513aa3838b05f737036c14fd268bc (patch)
tree47fcca481af735e8d6ec44fbbb21408adf19580b /unix/tkUnixRFont.c
parent729e9e1b7d1fc90806afaed638caee2ef76e58eb (diff)
downloadtk-ce768c117f9513aa3838b05f737036c14fd268bc.zip
tk-ce768c117f9513aa3838b05f737036c14fd268bc.tar.gz
tk-ce768c117f9513aa3838b05f737036c14fd268bc.tar.bz2
Fix [71b1319acc]: Regression in tkUnixRFont.c. Patch from Christian Werner.
Diffstat (limited to 'unix/tkUnixRFont.c')
-rw-r--r--unix/tkUnixRFont.c120
1 files changed, 66 insertions, 54 deletions
diff --git a/unix/tkUnixRFont.c b/unix/tkUnixRFont.c
index d43ed24..fe3cb0d 100644
--- a/unix/tkUnixRFont.c
+++ b/unix/tkUnixRFont.c
@@ -850,6 +850,7 @@ Tk_DrawChars(
* string when drawing. */
{
const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
+ const int minCoord = -maxCoord-1;
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
XGCValues values;
XftColor *xftcolor;
@@ -859,10 +860,6 @@ 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);
@@ -900,26 +897,28 @@ Tk_DrawChars(
ftFont = GetFont(fontPtr, c, 0.0);
if (ftFont) {
- int cx = x;
- int cy = y;
-
specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
&metrics);
- 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;
- }
+
+ /*
+ * Draw glyph only when it fits entirely into 16 bit coords.
+ */
+
+ if (x >= minCoord && y >= minCoord &&
+ x <= maxCoord - metrics.width &&
+ y <= maxCoord - metrics.height) {
+ specs[nspec].font = ftFont;
+ specs[nspec].x = x;
+ specs[nspec].y = y;
+ if (++nspec == NUM_SPEC) {
+ XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
+ specs, nspec);
+ nspec = 0;
+ }
}
+ x += metrics.xOff;
+ y += metrics.yOff;
}
}
if (nspec) {
@@ -982,7 +981,7 @@ TkDrawAngledChars(
double angle) /* What angle to put text at, in degrees. */
{
const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
- const int minCoord = -1000; /* Should be good enough... */
+ const int minCoord = -maxCoord-1;
UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
XGCValues values;
XftColor *xftcolor;
@@ -1021,7 +1020,7 @@ TkDrawAngledChars(
currentFtFont = NULL;
originX = originY = 0; /* lint */
- while (numBytes > 0 && x >= minCoord && y >= minCoord) {
+ while (numBytes > 0) {
XftFont *ftFont;
FcChar32 c;
@@ -1050,34 +1049,40 @@ TkDrawAngledChars(
* this information... but we'll be ready when it does!
*/
- XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
- originX, originY, glyphs, nglyph);
- }
- originX = ROUND16(x);
- originY = ROUND16(y);
- if (nglyph) {
XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
nglyph, &metrics);
- nglyph = 0;
- /*
- * 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;
- }
+ /*
+ * Draw glyph only when it fits entirely into 16 bit coords.
+ */
+
+ if (x >= minCoord && y >= minCoord &&
+ x <= maxCoord - metrics.width &&
+ y <= maxCoord - metrics.height) {
+
+ XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
+ originX, originY, glyphs, nglyph);
+ }
}
+ originX = ROUND16(x);
+ originY = ROUND16(y);
currentFtFont = ftFont;
}
glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
}
if (nglyph) {
- XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
- originX, originY, glyphs, nglyph);
+ XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
+ nglyph, &metrics);
+
+ /*
+ * Draw glyph only when it fits entirely into 16 bit coords.
+ */
+
+ if (x >= minCoord && y >= minCoord &&
+ x <= maxCoord - metrics.width &&
+ y <= maxCoord - metrics.height) {
+ XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
+ originX, originY, glyphs, nglyph);
+ }
}
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
int clen, nspec;
@@ -1105,7 +1110,7 @@ TkDrawAngledChars(
XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
}
nspec = 0;
- while (numBytes > 0 && x >= minCoord && y >= minCoord) {
+ while (numBytes > 0) {
XftFont *ftFont, *ft0Font;
FcChar32 c;
@@ -1123,21 +1128,28 @@ TkDrawAngledChars(
ftFont = GetFont(fontPtr, c, angle);
ft0Font = GetFont(fontPtr, c, 0.0);
if (ftFont && ft0Font) {
- specs[nspec].font = ftFont;
specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
- specs[nspec].x = ROUND16(x);
- specs[nspec].y = ROUND16(y);
XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
&metrics);
- 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;
+
+ /*
+ * Draw glyph only when it fits entirely into 16 bit coords.
+ */
+
+ if (x >= minCoord && y >= minCoord &&
+ x <= maxCoord - metrics.width &&
+ y <= maxCoord - metrics.height) {
+ specs[nspec].font = ftFont;
+ specs[nspec].x = ROUND16(x);
+ specs[nspec].y = ROUND16(y);
+ if (++nspec == NUM_SPEC) {
+ XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
+ specs, nspec);
+ nspec = 0;
+ }
}
+ x += metrics.xOff*cosA + metrics.yOff*sinA;
+ y += metrics.yOff*cosA - metrics.xOff*sinA;
}
}
if (nspec) {