bug 763873 - avoid repeatedly accessing aRanges.Length() within ComputeRanges. r=jdaggett
authorJonathan Kew <jkew@mozilla.com>
Tue, 26 Jun 2012 09:51:37 +0100
changeset 100369 064319559cb2f50e1ea9e20fca3e36ad4663a223
parent 100368 0c149cc0dd0cd1be91ef5f2581e1cf5b2902ddef
child 100370 7519820af249a17d6267f992db2e5648c29e76a3
push idunknown
push userunknown
push dateunknown
reviewersjdaggett
bugs763873
milestone16.0a1
bug 763873 - avoid repeatedly accessing aRanges.Length() within ComputeRanges. r=jdaggett
gfx/thebes/gfxFont.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -3406,16 +3406,18 @@ gfxFontGroup::MakeTextRun(const PRUnicha
 
 template<typename T>
 void
 gfxFontGroup::InitTextRun(gfxContext *aContext,
                           gfxTextRun *aTextRun,
                           const T *aString,
                           PRUint32 aLength)
 {
+    NS_ASSERTION(aLength > 0, "don't call InitTextRun for a zero-length run");
+
     // we need to do numeral processing even on 8-bit text,
     // in case we're converting Western to Hindi/Arabic digits
     PRInt32 numOption = gfxPlatform::GetPlatform()->GetBidiNumeralOption();
     nsAutoArrayPtr<PRUnichar> transformedString;
     if (numOption != IBMBIDI_NUMERAL_NOMINAL) {
         // scan the string for numerals that may need to be transformed;
         // if we find any, we'll make a local copy here and use that for
         // font matching and glyph generation/shaping
@@ -3522,16 +3524,19 @@ template<typename T>
 void
 gfxFontGroup::InitScriptRun(gfxContext *aContext,
                             gfxTextRun *aTextRun,
                             const T *aString,
                             PRUint32 aScriptRunStart,
                             PRUint32 aScriptRunEnd,
                             PRInt32 aRunScript)
 {
+    NS_ASSERTION(aScriptRunEnd > aScriptRunStart,
+                 "don't call InitScriptRun for a zero-length run");
+
     gfxFont *mainFont = GetFontAt(0);
 
     PRUint32 runStart = aScriptRunStart;
     nsAutoTArray<gfxTextRange,3> fontRanges;
     ComputeRanges(fontRanges, aString + aScriptRunStart,
                   aScriptRunEnd - aScriptRunStart, aRunScript);
     PRUint32 numRanges = fontRanges.Length();
 
@@ -3758,24 +3763,22 @@ gfxFontGroup::FindFontForChar(PRUint32 a
     return font.forget();
 }
 
 template<typename T>
 void gfxFontGroup::ComputeRanges(nsTArray<gfxTextRange>& aRanges,
                                  const T *aString, PRUint32 aLength,
                                  PRInt32 aRunScript)
 {
-    aRanges.Clear();
-
-    if (aLength == 0) {
-        return;
-    }
+    NS_ASSERTION(aRanges.Length() == 0, "aRanges must be initially empty");
+    NS_ASSERTION(aLength > 0, "don't call ComputeRanges for zero-length text");
 
     PRUint32 prevCh = 0;
     PRUint8 matchType = 0;
+    PRInt32 lastRangeIndex = -1;
 
     // initialize prevFont to the group's primary font, so that this will be
     // used for string-initial control chars, etc rather than risk hitting font
     // fallback for these (bug 716229)
     gfxFont *prevFont = GetFontAt(0);
 
     for (PRUint32 i = 0; i < aLength; i++) {
 
@@ -3798,41 +3801,44 @@ void gfxFontGroup::ComputeRanges(nsTArra
         }
 
         // find the font for this char
         nsRefPtr<gfxFont> font =
             FindFontForChar(ch, prevCh, aRunScript, prevFont, &matchType);
 
         prevCh = ch;
 
-        if (aRanges.Length() == 0) {
+        if (lastRangeIndex == -1) {
             // first char ==> make a new range
             aRanges.AppendElement(gfxTextRange(0, 1, font, matchType));
+            lastRangeIndex++;
             prevFont = font;
         } else {
             // if font has changed, make a new range
-            gfxTextRange& prevRange = aRanges[aRanges.Length() - 1];
+            gfxTextRange& prevRange = aRanges[lastRangeIndex];
             if (prevRange.font != font || prevRange.matchType != matchType) {
                 // close out the previous range
                 prevRange.end = origI;
                 aRanges.AppendElement(gfxTextRange(origI, i + 1,
                                                    font, matchType));
+                lastRangeIndex++;
 
                 // update prevFont for the next match, *unless* we switched
                 // fonts on a ZWJ, in which case propagating the changed font
                 // is probably not a good idea (see bug 619511)
                 if (sizeof(T) == sizeof(PRUint8) ||
                     !gfxFontUtils::IsJoinCauser(ch))
                 {
                     prevFont = font;
                 }
             }
         }
     }
-    aRanges[aRanges.Length() - 1].end = aLength;
+
+    aRanges[lastRangeIndex].end = aLength;
 }
 
 gfxUserFontSet* 
 gfxFontGroup::GetUserFontSet()
 {
     return mUserFontSet;
 }