From bfef246b4b49101d039b7bb39301fba4a533950e Mon Sep 17 00:00:00 2001 From: Simon Montagu Date: Thu, 24 Mar 2011 11:28:44 +0200 Subject: [PATCH] Bug 263359 part 1: refactor bidi resolution code, combining InitLogicalArray and CreateBlockBuffer. r=roc --- layout/base/nsBidiPresUtils.cpp | 95 ++++++++++++++------------------- layout/base/nsBidiPresUtils.h | 8 +-- layout/generic/nsBidiFrames.cpp | 8 +-- layout/generic/nsBidiFrames.h | 7 +-- 4 files changed, 45 insertions(+), 73 deletions(-) diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp index 66cabbe15216..e9f06254b587 100644 --- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -77,7 +77,7 @@ static const PRUnichar ALEF = 0x05D0; // Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp nsIFrame* -NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar); +NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8), mIndexMap(nsnull), @@ -318,6 +318,7 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) { mLogicalFrames.Clear(); mContentToFrameIndex.Clear(); + mBuffer.SetLength(0); nsPresContext *presContext = aBlockFrame->PresContext(); nsIPresShell* shell = presContext->PresShell(); @@ -328,34 +329,41 @@ nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset(); + PRUnichar ch = 0; if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) { nsIFrame *directionalFrame = nsnull; if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { - directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kRLO); + ch = kRLO; } else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { - directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kLRO); + ch = kLRO; } - - if (directionalFrame) { - mLogicalFrames.AppendElement(directionalFrame); + if (ch != 0) { + directionalFrame = NS_NewDirectionalFrame(shell, styleContext); + if (directionalFrame) { + mLogicalFrames.AppendElement(directionalFrame); + mBuffer.Append(ch); + } } } + mPrevContent = nsnull; for (nsBlockFrame* block = aBlockFrame; block; block = static_cast(block->GetNextContinuation())) { block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); InitLogicalArray(block->GetFirstChild(nsnull)); } - if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) { - nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF); + if (ch != 0) { + nsIFrame* directionalFrame = NS_NewDirectionalFrame(shell, styleContext); if (directionalFrame) { mLogicalFrames.AppendElement(directionalFrame); + mBuffer.Append(kPDF); } } - CreateBlockBuffer(); + // XXX: TODO: Handle preformatted text ('\n') + mBuffer.ReplaceChar("\t\r\n", kSpace); PRInt32 bufferLength = mBuffer.Length(); @@ -638,7 +646,7 @@ PRBool IsBidiLeaf(nsIFrame* aFrame) { } void -nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame) +nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame) { if (!aCurrentFrame) return; @@ -693,9 +701,10 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame) // Create a directional frame before the first frame of an // element specifying embedding or override if (ch != 0 && !frame->GetPrevContinuation()) { - nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, ch); + nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); if (dirFrame) { mLogicalFrames.AppendElement(dirFrame); + mBuffer.Append(ch); } } } @@ -711,6 +720,23 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame) mContentToFrameIndex.Put(content, mLogicalFrames.Length()); } mLogicalFrames.AppendElement(frame); + + // Append the content of the frame to the paragraph buffer + nsIAtom* frameType = frame->GetType(); + if (nsGkAtoms::textFrame == frameType) { + if (content != mPrevContent) { + mPrevContent = content; + content->AppendTextTo(mBuffer); + } + } else if (nsGkAtoms::brFrame == frameType) { + // break frame -- append line separator + mBuffer.Append(kLineSeparator); + } else { + // other frame type -- see the Unicode Bidi Algorithm: + // "...inline objects (such as graphics) are treated as if they are ... + // U+FFFC" + mBuffer.Append(kObjectSubstitute); + } } else { nsIFrame* kid = frame->GetFirstChild(nsnull); @@ -721,58 +747,15 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame) if (ch != 0 && !frame->GetNextContinuation()) { // Create a directional frame after the last frame of an // element specifying embedding or override - nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext, kPDF); + nsIFrame* dirFrame = NS_NewDirectionalFrame(shell, styleContext); if (dirFrame) { mLogicalFrames.AppendElement(dirFrame); + mBuffer.Append(kPDF); } } } // for } -void -nsBidiPresUtils::CreateBlockBuffer() -{ - mBuffer.SetLength(0); - - nsIFrame* frame; - nsIContent* prevContent = nsnull; - PRUint32 i; - PRUint32 count = mLogicalFrames.Length(); - - for (i = 0; i < count; i++) { - frame = mLogicalFrames[i]; - nsIAtom* frameType = frame->GetType(); - - if (nsGkAtoms::textFrame == frameType) { - nsIContent* content = frame->GetContent(); - if (!content) { - mSuccess = NS_OK; - break; - } - if (content == prevContent) { - continue; - } - prevContent = content; - content->AppendTextTo(mBuffer); - } - else if (nsGkAtoms::brFrame == frameType) { // break frame - // Append line separator - mBuffer.Append(kLineSeparator); - } - else if (nsGkAtoms::directionalFrame == frameType) { - nsDirectionalFrame* dirFrame = static_cast(frame); - mBuffer.Append(dirFrame->GetChar()); - } - else { // not text frame - // See the Unicode Bidi Algorithm: - // "...inline objects (such as graphics) are treated as if they are ... U+FFFC" - mBuffer.Append(kObjectSubstitute); - } - } - // XXX: TODO: Handle preformatted text ('\n') - mBuffer.ReplaceChar("\t\r\n", kSpace); -} - void nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, PRInt32 aNumFramesOnLine) diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h index 0976cfce5b66..1828c0901101 100644 --- a/layout/base/nsBidiPresUtils.h +++ b/layout/base/nsBidiPresUtils.h @@ -361,13 +361,6 @@ private: PRInt32 aPosResolveCount, nscoord* aWidth /* may be null */); - /** - * Create a string containing entire text content of this block. - * - * @lina 05/02/2000 - */ - void CreateBlockBuffer(); - /** * Set up an array of the frames after splitting frames so that each frame has * consistent directionality. At this point the frames are still in logical @@ -521,6 +514,7 @@ private: PRInt32* mIndexMap; PRUint8* mLevels; nsresult mSuccess; + nsIContent* mPrevContent; nsBidi* mBidiEngine; }; diff --git a/layout/generic/nsBidiFrames.cpp b/layout/generic/nsBidiFrames.cpp index 7a4be1fc3826..c56e83b0ae0d 100644 --- a/layout/generic/nsBidiFrames.cpp +++ b/layout/generic/nsBidiFrames.cpp @@ -42,8 +42,8 @@ #include "nsGkAtoms.h" -nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar) - : nsFrame(aContext), mChar(aChar) +nsDirectionalFrame::nsDirectionalFrame(nsStyleContext* aContext) + : nsFrame(aContext) { } @@ -66,9 +66,9 @@ nsDirectionalFrame::GetFrameName(nsAString& aResult) const #endif nsIFrame* -NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext, PRUnichar aChar) +NS_NewDirectionalFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { - return new (aPresShell) nsDirectionalFrame(aContext, aChar); + return new (aPresShell) nsDirectionalFrame(aContext); } NS_IMPL_FRAMEARENA_HELPERS(nsDirectionalFrame) diff --git a/layout/generic/nsBidiFrames.h b/layout/generic/nsBidiFrames.h index 0550b1f2daa8..f2ea3f961b20 100644 --- a/layout/generic/nsBidiFrames.h +++ b/layout/generic/nsBidiFrames.h @@ -52,7 +52,7 @@ protected: public: NS_DECL_FRAMEARENA_HELPERS - nsDirectionalFrame(nsStyleContext* aContext, PRUnichar aChar); + nsDirectionalFrame(nsStyleContext* aContext); /** * Get the "type" of the frame @@ -61,14 +61,9 @@ public: */ virtual nsIAtom* GetType() const; - PRUnichar GetChar() const { return mChar; } - #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif - -private: - PRUnichar mChar; };