else { while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE)) { if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset)) goto TryNextFrame;  if (isWhitespace) aPos->mContentOffset += contentLen; else break; } keepSearching = PR_FALSE; found = PR_TRUE; }
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;      result = mContent->GetDocument(doc);      if (NS_FAILED(result) || !doc) {        return result;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      NS_RELEASE(doc);      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;      result = mContent->GetDocument(doc);      if (NS_FAILED(result) || !doc) {        return result;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      NS_RELEASE(doc);      nsTextTransformer tx(lb, nsnull, aPresContext);      PrepareUnicodeText(tx, &indexBuffer, &paintBuffer, &textLength);      nsIFrame *frameUsed = nsnull;      PRInt32 start;      PRBool found = PR_TRUE;#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;        for (i = aPos->mStartOffset -1 - mContentOffset; i >=0;  i--){          if (ip[i] < ip[aPos->mStartOffset - mContentOffset]){            aPos->mContentOffset = i + mContentOffset;            break;          }        }        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;        for (i = aPos->mStartOffset +1 - mContentOffset; i <= mContentLength;  i++){          if (ip[i] > ip[aPos->mStartOffset - mContentOffset]){            aPos->mContentOffset = i + mContentOffset;            break;          }        }/*      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;      result = mContent->GetDocument(doc);      if (NS_FAILED(result) || !doc) {        return result;      }      nsCOMPtr<nsILineBreaker> lb;      doc->GetLineBreaker(getter_AddRefs(lb));      nsCOMPtr<nsIWordBreaker> wb;      doc->GetWordBreaker(getter_AddRefs(wb));      NS_RELEASE(doc);      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;#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        if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,                           PR_FALSE) &&          (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{              while (isWhitespace &&                     tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen,                                    &isWhitespace, PR_FALSE)){                aPos->mContentOffset -= contentLen;                aPos->mEatingWS = PR_TRUE;              }              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        if (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE) &&          (aPos->mStartOffset + contentLen <= (mContentLength + mContentOffset))){          if ((aPos->mEatingWS && isWhitespace) || !aPos->mEatingWS){            aPos->mContentOffset = aPos->mStartOffset + contentLen;            //check for whitespace next.            keepSearching = PR_TRUE;            aPos->mEatingWS = PR_TRUE;            if (!isWhitespace){					while (tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE))					{						if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset))							goto TryNextFrame;						if (isWhitespace)							aPos->mContentOffset += contentLen;						else							break;					}					keepSearching = PR_FALSE;					found = PR_TRUE;            }				else  //we just need to jump the space, done here				{					while(tx.GetNextWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace, &wasTransformed, PR_TRUE, PR_FALSE))					{						if (aPos->mStartOffset + contentLen > (mContentLength + mContentOffset))							goto TryNextFrame;						if (isWhitespace)							aPos->mContentOffset += contentLen;								 else							 break;					}					keepSearching = PR_FALSE;					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;}