bug 763873 - avoid repeatedly accessing aRanges.Length() within ComputeRanges. r=jdaggett
--- 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;
}