bug 615445 - don't overwrite clusters when storing glyphs in textrun. r=karlt a=joe
authorJonathan Kew <jfkthame@gmail.com>
Wed, 22 Dec 2010 14:27:43 +0000
changeset 59602 beca3b777fc5a121e50073b75f119f7508577b3e
parent 59601 d4215e592acac5f9e11d924cea4f5592ca581d91
child 59603 53dc4a2c24efe9d92ca1be228d83d5665a544669
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewerskarlt, joe
bugs615445
milestone2.0b9pre
bug 615445 - don't overwrite clusters when storing glyphs in textrun. r=karlt a=joe
gfx/thebes/gfxGDIShaper.cpp
gfx/thebes/gfxUniscribeShaper.cpp
--- a/gfx/thebes/gfxGDIShaper.cpp
+++ b/gfx/thebes/gfxGDIShaper.cpp
@@ -95,34 +95,37 @@ gfxGDIShaper::InitTextRun(gfxContext *aC
         return PR_FALSE;
     }
 
     gfxTextRun::CompressedGlyph g;
     PRUint32 i;
     PRInt32 lastWidth = 0;
     PRUint32 appUnitsPerDevPixel = aTextRun->GetAppUnitsPerDevUnit();
     for (i = 0; i < aRunLength; ++i) {
+        PRUint32 offset = aRunStart + i;
         PRInt32 advancePixels = partialWidthArray[i] - lastWidth;
         lastWidth = partialWidthArray[i];
         PRInt32 advanceAppUnits = advancePixels*appUnitsPerDevPixel;
         WCHAR glyph = glyphs[i];
-        NS_ASSERTION(!gfxFontGroup::IsInvalidChar(
-                         aTextRun->GetChar(aRunStart + i)),
+        NS_ASSERTION(!gfxFontGroup::IsInvalidChar(aTextRun->GetChar(offset)),
                      "Invalid character detected!");
+        PRBool atClusterStart = aTextRun->IsClusterStart(offset);
         if (advanceAppUnits >= 0 &&
             gfxTextRun::CompressedGlyph::IsSimpleAdvance(advanceAppUnits) &&
-            gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph)) {
-            aTextRun->SetSimpleGlyph(aRunStart + i,
+            gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph) &&
+            atClusterStart)
+        {
+            aTextRun->SetSimpleGlyph(offset,
                                      g.SetSimpleGlyph(advanceAppUnits, glyph));
         } else {
             gfxTextRun::DetailedGlyph details;
             details.mGlyphID = glyph;
             details.mAdvance = advanceAppUnits;
             details.mXOffset = 0;
             details.mYOffset = 0;
-            aTextRun->SetGlyphs(aRunStart + i,
-                                g.SetComplex(PR_TRUE, PR_TRUE, 1),
+            aTextRun->SetGlyphs(offset,
+                                g.SetComplex(atClusterStart, PR_TRUE, 1),
                                 &details);
         }
     }
 
     return PR_TRUE;
 }
--- a/gfx/thebes/gfxUniscribeShaper.cpp
+++ b/gfx/thebes/gfxUniscribeShaper.cpp
@@ -264,18 +264,19 @@ public:
         ScriptFontProperties(&sfp);
 
         PRUint32 offset = 0;
         nsAutoTArray<gfxTextRun::DetailedGlyph,1> detailedGlyphs;
         gfxTextRun::CompressedGlyph g;
         const PRUint32 appUnitsPerDevUnit = aRun->GetAppUnitsPerDevUnit();
         while (offset < mItemLength) {
             PRUint32 runOffset = offsetInRun + offset;
+            PRBool atClusterStart = aRun->IsClusterStart(runOffset);
             if (offset > 0 && mClusters[offset] == mClusters[offset - 1]) {
-                g.SetComplex(aRun->IsClusterStart(runOffset), PR_FALSE, 0);
+                g.SetComplex(atClusterStart, PR_FALSE, 0);
                 aRun->SetGlyphs(runOffset, g, nsnull);
             } else {
                 // Count glyphs for this character
                 PRUint32 k = mClusters[offset];
                 PRUint32 glyphCount = mNumGlyphs - k;
                 PRUint32 nextClusterOffset;
                 PRBool missing = IsGlyphMissing(&sfp, k);
                 for (nextClusterOffset = offset + 1; nextClusterOffset < mItemLength; ++nextClusterOffset) {
@@ -302,33 +303,37 @@ public:
                                               SURROGATE_TO_UCS4(mItemString[offset],
                                                                 mItemString[offset + 1]));
                     } else {
                         aRun->SetMissingGlyph(runOffset, mItemString[offset]);
                     }
                 } else if (glyphCount == 1 && advance >= 0 &&
                     mOffsets[k].dv == 0 && mOffsets[k].du == 0 &&
                     gfxTextRun::CompressedGlyph::IsSimpleAdvance(advance) &&
-                    gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph)) {
+                    gfxTextRun::CompressedGlyph::IsSimpleGlyphID(glyph) &&
+                    atClusterStart)
+                {
                     aRun->SetSimpleGlyph(runOffset, g.SetSimpleGlyph(advance, glyph));
                 } else {
                     if (detailedGlyphs.Length() < glyphCount) {
                         if (!detailedGlyphs.AppendElements(glyphCount - detailedGlyphs.Length()))
                             return;
                     }
                     PRUint32 i;
                     for (i = 0; i < glyphCount; ++i) {
                         gfxTextRun::DetailedGlyph *details = &detailedGlyphs[i];
                         details->mGlyphID = mGlyphs[k + i];
                         details->mAdvance = mAdvances[k + i]*appUnitsPerDevUnit;
                         details->mXOffset = float(mOffsets[k + i].du)*appUnitsPerDevUnit*aRun->GetDirection();
                         details->mYOffset = - float(mOffsets[k + i].dv)*appUnitsPerDevUnit;
                     }
                     aRun->SetGlyphs(runOffset,
-                        g.SetComplex(PR_TRUE, PR_TRUE, glyphCount), detailedGlyphs.Elements());
+                                    g.SetComplex(atClusterStart, PR_TRUE,
+                                                 glyphCount),
+                                    detailedGlyphs.Elements());
                 }
             }
             ++offset;
         }
     }
 
     void SelectFont() {
         if (mFontSelected)