bug 686190 - ensure glyph buffer is flushed when necessary during synthetic bolding. r=jdaggett
authorJonathan Kew <jfkthame@gmail.com>
Mon, 12 Sep 2011 13:10:46 +0100
changeset 77926 91906f4106817c721391921e60a591ff49788921
parent 77923 f3908eb901515fa929450bd31b7393ceccf98d6d
child 77927 e85c4dc116c5875f4ad6f62cf0a111dd5b656501
push id340
push userclegnitto@mozilla.com
push dateTue, 08 Nov 2011 22:56:33 +0000
treeherdermozilla-beta@f745dc151615 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs686190
milestone9.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 686190 - ensure glyph buffer is flushed when necessary during synthetic bolding. r=jdaggett
gfx/thebes/gfxFont.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1106,20 +1106,20 @@ struct GlyphBuffer {
         : mNumGlyphs(0) { }
 
     cairo_glyph_t *AppendGlyph() {
         return &mGlyphBuffer[mNumGlyphs++];
     }
 
     void Flush(cairo_t *aCR, PRBool aDrawToPath, PRBool aReverse,
                PRBool aFinish = PR_FALSE) {
-        // Ensure there's enough room for at least two glyphs in the
-        // buffer (because we may allocate two glyphs between flushes)
-        if (!aFinish && mNumGlyphs + 2 <= GLYPH_BUFFER_SIZE)
+        // Ensure there's enough room for a glyph to be added to the buffer
+        if (!aFinish && mNumGlyphs < GLYPH_BUFFER_SIZE) {
             return;
+        }
 
         if (aReverse) {
             for (PRUint32 i = 0; i < mNumGlyphs/2; ++i) {
                 cairo_glyph_t tmp = mGlyphBuffer[i];
                 mGlyphBuffer[i] = mGlyphBuffer[mNumGlyphs - 1 - i];
                 mGlyphBuffer[mNumGlyphs - 1 - i] = tmp;
             }
         }
@@ -1217,35 +1217,35 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUi
                 x -= advance;
                 glyphX = x;
             } else {
                 glyphX = x;
                 x += advance;
             }
             glyph->x = ToDeviceUnits(glyphX, devUnitsPerAppUnit);
             glyph->y = ToDeviceUnits(y, devUnitsPerAppUnit);
+            glyphs.Flush(cr, aDrawToPath, isRTL);
             
             // synthetic bolding by multi-striking with 1-pixel offsets
             // at least once, more if there's room (large font sizes)
             if (IsSyntheticBold()) {
                 double strikeOffset = synBoldOnePixelOffset;
                 PRInt32 strikeCount = strikes;
                 do {
                     cairo_glyph_t *doubleglyph;
                     doubleglyph = glyphs.AppendGlyph();
                     doubleglyph->index = glyph->index;
                     doubleglyph->x =
                         ToDeviceUnits(glyphX + strikeOffset * appUnitsPerDevUnit,
                                       devUnitsPerAppUnit);
                     doubleglyph->y = glyph->y;
                     strikeOffset += synBoldOnePixelOffset;
+                    glyphs.Flush(cr, aDrawToPath, isRTL);
                 } while (--strikeCount > 0);
             }
-            
-            glyphs.Flush(cr, aDrawToPath, isRTL);
         } else {
             PRUint32 glyphCount = glyphData->GetGlyphCount();
             if (glyphCount > 0) {
                 const gfxTextRun::DetailedGlyph *details =
                     aTextRun->GetDetailedGlyphs(i);
                 NS_ASSERTION(details, "detailedGlyph should not be missing!");
                 for (PRUint32 j = 0; j < glyphCount; ++j, ++details) {
                     double advance = details->mAdvance;
@@ -1270,34 +1270,34 @@ gfxFont::Draw(gfxTextRun *aTextRun, PRUi
                         glyph = glyphs.AppendGlyph();
                         glyph->index = details->mGlyphID;
                         double glyphX = x + details->mXOffset;
                         if (isRTL) {
                             glyphX -= advance;
                         }
                         glyph->x = ToDeviceUnits(glyphX, devUnitsPerAppUnit);
                         glyph->y = ToDeviceUnits(y + details->mYOffset, devUnitsPerAppUnit);
+                        glyphs.Flush(cr, aDrawToPath, isRTL);
 
                         if (IsSyntheticBold()) {
                             double strikeOffset = synBoldOnePixelOffset;
                             PRInt32 strikeCount = strikes;
                             do {
                                 cairo_glyph_t *doubleglyph;
                                 doubleglyph = glyphs.AppendGlyph();
                                 doubleglyph->index = glyph->index;
                                 doubleglyph->x =
                                     ToDeviceUnits(glyphX + strikeOffset *
                                                       appUnitsPerDevUnit,
                                                   devUnitsPerAppUnit);
                                 doubleglyph->y = glyph->y;
                                 strikeOffset += synBoldOnePixelOffset;
+                                glyphs.Flush(cr, aDrawToPath, isRTL);
                             } while (--strikeCount > 0);
                         }
-
-                        glyphs.Flush(cr, aDrawToPath, isRTL);
                     }
                     x += direction*advance;
                 }
             }
         }
 
         if (aSpacing) {
             double space = aSpacing[i - aStart].mAfter;