--- mozilla/gfx/src/gtk/nsFontMetricsXft.cpp.orig 2006-08-17 00:57:50 +0400 +++ mozilla/gfx/src/gtk/nsFontMetricsXft.cpp 2006-08-17 01:02:04 +0400 @@ -2189,19 +2189,27 @@ nsAutoDrawSpecBuffer::Flush() { if (mSpecPos) { - // Some Xft libraries will crash if none of the glyphs have any - // area. So before we draw, we scan through the glyphs. If we - // find any that have area, we can draw. - for (PRUint32 i = 0; i < mSpecPos; i++) { - XftGlyphFontSpec *sp = &mSpecBuffer[i]; - XGlyphInfo info; - XftGlyphExtents(GDK_DISPLAY(), sp->font, &sp->glyph, 1, &info); - if (info.width && info.height) { - // If we get here it means we found a drawable glyph. We will - // Draw all the remaining glyphs and then break out of the loop - XftDrawGlyphFontSpec(mDraw, mColor, mSpecBuffer+i, mSpecPos-i); - break; + // There are two Xft problems to work around here: + // 1. Some Xft libraries reportedly crash if none of the + // glyphs have any area. + // 2. Because of an apparent X server bug (see bug 252033), + // a glyph with no area may cause all following glyphs to be + // dropped under some circumstances. + // For this reason, we manually ship out blocks of glyphs with + // area and skip blocks of glyphs with no area. + PRUint32 start = 0; + while (start < mSpecPos) { + PRUint32 i; + for (i = start; i < mSpecPos; i++) { + XftGlyphFontSpec *sp = &mSpecBuffer[i]; + XGlyphInfo info; + XftGlyphExtents(GDK_DISPLAY(), sp->font, &sp->glyph, 1, &info); + if (!info.width || !info.height) + break; } + if (i > start) + XftDrawGlyphFontSpec(mDraw, mColor, mSpecBuffer+start, i-start); + start = i + 1; } mSpecPos = 0; }