From 5f7220fa9c60e48f5d36e169172c71d1d5a7e97a Mon Sep 17 00:00:00 2001 From: "ftang%netscape.com" Date: Wed, 24 Feb 1999 18:21:23 +0000 Subject: [PATCH] change nsTextTransformer to break line by calling nsILineBreak and make nsTextFrame pass the nsILineBreaker to nsTextTransformer git-svn-id: svn://10.0.0.236/trunk@21772 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsTextFrame.cpp | 56 +++++++++++-- mozilla/layout/generic/nsTextTransformer.cpp | 80 ++++++++++++------- mozilla/layout/generic/nsTextTransformer.h | 7 +- mozilla/layout/html/base/src/makefile.win | 2 + mozilla/layout/html/base/src/nsTextFrame.cpp | 56 +++++++++++-- .../html/base/src/nsTextTransformer.cpp | 80 ++++++++++++------- .../layout/html/base/src/nsTextTransformer.h | 7 +- 7 files changed, 210 insertions(+), 78 deletions(-) diff --git a/mozilla/layout/generic/nsTextFrame.cpp b/mozilla/layout/generic/nsTextFrame.cpp index 1e8c5fa437f..941cdd6237e 100644 --- a/mozilla/layout/generic/nsTextFrame.cpp +++ b/mozilla/layout/generic/nsTextFrame.cpp @@ -42,6 +42,7 @@ #include "nsIFocusTracker.h" #include "nsXIFConverter.h" #include "nsHTMLAtoms.h" +#include "nsILineBreaker.h" #include "nsITextContent.h" #include "nsTextReflow.h"/* XXX rename to nsTextRun */ @@ -826,7 +827,9 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, displaySelection ? ip : nsnull, paintBuf, textLength, width); @@ -1166,7 +1169,9 @@ TextFrame::PaintTextSlowly(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE, lb); aTextStyle.mNumSpaces = PrepareUnicodeText(tx, displaySelection ? ip : nsnull, paintBuf, textLength, width); @@ -1320,7 +1325,9 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, displaySelection ? ip : nsnull, rawPaintBuf, textLength, width); @@ -1537,8 +1544,14 @@ TextFrame::GetPosition(nsIPresContext& aCX, aCX.GetMetricsFor(font->mFont, getter_AddRefs(fm)); aRendContext->SetFont(fm); + nsCOMPtr shell; + aCX.GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Get the renderable form of the text - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, ip, paintBuf, textLength, width); ip[mContentLength] = ip[mContentLength-1]+1; @@ -1722,8 +1735,14 @@ TextFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext TextStyle ts(*inPresContext, *inRendContext, mStyleContext); + nsCOMPtr shell; + inPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, ip, paintBuf, textLength, width); PRUnichar* text = paintBuf; @@ -1799,7 +1818,14 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsIDocument* doc; + mContent->GetDocument(doc); + + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_IF_RELEASE(doc); + + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); nsresult result(NS_OK); switch (aAmount){ case eSelectNoAmount : { @@ -2003,9 +2029,15 @@ TextFrame::Reflow(nsIPresContext& aPresContext, PRBool endsInWhitespace = PR_FALSE; PRBool endsInNewline = PR_FALSE; + nsCOMPtr shell; + aPresContext.GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Setup text transformer to transform this frames text content PRUnichar wordBuf[WORD_BUF_SIZE]; - nsTextTransformer tx(wordBuf, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBuf, WORD_BUF_SIZE,lb); nsresult rv = tx.Init(/**textRun, XXX*/ this, startingOffset); if (NS_OK != rv) { return rv; @@ -2461,7 +2493,15 @@ TextFrame::ComputeWordFragmentWidth(nsLineLayout& aLineLayout, PRBool& aStop) { PRUnichar buf[TEXT_BUF_SIZE]; - nsTextTransformer tx(buf, TEXT_BUF_SIZE); + nsIDocument* doc; + + mContent->GetDocument(doc); + + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_IF_RELEASE(doc); + + nsTextTransformer tx(buf, TEXT_BUF_SIZE,lb); // XXX we need the content-offset of the text frame!!! 0 won't // always be right when continuations are in action tx.Init(/**textRun, XXX*/ aTextFrame, 0); diff --git a/mozilla/layout/generic/nsTextTransformer.cpp b/mozilla/layout/generic/nsTextTransformer.cpp index 5f3e1f887ee..9570bbf9ac4 100644 --- a/mozilla/layout/generic/nsTextTransformer.cpp +++ b/mozilla/layout/generic/nsTextTransformer.cpp @@ -22,6 +22,7 @@ #include "nsIStyleContext.h" #include "nsITextContent.h" #include "nsStyleConsts.h" +#include "nsILineBreaker.h" #include "nsIServiceManager.h" @@ -32,7 +33,6 @@ static NS_DEFINE_IID(kUnicharUtilCID, NS_UNICHARUTIL_CID); static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID); static nsICaseConversion* gCaseConv = nsnull; - // XXX put a copy in nsHTMLIIDs static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); @@ -41,12 +41,15 @@ static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); #define MAX_UNIBYTE 127 -nsTextTransformer::nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen) +nsTextTransformer::nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen, + nsILineBreaker* aLineBreaker) : mAutoBuffer(aBuffer), mBuffer(aBuffer), mBufferLength(aBufLen < 0 ? 0 : aBufLen), + mLineBreaker(aLineBreaker), mHasMultibyte(PR_FALSE) { + NS_IF_ADDREF(mLineBreaker); } nsTextTransformer::~nsTextTransformer() @@ -54,6 +57,7 @@ nsTextTransformer::~nsTextTransformer() if (mBuffer != mAutoBuffer) { delete [] mBuffer; } + NS_IF_RELEASE(mLineBreaker); } nsresult @@ -244,35 +248,51 @@ nsTextTransformer::GetNextWord(PRBool aInWord, 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++; + if(wordLen > 0) { + nsresult res = NS_OK; + PRBool breakBetween = PR_FALSE; + res = mLineBreaker->BreakInBetween(mBuffer, wordLen, + cp, (fragLen-offset), &breakBetween); + if ( breakBetween ) + goto done; - // 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 = (cp - offset) - cp0; - wordLen += numChars; - contentLen += numChars; - mCurrentFragOffset += numChars; - goto done; - } - numChars = (cp - offset) - cp0; - wordLen += numChars; - contentLen += numChars; + PRBool tryNextFrag = PR_FALSE; + PRUint32 next; + + // Find next position + res = mLineBreaker->Next(cp0, fragLen, offset, &next, &tryNextFrag); + + numChars = (next - offset); + // check buffer size before copy + if((bp + numChars ) > bufEnd) { + PRInt32 delta = bp - mBuffer; + if(!GrowBuffer()) { + goto done; + } + bp = mBuffer + delta; + bufEnd = mBuffer + mBufferLength; + } + + wordLen += numChars; + mCurrentFragOffset += numChars; + contentLen += numChars; + end = cp + numChars; + + // 1. convert nbsp into space + // 2. check mHasMultibyte flag + // 3. copy buffer + + while(cp < end) { + PRUnichar ch = *cp++; + if (CH_NBSP == ch) ch = ' '; + if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE; + *bp++ = ch; + } + if(! tryNextFrag) { + // can decide break position inside this TextFrag + goto done; + } + } } } else { diff --git a/mozilla/layout/generic/nsTextTransformer.h b/mozilla/layout/generic/nsTextTransformer.h index 795fc0c61f9..42ef32b2912 100644 --- a/mozilla/layout/generic/nsTextTransformer.h +++ b/mozilla/layout/generic/nsTextTransformer.h @@ -24,6 +24,7 @@ class nsIFrame; class nsTextRun; +class nsILineBreaker; /** * This object manages the transformation of text: @@ -43,7 +44,9 @@ class nsTextRun; */ class nsTextTransformer { public: - nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen); + + nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen, nsILineBreaker* aLineBreaker); + ~nsTextTransformer(); /** @@ -93,6 +96,8 @@ protected: PRUint8 mTextTransform; PRUint8 mWhiteSpace; + + nsILineBreaker* mLineBreaker; }; #endif /* nsTextTransformer_h___ */ diff --git a/mozilla/layout/html/base/src/makefile.win b/mozilla/layout/html/base/src/makefile.win index d55219a8c6f..0f37bc99f11 100644 --- a/mozilla/layout/html/base/src/makefile.win +++ b/mozilla/layout/html/base/src/makefile.win @@ -109,6 +109,8 @@ LINCS=-I$(PUBLIC)\xpcom -I$(PUBLIC)\raptor -I$(PUBLIC)\js \ -I..\..\content\src \ -I..\..\..\base\src -I$(PUBLIC)\plugin -I$(PUBLIC)\java \ -I$(PUBLIC)\pref \ + -I$(PUBLIC)\lwbrk \ + -I$(PUBLIC)\unicharutil \ -I$(PUBLIC)\oji LCFLAGS = \ diff --git a/mozilla/layout/html/base/src/nsTextFrame.cpp b/mozilla/layout/html/base/src/nsTextFrame.cpp index 1e8c5fa437f..941cdd6237e 100644 --- a/mozilla/layout/html/base/src/nsTextFrame.cpp +++ b/mozilla/layout/html/base/src/nsTextFrame.cpp @@ -42,6 +42,7 @@ #include "nsIFocusTracker.h" #include "nsXIFConverter.h" #include "nsHTMLAtoms.h" +#include "nsILineBreaker.h" #include "nsITextContent.h" #include "nsTextReflow.h"/* XXX rename to nsTextRun */ @@ -826,7 +827,9 @@ TextFrame::PaintUnicodeText(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, displaySelection ? ip : nsnull, paintBuf, textLength, width); @@ -1166,7 +1169,9 @@ TextFrame::PaintTextSlowly(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE, lb); aTextStyle.mNumSpaces = PrepareUnicodeText(tx, displaySelection ? ip : nsnull, paintBuf, textLength, width); @@ -1320,7 +1325,9 @@ TextFrame::PaintAsciiText(nsIPresContext& aPresContext, PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, displaySelection ? ip : nsnull, rawPaintBuf, textLength, width); @@ -1537,8 +1544,14 @@ TextFrame::GetPosition(nsIPresContext& aCX, aCX.GetMetricsFor(font->mFont, getter_AddRefs(fm)); aRendContext->SetFont(fm); + nsCOMPtr shell; + aCX.GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Get the renderable form of the text - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, ip, paintBuf, textLength, width); ip[mContentLength] = ip[mContentLength-1]+1; @@ -1722,8 +1735,14 @@ TextFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext TextStyle ts(*inPresContext, *inRendContext, mStyleContext); + nsCOMPtr shell; + inPresContext->GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); PrepareUnicodeText(tx, ip, paintBuf, textLength, width); PRUnichar* text = paintBuf; @@ -1799,7 +1818,14 @@ TextFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 PRInt32 textLength; // Transform text from content into renderable form - nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE); + nsIDocument* doc; + mContent->GetDocument(doc); + + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_IF_RELEASE(doc); + + nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb); nsresult result(NS_OK); switch (aAmount){ case eSelectNoAmount : { @@ -2003,9 +2029,15 @@ TextFrame::Reflow(nsIPresContext& aPresContext, PRBool endsInWhitespace = PR_FALSE; PRBool endsInNewline = PR_FALSE; + nsCOMPtr shell; + aPresContext.GetShell(getter_AddRefs(shell)); + nsCOMPtr doc; + shell->GetDocument(getter_AddRefs(doc)); // Setup text transformer to transform this frames text content PRUnichar wordBuf[WORD_BUF_SIZE]; - nsTextTransformer tx(wordBuf, WORD_BUF_SIZE); + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + nsTextTransformer tx(wordBuf, WORD_BUF_SIZE,lb); nsresult rv = tx.Init(/**textRun, XXX*/ this, startingOffset); if (NS_OK != rv) { return rv; @@ -2461,7 +2493,15 @@ TextFrame::ComputeWordFragmentWidth(nsLineLayout& aLineLayout, PRBool& aStop) { PRUnichar buf[TEXT_BUF_SIZE]; - nsTextTransformer tx(buf, TEXT_BUF_SIZE); + nsIDocument* doc; + + mContent->GetDocument(doc); + + nsCOMPtr lb; + doc->GetLineBreaker(getter_AddRefs(lb)); + NS_IF_RELEASE(doc); + + nsTextTransformer tx(buf, TEXT_BUF_SIZE,lb); // XXX we need the content-offset of the text frame!!! 0 won't // always be right when continuations are in action tx.Init(/**textRun, XXX*/ aTextFrame, 0); diff --git a/mozilla/layout/html/base/src/nsTextTransformer.cpp b/mozilla/layout/html/base/src/nsTextTransformer.cpp index 5f3e1f887ee..9570bbf9ac4 100644 --- a/mozilla/layout/html/base/src/nsTextTransformer.cpp +++ b/mozilla/layout/html/base/src/nsTextTransformer.cpp @@ -22,6 +22,7 @@ #include "nsIStyleContext.h" #include "nsITextContent.h" #include "nsStyleConsts.h" +#include "nsILineBreaker.h" #include "nsIServiceManager.h" @@ -32,7 +33,6 @@ static NS_DEFINE_IID(kUnicharUtilCID, NS_UNICHARUTIL_CID); static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID); static nsICaseConversion* gCaseConv = nsnull; - // XXX put a copy in nsHTMLIIDs static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); @@ -41,12 +41,15 @@ static NS_DEFINE_IID(kITextContentIID, NS_ITEXT_CONTENT_IID); #define MAX_UNIBYTE 127 -nsTextTransformer::nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen) +nsTextTransformer::nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen, + nsILineBreaker* aLineBreaker) : mAutoBuffer(aBuffer), mBuffer(aBuffer), mBufferLength(aBufLen < 0 ? 0 : aBufLen), + mLineBreaker(aLineBreaker), mHasMultibyte(PR_FALSE) { + NS_IF_ADDREF(mLineBreaker); } nsTextTransformer::~nsTextTransformer() @@ -54,6 +57,7 @@ nsTextTransformer::~nsTextTransformer() if (mBuffer != mAutoBuffer) { delete [] mBuffer; } + NS_IF_RELEASE(mLineBreaker); } nsresult @@ -244,35 +248,51 @@ nsTextTransformer::GetNextWord(PRBool aInWord, 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++; + if(wordLen > 0) { + nsresult res = NS_OK; + PRBool breakBetween = PR_FALSE; + res = mLineBreaker->BreakInBetween(mBuffer, wordLen, + cp, (fragLen-offset), &breakBetween); + if ( breakBetween ) + goto done; - // 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 = (cp - offset) - cp0; - wordLen += numChars; - contentLen += numChars; - mCurrentFragOffset += numChars; - goto done; - } - numChars = (cp - offset) - cp0; - wordLen += numChars; - contentLen += numChars; + PRBool tryNextFrag = PR_FALSE; + PRUint32 next; + + // Find next position + res = mLineBreaker->Next(cp0, fragLen, offset, &next, &tryNextFrag); + + numChars = (next - offset); + // check buffer size before copy + if((bp + numChars ) > bufEnd) { + PRInt32 delta = bp - mBuffer; + if(!GrowBuffer()) { + goto done; + } + bp = mBuffer + delta; + bufEnd = mBuffer + mBufferLength; + } + + wordLen += numChars; + mCurrentFragOffset += numChars; + contentLen += numChars; + end = cp + numChars; + + // 1. convert nbsp into space + // 2. check mHasMultibyte flag + // 3. copy buffer + + while(cp < end) { + PRUnichar ch = *cp++; + if (CH_NBSP == ch) ch = ' '; + if (ch > MAX_UNIBYTE) mHasMultibyte = PR_TRUE; + *bp++ = ch; + } + if(! tryNextFrag) { + // can decide break position inside this TextFrag + goto done; + } + } } } else { diff --git a/mozilla/layout/html/base/src/nsTextTransformer.h b/mozilla/layout/html/base/src/nsTextTransformer.h index 795fc0c61f9..42ef32b2912 100644 --- a/mozilla/layout/html/base/src/nsTextTransformer.h +++ b/mozilla/layout/html/base/src/nsTextTransformer.h @@ -24,6 +24,7 @@ class nsIFrame; class nsTextRun; +class nsILineBreaker; /** * This object manages the transformation of text: @@ -43,7 +44,9 @@ class nsTextRun; */ class nsTextTransformer { public: - nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen); + + nsTextTransformer(PRUnichar* aBuffer, PRInt32 aBufLen, nsILineBreaker* aLineBreaker); + ~nsTextTransformer(); /** @@ -93,6 +96,8 @@ protected: PRUint8 mTextTransform; PRUint8 mWhiteSpace; + + nsILineBreaker* mLineBreaker; }; #endif /* nsTextTransformer_h___ */