Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Static Protected Attributes
nsTextTransformer Class Reference

This object manages the transformation of text: More...

#include <nsTextTransformer.h>

Collaboration diagram for nsTextTransformer:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsTextTransformer (nsILineBreaker *aLineBreaker, nsIWordBreaker *aWordBreaker, nsPresContext *aPresContext)
 ~nsTextTransformer ()
nsresult Init (nsIFrame *aFrame, nsIContent *aContent, PRInt32 aStartingOffset, PRBool aForceArabicShaping=PR_FALSE, PRBool aLeaveAsAscii=PR_FALSE)
 Initialize the text transform.
PRInt32 GetContentLength () const
PRUnichar GetContentCharAt (PRInt32 aIndex)
PRUnicharGetNextWord (PRBool aInWord, PRInt32 *aWordLenResult, PRInt32 *aContentLenResult, PRBool *aIsWhitespaceResult, PRBool *aWasTransformed, PRBool aResetTransformBuf=PR_TRUE, PRBool aForLineBreak=PR_TRUE, PRBool aIsKeyboardSelect=PR_FALSE)
 Iterates the next word in the text fragment.
PRUnicharGetPrevWord (PRBool aInWord, PRInt32 *aWordLenResult, PRInt32 *aContentLenResult, PRBool *aIsWhitespaceResult, PRBool aForLineBreak=PR_TRUE, PRBool aIsKeyboardSelect=PR_FALSE)
PRBool LeaveAsAscii () const
PRBool HasMultibyte () const
PRBool TransformedTextIsAscii () const
void SetLeaveAsAscii (PRBool aValue)
void SetHasMultibyte (PRBool aValue)
void SetTransformedTextIsAscii (PRBool aValue)
PRUnicharGetWordBuffer ()
PRInt32 GetWordBufferLength () const

Static Public Member Functions

static PRBool GetWordSelectEatSpaceAfter ()
static PRBool GetWordSelectStopAtPunctuation ()
static nsresult Initialize ()
static void Shutdown ()

Protected Types

enum  { eNormal, ePreformatted, ePreWrap }

Protected Member Functions

PRInt32 ScanNormalWhiteSpace_F (PRInt32 aFragLen)
PRInt32 ScanNormalAsciiText_F (PRInt32 aFragLen, PRInt32 *aWordLen, PRBool *aWasTransformed)
PRInt32 ScanNormalAsciiText_F_ForWordBreak (PRInt32 aFragLen, PRInt32 *aWordLen, PRBool *aWasTransformed, PRBool aIsKeyboardSelect)
PRInt32 ScanNormalUnicodeText_F (PRInt32 aFragLen, PRBool aForLineBreak, PRInt32 *aWordLen, PRBool *aWasTransformed)
PRInt32 ScanPreWrapWhiteSpace_F (PRInt32 aFragLen, PRInt32 *aWordLen)
PRInt32 ScanPreAsciiData_F (PRInt32 aFragLen, PRInt32 *aWordLen, PRBool *aWasTransformed)
PRInt32 ScanPreData_F (PRInt32 aFragLen, PRInt32 *aWordLen, PRBool *aWasTransformed)
PRInt32 ScanNormalWhiteSpace_B ()
PRInt32 ScanNormalAsciiText_B (PRInt32 *aWordLen, PRBool aIsKeyboardSelect)
PRInt32 ScanNormalUnicodeText_B (PRBool aForLineBreak, PRInt32 *aWordLen)
PRInt32 ScanPreWrapWhiteSpace_B (PRInt32 *aWordLen)
PRInt32 ScanPreData_B (PRInt32 *aWordLen)
void ConvertTransformedTextToUnicode ()
void LanguageSpecificTransform (PRUnichar *aText, PRInt32 aLen, PRBool *aWasTransformed)
void DoArabicShaping (PRUnichar *aText, PRInt32 &aTextLength, PRBool *aWasTransformed)
void DoNumericShaping (PRUnichar *aText, PRInt32 &aTextLength, PRBool *aWasTransformed)

Static Protected Member Functions

static int WordSelectPrefCallback (const char *aPref, void *aClosure)

Protected Attributes

const nsTextFragmentmFrag
PRInt32 mOffset
enum nsTextTransformer:: { ... }  mMode
nsILineBreakermLineBreaker
nsIWordBreakermWordBreaker
nsLanguageSpecificTransformType mLanguageSpecificTransformType
nsAutoTextBuffer mTransformBuf
PRInt32 mBufferPos
PRUint8 mTextTransform
PRUint8 mFlags

Static Protected Attributes

static PRBool sWordSelectListenerPrefChecked = PR_FALSE
static PRBool sWordSelectEatSpaceAfter = PR_FALSE
static PRBool sWordSelectStopAtPunctuation = PR_FALSE

Detailed Description

This object manages the transformation of text:

Note that no transformations are applied that would impact word breaking (like mapping   into space, for example). In addition, this logic will not strip leading or trailing whitespace (across the entire run of text; leading whitespace can be skipped for a frames text because of whitespace compression).

Definition at line 151 of file nsTextTransformer.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
eNormal 
ePreformatted 
ePreWrap 

Definition at line 345 of file nsTextTransformer.h.


Constructor & Destructor Documentation

nsTextTransformer::nsTextTransformer ( nsILineBreaker aLineBreaker,
nsIWordBreaker aWordBreaker,
nsPresContext aPresContext 
)

Definition at line 169 of file nsTextTransformer.cpp.

  : mFrag(nsnull),
    mOffset(0),
    mMode(eNormal),
    mLineBreaker(aLineBreaker),
    mWordBreaker(aWordBreaker),
    mBufferPos(0),
    mTextTransform(NS_STYLE_TEXT_TRANSFORM_NONE),
    mFlags(0)
{
  MOZ_COUNT_CTOR(nsTextTransformer);

  mLanguageSpecificTransformType =
    aPresContext->LanguageSpecificTransformType();

#ifdef IBMBIDI
  mPresContext = aPresContext;
#endif
  if (aLineBreaker == nsnull && aWordBreaker == nsnull )
    NS_ASSERTION(0, "invalid creation of nsTextTransformer");
  
#ifdef DEBUG
  static PRBool firstTime = PR_TRUE;
  if (firstTime) {
    firstTime = PR_FALSE;
    SelfTest(aLineBreaker, aWordBreaker, aPresContext);
  }
#endif
}

Definition at line 201 of file nsTextTransformer.cpp.


Member Function Documentation

Definition at line 319 of file nsTextTransformer.cpp.

{
  // Go backwards over the characters and convert them.
  PRInt32         lastChar = mBufferPos - 1;
  unsigned char*  cp1 = (unsigned char*)mTransformBuf.mBuffer + lastChar;
  PRUnichar*      cp2 = mTransformBuf.mBuffer + lastChar;
  
  NS_ASSERTION(mTransformBuf.mBufferLen >= mBufferPos,
               "transform buffer is too small");
  for (PRInt32 count = mBufferPos; count > 0; count--) {
    *cp2-- = PRUnichar(*cp1--);
  }
}

Here is the caller graph for this function:

void nsTextTransformer::DoArabicShaping ( PRUnichar aText,
PRInt32 aTextLength,
PRBool aWasTransformed 
) [protected]

Definition at line 1467 of file nsTextTransformer.cpp.

{
  if (aTextLength <= 0)
    return;
  
  PRInt32 newLen;
  PRBool isVisual = mPresContext->IsVisualMode();

  nsAutoString buf;
  if (!EnsureStringLength(buf, aTextLength)) {
    // no way to signal OOM
    aTextLength = 0;
    return;
  }
  PRUnichar* buffer = buf.BeginWriting();
  
  ArabicShaping(aText, buf.Length(), buffer, (PRUint32 *)&newLen, !isVisual, !isVisual);

  if (newLen <= aTextLength) {
    aTextLength = newLen;
  } else {
    // Increasing |aTextLength| would cause a buffer overflow on |aText|
    // by the memcpy() below.
    NS_ERROR("ArabicShaping should not have increased the text length");
  }
  *aWasTransformed = PR_TRUE;

  memcpy(aText, buffer, aTextLength * sizeof(PRUnichar));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTextTransformer::DoNumericShaping ( PRUnichar aText,
PRInt32 aTextLength,
PRBool aWasTransformed 
) [protected]

Definition at line 1500 of file nsTextTransformer.cpp.

{
  if (aTextLength <= 0)
    return;

  PRUint32 bidiOptions = mPresContext->GetBidi();

  switch (GET_BIDI_OPTION_NUMERAL(bidiOptions)) {

    case IBMBIDI_NUMERAL_HINDI:
      HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_HINDI);
      break;

    case IBMBIDI_NUMERAL_ARABIC:
      HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_ARABIC);
      break;

    case IBMBIDI_NUMERAL_REGULAR:

      switch (mCharType) {

        case eCharType_EuropeanNumber:
          HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_ARABIC);
          break;

        case eCharType_ArabicNumber:
          HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_HINDI);
          break;

        default:
          break;
      }
      break;

    case IBMBIDI_NUMERAL_HINDICONTEXT:
      if (((GET_BIDI_OPTION_DIRECTION(bidiOptions)==IBMBIDI_TEXTDIRECTION_RTL) &&
           (IS_ARABIC_DIGIT (aText[0]))) ||
          (eCharType_ArabicNumber == mCharType))
        HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_HINDI);
      else if (eCharType_EuropeanNumber == mCharType)
        HandleNumbers(aText, aTextLength, IBMBIDI_NUMERAL_ARABIC);
      break;

    case IBMBIDI_NUMERAL_NOMINAL:
    default:
      break;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 183 of file nsTextTransformer.h.

                                             {
    return (mFrag && aIndex < mFrag->GetLength()) ? mFrag->CharAt(aIndex) : 0;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 179 of file nsTextTransformer.h.

                                   {
    return mFrag ? mFrag->GetLength() : 0;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

PRUnichar * nsTextTransformer::GetNextWord ( PRBool  aInWord,
PRInt32 aWordLenResult,
PRInt32 aContentLenResult,
PRBool aIsWhitespaceResult,
PRBool aWasTransformed,
PRBool  aResetTransformBuf = PR_TRUE,
PRBool  aForLineBreak = PR_TRUE,
PRBool  aIsKeyboardSelect = PR_FALSE 
)

Iterates the next word in the text fragment.

Returns a pointer to the word, the number of characters in the word, the content length of the word, whether it is whitespace, and whether the text was transformed (any of the transformations listed above). The content length can be greater than the word length if whitespace compression occured or if characters were discarded

The default behavior is to reset the transform buffer to the beginning, but you can choose to not reste it and buffer across multiple words

Definition at line 836 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 fragLen = frag->GetLength();
  if (*aWordLenResult > 0 && *aWordLenResult < fragLen) {
    fragLen = *aWordLenResult;
  }

  PRInt32 offset = mOffset;
  PRInt32 wordLen = 0;
  PRBool isWhitespace = PR_FALSE;
  PRUnichar* result = nsnull;
  PRInt32 prevBufferPos;
  PRBool skippedWhitespace = PR_FALSE;

  // Initialize OUT parameter
  *aWasTransformed = PR_FALSE;

  // See if we should reset the current buffer position back to the
  // beginning of the buffer
  if (aResetTransformBuf) {
    mBufferPos = 0;
    SetTransformedTextIsAscii(LeaveAsAscii());
  }
  prevBufferPos = mBufferPos;

  // Fix word breaking problem w/ PREFORMAT and PREWRAP
  // for word breaking, we should really go to the normal code
  if((! aForLineBreak) && (eNormal != mMode))
     mMode = eNormal;

  while (offset < fragLen) {
    PRUnichar firstChar = frag->CharAt(offset);

    // Eat up any discarded characters before dispatching
    if (IS_DISCARDED(firstChar)) {
      offset++;
      continue;
    }

    switch (mMode) {
      default:
      case eNormal:
        if (XP_IS_SPACE(firstChar)) {
          offset = ScanNormalWhiteSpace_F(fragLen);

          // if this is just a '\n', and characters before and after it are CJK chars, 
          // we will skip this one.
          if (firstChar == '\n' && 
              offset - mOffset == 1 && 
              mOffset > 0 &&
              offset < fragLen) 
          {
            PRUnichar lastChar = frag->CharAt(mOffset - 1);
            PRUnichar nextChar = frag->CharAt(offset);
            if (IS_CJ_CHAR(lastChar) && IS_CJ_CHAR(nextChar)) {
              skippedWhitespace = PR_TRUE;
              --mBufferPos;
              mOffset = offset;
              continue;            }
          }
          if (firstChar != ' ') {
            *aWasTransformed = PR_TRUE;
          }
          wordLen = 1;
          isWhitespace = PR_TRUE;
        }
        else if (CH_NBSP == firstChar && !aForLineBreak) {
          wordLen = 1;
          isWhitespace = PR_TRUE;
          *aWasTransformed = PR_TRUE;

          // Make sure we have enough room in the transform buffer
          if (mBufferPos >= mTransformBuf.mBufferLen) {
             mTransformBuf.GrowBy(128);
          }

          offset++;
          if (TransformedTextIsAscii()) {
            ((unsigned char*)mTransformBuf.mBuffer)[mBufferPos++] = ' ';
          } else {
            mTransformBuf.mBuffer[mBufferPos++] = PRUnichar(' ');
          }
        }
        else if (frag->Is2b()) {
#ifdef IBMBIDI
          wordLen = *aWordLenResult;
#endif
          offset = ScanNormalUnicodeText_F(fragLen, aForLineBreak, &wordLen, aWasTransformed);
        }
        else {
          if (!aForLineBreak)
            offset = ScanNormalAsciiText_F_ForWordBreak(fragLen, &wordLen, 
                                                        aWasTransformed, 
                                                        aIsKeyboardSelect);
          else
            offset = ScanNormalAsciiText_F(fragLen, &wordLen, aWasTransformed);
        }
        break;

      case ePreformatted:
        if (('\n' == firstChar) || ('\t' == firstChar)) {
          mTransformBuf.mBuffer[mBufferPos++] = firstChar;
          offset++;
          wordLen = 1;
          isWhitespace = PR_TRUE;
        }
        else if (frag->Is2b()) {
          offset = ScanPreData_F(fragLen, &wordLen, aWasTransformed);
        }
        else {
          offset = ScanPreAsciiData_F(fragLen, &wordLen, aWasTransformed);
        }
        break;

      case ePreWrap:
        if (XP_IS_SPACE(firstChar)) {
          if (('\n' == firstChar) || ('\t' == firstChar)) {
            mTransformBuf.mBuffer[mBufferPos++] = firstChar;
            offset++;
            wordLen = 1;
          }
          else {
            offset = ScanPreWrapWhiteSpace_F(fragLen, &wordLen);
          }
          isWhitespace = PR_TRUE;
        }
        else if (frag->Is2b()) {
#ifdef IBMBIDI
          wordLen = *aWordLenResult;
#endif
          offset = ScanNormalUnicodeText_F(fragLen, aForLineBreak, &wordLen, aWasTransformed);
        }
        else {
          if (!aForLineBreak)
            offset = ScanNormalAsciiText_F_ForWordBreak(fragLen, &wordLen, aWasTransformed, 
                                                        aIsKeyboardSelect);
          else
            offset = ScanNormalAsciiText_F(fragLen, &wordLen, aWasTransformed);
        }
        break;
    }

    if (TransformedTextIsAscii()) {
      unsigned char* wordPtr = (unsigned char*)mTransformBuf.mBuffer + prevBufferPos;
      
      if (!isWhitespace) {
        switch (mTextTransform) {
        case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
          if (!aInWord)
            *wordPtr = toupper(*wordPtr);
          break;
        case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
          AsciiToLowerCase(wordPtr, wordLen);
          break;
        case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
          AsciiToUpperCase(wordPtr, wordLen);
          break;
        }
        NS_ASSERTION(mLanguageSpecificTransformType ==
                     eLanguageSpecificTransformType_None,
                     "should not be ASCII for language specific transforms");
      }
      result = (PRUnichar*)wordPtr;

    } else {
      result = &mTransformBuf.mBuffer[prevBufferPos];

      if (!isWhitespace) {
        switch (mTextTransform) {
        case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
          if(NS_SUCCEEDED(EnsureCaseConv()))
            gCaseConv->ToTitle(result, result, wordLen, !aInWord);
          // if the first character is szlig
          if(kSzlig == *result)
          {
              if (mBufferPos + 1 >= mTransformBuf.mBufferLen) {
                mTransformBuf.GrowBy(128);
                result = &mTransformBuf.mBuffer[prevBufferPos];
              }
              PRUnichar* src = result +  mBufferPos-prevBufferPos;
              while(src>result) 
              {
                *src = *(src-1);
                src--;
              }
              result[0] = PRUnichar('S');
              result[1] = PRUnichar('S');
              wordLen++;
          }
          break;
        case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
          if(NS_SUCCEEDED(EnsureCaseConv()))
            gCaseConv->ToLower(result, result, wordLen);
          break;
        case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
          {
            if(NS_SUCCEEDED(EnsureCaseConv()))
              gCaseConv->ToUpper(result, result, wordLen);

            // first we search for German Szlig
            PRInt32 szligCnt = CountGermanSzlig(result, wordLen);
            if(szligCnt > 0) {
              // Make sure we have enough room in the transform buffer
              if (mBufferPos + szligCnt >= mTransformBuf.mBufferLen)
              {
                mTransformBuf.GrowBy(128);
                result = &mTransformBuf.mBuffer[prevBufferPos];
              }
              ReplaceGermanSzligToSS(result, mBufferPos-prevBufferPos, szligCnt);
              wordLen += szligCnt;
            }
          }
          break;
        }
        if (mLanguageSpecificTransformType !=
            eLanguageSpecificTransformType_None) {
          LanguageSpecificTransform(result, wordLen, aWasTransformed);
        }
        if (NeedsArabicShaping()) {
          DoArabicShaping(result, wordLen, aWasTransformed);
        }
        if (NeedsNumericShaping()) {
          DoNumericShaping(result, wordLen, aWasTransformed);
        }
      }
    }

    break;
  }

  *aIsWhiteSpaceResult = isWhitespace;
  *aWordLenResult = wordLen;
  *aContentLenResult = offset - mOffset;

  // we need to adjust the length if a '\n' has been skip between CJK chars
  *aContentLenResult += (skippedWhitespace ? 1 : 0);

  // If the word length doesn't match the content length then we transformed
  // the text
  if ((mTextTransform != NS_STYLE_TEXT_TRANSFORM_NONE) ||
      (*aWordLenResult != *aContentLenResult)) {
    *aWasTransformed = PR_TRUE;
    mBufferPos = prevBufferPos + *aWordLenResult;
  }

  mOffset = offset;

  NS_ASSERTION(mBufferPos == prevBufferPos + *aWordLenResult, "internal error");
  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRUnichar * nsTextTransformer::GetPrevWord ( PRBool  aInWord,
PRInt32 aWordLenResult,
PRInt32 aContentLenResult,
PRBool aIsWhitespaceResult,
PRBool  aForLineBreak = PR_TRUE,
PRBool  aIsKeyboardSelect = PR_FALSE 
)

Definition at line 1342 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRInt32 wordLen = 0;
  PRBool isWhitespace = PR_FALSE;
  PRUnichar* result = nsnull;

  // Fix word breaking problem w/ PREFORMAT and PREWRAP
  // for word breaking, we should really go to the normal code
  if((! aForLineBreak) && (eNormal != mMode))
     mMode = eNormal;

#ifdef IBMBIDI
  PRInt32 limit = (*aWordLenResult > 0) ? *aWordLenResult : 0;
  while (--offset >= limit) {
#else
  while (--offset >= 0) {
#endif
    PRUnichar firstChar = frag->CharAt(offset);

    // Eat up any discarded characters before dispatching
    if (IS_DISCARDED(firstChar)) {
      continue;
    }

    switch (mMode) {
      default:
      case eNormal:
        if (XP_IS_SPACE(firstChar)) {
          offset = ScanNormalWhiteSpace_B();
          wordLen = 1;
          isWhitespace = PR_TRUE;
        }
        else if (CH_NBSP == firstChar && !aForLineBreak) {
          wordLen = 1;
          isWhitespace = PR_TRUE;
          mTransformBuf.mBuffer[mTransformBuf.mBufferLen - 1] = ' ';
          offset--;
        } else if (frag->Is2b()) {
#ifdef IBMBIDI
          wordLen = *aWordLenResult;
#endif
          offset = ScanNormalUnicodeText_B(aForLineBreak, &wordLen);
        }
        else {
          offset = ScanNormalAsciiText_B(&wordLen, aIsKeyboardSelect);
        }
        break;

      case ePreformatted:
        if (('\n' == firstChar) || ('\t' == firstChar)) {
          mTransformBuf.mBuffer[mTransformBuf.mBufferLen-1] = firstChar;
          offset--;  // make sure we overshoot
          wordLen = 1;
          isWhitespace = PR_TRUE;
        }
        else {
          offset = ScanPreData_B(&wordLen);
        }
        break;

      case ePreWrap:
        if (XP_IS_SPACE(firstChar)) {
          if (('\n' == firstChar) || ('\t' == firstChar)) {
            mTransformBuf.mBuffer[mTransformBuf.mBufferLen-1] = firstChar;
            offset--;  // make sure we overshoot
            wordLen = 1;
          }
          else {
            offset = ScanPreWrapWhiteSpace_B(&wordLen);
          }
          isWhitespace = PR_TRUE;
        }
        else if (frag->Is2b()) {
#ifdef IBMBIDI
          wordLen = *aWordLenResult;
#endif
          offset = ScanNormalUnicodeText_B(aForLineBreak, &wordLen);
        }
        else {
          offset = ScanNormalAsciiText_B(&wordLen, aIsKeyboardSelect);
        }
        break;
    }

    // Backwards scanning routines *always* overshoot by one for the
    // returned offset value.
    offset = offset + 1;

    result = mTransformBuf.GetBufferEnd() - wordLen;

    if (!isWhitespace) {
      switch (mTextTransform) {
        case NS_STYLE_TEXT_TRANSFORM_CAPITALIZE:
          if(NS_SUCCEEDED(EnsureCaseConv()))
            gCaseConv->ToTitle(result, result, wordLen, !aInWord);
          break;
        case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
          if(NS_SUCCEEDED(EnsureCaseConv()))
            gCaseConv->ToLower(result, result, wordLen);
          break;
        case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
          if(NS_SUCCEEDED(EnsureCaseConv()))
            gCaseConv->ToUpper(result, result, wordLen);
          break;
      }
    }
    break;
  }

  *aWordLenResult = wordLen;
  *aContentLenResult = mOffset - offset;
  *aIsWhiteSpaceResult = isWhitespace;

  mOffset = offset;
  return result;
}

Here is the call graph for this function:

Definition at line 278 of file nsTextTransformer.h.

                             {
    return mTransformBuf.GetBuffer();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 282 of file nsTextTransformer.h.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 286 of file nsTextTransformer.h.

Here is the caller graph for this function:

Definition at line 290 of file nsTextTransformer.h.

Definition at line 222 of file nsTextTransformer.h.

Here is the caller graph for this function:

nsresult nsTextTransformer::Init ( nsIFrame aFrame,
nsIContent aContent,
PRInt32  aStartingOffset,
PRBool  aForceArabicShaping = PR_FALSE,
PRBool  aLeaveAsAscii = PR_FALSE 
)

Initialize the text transform.

Use GetNextWord() and GetPrevWord() to iterate the text

The default is to transform all text to Unicode; however, you can specify that the text should be left as ascii if possible. Note that we don't step the text down from Unicode to ascii (even if it doesn't contain multibyte characters) so this only happens for text fragments that contain 1-byte text. XXX This is currently not implemented for GetPreviousWord()

See also:
TransformedTextIsAscii()

Definition at line 207 of file nsTextTransformer.cpp.

{
  /*
   * If the document has Bidi content, check whether we need to do
   * Arabic shaping.
   *
   *  Does the frame contains Arabic characters
   *   (mCharType == eCharType_RightToLeftArabic)?
   *  Are we rendering character by character (aForceArabicShaping ==
   *   PR_TRUE)? If so, we always do our own Arabic shaping, even if
   *   the platform has native shaping support. Otherwise, we only do
   *   shaping if the platform has no shaping support.
   *
   *  We do numeric shaping in all Bidi documents.
   */
  if (mPresContext->BidiEnabled()) {
    mCharType = (nsCharType)NS_PTR_TO_INT32(mPresContext->PropertyTable()->GetProperty(aFrame, nsLayoutAtoms::charType));
    if (mCharType == eCharType_RightToLeftArabic) {
      if (aForceArabicShaping) {
        SetNeedsArabicShaping(PR_TRUE);
      }
      else {
        if (!mPresContext->IsBidiSystem()) {
          SetNeedsArabicShaping(PR_TRUE);
        }
      }
    }
    SetNeedsNumericShaping(PR_TRUE);
  }

  // Get the contents text content
  nsresult rv;
  nsCOMPtr<nsITextContent> tc = do_QueryInterface(aContent, &rv);
  if (tc.get()) {
    mFrag = tc->Text();

    // Sanitize aStartingOffset
    if (aStartingOffset < 0) {
      NS_WARNING("bad starting offset");
      aStartingOffset = 0;
    }
    else if (aStartingOffset > mFrag->GetLength()) {
      NS_WARNING("bad starting offset");
      aStartingOffset = mFrag->GetLength();
    }
    mOffset = aStartingOffset;

    // Get the frames text style information
    const nsStyleText* styleText = aFrame->GetStyleText();
    if (NS_STYLE_WHITESPACE_PRE == styleText->mWhiteSpace) {
      mMode = ePreformatted;
    }
    else if (NS_STYLE_WHITESPACE_MOZ_PRE_WRAP == styleText->mWhiteSpace) {
      mMode = ePreWrap;
    }
    mTextTransform = styleText->mTextTransform;
    
    if (aLeaveAsAscii) { // See if the text fragment is 1-byte text
      SetLeaveAsAscii(PR_TRUE);        
      // XXX Currently we only leave it as ascii for normal text and not for preformatted
      // or preformatted wrapped text or language specific transforms
      if (mFrag->Is2b() || (eNormal != mMode) ||
          (mLanguageSpecificTransformType !=
           eLanguageSpecificTransformType_None))
        // We don't step down from Unicode to ascii
        SetLeaveAsAscii(PR_FALSE);           
    } 
    else 
      SetLeaveAsAscii(PR_FALSE);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsTextTransformer::LanguageSpecificTransform ( PRUnichar aText,
PRInt32  aLen,
PRBool aWasTransformed 
) [protected]

Definition at line 807 of file nsTextTransformer.cpp.

{
  if (mLanguageSpecificTransformType ==
      eLanguageSpecificTransformType_Japanese) {
    for (PRInt32 i = 0; i < aLen; i++) {
      if (aText[i] == 0x5C) { // BACKSLASH
        aText[i] = 0xA5; // YEN SIGN
        SetHasMultibyte(PR_TRUE);        
        *aWasTransformed = PR_TRUE;
      }
#if 0
      /*
       * We considered doing this, but since some systems may not have fonts
       * with this OVERLINE glyph, we decided not to do this.
       */
      else if (aText[i] == 0x7E) { // TILDE
        aText[i] = 0x203E; // OVERLINE
        SetHasMultibyte(PR_TRUE);        
        *aWasTransformed = PR_TRUE;
      }
#endif
    }
  }
  /* we once do transformation for Korean, but later decide to remove it */
  /* see bug 88050 for more information */
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 217 of file nsTextTransformer.h.

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanNormalAsciiText_B ( PRInt32 aWordLen,
PRBool  aIsKeyboardSelect 
) [protected]

Definition at line 1121 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRUnichar* bp = mTransformBuf.GetBufferEnd();
  PRUnichar* startbp = mTransformBuf.GetBuffer();

  PRUnichar ch = frag->CharAt(offset - 1);
  // Treat high bit chars as alphanumeric, otherwise we get stuck on accented letters
  // We can't trust isalnum() results for isalnum()
  // Therefore we don't stop at non-ascii (high bit) punctuation,
  // which is just fine. The punctuation we care about is low bit.
  PRBool readingAlphaNumeric = isalnum(ch) || !IS_ASCII_CHAR(ch);

  while (--offset >= 0) {
    PRUnichar ch = frag->CharAt(offset);
    if (CH_NBSP == ch) {
      ch = ' ';
    }
    if (XP_IS_SPACE(ch)) {
      break;
    }
    else if (IS_DISCARDED(ch)) {
      continue;
    } 
    else if (sWordSelectStopAtPunctuation && readingAlphaNumeric && 
             !isalnum(ch) && IS_ASCII_CHAR(ch)) {
      // Break on ascii punctuation
      break;
    }
    else if (sWordSelectStopAtPunctuation && !readingAlphaNumeric &&
             (isalnum(ch) || !IS_ASCII_CHAR(ch))) {
      if (!aIsKeyboardSelect)
        break;
      readingAlphaNumeric = PR_TRUE;
    }
    
    if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
    if (bp == startbp) {
      PRInt32 oldLength = mTransformBuf.mBufferLen;
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        break;
      }
      bp = mTransformBuf.GetBufferEnd() - oldLength;
      startbp = mTransformBuf.GetBuffer();
    }
    *--bp = ch;
  }

  *aWordLen = mTransformBuf.GetBufferEnd() - bp;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanNormalAsciiText_F ( PRInt32  aFragLen,
PRInt32 aWordLen,
PRBool aWasTransformed 
) [protected]

Definition at line 335 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRInt32 prevBufferPos = mBufferPos;
  const unsigned char* cp = (const unsigned char*)frag->Get1b() + offset;
  union {
    unsigned char* bp1;
    PRUnichar* bp2;
  };
  bp2 = mTransformBuf.GetBuffer();
  if (TransformedTextIsAscii()) {
    bp1 += mBufferPos;
  } else {
    bp2 += mBufferPos;
  }

  for (; offset < aFragLen; offset++) {
    unsigned char ch = *cp++;
    if (XP_IS_SPACE(ch)) {
      break;
    }
    if (CH_NBSP == ch) {
      ch = ' ';
      *aWasTransformed = PR_TRUE;
    }
    else if (IS_DISCARDED(ch)) {
      // Strip discarded characters from the transformed output
      continue;
    }
    if (ch > MAX_UNIBYTE) {
      // The text has a multibyte character so we can no longer leave the
      // text as ascii text
      SetHasMultibyte(PR_TRUE);        
              
      if (TransformedTextIsAscii()) { 
        SetTransformedTextIsAscii(PR_FALSE);
        *aWasTransformed = PR_TRUE;

        // Transform any existing ascii text to Unicode
        if (mBufferPos > 0) {
          ConvertTransformedTextToUnicode();
          bp2 = mTransformBuf.GetBuffer() + mBufferPos;
        }
      }
    }
    if (mBufferPos >= mTransformBuf.mBufferLen) {
      nsresult rv = mTransformBuf.GrowBy(128);
      if (NS_FAILED(rv)) {
        // If we run out of space then just truncate the text
        break;
      }
      bp2 = mTransformBuf.GetBuffer();
      if (TransformedTextIsAscii()) {
        bp1 += mBufferPos;
      } else {
        bp2 += mBufferPos;
      }
    }
    if (TransformedTextIsAscii()) {
      *bp1++ = ch;
    } else {
      *bp2++ = PRUnichar(ch);
    }
    mBufferPos++;
  }

  *aWordLen = mBufferPos - prevBufferPos;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanNormalAsciiText_F_ForWordBreak ( PRInt32  aFragLen,
PRInt32 aWordLen,
PRBool aWasTransformed,
PRBool  aIsKeyboardSelect 
) [protected]

Definition at line 409 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRInt32 prevBufferPos = mBufferPos;
  PRBool breakAfterThis = PR_FALSE;
  const unsigned char* cp = (const unsigned char*)frag->Get1b() + offset;
  union {
    unsigned char* bp1;
    PRUnichar* bp2;
  };
  bp2 = mTransformBuf.GetBuffer();
  if (TransformedTextIsAscii()) {
    bp1 += mBufferPos;
  } else {
    bp2 += mBufferPos;
  }
  PRBool readingAlphaNumeric = PR_TRUE; //only used in sWordSelectStopAtPunctuation

  // We must know if we are starting in alpha numerics.
  // Treat high bit chars as alphanumeric, otherwise we get stuck on accented letters
  // We can't trust isalnum() results for isalnum()
  // Therefore we don't stop at non-ascii (high bit) punctuation,
  // which is just fine. The punctuation we care about is low bit.
  if (sWordSelectStopAtPunctuation && offset < aFragLen)
    readingAlphaNumeric = isalnum((unsigned char)*cp) || !IS_ASCII_CHAR(*cp);
  
  for (; offset < aFragLen && !breakAfterThis; offset++) {
    unsigned char ch = *cp++;
    if (CH_NBSP == ch) {
      ch = ' ';
      *aWasTransformed = PR_TRUE;
      if (offset == mOffset)
        breakAfterThis = PR_TRUE;
      else
        break;
    }
    else if (XP_IS_SPACE(ch)) {
      break;
    }
    else if (sWordSelectStopAtPunctuation && 
             readingAlphaNumeric && !isalnum(ch) && IS_ASCII_CHAR(ch)) {
      if (!aIsKeyboardSelect)
        break;
      // For keyboard move-by-word, need to pass by at least
      // one alphanumeric char before stopping at punct
      readingAlphaNumeric = PR_FALSE;
    }
    else if (sWordSelectStopAtPunctuation && 
            !readingAlphaNumeric && (isalnum(ch) || !IS_ASCII_CHAR(ch))) {
      // On some platforms, punctuation breaks for word selection
      break;
    }
    else if (IS_DISCARDED(ch)) {
      // Strip discarded characters from the transformed output
      continue;
    }
    if (ch > MAX_UNIBYTE) {
      // The text has a multibyte character so we can no longer leave the
      // text as ascii text
      SetHasMultibyte(PR_TRUE);

      if (TransformedTextIsAscii()) {
        SetTransformedTextIsAscii(PR_FALSE);
        *aWasTransformed = PR_TRUE;

        // Transform any existing ascii text to Unicode
        if (mBufferPos > 0) {
          ConvertTransformedTextToUnicode();
          bp2 = mTransformBuf.GetBuffer() + mBufferPos;
        }
      }
    }
    if (mBufferPos >= mTransformBuf.mBufferLen) {
      nsresult rv = mTransformBuf.GrowBy(128);
      if (NS_FAILED(rv)) {
        // If we run out of space then just truncate the text
        break;
      }
      bp2 = mTransformBuf.GetBuffer();
      if (TransformedTextIsAscii()) {
        bp1 += mBufferPos;
      } else {
        bp2 += mBufferPos;
      }
    }
    if (TransformedTextIsAscii()) {
      *bp1++ = ch;
    } else {
      *bp2++ = PRUnichar(ch);
    }
    mBufferPos++;
  }

  *aWordLen = mBufferPos - prevBufferPos;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanNormalUnicodeText_B ( PRBool  aForLineBreak,
PRInt32 aWordLen 
) [protected]

Definition at line 1178 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  const PRUnichar* cp0 = frag->Get2b();
  PRInt32 offset = mOffset - 1;

  PRUnichar firstChar = frag->CharAt(offset);

#ifdef IBMBIDI
  PRInt32 limit = (*aWordLen > 0) ? *aWordLen : 0;
  
  while (offset > limit && IS_BIDI_CONTROL(firstChar) ) {
    firstChar = frag->CharAt(--offset);
  }
#endif

  mTransformBuf.mBuffer[mTransformBuf.mBufferLen - 1] = firstChar;
  if (firstChar > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);

  PRInt32 numChars = 1;

#ifdef IBMBIDI
  if (offset > limit) {
#else
  if (offset > 0) {
#endif
    const PRUnichar* cp = cp0 + offset;
    PRBool breakBetween = PR_FALSE;
    if (aForLineBreak) {
      mLineBreaker->BreakInBetween(cp0, offset + 1,
                                   mTransformBuf.GetBufferEnd()-1, 1,
                                   &breakBetween);
    }
    else {
      mWordBreaker->BreakInBetween(cp0, offset + 1,
                                   mTransformBuf.GetBufferEnd()-1, 1,
                                   &breakBetween);
    }

    if (!breakBetween) {
      // Find next position
      PRBool tryPrevFrag;
      PRUint32 prev;
      if (aForLineBreak) {
        mLineBreaker->Prev(cp0, offset, offset, &prev, &tryPrevFrag);
      }
      else {
        mWordBreaker->PrevWord(cp0, offset, offset, &prev, &tryPrevFrag);
      }
      numChars = (PRInt32) ((PRUint32) offset - prev) + 1;

      // Grow buffer before copying
      nsresult rv = mTransformBuf.GrowTo(numChars);
      if (NS_FAILED(rv)) {
        numChars = mTransformBuf.GetBufferLength();
      }

      // 1. convert nbsp into space
      // 2. check mHasMultibyte flag
      // 3. copy buffer
      PRUnichar* bp = mTransformBuf.GetBufferEnd() - 1;
      const PRUnichar* end = cp - numChars + 1;
      while (cp > end) {
        PRUnichar ch = *--cp;
        if (CH_NBSP == ch) {
          ch = ' ';
        }
        else if (IS_DISCARDED(ch)) {
          continue;
        }
        if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
        *--bp = ch;
      }

      // Recompute offset and numChars in case we stripped something
      offset = offset - numChars;
      numChars =  mTransformBuf.GetBufferEnd() - bp;
    }
  }
  else 
         offset--;

  *aWordLen = numChars;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanNormalUnicodeText_F ( PRInt32  aFragLen,
PRBool  aForLineBreak,
PRInt32 aWordLen,
PRBool aWasTransformed 
) [protected]

Definition at line 513 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  const PRUnichar* cp0 = frag->Get2b();
  PRInt32 offset = mOffset;

  PRUnichar firstChar = frag->CharAt(offset++);

#ifdef IBMBIDI
  // Need to strip BIDI controls even when those are 'firstChars'.
  // This doesn't seem to produce bug 14280 (or similar bugs).
  while (offset < aFragLen && IS_BIDI_CONTROL(firstChar) ) {
    firstChar = frag->CharAt(offset++);
  }
#endif // IBMBIDI

  if (firstChar > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);

  // Only evaluate complex breaking logic if there are more characters
  // beyond the first to look at.
  PRInt32 numChars = 1;
  if (offset < aFragLen) {
    const PRUnichar* cp = cp0 + offset;
    PRBool breakBetween = PR_FALSE;
    if (aForLineBreak) {
      mLineBreaker->BreakInBetween(&firstChar, 1, cp, (aFragLen-offset), &breakBetween);
    }
    else {
      mWordBreaker->BreakInBetween(&firstChar, 1, cp, (aFragLen-offset), &breakBetween);
    }

    // don't transform the first character until after BreakInBetween is called
    // Kipp originally did this at the top of the function, which was too early.
    // see bug 14280
    if (CH_NBSP == firstChar) {
      firstChar = ' ';
      *aWasTransformed = PR_TRUE;
    }
    nsresult rv = mTransformBuf.GrowTo(mBufferPos + 1);
    if (NS_FAILED(rv)) {
              *aWordLen = 0;
              return offset - 1;
       }

    mTransformBuf.mBuffer[mBufferPos++] = firstChar;

    if (!breakBetween) {
      // Find next position
      PRBool tryNextFrag;
      PRUint32 next;
      if (aForLineBreak) {
        mLineBreaker->Next(cp0, aFragLen, offset, &next, &tryNextFrag);
      }
      else {
        mWordBreaker->NextWord(cp0, aFragLen, offset, &next, &tryNextFrag);
      }
      numChars = (PRInt32) (next - (PRUint32) offset) + 1;

      // Since we know the number of characters we're adding grow the buffer
      // now before we start copying
      nsresult rv = mTransformBuf.GrowTo(mBufferPos + numChars);
      if (NS_FAILED(rv)) {
        numChars = mTransformBuf.GetBufferLength() - mBufferPos;
      }

      offset += numChars - 1;

      // 1. convert nbsp into space
      // 2. check for discarded characters
      // 3. check mHasMultibyte flag
      // 4. copy buffer
      PRUnichar* bp = &mTransformBuf.mBuffer[mBufferPos];
      const PRUnichar* end = cp + numChars - 1;
      while (cp < end) {
        PRUnichar ch = *cp++;
        if (CH_NBSP == ch) {
          ch = ' ';
        }
        else if (IS_DISCARDED(ch) || (ch == 0x0a) || (ch == 0x0d)) {
          // Strip discarded characters from the transformed output
          numChars--;
          continue;
        }
        if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
        *bp++ = ch;
        mBufferPos++;
      }
    }
  }
  else 
  { // transform the first character
    // we do this here, rather than at the top of the function (like Kipp originally had it)
    // because if we must call BreakInBetween, then we must do so before the transformation
    // this is the case where BreakInBetween does not need to be called at all.
    // see bug 14280
    if (CH_NBSP == firstChar) {
      firstChar = ' ';
      *aWasTransformed = PR_TRUE;
    }
    nsresult rv = mTransformBuf.GrowTo(mBufferPos + 1);
    if (NS_FAILED(rv)) {
              *aWordLen = 0;
              return offset - 1;
       }
    mTransformBuf.mBuffer[mBufferPos++] = firstChar;
  }

  *aWordLen = numChars;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1099 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;

  while (--offset >= 0) {
    PRUnichar ch = frag->CharAt(offset);
    if (!XP_IS_SPACE(ch)) {
      // If character is not discardable then stop looping, otherwise
      // let the discarded character collapse with the other spaces.
      if (!IS_DISCARDED(ch)) {
        break;
      }
    }
  }

  mTransformBuf.mBuffer[mTransformBuf.mBufferLen - 1] = ' ';
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 288 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;

  for (; offset < aFragLen; offset++) {
    PRUnichar ch = frag->CharAt(offset);
    if (!XP_IS_SPACE(ch)) {
      // If character is not discardable then stop looping, otherwise
      // let the discarded character collapse with the other spaces.
      if (!IS_DISCARDED(ch)) {
        break;
      }
    }
  }

  // Make sure we have enough room in the transform buffer
  if (mBufferPos >= mTransformBuf.mBufferLen) {
    mTransformBuf.GrowBy(128);
  }

  if (TransformedTextIsAscii()) {
    unsigned char*  bp = (unsigned char*)mTransformBuf.mBuffer;
    bp[mBufferPos++] = ' ';
  } else {
    mTransformBuf.mBuffer[mBufferPos++] = PRUnichar(' ');
  }
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanPreAsciiData_F ( PRInt32  aFragLen,
PRInt32 aWordLen,
PRBool aWasTransformed 
) [protected]

Definition at line 713 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRUnichar* bp = mTransformBuf.GetBuffer() + mBufferPos;
  PRUnichar* endbp = mTransformBuf.GetBufferEnd();
  const unsigned char* cp = (const unsigned char*) frag->Get1b();
  const unsigned char* end = cp + aFragLen;
  PRInt32 prevBufferPos = mBufferPos;
  cp += mOffset;

  while (cp < end) {
    PRUnichar ch = (PRUnichar) *cp++;
    if ((ch == '\t') || (ch == '\n')) {
      cp--;
      break;
    }
    if (CH_NBSP == ch) {
      ch = ' ';
      *aWasTransformed = PR_TRUE;
    }
    else if (IS_DISCARDED(ch)) {
      continue;
    }
    if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
    if (bp == endbp) {
      PRInt32 oldLength = bp - mTransformBuf.GetBuffer();
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        break;
      }
      bp = mTransformBuf.GetBuffer() + oldLength;
      endbp = mTransformBuf.GetBufferEnd();
    }
    *bp++ = ch;
    mBufferPos++;
  }

  *aWordLen = mBufferPos - prevBufferPos;
  return cp - ((const unsigned char*)frag->Get1b());
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanPreData_B ( PRInt32 aWordLen) [protected]

Definition at line 1302 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRUnichar* bp = mTransformBuf.GetBufferEnd();
  PRUnichar* startbp = mTransformBuf.GetBuffer();

  while (--offset >= 0) {
    PRUnichar ch = frag->CharAt(offset);
    if ((ch == '\t') || (ch == '\n')) {
      break;
    }
    if (CH_NBSP == ch) {
      ch = ' ';
    }
    else if (IS_DISCARDED(ch)) {
      continue;
    }
    if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
    if (bp == startbp) {
      PRInt32 oldLength = mTransformBuf.mBufferLen;
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        offset++;
        break;
      }
      bp = mTransformBuf.GetBufferEnd() - oldLength;
      startbp = mTransformBuf.GetBuffer();
    }
    *--bp = ch;
  }

  *aWordLen = mTransformBuf.GetBufferEnd() - bp;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanPreData_F ( PRInt32  aFragLen,
PRInt32 aWordLen,
PRBool aWasTransformed 
) [protected]

Definition at line 668 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRUnichar* bp = mTransformBuf.GetBuffer() + mBufferPos;
  PRUnichar* endbp = mTransformBuf.GetBufferEnd();
  PRInt32 prevBufferPos = mBufferPos;

  for (; offset < aFragLen; offset++) {
    // This function is used for both Unicode and ascii strings so don't
    // make any assumptions about what kind of data it is
    PRUnichar ch = frag->CharAt(offset);
    if ((ch == '\t') || (ch == '\n')) {
      break;
    }
    if (CH_NBSP == ch) {
      ch = ' ';
      *aWasTransformed = PR_TRUE;
    }
    else if (IS_DISCARDED(ch)) {
      continue;
    }
    if (ch > MAX_UNIBYTE) SetHasMultibyte(PR_TRUE);
    if (bp == endbp) {
      PRInt32 oldLength = bp - mTransformBuf.GetBuffer();
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        break;
      }
      bp = mTransformBuf.GetBuffer() + oldLength;
      endbp = mTransformBuf.GetBufferEnd();
    }
    *bp++ = ch;
    mBufferPos++;
  }

  *aWordLen = mBufferPos - prevBufferPos;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1267 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRUnichar* bp = mTransformBuf.GetBufferEnd();
  PRUnichar* startbp = mTransformBuf.GetBuffer();

  while (--offset >= 0) {
    PRUnichar ch = frag->CharAt(offset);
    if (!XP_IS_SPACE(ch) || (ch == '\t') || (ch == '\n')) {
      // Keep looping if this is a discarded character
      if (IS_DISCARDED(ch)) {
        continue;
      }
      break;
    }
    if (bp == startbp) {
      PRInt32 oldLength = mTransformBuf.mBufferLen;
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        break;
      }
      bp = mTransformBuf.GetBufferEnd() - oldLength;
      startbp = mTransformBuf.GetBuffer();
    }
    *--bp = ' ';
  }

  *aWordLen = mTransformBuf.GetBufferEnd() - bp;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRInt32 nsTextTransformer::ScanPreWrapWhiteSpace_F ( PRInt32  aFragLen,
PRInt32 aWordLen 
) [protected]

Definition at line 629 of file nsTextTransformer.cpp.

{
  const nsTextFragment* frag = mFrag;
  PRInt32 offset = mOffset;
  PRUnichar* bp = mTransformBuf.GetBuffer() + mBufferPos;
  PRUnichar* endbp = mTransformBuf.GetBufferEnd();
  PRInt32 prevBufferPos = mBufferPos;

  for (; offset < aFragLen; offset++) {
    // This function is used for both Unicode and ascii strings so don't
    // make any assumptions about what kind of data it is
    PRUnichar ch = frag->CharAt(offset);
    if (!XP_IS_SPACE(ch) || (ch == '\t') || (ch == '\n')) {
      if (IS_DISCARDED(ch)) {
        // Keep looping if this is a discarded character
        continue;
      }
      break;
    }
    if (bp == endbp) {
      PRInt32 oldLength = bp - mTransformBuf.GetBuffer();
      nsresult rv = mTransformBuf.GrowBy(1000);
      if (NS_FAILED(rv)) {
        // If we run out of space (unlikely) then just chop the input
        break;
      }
      bp = mTransformBuf.GetBuffer() + oldLength;
      endbp = mTransformBuf.GetBufferEnd();
    }
    *bp++ = ' ';
    mBufferPos++;
  }

  *aWordLen = mBufferPos - prevBufferPos;
  return offset;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 253 of file nsTextTransformer.h.

Here is the caller graph for this function:

Definition at line 247 of file nsTextTransformer.h.

Here is the caller graph for this function:

Definition at line 259 of file nsTextTransformer.h.

Here is the caller graph for this function:

Definition at line 228 of file nsTextTransformer.h.

Here is the caller graph for this function:

int nsTextTransformer::WordSelectPrefCallback ( const char *  aPref,
void aClosure 
) [static, protected]

Definition at line 66 of file nsTextTransformer.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 368 of file nsTextTransformer.h.

Definition at line 374 of file nsTextTransformer.h.

Definition at line 339 of file nsTextTransformer.h.

Definition at line 355 of file nsTextTransformer.h.

Definition at line 351 of file nsTextTransformer.h.

enum { ... } nsTextTransformer::mMode [protected]

Definition at line 342 of file nsTextTransformer.h.

Definition at line 371 of file nsTextTransformer.h.

Definition at line 364 of file nsTextTransformer.h.

Definition at line 353 of file nsTextTransformer.h.

Definition at line 379 of file nsTextTransformer.h.

Definition at line 378 of file nsTextTransformer.h.

Definition at line 380 of file nsTextTransformer.h.


The documentation for this class was generated from the following files: