Bug#181815: xlibs: Problem with XRenderCompositeText16 in Render extension
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 <mharris@redhat.com> 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;
}
}
Reply to: