Package: xlibs Version: 4.2.1-5 Severity: important Tags: patch upstream sid
Hello Branden, Mozilla Xft users (including myself) have been experiencing strange disappearing text problem, as explained in Mozilla Bugzilla "Bug #187377: Characters disappear with xft if fallback triggered twice on the same line" and related bug reports. See: http://bugzilla.mozilla.org/show_bug.cgi?id=187377 Most bug reporters use Debian or FreeBSD. This problem does not happen on Red Hat 8.0. I guess not many people know the fix yet. The details of this bug came up on the XFree86 fonts mailing list just two days ago: ITO Tsuyoshi says: While performing some test about Mozilla Bugzilla Bug #187377 [1], I found that XRenderCompositeText16 function in Render extension does not draw text as intended when multiple glyphsets are involved in one call. According to the code of the Render extension on X server side, XRenderCompositeText16 should send a "glyphset-switch sign" (a glyph element with len = 0xff) to the X server when it encounters a glyph element whose glyphset is different from the one of the previous glyph element. However, it actually sends the glyphset-switch sign when it encounters a glyph element whose glyphset is different from the one of the _first_ glyph element. XRenderCompositeText{8,32} probably have the same problem. and provided a patch. Keith Packard replied: Your analysis is quite correct. A fix solving this issue was placed in XFree86 CVS on 2002-8-31. That patch was also included in Red Hat 8.0, probably days before it was final: * Sun Sep 01 2002 Mike A. Harris <[EMAIL PROTECTED]> 4.2.0-70 ... - Added XFree86-4.2.0-libXrender-bugfix.patch to fix showstopper (#73243) That patch (still identical to the one in current XFree86-4.3 CVS) is attached. Please include this in your next upload. (Feel free to change the "094_" number. :-) Thanks! Anthony -- System Information: Debian Release: testing/unstable Architecture: i386 Kernel: Linux anthony 2.4.21-pre4-ac1 #1 Mon Feb 3 03:11:48 HKT 2003 i686 Versions of packages xlibs depends on: ii libc6 2.3.1-12 GNU C Library: Shared libraries an ii libfreetype6 2.1.3-10 FreeType 2 font engine, shared lib ii xfree86-common 4.2.1-5 X Window System (XFree86) infrastr -- no debconf information
Index: lib/Xrender/Glyph.c =================================================================== RCS file: /cvs/xc/lib/Xrender/Glyph.c,v retrieving revision 1.7 retrieving revision 1.10 diff -u -p -r1.7 -r1.10 --- xc/lib/Xrender/Glyph.c 2001/12/27 01:16:00 1.7 +++ xc/lib/Xrender/Glyph.c 2002/08/31 18:15:45 1.10 @@ -125,6 +125,7 @@ XRenderFreeGlyphs (Display *dpy, GetReq(RenderFreeGlyphs, req); req->reqType = info->codes->major_opcode; req->renderReqType = X_RenderFreeGlyphs; + req->glyphset = glyphset; len = nglyphs; SetReqLen(req, len, len); len <<= 2; @@ -390,6 +391,7 @@ XRenderCompositeText8 (Display *dp { XExtDisplayInfo *info = XRenderFindDisplay (dpy); xRenderCompositeGlyphs8Req *req; + GlyphSet glyphset; long len; long elen; xGlyphElt *elt; @@ -419,10 +421,17 @@ XRenderCompositeText8 (Display *dp */ len = 0; + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { - if (elts[i].glyphset != req->glyphset) + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; len += (SIZEOF (xGlyphElt) + 4) >> 2; + } nchars = elts[i].nchars; /* * xGlyphElt must be aligned on a 32-bit boundary; this is @@ -434,26 +443,24 @@ XRenderCompositeText8 (Display *dp } req->length += len; - /* - * If the entire request does not fit into the remaining space in the - * buffer, flush the buffer first. - */ - if (dpy->bufptr + (len << 2) > dpy->bufmax) - _XFlush (dpy); - + /* + * Send the glyphs + */ + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { /* * Switch glyphsets */ - if (elts[i].glyphset != req->glyphset) + if (elts[i].glyphset != glyphset) { + glyphset = elts[i].glyphset; BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); elt->len = 0xff; elt->deltax = 0; elt->deltay = 0; - Data32(dpy, &elts[i].glyphset, 4); + Data32(dpy, &glyphset, 4); } nchars = elts[i].nchars; xDst = elts[i].xOff; @@ -461,15 +468,17 @@ XRenderCompositeText8 (Display *dp chars = elts[i].chars; while (nchars) { + int this_chars = nchars > MAX_8 ? MAX_8 : nchars; + BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) - elt->len = nchars > MAX_8 ? MAX_8 : nchars; + elt->len = this_chars; elt->deltax = xDst; elt->deltay = yDst; xDst = 0; yDst = 0; - Data (dpy, chars, elt->len); - nchars -= elt->len; - chars += elt->len; + Data (dpy, chars, this_chars); + nchars -= this_chars; + chars += this_chars; } } @@ -492,6 +501,7 @@ XRenderCompositeText16 (Display *d { XExtDisplayInfo *info = XRenderFindDisplay (dpy); xRenderCompositeGlyphs16Req *req; + GlyphSet glyphset; long len; long elen; xGlyphElt *elt; @@ -521,10 +531,17 @@ XRenderCompositeText16 (Display *d */ len = 0; + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { - if (elts[i].glyphset != req->glyphset) + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; len += (SIZEOF (xGlyphElt) + 4) >> 2; + } nchars = elts[i].nchars; /* * xGlyphElt must be aligned on a 32-bit boundary; this is @@ -536,26 +553,21 @@ XRenderCompositeText16 (Display *d } req->length += len; - /* - * If the entire request does not fit into the remaining space in the - * buffer, flush the buffer first. - */ - if (dpy->bufptr + (len << 2) > dpy->bufmax) - _XFlush (dpy); - + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { /* * Switch glyphsets */ - if (elts[i].glyphset != req->glyphset) + if (elts[i].glyphset != glyphset) { + glyphset = elts[i].glyphset; BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); elt->len = 0xff; elt->deltax = 0; elt->deltay = 0; - Data32(dpy, &elts[i].glyphset, 4); + Data32(dpy, &glyphset, 4); } nchars = elts[i].nchars; xDst = elts[i].xOff; @@ -563,15 +575,18 @@ XRenderCompositeText16 (Display *d chars = elts[i].chars; while (nchars) { + int this_chars = nchars > MAX_16 ? MAX_16 : nchars; + int this_bytes = this_chars * 2; + BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) - elt->len = nchars > MAX_16 ? MAX_16 : nchars; + elt->len = this_chars; elt->deltax = xDst; elt->deltay = yDst; xDst = 0; yDst = 0; - Data16 (dpy, chars, elt->len * 2); - nchars -= elt->len; - chars += elt->len; + Data16 (dpy, chars, this_bytes); + nchars -= this_chars; + chars += this_chars; } } @@ -594,6 +609,7 @@ XRenderCompositeText32 (Display *d { XExtDisplayInfo *info = XRenderFindDisplay (dpy); xRenderCompositeGlyphs32Req *req; + GlyphSet glyphset; long len; long elen; xGlyphElt *elt; @@ -607,6 +623,7 @@ XRenderCompositeText32 (Display *d RenderSimpleCheckExtension (dpy, info); LockDisplay(dpy); + GetReq(RenderCompositeGlyphs32, req); req->reqType = info->codes->major_opcode; req->renderReqType = X_RenderCompositeGlyphs32; @@ -623,36 +640,38 @@ XRenderCompositeText32 (Display *d */ len = 0; + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { - if (elts[i].glyphset != req->glyphset) + /* + * Check for glyphset change + */ + if (elts[i].glyphset != glyphset) + { + glyphset = elts[i].glyphset; len += (SIZEOF (xGlyphElt) + 4) >> 2; + } nchars = elts[i].nchars; elen = SIZEOF(xGlyphElt) * ((nchars + MAX_32) / MAX_32) + nchars *4; len += (elen + 3) >> 2; } req->length += len; - /* - * If the entire request does not fit into the remaining space in the - * buffer, flush the buffer first. - */ - - if (dpy->bufptr + (len << 2) > dpy->bufmax) - _XFlush (dpy); + glyphset = elts[0].glyphset; for (i = 0; i < nelt; i++) { /* * Switch glyphsets */ - if (elts[i].glyphset != req->glyphset) + if (elts[i].glyphset != glyphset) { + glyphset = elts[i].glyphset; BufAlloc (xGlyphElt *, elt, SIZEOF (xGlyphElt)); elt->len = 0xff; elt->deltax = 0; elt->deltay = 0; - Data32(dpy, &elts[i].glyphset, 4); + Data32(dpy, &glyphset, 4); } nchars = elts[i].nchars; xDst = elts[i].xOff; @@ -660,15 +679,17 @@ XRenderCompositeText32 (Display *d chars = elts[i].chars; while (nchars) { + int this_chars = nchars > MAX_32 ? MAX_32 : nchars; + int this_bytes = this_chars * 4; BufAlloc (xGlyphElt *, elt, SIZEOF(xGlyphElt)) - elt->len = nchars > MAX_32 ? MAX_32 : nchars; + elt->len = this_chars; elt->deltax = xDst; elt->deltay = yDst; xDst = 0; yDst = 0; - Data32 (dpy, chars, elt->len * 4); - nchars -= elt->len; - chars += elt->len; + Data32 (dpy, chars, this_bytes); + nchars -= this_chars; + chars += this_chars; } }