PRUnichar* aBuffer, PRInt32 aLength,
PRUnichar* aBuffer, PRInt32 aLength, PRBool aIsEndOfFrame,
nsTextFrame::GetTextDimensionsOrLength(nsIRenderingContext& aRenderingContext,                TextStyle& aStyle,                PRUnichar* aBuffer, PRInt32 aLength,                nsTextDimensions* aDimensionsResult,                PRBool aGetTextDimensions/* true=get dimensions false = return length up to aDimensionsResult.width size*/){  PRUnichar *inBuffer = aBuffer;  PRInt32 length = aLength;  nsAutoTextBuffer dimensionsBuffer;  if (NS_FAILED(dimensionsBuffer.GrowTo(length))) {    aDimensionsResult->Clear();    return 0;  }  PRUnichar* bp = dimensionsBuffer.mBuffer;  nsIFontMetrics* lastFont = aStyle.mLastFont;  nsTextDimensions sum, glyphDimensions;  PRBool justifying = aStyle.mJustifying &&    (aStyle.mNumJustifiableCharacterReceivingExtraJot != 0 || aStyle.mExtraSpacePerJustifiableCharacter != 0);  PRBool isCJ = IsChineseJapaneseLangGroup();  while (--length >= 0) {    PRUnichar ch = *inBuffer++;    if (aStyle.mSmallCaps &&        (IsLowerCase(ch) || (ch == kSZLIG))) {      PRUnichar upper_ch;      // German szlig should be expanded to "SS".      if (ch == kSZLIG)        upper_ch = (PRUnichar)'S';      else        upper_ch = ToUpperCase(ch);      if (lastFont != aStyle.mSmallFont) {        lastFont = aStyle.mSmallFont;        aRenderingContext.SetFont(lastFont);      }      aRenderingContext.GetTextDimensions(&upper_ch, (PRUint32)1, glyphDimensions);      glyphDimensions.width += aStyle.mLetterSpacing;      if (ch == kSZLIG)        glyphDimensions.width += glyphDimensions.width;    }    else if (ch == ' ') {      glyphDimensions.width = aStyle.mSpaceWidth + aStyle.mLetterSpacing        + aStyle.mWordSpacing;    }    else {      if (lastFont != aStyle.mNormalFont) {        lastFont = aStyle.mNormalFont;        aRenderingContext.SetFont(lastFont);      }      aRenderingContext.GetTextDimensions(&ch, (PRUint32)1, glyphDimensions);      glyphDimensions.width += aStyle.mLetterSpacing;    }    if (justifying && IsJustifiableCharacter(ch, isCJ)) {      glyphDimensions.width += aStyle.mExtraSpacePerJustifiableCharacter;      if ((PRUint32)--aStyle.mNumJustifiableCharacterToMeasure            < (PRUint32)aStyle.mNumJustifiableCharacterReceivingExtraJot) {        ++glyphDimensions.width;      }    }    sum.Combine(glyphDimensions);    *bp++ = ch;    if (!aGetTextDimensions && sum.width >= aDimensionsResult->width) {      PRInt32 result = aLength - length;      if (2*(sum.width - aDimensionsResult->width) > glyphDimensions.width) //then we have gone too far, back up 1        result--;      aStyle.mLastFont = lastFont;      return result;    }  }  aStyle.mLastFont = lastFont;  *aDimensionsResult = sum;  return aLength;}