nsCOMPtr<nsILineBreaker> lb; doc->GetLineBreaker(getter_AddRefs(lb));  nsTextTransformer tx(lb, nsnull, aPresContext);
nsTextTransformer tx(doc->GetLineBreaker(), nsnull, aPresContext);
nsTextFrame::PeekOffset(nsIPresContext* aPresContext, nsPeekOffsetStruct *aPos) {#ifdef IBMBIDI  PRUint8 level, baseLevel;  GetBidiProperty(aPresContext, nsLayoutAtoms::embeddingLevel, (void**)&level,sizeof(level));  GetBidiProperty(aPresContext, nsLayoutAtoms::baseLevel, (void**)&baseLevel,sizeof(baseLevel));  PRBool isOddLevel = (level & 1);  if ((eSelectCharacter == aPos->mAmount)      || (eSelectWord == aPos->mAmount))    aPos->mPreferLeft ^= isOddLevel;#endif  if (!aPos || !mContent)    return NS_ERROR_NULL_POINTER;  if (aPos->mStartOffset < 0 )    aPos->mStartOffset = mContentLength + mContentOffset;  if (aPos->mStartOffset < mContentOffset){    aPos->mStartOffset = mContentOffset;  }  if (aPos->mStartOffset > (mContentOffset + mContentLength)){    nsIFrame *nextInFlow;#ifdef IBMBIDI    if (isOddLevel) {      GetBidiProperty(aPresContext, nsLayoutAtoms::nextBidi, (void**) &nextInFlow,sizeof(nextInFlow));    }    else#endif    GetNextInFlow(&nextInFlow);    if (!nextInFlow){      NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more flow \n");      return NS_ERROR_INVALID_ARG;    }    return nextInFlow->PeekOffset(aPresContext, aPos);  }   if (aPos->mAmount == eSelectLine || aPos->mAmount == eSelectBeginLine       || aPos->mAmount == eSelectEndLine || aPos->mAmount == eSelectParagraph)  {      return nsFrame::PeekOffset(aPresContext, aPos);  }  nsAutoTextBuffer paintBuffer;  nsAutoIndexBuffer indexBuffer;  nsresult rv = indexBuffer.GrowTo(mContentLength + 1);  if (NS_FAILED(rv)) {    return rv;  }  PRInt32* ip = indexBuffer.mBuffer;  PRInt32 textLength;  nsresult result(NS_ERROR_FAILURE);  aPos->mResultContent = mContent;//do this right off  switch (aPos->mAmount){    case eSelectNoAmount:    {      // Transform text from content into renderable form      nsIDocument* doc = mContent->GetDocument();      if (!doc) {        return NS_OK;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      nsTextTransformer tx(lb, nsnull, aPresContext);      PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);      if (textLength)//if no renderable length, you cant park here.      {        aPos->mContentOffset = aPos->mStartOffset;        result = NS_OK;      }      else      {        aPos->mAmount = eSelectDir;//go to "next" or previous frame based on direction not THIS frame        result = GetFrameFromDirection(aPresContext, aPos);        if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)          return aPos->mResultFrame->PeekOffset(aPresContext, aPos);        else if (NS_FAILED(result))          return result;      }    }    break;    case eSelectCharacter:    {      // Transform text from content into renderable form      nsIDocument* doc = mContent->GetDocument();      if (!doc) {        return NS_OK;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      nsTextTransformer tx(lb, nsnull, aPresContext);      PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);      nsIFrame *frameUsed = nsnull;      PRInt32 start;      PRBool found = PR_TRUE;      PRBool selectable;      PRUint8 selectStyle;      IsSelectable(&selectable, &selectStyle);      if ( selectStyle == NS_STYLE_USER_SELECT_ALL )        found = PR_FALSE;      else      {  #ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next        // so that right arrow always moves to the right on screen        // and left arrow always moves left        if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||             ((aPos->mDirection == eDirNext) && isOddLevel) ){  #else        if (aPos->mDirection == eDirPrevious){  #endif          aPos->mContentOffset = 0;          PRInt32 i;  #ifdef SUNCTL          static NS_DEFINE_CID(kLECID, NS_ULE_CID);          nsCOMPtr<nsILE> mCtlObj;          mCtlObj = do_CreateInstance(kLECID, &rv);          if (NS_FAILED(rv)) {            NS_WARNING("Cell based cursor movement will not be supported\n");            mCtlObj = nsnull;  #endif /* SUNCTL */          for (i = aPos->mStartOffset -1 - mContentOffset; i >=0;  i--){            if ((ip[i] < ip[aPos->mStartOffset - mContentOffset]) &&                (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))            {              aPos->mContentOffset = i + mContentOffset;              break;            }          }  #ifdef SUNCTL          }          else {            if (aPos->mStartOffset < 1) {              // go to prev              i = -1;            } else {              PRInt32 mPreviousOffset;              mCtlObj->PrevCluster(NS_REINTERPRET_CAST(const PRUnichar*, paintBuffer.mBuffer),                                 textLength,aPos->mStartOffset,                                  &mPreviousOffset);              aPos->mContentOffset = i = mPreviousOffset;            }          }  #endif /* SUNCTL */          if (i <0){            found = PR_FALSE;            GetPrevInFlow(&frameUsed);            start = mContentOffset;            aPos->mContentOffset = start;//in case next call fails we stop at this offset          }        }  #ifdef IBMBIDI // Simon, as above         else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||                  ((aPos->mDirection == eDirPrevious) && isOddLevel) ){  #else        else if (aPos->mDirection == eDirNext){  #endif          PRInt32 i;          aPos->mContentOffset = mContentLength;  #ifdef SUNCTL          static NS_DEFINE_CID(kLECID, NS_ULE_CID);          nsCOMPtr<nsILE> mCtlObj;          mCtlObj = do_CreateInstance(kLECID, &rv);          if (NS_FAILED(rv)) {            NS_WARNING("Cell based cursor movement will not be supported\n");            mCtlObj = nsnull;  #endif /* SUNCTL */          for (i = aPos->mStartOffset +1 - mContentOffset; i <= mContentLength;  i++){            if ((ip[i] > ip[aPos->mStartOffset - mContentOffset]) &&                (! IS_LOW_SURROGATE(paintBuffer.mBuffer[ip[i]-mContentOffset])))            {              aPos->mContentOffset = i + mContentOffset;              break;            }          }  #ifdef SUNCTL          }          else {            if (aPos->mStartOffset >= textLength) {              // go to next              i = mContentLength + 1;            } else {              PRInt32 mNextOffset;              mCtlObj->NextCluster(NS_REINTERPRET_CAST(const PRUnichar*, paintBuffer.mBuffer),                                 textLength, aPos->mStartOffset,                                 &mNextOffset);              aPos->mContentOffset = i = mNextOffset;            }          }  #endif /* SUNCTL */  /*      if (aStartOffset == 0 && (mState & TEXT_SKIP_LEADING_WS))          i--; //back up because we just skipped over some white space. why skip over the char also?  */          if (i > mContentLength){            found = PR_FALSE;            GetNextInFlow(&frameUsed);            start = mContentOffset + mContentLength;            aPos->mContentOffset = start;//in case next call fails we stop at this offset          }        }      }      if (!found)      {        result = GetFrameFromDirection(aPresContext, aPos);        if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)        {          result = aPos->mResultFrame->PeekOffset(aPresContext, aPos);          if (NS_FAILED(result))            return result;        }      }      else         aPos->mResultContent = mContent;    }    break;    case eSelectWord:    {      // Transform text from content into renderable form      nsIDocument* doc = mContent->GetDocument();      if (!doc) {        return result;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      nsCOMPtr<nsIWordBreaker> wb;      doc->GetWordBreaker(getter_AddRefs(wb));      nsTextTransformer tx(lb, wb, aPresContext);      PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);      nsIFrame *frameUsed = nsnull;      PRBool keepSearching; //if you run out of chars before you hit the end of word, maybe next frame has more text to select?      PRInt32 start;      PRBool found = PR_FALSE;      PRBool isWhitespace, wasTransformed;      PRInt32 wordLen, contentLen;            PRBool selectable;      PRUint8 selectStyle;      IsSelectable(&selectable, &selectStyle);      if ( selectStyle == NS_STYLE_USER_SELECT_ALL )        found = PR_FALSE;      else      {      #ifdef IBMBIDI // Simon - RTL frames reverse meaning of previous and next        // so that right arrow always moves to the right on screen        // and left arrow always moves left        if ( ((aPos->mDirection == eDirPrevious) && !isOddLevel) ||             ((aPos->mDirection == eDirNext) && isOddLevel) ) {#else        if (aPos->mDirection == eDirPrevious){#endif          keepSearching = PR_TRUE;          tx.Init(this, mContent, aPos->mStartOffset);          aPos->mContentOffset = mContentOffset;//initialize#ifdef IBMBIDI          wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;#endif // IBMBIDI          if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,                             PR_FALSE, aPos->mIsKeyboardSelect) &&            (aPos->mStartOffset - contentLen >= mContentOffset) ){            if ((aPos->mEatingWS && !isWhitespace) || !aPos->mEatingWS){              aPos->mContentOffset = aPos->mStartOffset - contentLen;              //check for whitespace next.              if (isWhitespace && aPos->mContentOffset <= mContentOffset)              {                keepSearching = PR_FALSE;//reached the beginning of a word                aPos->mEatingWS = PR_FALSE;//if no real word then              }              else{#ifdef IBMBIDI                wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;#endif // IBMBIDI                while (isWhitespace &&                       tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen,                                      &isWhitespace, PR_FALSE,                                      aPos->mIsKeyboardSelect)){                  aPos->mContentOffset -= contentLen;                  aPos->mEatingWS = PR_TRUE;#ifdef IBMBIDI                  wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset : -1;#endif // IBMBIDI                }                aPos->mEatingWS = !isWhitespace;//nowhite space, just eat chars.                keepSearching = aPos->mContentOffset <= mContentOffset;                if (!isWhitespace){                  if (!keepSearching)                    found = PR_TRUE;                else                  aPos->mEatingWS = PR_TRUE;                }              }            }            else {              aPos->mContentOffset = mContentLength + mContentOffset;              found = PR_TRUE;            }          }        }#ifdef IBMBIDI // Simon, as above         else if ( ((aPos->mDirection == eDirNext) && !isOddLevel) ||                  ((aPos->mDirection == eDirPrevious) && isOddLevel) ) {#else        else if (aPos->mDirection == eDirNext) {#endif          tx.Init(this, mContent, aPos->mStartOffset );          aPos->mContentOffset = mContentOffset + mContentLength;//initialize#ifdef IBMBIDI          wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset + mContentLength : -1;#endif // IBMBIDI          if (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect) &&            (aPos->mStartOffset + contentLen <= (mContentLength + mContentOffset))){            if ((aPos->mEatingWS && isWhitespace) || !aPos->mEatingWS){              aPos->mContentOffset = aPos->mStartOffset + contentLen;              // check for whitespace next. On some platforms (mac), we want the selection to end              // at the end of the word (not the beginning of the next one), so don't slurp up any extra whitespace.              if ( sWordSelectEatSpaceAfter ) {                keepSearching = PR_TRUE;                aPos->mEatingWS = PR_TRUE;              if (!isWhitespace){#ifdef IBMBIDI                wordLen = (mState & NS_FRAME_IS_BIDI)                        ? mContentOffset + mContentLength : -1;#endif // IBMBIDI                  while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect))                  {                    if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset))                      goto TryNextFrame;                    if (isWhitespace)                      aPos->mContentOffset += contentLen;                    else                      break;#ifdef IBMBIDI                  wordLen = (mState & NS_FRAME_IS_BIDI)                          ? mContentOffset + mContentLength : -1;#endif // IBMBIDI                  }                  keepSearching = (mContentOffset + mContentLength) <= aPos->mContentOffset;                  if (!keepSearching)                    found = PR_TRUE;                }                else  //we just need to jump the space, done here                {#ifdef IBMBIDI                wordLen = (mState & NS_FRAME_IS_BIDI)                        ? mContentOffset + mContentLength : -1;#endif // IBMBIDI                  while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE, aPos->mIsKeyboardSelect))                  {                    if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset))                      goto TryNextFrame;                    if (isWhitespace)                      aPos->mContentOffset += contentLen;		                    else                      break;#ifdef IBMBIDI              wordLen = (mState & NS_FRAME_IS_BIDI) ? mContentOffset + mContentLength : -1;#endif // IBMBIDI                  }                  keepSearching = (mContentOffset + mContentLength) <= aPos->mContentOffset;                  if (!keepSearching)                    found = PR_TRUE;                }              } // if we should eat space to the next word              else {                keepSearching = (mContentOffset + mContentLength) <= aPos->mContentOffset;                if (!keepSearching)                  found = PR_TRUE;              }            }            else if (aPos->mEatingWS)			   {              aPos->mContentOffset = mContentOffset;				  found = PR_TRUE;			   }            if (!isWhitespace){              aPos->mEatingWS = PR_FALSE;            }            else if (!keepSearching) //we have found the "whole" word so just looking for WS              aPos->mEatingWS = PR_TRUE;          }   TryNextFrame:        		    GetNextInFlow(&frameUsed);          start = 0;        }      }      if (!found || (aPos->mContentOffset > (mContentOffset + mContentLength)) || (aPos->mContentOffset < mContentOffset))      {        aPos->mContentOffset = PR_MIN(aPos->mContentOffset, mContentOffset + mContentLength);        aPos->mContentOffset = PR_MAX(aPos->mContentOffset, mContentOffset);        result = GetFrameFromDirection(aPresContext, aPos);        if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)        {          if (NS_SUCCEEDED(result = aPos->mResultFrame->PeekOffset(aPresContext, aPos)))            return NS_OK;//else fall through          else if (aPos->mDirection == eDirNext)            aPos->mContentOffset = mContentOffset + mContentLength;          else            aPos->mContentOffset = mContentOffset;        }        else           aPos->mResultContent = mContent;      }      else       {        aPos->mResultContent = mContent;      }    }    break;#ifdef IBMBIDI    case eSelectDir:      result = GetFrameFromDirection(aPresContext, aPos);      if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)        return aPos->mResultFrame->PeekOffset(aPresContext, aPos);      else {        return result;      }      break;#endif    default:      result = NS_ERROR_FAILURE; break;  }  aPos->mContentOffsetEnd = aPos->mContentOffset;  if (NS_FAILED(result)){    aPos->mResultContent = mContent;    //aPos->mContentOffset = aPos->mStartOffset;    result = NS_OK;  }  aPos->mResultFrame = this;  return result;}