gettig word jumping to work, adding GetPrevWord to texttransformer

git-svn-id: svn://10.0.0.236/trunk@21451 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mjudge%netscape.com
1999-02-22 03:20:59 +00:00
parent 4589e1e0e1
commit 465cddb814
6 changed files with 696 additions and 76 deletions

View File

@@ -1790,9 +1790,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
// Transform text from content into renderable form
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
PrepareUnicodeText(tx, ip, paintBuf, textLength, width);
ip[mContentLength] = ip[mContentLength-1]+1; //must set up last one for selection beyond edge
nsresult result(NS_OK);
switch (aAmount){
case eSelectNoAmount : {
@@ -1803,6 +1800,11 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
}
break;
case eSelectCharacter : {
PrepareUnicodeText(tx, ip, paintBuf, textLength, width);
ip[mContentLength] = ip[mContentLength-1]+1; //must set up last one for selection beyond edge
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
if (aDirection == eDirPrevious){
PRInt32 i;
for (i = aStartOffset -1; i >=0; i--){
@@ -1813,45 +1815,85 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
}
}
if (i <0){
nsIFrame *prev = GetPrevInFlow();
if (prev){
return prev->PeekOffset(eSelectCharacter, aDirection, -1, aResultFrame,
found = PR_FALSE;
frameUsed = GetPrevInFlow();
start = -1;
}
}
else if (aDirection == eDirNext){
PRInt32 i;
for (i = aStartOffset +1; i <= mContentLength; i++){
if (ip[i] > ip[aStartOffset]){
*aResultFrame = this;
*aFrameOffset = i;
break;
}
}
if (aStartOffset == 0 && (mFlags & 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;
frameUsed = GetNextInFlow();
start = 0;
}
}
if (!found){
if (frameUsed){
return frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, -1, aResultFrame,
aFrameOffset, aContentOffset);
}
}
}
else
if (aDirection == eDirNext){
PRInt32 i;
for (i = aStartOffset +1; i <= mContentLength; i++){
if (ip[i] > ip[aStartOffset]){
*aResultFrame = this;
*aFrameOffset = i;
break;
}
}
if (aStartOffset == 0 && (mFlags & TEXT_SKIP_LEADING_WS))
i--; //back up because we just skipped over some white space. why skip over the char also?
if (i > mContentLength){
nsIFrame *next = GetNextInFlow();
if (next){
return next->PeekOffset(eSelectCharacter, aDirection, 0, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, 0, aResultFrame,
aFrameOffset, aContentOffset);
}
}
}
*aContentOffset = mContentOffset;
}
*aContentOffset = mContentOffset;
}
break;
case eSelectWord :
case eSelectWord : {
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
PRBool isWhitespace;
PRInt32 wordLen, contentLen;
if (aDirection == eDirPrevious){
tx.Init(this, mContentOffset + aStartOffset);
if (tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){
*aFrameOffset = aStartOffset - contentLen;
//check for whitespace next.
if (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace))
*aFrameOffset -= contentLen;
found = PR_TRUE;
}
frameUsed = GetPrevInFlow();
start = -1; //start at end
}
else if (aDirection == eDirNext){
tx.Init(this, mContentOffset + aStartOffset );
if (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace)){
*aFrameOffset = aStartOffset + contentLen;
//check for whitespace next.
if (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace)
*aFrameOffset += contentLen;
found = PR_TRUE;
}
frameUsed = GetNextInFlow();
start = 0;
}
if (!found || (*aFrameOffset > mContentLength) || (*aFrameOffset < mContentOffset)){ //gone too far
if (frameUsed){
return frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
}
*aContentOffset = mContentOffset;
*aResultFrame = this;
}
break;
case eSelectLine :
default: result = NS_ERROR_FAILURE; break;
}

View File

@@ -379,6 +379,270 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
return mBuffer;
}
PRUnichar*
nsTextTransformer::GetPrevWord(PRBool aInWord,
PRInt32& aWordLenResult,
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult)
{
NS_PRECONDITION(mOffset <= mContentLength, "bad offset");
// See if the content has been exhausted
if (mOffset == 0) {
aWordLenResult = 0;
aContentLenResult = 0;
return nsnull;
}
PRUnichar* bp = mBuffer;
PRUnichar* bufEnd = mBuffer + mBufferLength;
const nsTextFragment* frag = mCurrentFrag;
const nsTextFragment* lastFrag = mFrags;//1st is the last
PRInt32 wordLen = 1;
PRInt32 contentLen = 1;
// Set the isWhitespace flag by examining the next character in the
// text fragment.
PRInt32 offset = mCurrentFragOffset-1;
PRUnichar firstChar;
if (frag->Is2b()) {
const PRUnichar* up = frag->Get2b();
firstChar = up[offset];
}
else {
const unsigned char* cp = (const unsigned char*) frag->Get1b();
if (offset > 0)
firstChar = PRUnichar(cp[offset]);
else
firstChar = PRUnichar(cp[0]);
}
PRBool isWhitespace = XP_IS_SPACE(firstChar);
offset--;
if (isWhitespace) {
if (NS_STYLE_WHITESPACE_PRE == mWhiteSpace) {
if ('\t' == firstChar) {
// Leave tab alone so that caller can expand it
}
else if ('\n' == firstChar) {
// Advance content past newline but do not allow newline to
// remain in the word.
wordLen--;
}
else {
firstChar = ' ';
}
}
else {
firstChar = ' ';
}
}
else if (CH_NBSP == firstChar) {
firstChar = ' ';
}
else {
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(firstChar)) {
firstChar = XP_TO_LOWER(firstChar);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(firstChar)) {
firstChar = XP_TO_UPPER(firstChar);
}
break;
}
}
*bp++ = firstChar;
mCurrentFragOffset = offset +1;
if (offset < 0) {
if (mCurrentFrag == mFrags){
goto really_done;
}
mCurrentFrag = --frag;
offset = mCurrentFrag->GetLength()-1;
}
if (isWhitespace && (NS_STYLE_WHITESPACE_PRE == mWhiteSpace)) {
goto really_done;
}
PRInt32 numChars;
do {
PRInt32 fragLen = frag->GetLength();
// Scan characters in this fragment that are the same kind as the
// isWhitespace flag indicates.
if (frag->Is2b()) {
const PRUnichar* cp0 = frag->Get2b();
const PRUnichar* end = cp0;
const PRUnichar* cp = cp0 + offset;
if (isWhitespace) {
while (cp > end) {
PRUnichar ch = *cp;
if (XP_IS_SPACE(ch)) {
cp--;
continue;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
}
else {
while (cp > end) {
PRUnichar ch = *cp;
if (!XP_IS_SPACE(ch)) {
if (CH_NBSP == ch) ch = ' ';
if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE;
cp--;
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(ch)) {
ch = XP_TO_LOWER(ch);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(ch)) {
ch = XP_TO_UPPER(ch);
}
break;
}
// Store character in buffer; grow buffer if we have to
NS_ASSERTION(bp < bufEnd, "whoops");
*bp++ = ch;
if (bp == bufEnd) {
PRInt32 delta = bp - mBuffer;
if (!GrowBuffer()) {
goto done;
}
bp = mBuffer + delta;
bufEnd = mBuffer + mBufferLength;
}
continue;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
}
}
else {
const unsigned char* cp0 = (const unsigned char*) frag->Get1b();
const unsigned char* end = cp0;
const unsigned char* cp = cp0 + offset;
if (isWhitespace) {
while (cp > end) {
PRUnichar ch = PRUnichar(*cp);
if (XP_IS_SPACE(ch)) {
cp--;
continue;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
}
else {
while (cp > end) {
PRUnichar ch = PRUnichar(*cp);
if (!XP_IS_SPACE(ch)) {
if (CH_NBSP == ch) ch = ' ';
if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE;
cp--;
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(ch)) {
ch = XP_TO_LOWER(ch);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(ch)) {
ch = XP_TO_UPPER(ch);
}
break;
}
// Store character in buffer; grow buffer if we have to
NS_ASSERTION(bp < bufEnd, "whoops");
*bp++ = ch;
if (bp == bufEnd) {
PRInt32 delta = bp - mBuffer;
if (!GrowBuffer()) {
goto done;
}
bp = mBuffer + delta;
bufEnd = mBuffer + mBufferLength;
}
continue;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
}
}
// Advance to next text fragment
if (frag != lastFrag)
{
frag--;
mCurrentFrag = frag;
mCurrentFragOffset = mCurrentFrag->GetLength()-1;
offset = mCurrentFragOffset;
}
else
mCurrentFragOffset = 0;
}
while (frag > lastFrag);
done:;
if (!aInWord && !isWhitespace &&
(NS_STYLE_TEXT_TRANSFORM_CAPITALIZE == mTextTransform)) {
PRInt32 n = wordLen;
PRUnichar* bp = mBuffer;
for (; --n >= 0; bp++) {
PRUnichar ch = *bp;
if (' ' == ch) {
// Skip over NBSP's that were mapped to space
continue;
}
if (XP_IS_LOWERCASE(ch)) {
*bp = XP_TO_UPPER(ch);
}
break;
}
}
really_done:;
mOffset -= contentLen;
NS_ASSERTION(mOffset >= 0, "whoops");
aWordLenResult = wordLen;
aContentLenResult = contentLen;
aIsWhitespaceResult = isWhitespace;
return mBuffer;
}
PRUnichar*
nsTextTransformer::GetTextAt(PRInt32 aOffset)
{

View File

@@ -64,6 +64,10 @@ public:
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult);
PRUnichar* GetPrevWord(PRBool aInWord,
PRInt32& aWordLenResult,
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult);
PRBool HasMultibyte() const {
return mHasMultibyte;
}

View File

@@ -1790,9 +1790,6 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
// Transform text from content into renderable form
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE);
PrepareUnicodeText(tx, ip, paintBuf, textLength, width);
ip[mContentLength] = ip[mContentLength-1]+1; //must set up last one for selection beyond edge
nsresult result(NS_OK);
switch (aAmount){
case eSelectNoAmount : {
@@ -1803,6 +1800,11 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
}
break;
case eSelectCharacter : {
PrepareUnicodeText(tx, ip, paintBuf, textLength, width);
ip[mContentLength] = ip[mContentLength-1]+1; //must set up last one for selection beyond edge
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
if (aDirection == eDirPrevious){
PRInt32 i;
for (i = aStartOffset -1; i >=0; i--){
@@ -1813,45 +1815,85 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32
}
}
if (i <0){
nsIFrame *prev = GetPrevInFlow();
if (prev){
return prev->PeekOffset(eSelectCharacter, aDirection, -1, aResultFrame,
found = PR_FALSE;
frameUsed = GetPrevInFlow();
start = -1;
}
}
else if (aDirection == eDirNext){
PRInt32 i;
for (i = aStartOffset +1; i <= mContentLength; i++){
if (ip[i] > ip[aStartOffset]){
*aResultFrame = this;
*aFrameOffset = i;
break;
}
}
if (aStartOffset == 0 && (mFlags & 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;
frameUsed = GetNextInFlow();
start = 0;
}
}
if (!found){
if (frameUsed){
return frameUsed->PeekOffset(eSelectCharacter, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, -1, aResultFrame,
aFrameOffset, aContentOffset);
}
}
}
else
if (aDirection == eDirNext){
PRInt32 i;
for (i = aStartOffset +1; i <= mContentLength; i++){
if (ip[i] > ip[aStartOffset]){
*aResultFrame = this;
*aFrameOffset = i;
break;
}
}
if (aStartOffset == 0 && (mFlags & TEXT_SKIP_LEADING_WS))
i--; //back up because we just skipped over some white space. why skip over the char also?
if (i > mContentLength){
nsIFrame *next = GetNextInFlow();
if (next){
return next->PeekOffset(eSelectCharacter, aDirection, 0, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(eSelectCharacter, aDirection, 0, aResultFrame,
aFrameOffset, aContentOffset);
}
}
}
*aContentOffset = mContentOffset;
}
*aContentOffset = mContentOffset;
}
break;
case eSelectWord :
case eSelectWord : {
nsIFrame *frameUsed = nsnull;
PRInt32 start;
PRBool found = PR_TRUE;
PRBool isWhitespace;
PRInt32 wordLen, contentLen;
if (aDirection == eDirPrevious){
tx.Init(this, mContentOffset + aStartOffset);
if (tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace)){
*aFrameOffset = aStartOffset - contentLen;
//check for whitespace next.
if (isWhitespace && tx.GetPrevWord(PR_FALSE, wordLen, contentLen, isWhitespace))
*aFrameOffset -= contentLen;
found = PR_TRUE;
}
frameUsed = GetPrevInFlow();
start = -1; //start at end
}
else if (aDirection == eDirNext){
tx.Init(this, mContentOffset + aStartOffset );
if (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace)){
*aFrameOffset = aStartOffset + contentLen;
//check for whitespace next.
if (tx.GetNextWord(PR_FALSE, wordLen, contentLen, isWhitespace) && isWhitespace)
*aFrameOffset += contentLen;
found = PR_TRUE;
}
frameUsed = GetNextInFlow();
start = 0;
}
if (!found || (*aFrameOffset > mContentLength) || (*aFrameOffset < mContentOffset)){ //gone too far
if (frameUsed){
return frameUsed->PeekOffset(aAmount, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
else {//reached end ask the frame for help
return nsFrame::PeekOffset(aAmount, aDirection, start, aResultFrame,
aFrameOffset, aContentOffset);
}
}
*aContentOffset = mContentOffset;
*aResultFrame = this;
}
break;
case eSelectLine :
default: result = NS_ERROR_FAILURE; break;
}

View File

@@ -379,6 +379,270 @@ nsTextTransformer::GetNextWord(PRBool aInWord,
return mBuffer;
}
PRUnichar*
nsTextTransformer::GetPrevWord(PRBool aInWord,
PRInt32& aWordLenResult,
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult)
{
NS_PRECONDITION(mOffset <= mContentLength, "bad offset");
// See if the content has been exhausted
if (mOffset == 0) {
aWordLenResult = 0;
aContentLenResult = 0;
return nsnull;
}
PRUnichar* bp = mBuffer;
PRUnichar* bufEnd = mBuffer + mBufferLength;
const nsTextFragment* frag = mCurrentFrag;
const nsTextFragment* lastFrag = mFrags;//1st is the last
PRInt32 wordLen = 1;
PRInt32 contentLen = 1;
// Set the isWhitespace flag by examining the next character in the
// text fragment.
PRInt32 offset = mCurrentFragOffset-1;
PRUnichar firstChar;
if (frag->Is2b()) {
const PRUnichar* up = frag->Get2b();
firstChar = up[offset];
}
else {
const unsigned char* cp = (const unsigned char*) frag->Get1b();
if (offset > 0)
firstChar = PRUnichar(cp[offset]);
else
firstChar = PRUnichar(cp[0]);
}
PRBool isWhitespace = XP_IS_SPACE(firstChar);
offset--;
if (isWhitespace) {
if (NS_STYLE_WHITESPACE_PRE == mWhiteSpace) {
if ('\t' == firstChar) {
// Leave tab alone so that caller can expand it
}
else if ('\n' == firstChar) {
// Advance content past newline but do not allow newline to
// remain in the word.
wordLen--;
}
else {
firstChar = ' ';
}
}
else {
firstChar = ' ';
}
}
else if (CH_NBSP == firstChar) {
firstChar = ' ';
}
else {
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(firstChar)) {
firstChar = XP_TO_LOWER(firstChar);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(firstChar)) {
firstChar = XP_TO_UPPER(firstChar);
}
break;
}
}
*bp++ = firstChar;
mCurrentFragOffset = offset +1;
if (offset < 0) {
if (mCurrentFrag == mFrags){
goto really_done;
}
mCurrentFrag = --frag;
offset = mCurrentFrag->GetLength()-1;
}
if (isWhitespace && (NS_STYLE_WHITESPACE_PRE == mWhiteSpace)) {
goto really_done;
}
PRInt32 numChars;
do {
PRInt32 fragLen = frag->GetLength();
// Scan characters in this fragment that are the same kind as the
// isWhitespace flag indicates.
if (frag->Is2b()) {
const PRUnichar* cp0 = frag->Get2b();
const PRUnichar* end = cp0;
const PRUnichar* cp = cp0 + offset;
if (isWhitespace) {
while (cp > end) {
PRUnichar ch = *cp;
if (XP_IS_SPACE(ch)) {
cp--;
continue;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
}
else {
while (cp > end) {
PRUnichar ch = *cp;
if (!XP_IS_SPACE(ch)) {
if (CH_NBSP == ch) ch = ' ';
if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE;
cp--;
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(ch)) {
ch = XP_TO_LOWER(ch);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(ch)) {
ch = XP_TO_UPPER(ch);
}
break;
}
// Store character in buffer; grow buffer if we have to
NS_ASSERTION(bp < bufEnd, "whoops");
*bp++ = ch;
if (bp == bufEnd) {
PRInt32 delta = bp - mBuffer;
if (!GrowBuffer()) {
goto done;
}
bp = mBuffer + delta;
bufEnd = mBuffer + mBufferLength;
}
continue;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
}
}
else {
const unsigned char* cp0 = (const unsigned char*) frag->Get1b();
const unsigned char* end = cp0;
const unsigned char* cp = cp0 + offset;
if (isWhitespace) {
while (cp > end) {
PRUnichar ch = PRUnichar(*cp);
if (XP_IS_SPACE(ch)) {
cp--;
continue;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
contentLen += numChars;
}
else {
while (cp > end) {
PRUnichar ch = PRUnichar(*cp);
if (!XP_IS_SPACE(ch)) {
if (CH_NBSP == ch) ch = ' ';
if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE;
cp--;
switch (mTextTransform) {
case NS_STYLE_TEXT_TRANSFORM_LOWERCASE:
if (XP_IS_UPPERCASE(ch)) {
ch = XP_TO_LOWER(ch);
}
break;
case NS_STYLE_TEXT_TRANSFORM_UPPERCASE:
if (XP_IS_LOWERCASE(ch)) {
ch = XP_TO_UPPER(ch);
}
break;
}
// Store character in buffer; grow buffer if we have to
NS_ASSERTION(bp < bufEnd, "whoops");
*bp++ = ch;
if (bp == bufEnd) {
PRInt32 delta = bp - mBuffer;
if (!GrowBuffer()) {
goto done;
}
bp = mBuffer + delta;
bufEnd = mBuffer + mBufferLength;
}
continue;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
mCurrentFragOffset -= numChars;
goto done;
}
numChars = (cp0 + offset) - cp;
wordLen += numChars;
contentLen += numChars;
}
}
// Advance to next text fragment
if (frag != lastFrag)
{
frag--;
mCurrentFrag = frag;
mCurrentFragOffset = mCurrentFrag->GetLength()-1;
offset = mCurrentFragOffset;
}
else
mCurrentFragOffset = 0;
}
while (frag > lastFrag);
done:;
if (!aInWord && !isWhitespace &&
(NS_STYLE_TEXT_TRANSFORM_CAPITALIZE == mTextTransform)) {
PRInt32 n = wordLen;
PRUnichar* bp = mBuffer;
for (; --n >= 0; bp++) {
PRUnichar ch = *bp;
if (' ' == ch) {
// Skip over NBSP's that were mapped to space
continue;
}
if (XP_IS_LOWERCASE(ch)) {
*bp = XP_TO_UPPER(ch);
}
break;
}
}
really_done:;
mOffset -= contentLen;
NS_ASSERTION(mOffset >= 0, "whoops");
aWordLenResult = wordLen;
aContentLenResult = contentLen;
aIsWhitespaceResult = isWhitespace;
return mBuffer;
}
PRUnichar*
nsTextTransformer::GetTextAt(PRInt32 aOffset)
{

View File

@@ -64,6 +64,10 @@ public:
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult);
PRUnichar* GetPrevWord(PRBool aInWord,
PRInt32& aWordLenResult,
PRInt32& aContentLenResult,
PRBool& aIsWhitespaceResult);
PRBool HasMultibyte() const {
return mHasMultibyte;
}