Mozilla Home
Privacy
Cookies
Legal
Bugzilla
Browse
Advanced Search
New Bug
Reports
Documentation
Log In
Log In with GitHub
or
Remember me
Browse
Advanced Search
New Bug
Reports
Documentation
Attachment 523097 Details for
Bug 624798
[patch]
Patch v.2. updated to tip and to comments
624798.diff (text/plain), 110.86 KB, created by
Simon Montagu :smontagu
(
hide
)
Description:
Patch v.2. updated to tip and to comments
Filename:
MIME Type:
Creator:
Simon Montagu :smontagu
Size:
110.86 KB
patch
obsolete
>diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp >--- a/content/canvas/src/nsCanvasRenderingContext2D.cpp >+++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp >@@ -107,16 +107,17 @@ > #include "gfxPlatform.h" > #include "gfxFont.h" > #include "gfxTextRunCache.h" > #include "gfxBlur.h" > #include "gfxUtils.h" > > #include "nsFrameManager.h" > #include "nsFrameLoader.h" >+#include "nsBidi.h" > #include "nsBidiPresUtils.h" > #include "Layers.h" > #include "CanvasUtils.h" > #include "nsIMemoryReporter.h" > #include "nsStyleUtil.h" > #include "CanvasImageCache.h" > > #ifdef MOZ_IPC >@@ -2680,20 +2681,16 @@ nsCanvasRenderingContext2D::DrawOrMeasur > } > > nsIPresShell* presShell = GetPresShell(); > if (!presShell) > return NS_ERROR_FAILURE; > > nsIDocument* document = presShell->GetDocument(); > >- nsBidiPresUtils* bidiUtils = presShell->GetPresContext()->GetBidiUtils(); >- if (!bidiUtils) >- return NS_ERROR_FAILURE; >- > // replace all the whitespace characters with U+0020 SPACE > nsAutoString textToDraw(aRawText); > TextReplaceWhitespaceCharacters(textToDraw); > > // for now, default to ltr if not in doc > PRBool isRTL = PR_FALSE; > > if (content && content->IsInDoc()) { >@@ -2729,25 +2726,27 @@ nsCanvasRenderingContext2D::DrawOrMeasur > > processor.mFontgrp = GetCurrentFontStyle(); > NS_ASSERTION(processor.mFontgrp, "font group is null"); > > nscoord totalWidth; > > // calls bidi algo twice since it needs the full text width and the > // bounding boxes before rendering anything >- rv = bidiUtils->ProcessText(textToDraw.get(), >- textToDraw.Length(), >- isRTL ? NSBIDI_RTL : NSBIDI_LTR, >- presShell->GetPresContext(), >- processor, >- nsBidiPresUtils::MODE_MEASURE, >- nsnull, >- 0, >- &totalWidth); >+ nsBidi bidiEngine; >+ rv = nsBidiPresUtils::ProcessText(textToDraw.get(), >+ textToDraw.Length(), >+ isRTL ? NSBIDI_RTL : NSBIDI_LTR, >+ presShell->GetPresContext(), >+ processor, >+ nsBidiPresUtils::MODE_MEASURE, >+ nsnull, >+ 0, >+ &totalWidth, >+ &bidiEngine); > if (NS_FAILED(rv)) > return rv; > > if (aWidth) > *aWidth = static_cast<float>(totalWidth); > > // if only measuring, don't need to do any more work > if (aOp==TEXT_DRAW_OPERATION_MEASURE) >@@ -2835,25 +2834,26 @@ nsCanvasRenderingContext2D::DrawOrMeasur > > gfxContext* ctx = ShadowInitialize(drawExtents, blur); > > if (ctx) { > CopyContext(ctx, mThebes); > ctx->SetOperator(gfxContext::OPERATOR_SOURCE); > processor.mThebes = ctx; > >- rv = bidiUtils->ProcessText(textToDraw.get(), >- textToDraw.Length(), >- isRTL ? NSBIDI_RTL : NSBIDI_LTR, >- presShell->GetPresContext(), >- processor, >- nsBidiPresUtils::MODE_DRAW, >- nsnull, >- 0, >- nsnull); >+ rv = nsBidiPresUtils::ProcessText(textToDraw.get(), >+ textToDraw.Length(), >+ isRTL ? NSBIDI_RTL : NSBIDI_LTR, >+ presShell->GetPresContext(), >+ processor, >+ nsBidiPresUtils::MODE_DRAW, >+ nsnull, >+ 0, >+ nsnull, >+ &bidiEngine); > if (NS_FAILED(rv)) > return rv; > > ShadowFinalize(blur); > } > > processor.mThebes = mThebes; > } >@@ -2872,25 +2872,26 @@ nsCanvasRenderingContext2D::DrawOrMeasur > > // don't want operators to be applied twice > mThebes->SetOperator(gfxContext::OPERATOR_SOURCE); > } > > ApplyStyle(STYLE_FILL); > } > >- rv = bidiUtils->ProcessText(textToDraw.get(), >- textToDraw.Length(), >- isRTL ? NSBIDI_RTL : NSBIDI_LTR, >- presShell->GetPresContext(), >- processor, >- nsBidiPresUtils::MODE_DRAW, >- nsnull, >- 0, >- nsnull); >+ rv = nsBidiPresUtils::ProcessText(textToDraw.get(), >+ textToDraw.Length(), >+ isRTL ? NSBIDI_RTL : NSBIDI_LTR, >+ presShell->GetPresContext(), >+ processor, >+ nsBidiPresUtils::MODE_DRAW, >+ nsnull, >+ 0, >+ nsnull, >+ &bidiEngine); > > // this needs to be restored before function can return > if (doUseIntermediateSurface) { > mThebes->PopGroupToSource(); > DirtyAllStyles(); > } > > if (NS_FAILED(rv)) >diff --git a/layout/base/nsBidi.h b/layout/base/nsBidi.h >--- a/layout/base/nsBidi.h >+++ b/layout/base/nsBidi.h >@@ -768,17 +768,17 @@ public: > * the number of objects to be reordered. > * It must be <code>aLength>0</code>. > * > * @param aIndexMap is a pointer to an array of <code>aLength</code> > * indexes which will reflect the reordering of the characters. > * The array does not need to be initialized.<p> > * The index map will result in <code>aIndexMap[aLogicalIndex]==aVisualIndex</code>. > */ >- nsresult ReorderLogical(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap); >+ static nsresult ReorderLogical(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap); > #endif // FULL_BIDI_ENGINE > /** > * This is a convenience function that does not use a nsBidi object. > * It is intended to be used for when an application has determined the levels > * of objects (character sequences) and just needs to have them reordered (L2). > * This is equivalent to using <code>GetVisualMap</code> on a > * <code>nsBidi</code> object. > * >@@ -789,17 +789,17 @@ public: > * the number of objects to be reordered. > * It must be <code>aLength>0</code>. > * > * @param aIndexMap is a pointer to an array of <code>aLength</code> > * indexes which will reflect the reordering of the characters. > * The array does not need to be initialized.<p> > * The index map will result in <code>aIndexMap[aVisualIndex]==aLogicalIndex</code>. > */ >- nsresult ReorderVisual(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap); >+ static nsresult ReorderVisual(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap); > > #ifdef FULL_BIDI_ENGINE > /** > * Invert an index map. > * The one-to-one index mapping of the first map is inverted and written to > * the second one. > * > * @param aSrcMap is an array with <code>aLength</code> indexes >@@ -912,16 +912,16 @@ private: > void SetTrailingWSStart(); > > PRBool GetRuns(); > > void GetSingleRun(nsBidiLevel aLevel); > > void ReorderLine(nsBidiLevel aMinLevel, nsBidiLevel aMaxLevel); > >- PRBool PrepareReorder(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap, nsBidiLevel *aMinLevel, nsBidiLevel *aMaxLevel); >+ static PRBool PrepareReorder(const nsBidiLevel *aLevels, PRInt32 aLength, PRInt32 *aIndexMap, nsBidiLevel *aMinLevel, nsBidiLevel *aMaxLevel); > > PRInt32 doWriteReverse(const PRUnichar *src, PRInt32 srcLength, > PRUnichar *dest, PRUint16 options); > > }; > > #endif // _nsBidi_h_ >diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp >--- a/layout/base/nsBidiPresUtils.cpp >+++ b/layout/base/nsBidiPresUtils.cpp >@@ -66,51 +66,197 @@ using namespace mozilla; > static const PRUnichar kSpace = 0x0020; > static const PRUnichar kLineSeparator = 0x2028; > static const PRUnichar kObjectSubstitute = 0xFFFC; > static const PRUnichar kLRE = 0x202A; > static const PRUnichar kRLE = 0x202B; > static const PRUnichar kLRO = 0x202D; > static const PRUnichar kRLO = 0x202E; > static const PRUnichar kPDF = 0x202C; >-static const PRUnichar ALEF = 0x05D0; >- >-#define CHAR_IS_HEBREW(c) ((0x0590 <= (c)) && ((c)<= 0x05FF)) >-// Note: The above code are moved from gfx/src/windows/nsRenderingContextWin.cpp > > #define NS_BIDI_CONTROL_FRAME ((nsIFrame*)0xfffb1d1) > >-nsBidiPresUtils::nsBidiPresUtils() : mArraySize(8), >- mIndexMap(nsnull), >- mLevels(nsnull), >- mSuccess(NS_ERROR_FAILURE), >- mBidiEngine(nsnull) >-{ >- mBidiEngine = new nsBidi(); >- if (mBidiEngine && mContentToFrameIndex.Init()) { >- mSuccess = NS_OK; >+struct BidiParagraphData { >+ nsString mBuffer; >+ nsAutoTArray<PRUnichar, 16> mEmbeddingStack; >+ nsTArray<nsIFrame*> mLogicalFrames; >+ nsDataHashtable<nsISupportsHashKey, PRInt32> mContentToFrameIndex; >+ PRPackedBool mIsVisual; >+ nsBidiLevel mParaLevel; >+ nsIContent* mPrevContent; >+ nsAutoPtr<nsBidi> mBidiEngine; >+ >+ void Init(nsBlockFrame *aBlockFrame) >+ { >+ mContentToFrameIndex.Init(); >+ mBidiEngine = new nsBidi(); >+ mPrevContent = nsnull; >+ mParaLevel = >+ (NS_STYLE_DIRECTION_RTL == aBlockFrame->GetStyleVisibility()->mDirection) ? >+ NSBIDI_RTL : NSBIDI_LTR; >+ >+ mIsVisual = aBlockFrame->PresContext()->IsVisualMode(); >+ if (mIsVisual) { >+ /** >+ * Drill up in content to detect whether this is an element that needs to >+ * be rendered with logical order even on visual pages. >+ * >+ * We always use logical order on form controls, firstly so that text >+ * entry will be in logical order, but also because visual pages were >+ * written with the assumption that even if the browser had no support >+ * for right-to-left text rendering, it would use native widgets with >+ * bidi support to display form controls. >+ * >+ * We also use logical order in XUL elements, since we expect that if a >+ * XUL element appears in a visual page, it will be generated by an XBL >+ * binding and contain localized text which will be in logical order. >+ */ >+ for (nsIContent* content = aBlockFrame->GetContent() ; content; >+ content = content->GetParent()) { >+ if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) || >+ content->IsXUL()) { >+ mIsVisual = PR_FALSE; >+ break; >+ } >+ } >+ } > } >-} > >-nsBidiPresUtils::~nsBidiPresUtils() >-{ >- if (mLevels) { >- delete[] mLevels; >+ nsresult SetPara() >+ { >+ return mBidiEngine->SetPara(mBuffer.get(), BufferLength(), >+ mParaLevel, nsnull); > } >- if (mIndexMap) { >- delete[] mIndexMap; >+ >+ nsresult CountRuns(PRInt32 *runCount){ return mBidiEngine->CountRuns(runCount); } >+ >+ nsresult GetLogicalRun(PRInt32 aLogicalStart, >+ PRInt32* aLogicalLimit, >+ nsBidiLevel* aLevel) >+ { >+ nsresult rv = mBidiEngine->GetLogicalRun(aLogicalStart, >+ aLogicalLimit, aLevel); >+ if (mIsVisual || NS_FAILED(rv)) >+ *aLevel = mParaLevel; >+ return rv; > } >- delete mBidiEngine; >-} > >-PRBool >-nsBidiPresUtils::IsSuccessful() const >-{ >- return NS_SUCCEEDED(mSuccess); >-} >+ void ResetData() >+ { >+ mLogicalFrames.Clear(); >+ mContentToFrameIndex.Clear(); >+ mBuffer.SetLength(0); >+ for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { >+ mBuffer.Append(mEmbeddingStack[i]); >+ mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >+ } >+ } >+ >+ void AppendFrame(nsIFrame* aFrame, nsIContent* aContent = nsnull) >+ { >+ if (aContent) { >+ mContentToFrameIndex.Put(aContent, FrameCount()); >+ } >+ mLogicalFrames.AppendElement(aFrame); >+ } >+ >+ PRInt32 GetLastFrameForContent(nsIContent *aContent) >+ { >+ PRInt32 index = 0; >+ mContentToFrameIndex.Get(aContent, &index); >+ return index; >+ } >+ >+ PRInt32 FrameCount(){ return mLogicalFrames.Length(); } >+ >+ PRInt32 BufferLength(){ return mBuffer.Length(); } >+ >+ nsIFrame* FrameAt(PRInt32 aIndex){ return mLogicalFrames[aIndex]; } >+ >+ void AppendUnichar(PRUnichar aCh){ mBuffer.Append(aCh); } >+ >+ void AppendString(const nsDependentSubstring& aString){ mBuffer.Append(aString); } >+ >+ void PushBidiControl(PRUnichar aCh) >+ { >+ mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >+ mBuffer.Append(aCh); >+ mEmbeddingStack.AppendElement(aCh); >+ } >+ >+ void PopBidiControl() >+ { >+ mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >+ mBuffer.Append(kPDF); >+ NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow"); >+ mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1); >+ } >+ >+ void ClearBidiControls() >+ { >+ for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { >+ mBuffer.Append(kPDF); >+ mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >+ } >+ } >+}; >+ >+struct BidiLineData { >+ nsTArray<nsIFrame*> mLogicalFrames; >+ nsTArray<nsIFrame*> mVisualFrames; >+ nsTArray<PRInt32> mIndexMap; >+ nsAutoTArray<PRUint8, 18> mLevels; >+ PRBool mIsReordered; >+ >+ BidiLineData(nsIFrame* aFirstFrameOnLine, PRInt32 aNumFramesOnLine) >+ { >+ /** >+ * Initialize the logically-ordered array of frames using the top-level >+ * frames of a single line >+ */ >+ mLogicalFrames.Clear(); >+ >+ PRBool isReordered = PR_FALSE; >+ PRBool hasRTLFrames = PR_FALSE; >+ >+ for (nsIFrame* frame = aFirstFrameOnLine; >+ frame && aNumFramesOnLine--; >+ frame = frame->GetNextSibling()) { >+ AppendFrame(frame); >+ PRUint8 level = nsBidiPresUtils::GetFrameEmbeddingLevel(frame); >+ mLevels.AppendElement(level); >+ mIndexMap.AppendElement(0); >+ if (level & 1) { >+ hasRTLFrames = PR_TRUE; >+ } >+ } >+ >+ // Reorder the line >+ nsBidi::ReorderVisual(mLevels.Elements(), FrameCount(), >+ mIndexMap.Elements()); >+ >+ for (PRInt32 i = 0; i < FrameCount(); i++) { >+ mVisualFrames.AppendElement(LogicalFrameAt(mIndexMap[i])); >+ if (i != mIndexMap[i]) { >+ isReordered = PR_TRUE; >+ } >+ } >+ >+ // If there's an RTL frame, assume the line is reordered >+ mIsReordered = isReordered || hasRTLFrames; >+ } >+ >+ void AppendFrame(nsIFrame* aFrame){ mLogicalFrames.AppendElement(aFrame); } >+ >+ PRInt32 FrameCount(){ return mLogicalFrames.Length(); } >+ >+ nsIFrame* LogicalFrameAt(PRInt32 aIndex){ return mLogicalFrames[aIndex]; } >+ >+ nsIFrame* VisualFrameAt(PRInt32 aIndex){ return mVisualFrames[aIndex]; } >+}; > > /* Some helper methods for Resolve() */ > > // Should this frame be split between text runs? > PRBool > IsBidiSplittable(nsIFrame* aFrame) { > nsIAtom* frameType = aFrame->GetType(); > // Bidi inline containers should be split, unless they're line frames. >@@ -322,181 +468,137 @@ AdvanceLineIteratorToFrame(nsIFrame* aFr > * The rendering layer requires each text frame to contain text in only one > * direction, so we may need to call EnsureBidiContinuation() to split frames. > * We may also need to call RemoveBidiContinuation() to convert frames created > * by EnsureBidiContinuation() in previous reflows into fluid continuations. > */ > nsresult > nsBidiPresUtils::Resolve(nsBlockFrame* aBlockFrame) > { >- mLogicalFrames.Clear(); >- mContentToFrameIndex.Clear(); >- mBuffer.SetLength(0); >- mEmbeddingStack.Clear(); >- >- nsPresContext *presContext = aBlockFrame->PresContext(); >- >- const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); >- >- mParaLevel = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? >- NSBIDI_RTL : NSBIDI_LTR; >- >- mLineIter = new nsBlockInFlowLineIterator(aBlockFrame, >- aBlockFrame->begin_lines(), >- PR_FALSE); >- if (mLineIter->GetLine() == aBlockFrame->end_lines()) { >- // Advance to first valid line (might be in a next-continuation) >- mLineIter->Next(); >- } >- >- mIsVisual = presContext->IsVisualMode(); >- if (mIsVisual) { >- /** >- * Drill up in content to detect whether this is an element that needs to be >- * rendered with logical order even on visual pages. >- * >- * We always use logical order on form controls, firstly so that text entry >- * will be in logical order, but also because visual pages were written with >- * the assumption that even if the browser had no support for right-to-left >- * text rendering, it would use native widgets with bidi support to display >- * form controls. >- * >- * We also use logical order in XUL elements, since we expect that if a XUL >- * element appears in a visual page, it will be generated by an XBL binding >- * and contain localized text which will be in logical order. >- */ >- for (nsIContent* content = aBlockFrame->GetContent() ; content; >- content = content->GetParent()) { >- if (content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) || >- content->IsXUL()) { >- mIsVisual = PR_FALSE; >- break; >- } >- } >- } >- mPrevFrame = nsnull; >+ BidiParagraphData bpd; >+ bpd.Init(aBlockFrame); > > // handle bidi-override being set on the block itself before calling > // TraverseFrames. > const nsStyleTextReset* text = aBlockFrame->GetStyleTextReset(); > PRUnichar ch = 0; > if (text->mUnicodeBidi == NS_STYLE_UNICODE_BIDI_OVERRIDE) { >+ const nsStyleVisibility* vis = aBlockFrame->GetStyleVisibility(); > if (NS_STYLE_DIRECTION_RTL == vis->mDirection) { > ch = kRLO; > } > else if (NS_STYLE_DIRECTION_LTR == vis->mDirection) { > ch = kLRO; > } > if (ch != 0) { >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- mBuffer.Append(ch); >- mEmbeddingStack.AppendElement(ch); >+ bpd.PushBidiControl(ch); > } > } >- mPrevContent = nsnull; > for (nsBlockFrame* block = aBlockFrame; block; > block = static_cast<nsBlockFrame*>(block->GetNextContinuation())) { > block->RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION); >- TraverseFrames(aBlockFrame, block->GetFirstChild(nsnull)); >+ TraverseFrames(aBlockFrame, block->GetFirstChild(nsnull), &bpd); > } > > if (ch != 0) { >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- mBuffer.Append(kPDF); >- NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow"); >- mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1); >+ bpd.PopBidiControl(); > } > > // Resolve final paragraph >- ResolveParagraph(aBlockFrame); >- return mSuccess; >+ return ResolveParagraph(aBlockFrame, &bpd); > } > >-void >-nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame) >+nsresult >+nsBidiPresUtils::ResolveParagraph(nsBlockFrame* aBlockFrame, >+ BidiParagraphData* aBpd) > { > nsPresContext *presContext = aBlockFrame->PresContext(); >- PRInt32 bufferLength = mBuffer.Length(); > >- if (bufferLength < 1) { >- mSuccess = NS_OK; >- return; >+ if (aBpd->BufferLength() < 1) { >+ return NS_OK; > } >- mBuffer.ReplaceChar("\t\r\n", kSpace); >+ aBpd->mBuffer.ReplaceChar("\t\r\n", kSpace); > > PRInt32 runCount; >- PRUint8 embeddingLevel = mParaLevel; >+ PRUint8 embeddingLevel = aBpd->mParaLevel; > >- mSuccess = mBidiEngine->SetPara(mBuffer.get(), bufferLength, mParaLevel, nsnull); >- if (NS_FAILED(mSuccess) ) { >- return; >- } >+ nsresult rv = aBpd->SetPara(); >+ NS_ENSURE_SUCCESS(rv, rv); > >- mSuccess = mBidiEngine->CountRuns(&runCount); >- if (NS_FAILED(mSuccess) ) { >- return; >- } >+ rv = aBpd->CountRuns(&runCount); >+ NS_ENSURE_SUCCESS(rv, rv); >+ > PRInt32 runLength = 0; // the length of the current run of text > PRInt32 lineOffset = 0; // the start of the current run > PRInt32 logicalLimit = 0; // the end of the current run + 1 > PRInt32 numRun = -1; > PRInt32 fragmentLength = 0; // the length of the current text frame > PRInt32 frameIndex = -1; // index to the frames in mLogicalFrames >- PRInt32 frameCount = mLogicalFrames.Length(); >+ PRInt32 frameCount = aBpd->FrameCount(); > PRInt32 contentOffset = 0; // offset of current frame in its content node > PRBool isTextFrame = PR_FALSE; > nsIFrame* frame = nsnull; > nsIContent* content = nsnull; >- PRInt32 contentTextLength; >+ PRInt32 contentTextLength = 0; > > FramePropertyTable *propTable = presContext->PropertyTable(); >+ >+ nsBlockInFlowLineIterator lineIter(aBlockFrame, >+ aBlockFrame->begin_lines(), >+ PR_FALSE); >+ if (lineIter.GetLine() == aBlockFrame->end_lines()) { >+ // Advance to first valid line (might be in a next-continuation) >+ lineIter.Next(); >+ } >+ nsIFrame* prevFrame = nsnull; >+ > PRBool lineNeedsUpdate = PR_FALSE; > > #ifdef NOISY_BIDI >- if (mBuffer[0] != kObjectSubstitute) { >+ if (aBpd->mBuffer[0] != kObjectSubstitute) { > printf("Before Resolve(), aBlockFrame=0x%p, mBuffer='%s', frameCount=%d\n", >- (void*)aBlockFrame, NS_ConvertUTF16toUTF8(mBuffer).get(), frameCount); >+ (void*)aBlockFrame, NS_ConvertUTF16toUTF8(aBpd->mBuffer).get(), frameCount); > #ifdef REALLY_NOISY_BIDI > printf(" block frame tree=:\n"); > aBlockFrame->List(stdout, 0); > #endif > } > #endif > for (; ;) { > if (fragmentLength <= 0) { > // Get the next frame from mLogicalFrames > if (++frameIndex >= frameCount) { > break; > } >- frame = mLogicalFrames[frameIndex]; >+ frame = aBpd->FrameAt(frameIndex); > lineNeedsUpdate = PR_TRUE; > if (frame == NS_BIDI_CONTROL_FRAME || > nsGkAtoms::textFrame != frame->GetType()) { > /* > * Any non-text frame corresponds to a single character in the text buffer > * (a bidi control character, LINE SEPARATOR, or OBJECT SUBSTITUTE) > */ > isTextFrame = PR_FALSE; > fragmentLength = 1; > } > else { > content = frame->GetContent(); > if (!content) { >- mSuccess = NS_OK; >+ rv = NS_OK; > break; > } > contentTextLength = content->TextLength(); > if (contentTextLength == 0) { > frame->AdjustOffsetsForBidi(0, 0); > // Set the base level and embedding level of the current run even > // on an empty frame. Otherwise frame reordering will not be correct. > propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(), > NS_INT32_TO_PTR(embeddingLevel)); > propTable->Set(frame, nsIFrame::BaseLevelProperty(), >- NS_INT32_TO_PTR(mParaLevel)); >+ NS_INT32_TO_PTR(aBpd->mParaLevel)); > continue; > } > PRInt32 start, end; > frame->GetOffsets(start, end); > NS_ASSERTION(!(contentTextLength < end - start), > "Frame offsets don't fit in content"); > fragmentLength = NS_MIN(contentTextLength, end - start); > contentOffset = start; >@@ -505,105 +607,103 @@ nsBidiPresUtils::ResolveParagraph(nsBloc > } // if (fragmentLength <= 0) > > if (runLength <= 0) { > // Get the next run of text from the Bidi engine > if (++numRun >= runCount) { > break; > } > lineOffset = logicalLimit; >- if (NS_FAILED(mBidiEngine->GetLogicalRun( >+ if (NS_FAILED(aBpd->GetLogicalRun( > lineOffset, &logicalLimit, &embeddingLevel) ) ) { > break; > } > runLength = logicalLimit - lineOffset; >- if (mIsVisual) { >- embeddingLevel = mParaLevel; >- } > } // if (runLength <= 0) > > if (frame == NS_BIDI_CONTROL_FRAME) { > frame = nsnull; > ++lineOffset; > } > else { > propTable->Set(frame, nsIFrame::EmbeddingLevelProperty(), > NS_INT32_TO_PTR(embeddingLevel)); > propTable->Set(frame, nsIFrame::BaseLevelProperty(), >- NS_INT32_TO_PTR(mParaLevel)); >+ NS_INT32_TO_PTR(aBpd->mParaLevel)); > if (isTextFrame) { > if ( (runLength > 0) && (runLength < fragmentLength) ) { > /* > * The text in this frame continues beyond the end of this directional run. > * Create a non-fluid continuation frame for the next directional run. > */ > if (lineNeedsUpdate) { >- AdvanceLineIteratorToFrame(frame, mLineIter, mPrevFrame); >+ AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame); > lineNeedsUpdate = PR_FALSE; > } >- mLineIter->GetLine()->MarkDirty(); >+ lineIter.GetLine()->MarkDirty(); > nsIFrame* nextBidi; > PRInt32 runEnd = contentOffset + runLength; >- EnsureBidiContinuation(frame, &nextBidi, frameIndex, >- contentOffset, >- runEnd); >- if (NS_FAILED(mSuccess)) { >+ rv = EnsureBidiContinuation(frame, &nextBidi, frameIndex, >+ contentOffset, >+ runEnd); >+ if (NS_FAILED(rv)) { > break; > } > nextBidi->AdjustOffsetsForBidi(runEnd, > contentOffset + fragmentLength); > frame = nextBidi; > contentOffset = runEnd; > } // if (runLength < fragmentLength) > else { > if (contentOffset + fragmentLength == contentTextLength) { > /* > * We have finished all the text in this content node. Convert any > * further non-fluid continuations to fluid continuations and advance > * frameIndex to the last frame in the content node > */ >- PRInt32 newIndex = 0; >- mContentToFrameIndex.Get(content, &newIndex); >+ PRInt32 newIndex = aBpd->GetLastFrameForContent(content); > if (newIndex > frameIndex) { >- RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset); >+ RemoveBidiContinuation(aBpd, frame, >+ frameIndex, newIndex, lineOffset); > frameIndex = newIndex; > } > } else if (fragmentLength > 0 && runLength > fragmentLength) { > /* > * There is more text that belongs to this directional run in the next > * text frame: make sure it is a fluid continuation of the current frame. > * Do not advance frameIndex, because the next frame may contain > * multi-directional text and need to be split > */ > PRInt32 newIndex = frameIndex; > do { > } while (++newIndex < frameCount && >- mLogicalFrames[newIndex] == NS_BIDI_CONTROL_FRAME); >+ aBpd->FrameAt(newIndex) == NS_BIDI_CONTROL_FRAME); > if (newIndex < frameCount) { >- RemoveBidiContinuation(frame, frameIndex, newIndex, lineOffset); >+ RemoveBidiContinuation(aBpd, frame, >+ frameIndex, newIndex, lineOffset); > } > } else if (runLength == fragmentLength && > numRun + 1 < runCount) { > /* > * If the directional run ends at the end of the frame, and this is > * not the end of our paragraph, make sure that the next frame is a > * non-fluid continuation > */ > nsIFrame* next = frame->GetNextInFlow(); > if (next) { > frame->SetNextContinuation(next); > next->SetPrevContinuation(frame); > } > } > frame->AdjustOffsetsForBidi(contentOffset, contentOffset + fragmentLength); > if (lineNeedsUpdate) { >- AdvanceLineIteratorToFrame(frame, mLineIter, mPrevFrame); >+ AdvanceLineIteratorToFrame(frame, &lineIter, prevFrame); > lineNeedsUpdate = PR_FALSE; > } >- mLineIter->GetLine()->MarkDirty(); >+ lineIter.GetLine()->MarkDirty(); > } > } // isTextFrame > else { > ++lineOffset; > } > } // not bidi control frame > PRInt32 temp = runLength; > runLength -= fragmentLength; >@@ -642,34 +742,36 @@ nsBidiPresUtils::ResolveParagraph(nsBloc > // We're not at an end of a run. If |frame| is the last child of its > // parent, and its ancestors happen to have bidi continuations, convert > // them into fluid continuations. > JoinInlineAncestors(frame); > } > } > } // for > #ifdef REALLY_NOISY_BIDI >- if (mBuffer[0] != kObjectSubstitute) { >+ if (aBpd->mBuffer[0] != kObjectSubstitute) { > printf("---\nAfter Resolve(), frameTree =:\n"); > aBlockFrame->List(stdout, 0); > printf("===\n"); > } > #endif >+ return rv; > } > > // Should this frame be treated as a leaf (e.g. when building mLogicalFrames)? > PRBool IsBidiLeaf(nsIFrame* aFrame) { > nsIFrame* kid = aFrame->GetFirstChild(nsnull); > return !kid > || !aFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer); > } > > void > nsBidiPresUtils::TraverseFrames(nsBlockFrame* aBlockFrame, >- nsIFrame* aCurrentFrame) >+ nsIFrame* aCurrentFrame, >+ BidiParagraphData* aBpd) > { > if (!aCurrentFrame) > return; > > nsIFrame* childFrame = aCurrentFrame; > do { > /* > * It's important to get the next sibling and next continuation *before* >@@ -717,41 +819,36 @@ nsBidiPresUtils::TraverseFrames(nsBlockF > ch = kLRO; > } > break; > } > > // Add a dummy frame pointer representing a bidi control code before the > // first frame of an element specifying embedding or override > if (ch != 0 && !frame->GetPrevContinuation()) { >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- mBuffer.Append(ch); >- mEmbeddingStack.AppendElement(ch); >+ aBpd->PushBidiControl(ch); > } > } > > if (IsBidiLeaf(frame)) { > /* Bidi leaf frame: add the frame to the mLogicalFrames array, > * and add its index to the mContentToFrameIndex hashtable. This > * will be used in RemoveBidiContinuation() to identify the last > * frame in the array with a given content. > */ > nsIContent* content = frame->GetContent(); >- if (content) { >- mContentToFrameIndex.Put(content, mLogicalFrames.Length()); >- } >- mLogicalFrames.AppendElement(frame); >+ aBpd->AppendFrame(frame, content); > > // Append the content of the frame to the paragraph buffer > nsIAtom* frameType = frame->GetType(); > if (nsGkAtoms::textFrame == frameType) { >- if (content != mPrevContent) { >- mPrevContent = content; >+ if (content != aBpd->mPrevContent) { >+ aBpd->mPrevContent = content; > if (!frame->GetStyleContext()->GetStyleText()->NewlineIsSignificant()) { >- content->AppendTextTo(mBuffer); >+ content->AppendTextTo(aBpd->mBuffer); > } else { > /* > * For preformatted text we have to do bidi resolution on each line > * separately. > */ > nsAutoString text; > content->AppendTextTo(text); > nsIFrame* next; >@@ -762,48 +859,48 @@ nsBidiPresUtils::TraverseFrames(nsBlockF > frame->GetOffsets(start, end); > PRInt32 endLine = text.FindCharInSet(NS_LITERAL_STRING("\n\r"), > start); > if (endLine == -1) { > /* > * If there is no newline in the frame, just save the text and > * do bidi resolution later > */ >- mBuffer.Append(Substring(text, start)); >+ aBpd->AppendString(Substring(text, start)); > break; > } > > /* > * If there is a newline in the frame, break the frame after the > * newline, do bidi resolution and repeat until the end of the > * element. > */ > ++endLine; > > /* > * If the frame ends before the new line, save the text and move > * into the next continuation > */ > while (end < endLine) { >- mBuffer.Append(Substring(text, start, end - start)); >+ aBpd->AppendString(Substring(text, start, end - start)); > frame = frame->GetNextContinuation(); > NS_ASSERTION(frame, "Premature end of continuation chain"); > frame->GetOffsets(start, end); >- mLogicalFrames.AppendElement(frame); >+ aBpd->AppendFrame(frame); > > /* > * If we have already overshot the saved next-sibling while > * scanning the frame's continuations, advance it. > */ > if (frame == nextSibling) { > nextSibling = frame->GetNextSibling(); > } > } > >- mBuffer.Append(Substring(text, start, endLine - start)); >+ aBpd->AppendString(Substring(text, start, endLine - start)); > > if (PRUint32(endLine) < text.Length()) { > next = frame->GetNextInFlow(); > if (!next) { > // If the frame already has a bidi continuation, make it fluid > next = frame->GetNextContinuation(); > if (next) { > MakeContinuationFluid(frame, next); >@@ -811,185 +908,93 @@ nsBidiPresUtils::TraverseFrames(nsBlockF > } else { > // If the frame has no next in flow, create one > CreateContinuation(frame, &next, PR_TRUE); > } > } > nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame); > textFrame->SetLength(endLine - start, nsnull); > } >- ResolveParagraphWithinBlock(aBlockFrame); >+ ResolveParagraphWithinBlock(aBlockFrame, aBpd); > > if (next) { > frame = next; >- mLogicalFrames.AppendElement(frame); >+ aBpd->AppendFrame(frame); > } > > /* > * If we have already overshot the saved next-sibling while > * scanning the frame's continuations, advance it. > */ > if (frame && frame == nextSibling) { > nextSibling = frame->GetNextSibling(); > } > > } while (next); > } > } > } else if (nsGkAtoms::brFrame == frameType) { > // break frame -- append line separator >- mBuffer.Append(kLineSeparator); >- ResolveParagraphWithinBlock(aBlockFrame); >+ aBpd->AppendUnichar(kLineSeparator); >+ ResolveParagraphWithinBlock(aBlockFrame, aBpd); > } 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); >+ aBpd->AppendUnichar(kObjectSubstitute); > if (!frame->GetStyleContext()->GetStyleDisplay()->IsInlineOutside()) { > // if it is not inline, end the paragraph >- ResolveParagraphWithinBlock(aBlockFrame); >+ ResolveParagraphWithinBlock(aBlockFrame, aBpd); > } > } > } > else { > // For a non-leaf frame, recurse into TraverseFrames > nsIFrame* kid = frame->GetFirstChild(nsnull); >- TraverseFrames(aBlockFrame, kid); >+ TraverseFrames(aBlockFrame, kid, aBpd); > } > > // If the element is attributed by dir, indicate direction pop (add PDF frame) > if (ch != 0 && isLastFrame) { > // Add a dummy frame pointer representing a bidi control code after the > // last frame of an element specifying embedding or override >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- mBuffer.Append(kPDF); >- NS_ASSERTION(mEmbeddingStack.Length(), "embedding/override underflow"); >- mEmbeddingStack.TruncateLength(mEmbeddingStack.Length() - 1); >+ aBpd->PopBidiControl(); > } > childFrame = nextSibling; > } while (childFrame); > } > > void >-nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame) >+nsBidiPresUtils::ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame, >+ BidiParagraphData* aBpd) > { >- nsIPresShell* shell; >- nsStyleContext* styleContext; >+ aBpd->ClearBidiControls(); > >- if (mEmbeddingStack.Length() > 0) { >- shell = aBlockFrame->PresContext()->PresShell(); >- styleContext = aBlockFrame->GetStyleContext(); >- >- // pop all embeddings and overrides >- for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { >- mBuffer.Append(kPDF); >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- } >- } >- >- ResolveParagraph(aBlockFrame); >+ ResolveParagraph(aBlockFrame, aBpd); > > // Clear the frame array and paragraph buffer, and restore the stored > // embeddings and overrides >- mLogicalFrames.Clear(); >- mContentToFrameIndex.Clear(); >- mBuffer.SetLength(0); >- if (mEmbeddingStack.Length() > 0) { >- for (PRUint32 i = 0; i < mEmbeddingStack.Length(); ++i) { >- mBuffer.Append(mEmbeddingStack[i]); >- mLogicalFrames.AppendElement(NS_BIDI_CONTROL_FRAME); >- } >- } >+ aBpd->ResetData(); > } > > void > nsBidiPresUtils::ReorderFrames(nsIFrame* aFirstFrameOnLine, > PRInt32 aNumFramesOnLine) > { > // If this line consists of a line frame, reorder the line frame's children. > if (aFirstFrameOnLine->GetType() == nsGkAtoms::lineFrame) { > aFirstFrameOnLine = aFirstFrameOnLine->GetFirstChild(nsnull); > if (!aFirstFrameOnLine) > return; > // All children of the line frame are on the first line. Setting aNumFramesOnLine > // to -1 makes InitLogicalArrayFromLine look at all of them. > aNumFramesOnLine = -1; > } >- >- InitLogicalArrayFromLine(aFirstFrameOnLine, aNumFramesOnLine); >- >- PRBool isReordered; >- PRBool hasRTLFrames; >- Reorder(isReordered, hasRTLFrames); >- RepositionInlineFrames(aFirstFrameOnLine); >-} >- >-nsresult >-nsBidiPresUtils::Reorder(PRBool& aReordered, PRBool& aHasRTLFrames) >-{ >- aReordered = PR_FALSE; >- aHasRTLFrames = PR_FALSE; >- PRInt32 count = mLogicalFrames.Length(); >- >- if (mArraySize < count) { >- mArraySize = count << 1; >- if (mLevels) { >- delete[] mLevels; >- mLevels = nsnull; >- } >- if (mIndexMap) { >- delete[] mIndexMap; >- mIndexMap = nsnull; >- } >- } >- if (!mLevels) { >- mLevels = new PRUint8[mArraySize]; >- if (!mLevels) { >- return NS_ERROR_OUT_OF_MEMORY; >- } >- } >- memset(mLevels, 0, sizeof(PRUint8) * mArraySize); >- >- nsIFrame* frame; >- PRInt32 i; >- >- for (i = 0; i < count; i++) { >- frame = mLogicalFrames[i]; >- mLevels[i] = GetFrameEmbeddingLevel(frame); >- if (mLevels[i] & 1) { >- aHasRTLFrames = PR_TRUE; >- } >- } >- if (!mIndexMap) { >- mIndexMap = new PRInt32[mArraySize]; >- } >- if (!mIndexMap) { >- mSuccess = NS_ERROR_OUT_OF_MEMORY; >- } >- else { >- memset(mIndexMap, 0, sizeof(PRUint32) * mArraySize); >- >- mSuccess = mBidiEngine->ReorderVisual(mLevels, count, mIndexMap); >- >- if (NS_SUCCEEDED(mSuccess) ) { >- mVisualFrames.Clear(); >- >- for (i = 0; i < count; i++) { >- mVisualFrames.AppendElement(mLogicalFrames[mIndexMap[i]]); >- if (i != mIndexMap[i]) { >- aReordered = PR_TRUE; >- } >- } >- } // NS_SUCCEEDED(mSuccess) >- } // indexMap >- >- if (NS_FAILED(mSuccess) ) { >- aReordered = PR_FALSE; >- } >- return mSuccess; >+ BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); >+ RepositionInlineFrames(&bld, aFirstFrameOnLine); > } > > nsBidiLevel > nsBidiPresUtils::GetFrameEmbeddingLevel(nsIFrame* aFrame) > { > nsIFrame* firstLeaf = aFrame; > while (!IsBidiLeaf(firstLeaf)) { > nsIFrame* firstChild = firstLeaf->GetFirstChild(nsnull); >@@ -1009,17 +1014,17 @@ nsBidiPresUtils::GetFrameBaseLevel(nsIFr > } > return NS_GET_BASE_LEVEL(firstLeaf); > } > > void > nsBidiPresUtils::IsLeftOrRightMost(nsIFrame* aFrame, > nsContinuationStates* aContinuationStates, > PRBool& aIsLeftMost /* out */, >- PRBool& aIsRightMost /* out */) const >+ PRBool& aIsRightMost /* out */) > { > const nsStyleVisibility* vis = aFrame->GetStyleVisibility(); > PRBool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection); > > /* > * Since we lay out frames from left to right (in both LTR and RTL), visiting a > * frame with 'mFirstVisualFrame == nsnull', means it's the first appearance of > * one of its continuation chain frames on the line. >@@ -1103,17 +1108,17 @@ nsBidiPresUtils::IsLeftOrRightMost(nsIFr > // Reduce number of remaining frames of the continuation chain on the line. > firstFrameState->mFrameCount--; > } > > void > nsBidiPresUtils::RepositionFrame(nsIFrame* aFrame, > PRBool aIsOddLevel, > nscoord& aLeft, >- nsContinuationStates* aContinuationStates) const >+ nsContinuationStates* aContinuationStates) > { > if (!aFrame) > return; > > PRBool isLeftMost, isRightMost; > IsLeftOrRightMost(aFrame, > aContinuationStates, > isLeftMost /* out */, >@@ -1188,17 +1193,17 @@ nsBidiPresUtils::RepositionFrame(nsIFram > aFrame->SetRect(nsRect(start, rect.y, aLeft - start, rect.height)); > > if (isRightMost) > aLeft += margin.right; > } > > void > nsBidiPresUtils::InitContinuationStates(nsIFrame* aFrame, >- nsContinuationStates* aContinuationStates) const >+ nsContinuationStates* aContinuationStates) > { > nsFrameContinuationState* state = aContinuationStates->PutEntry(aFrame); > state->mFirstVisualFrame = nsnull; > state->mFrameCount = 0; > > if (!IsBidiLeaf(aFrame)) { > // Continue for child frames > nsIFrame* frame; >@@ -1207,165 +1212,145 @@ nsBidiPresUtils::InitContinuationStates( > frame = frame->GetNextSibling()) { > InitContinuationStates(frame, > aContinuationStates); > } > } > } > > void >-nsBidiPresUtils::RepositionInlineFrames(nsIFrame* aFirstChild) const >+nsBidiPresUtils::RepositionInlineFrames(BidiLineData *aBld, >+ nsIFrame* aFirstChild) > { > const nsStyleVisibility* vis = aFirstChild->GetStyleVisibility(); > PRBool isLTR = (NS_STYLE_DIRECTION_LTR == vis->mDirection); > nscoord leftSpace = 0; > > // This method is called from nsBlockFrame::PlaceLine via the call to > // bidiUtils->ReorderFrames, so this is guaranteed to be after the inlines > // have been reflowed, which is required for GetUsedMargin/Border/Padding > nsMargin margin = aFirstChild->GetUsedMargin(); > if (!aFirstChild->GetPrevContinuation() && > !nsLayoutUtils::FrameIsNonFirstInIBSplit(aFirstChild)) > leftSpace = isLTR ? margin.left : margin.right; > > nscoord left = aFirstChild->GetPosition().x - leftSpace; > nsIFrame* frame; >- PRInt32 count = mVisualFrames.Length(); >+ PRInt32 count = aBld->mVisualFrames.Length(); > PRInt32 index; > nsContinuationStates continuationStates; > > continuationStates.Init(); > > // Initialize continuation states to (nsnull, 0) for > // each frame on the line. > for (index = 0; index < count; index++) { >- InitContinuationStates(mVisualFrames[index], &continuationStates); >+ InitContinuationStates(aBld->VisualFrameAt(index), &continuationStates); > } > > // Reposition frames in visual order > for (index = 0; index < count; index++) { >- frame = mVisualFrames[index]; >+ frame = aBld->VisualFrameAt(index); > RepositionFrame(frame, >- (mLevels[mIndexMap[index]] & 1), >+ (aBld->mLevels[aBld->mIndexMap[index]] & 1), > left, > &continuationStates); > } // for > } > >-void >-nsBidiPresUtils::InitLogicalArrayFromLine(nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine) { >- mLogicalFrames.Clear(); >- for (nsIFrame* frame = aFirstFrameOnLine; >- frame && aNumFramesOnLine--; >- frame = frame->GetNextSibling()) { >- mLogicalFrames.AppendElement(frame); >- } >-} >- > PRBool > nsBidiPresUtils::CheckLineOrder(nsIFrame* aFirstFrameOnLine, > PRInt32 aNumFramesOnLine, > nsIFrame** aFirstVisual, > nsIFrame** aLastVisual) > { >- InitLogicalArrayFromLine(aFirstFrameOnLine, aNumFramesOnLine); >- >- PRBool isReordered; >- PRBool hasRTLFrames; >- Reorder(isReordered, hasRTLFrames); >- PRInt32 count = mLogicalFrames.Length(); >+ BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); >+ PRInt32 count = bld.FrameCount(); > > if (aFirstVisual) { >- *aFirstVisual = mVisualFrames[0]; >+ *aFirstVisual = bld.VisualFrameAt(0); > } > if (aLastVisual) { >- *aLastVisual = mVisualFrames[count-1]; >+ *aLastVisual = bld.VisualFrameAt(count-1); > } > >- // If there's an RTL frame, assume the line is reordered >- return isReordered || hasRTLFrames; >+ return bld.mIsReordered; > } > > nsIFrame* > nsBidiPresUtils::GetFrameToRightOf(const nsIFrame* aFrame, > nsIFrame* aFirstFrameOnLine, > PRInt32 aNumFramesOnLine) > { >- InitLogicalArrayFromLine(aFirstFrameOnLine, aNumFramesOnLine); >- >- PRBool isReordered; >- PRBool hasRTLFrames; >- Reorder(isReordered, hasRTLFrames); >- PRInt32 count = mVisualFrames.Length(); >+ BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); >+ >+ PRInt32 count = bld.mVisualFrames.Length(); > > if (aFrame == nsnull) >- return mVisualFrames[0]; >+ return bld.VisualFrameAt(0); > > for (PRInt32 i = 0; i < count - 1; i++) { >- if (mVisualFrames[i] == aFrame) { >- return mVisualFrames[i+1]; >+ if (bld.VisualFrameAt(i) == aFrame) { >+ return bld.VisualFrameAt(i+1); > } > } > > return nsnull; > } > > nsIFrame* > nsBidiPresUtils::GetFrameToLeftOf(const nsIFrame* aFrame, > nsIFrame* aFirstFrameOnLine, > PRInt32 aNumFramesOnLine) > { >- InitLogicalArrayFromLine(aFirstFrameOnLine, aNumFramesOnLine); >- >- PRBool isReordered; >- PRBool hasRTLFrames; >- Reorder(isReordered, hasRTLFrames); >- PRInt32 count = mVisualFrames.Length(); >+ BidiLineData bld(aFirstFrameOnLine, aNumFramesOnLine); >+ >+ PRInt32 count = bld.mVisualFrames.Length(); > > if (aFrame == nsnull) >- return mVisualFrames[count-1]; >+ return bld.VisualFrameAt(count-1); > > for (PRInt32 i = 1; i < count; i++) { >- if (mVisualFrames[i] == aFrame) { >- return mVisualFrames[i-1]; >+ if (bld.VisualFrameAt(i) == aFrame) { >+ return bld.VisualFrameAt(i-1); > } > } > > return nsnull; > } > >-inline void >+inline nsresult > nsBidiPresUtils::EnsureBidiContinuation(nsIFrame* aFrame, > nsIFrame** aNewFrame, > PRInt32& aFrameIndex, > PRInt32 aStart, > PRInt32 aEnd) > { > NS_PRECONDITION(aNewFrame, "null OUT ptr"); > NS_PRECONDITION(aFrame, "aFrame is null"); > > aFrame->AdjustOffsetsForBidi(aStart, aEnd); >- mSuccess = CreateContinuation(aFrame, aNewFrame, PR_FALSE); >+ return CreateContinuation(aFrame, aNewFrame, PR_FALSE); > } > > void >-nsBidiPresUtils::RemoveBidiContinuation(nsIFrame* aFrame, >+nsBidiPresUtils::RemoveBidiContinuation(BidiParagraphData *aBpd, >+ nsIFrame* aFrame, > PRInt32 aFirstIndex, > PRInt32 aLastIndex, >- PRInt32& aOffset) const >+ PRInt32& aOffset) > { > FrameProperties props = aFrame->Properties(); > nsBidiLevel embeddingLevel = > (nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::EmbeddingLevelProperty())); > nsBidiLevel baseLevel = > (nsBidiLevel)NS_PTR_TO_INT32(props.Get(nsIFrame::BaseLevelProperty())); > > for (PRInt32 index = aFirstIndex + 1; index <= aLastIndex; index++) { >- nsIFrame* frame = mLogicalFrames[index]; >+ nsIFrame* frame = aBpd->FrameAt(index); > if (frame == NS_BIDI_CONTROL_FRAME) { > ++aOffset; > } > else { > // Make the frame and its continuation ancestors fluid, > // so they can be reused or deleted by normal reflow code > FrameProperties frameProps = frame->Properties(); > frameProps.Set(nsIFrame::EmbeddingLevelProperty(), >@@ -1449,17 +1434,17 @@ nsBidiPresUtils::FormatUnicodeText(nsPre > } > > StripBidiControlCharacters(aText, aTextLength); > return rv; > } > > void > nsBidiPresUtils::StripBidiControlCharacters(PRUnichar* aText, >- PRInt32& aTextLength) const >+ PRInt32& aTextLength) > { > if ( (nsnull == aText) || (aTextLength < 1) ) { > return; > } > > PRInt32 stripLen = 0; > > for (PRInt32 i = 0; i < aTextLength; i++) { >@@ -1492,43 +1477,45 @@ RemoveDiacritics(PRUnichar* aText, > } > aTextLength = i - offset; > aText[aTextLength] = 0; > } > } > #endif > > void >-nsBidiPresUtils::CalculateCharType(PRInt32& aOffset, >+nsBidiPresUtils::CalculateCharType(nsBidi* aBidiEngine, >+ const PRUnichar* aText, >+ PRInt32& aOffset, > PRInt32 aCharTypeLimit, > PRInt32& aRunLimit, > PRInt32& aRunLength, > PRInt32& aRunCount, > PRUint8& aCharType, >- PRUint8& aPrevCharType) const >+ PRUint8& aPrevCharType) > > { > PRBool strongTypeFound = PR_FALSE; > PRInt32 offset; > nsCharType charType; > > aCharType = eCharType_OtherNeutral; > > for (offset = aOffset; offset < aCharTypeLimit; offset++) { > // Make sure we give RTL chartype to all characters that would be classified > // as Right-To-Left by a bidi platform. > // (May differ from the UnicodeData, eg we set RTL chartype to some NSMs.) >- if (IS_HEBREW_CHAR(mBuffer[offset]) ) { >+ if (IS_HEBREW_CHAR(aText[offset]) ) { > charType = eCharType_RightToLeft; > } >- else if (IS_ARABIC_ALPHABETIC(mBuffer[offset]) ) { >+ else if (IS_ARABIC_ALPHABETIC(aText[offset]) ) { > charType = eCharType_RightToLeftArabic; > } > else { >- mBidiEngine->GetCharTypeAt(offset, &charType); >+ aBidiEngine->GetCharTypeAt(offset, &charType); > } > > if (!CHARTYPE_IS_WEAK(charType) ) { > > if (strongTypeFound > && (charType != aPrevCharType) > && (CHARTYPE_IS_RTL(charType) || CHARTYPE_IS_RTL(aPrevCharType) ) ) { > // Stop at this point to ensure uni-directionality of the text >@@ -1561,54 +1548,55 @@ nsBidiPresUtils::CalculateCharType(PRInt > nsresult nsBidiPresUtils::ProcessText(const PRUnichar* aText, > PRInt32 aLength, > nsBidiDirection aBaseDirection, > nsPresContext* aPresContext, > BidiProcessor& aprocessor, > Mode aMode, > nsBidiPositionResolve* aPosResolve, > PRInt32 aPosResolveCount, >- nscoord* aWidth) >+ nscoord* aWidth, >+ nsBidi* aBidiEngine) > { > NS_ASSERTION((aPosResolve == nsnull) != (aPosResolveCount > 0), "Incorrect aPosResolve / aPosResolveCount arguments"); > > PRInt32 runCount; > >- mBuffer.Assign(aText, aLength); >+ nsAutoString textBuffer(aText, aLength); > >- nsresult rv = mBidiEngine->SetPara(mBuffer.get(), aLength, aBaseDirection, nsnull); >+ nsresult rv = aBidiEngine->SetPara(aText, aLength, aBaseDirection, nsnull); > if (NS_FAILED(rv)) > return rv; > >- rv = mBidiEngine->CountRuns(&runCount); >+ rv = aBidiEngine->CountRuns(&runCount); > if (NS_FAILED(rv)) > return rv; > > nscoord xOffset = 0; >- nscoord width, xEndRun; >+ nscoord width, xEndRun = 0; > nscoord totalWidth = 0; > PRInt32 i, start, limit, length; > PRUint32 visualStart = 0; > PRUint8 charType; > PRUint8 prevType = eCharType_LeftToRight; > nsBidiLevel level; > > for(int nPosResolve=0; nPosResolve < aPosResolveCount; ++nPosResolve) > { > aPosResolve[nPosResolve].visualIndex = kNotFound; > aPosResolve[nPosResolve].visualLeftTwips = kNotFound; > aPosResolve[nPosResolve].visualWidth = kNotFound; > } > > for (i = 0; i < runCount; i++) { >- rv = mBidiEngine->GetVisualRun(i, &start, &length, &aBaseDirection); >+ rv = aBidiEngine->GetVisualRun(i, &start, &length, &aBaseDirection); > if (NS_FAILED(rv)) > return rv; > >- rv = mBidiEngine->GetLogicalRun(start, &limit, &level); >+ rv = aBidiEngine->GetLogicalRun(start, &limit, &level); > if (NS_FAILED(rv)) > return rv; > > PRInt32 subRunLength = limit - start; > PRInt32 lineOffset = start; > PRInt32 typeLimit = NS_MIN(limit, aLength); > PRInt32 subRunCount = 1; > PRInt32 subRunLimit = typeLimit; >@@ -1630,17 +1618,17 @@ nsresult nsBidiPresUtils::ProcessText(co > width = aprocessor.GetWidth(); > xOffset += width; > xEndRun = xOffset; > } > > while (subRunCount > 0) { > // CalculateCharType can increment subRunCount if the run > // contains mixed character types >- CalculateCharType(lineOffset, typeLimit, subRunLimit, subRunLength, subRunCount, charType, prevType); >+ CalculateCharType(aBidiEngine, aText, lineOffset, typeLimit, subRunLimit, subRunLength, subRunCount, charType, prevType); > > nsAutoString runVisualText; > runVisualText.Assign(aText + start, subRunLength); > if (PRInt32(runVisualText.Length()) < subRunLength) > return NS_ERROR_OUT_OF_MEMORY; > FormatUnicodeText(aPresContext, runVisualText.BeginWriting(), subRunLength, > (nsCharType)charType, level & 1); > >@@ -1821,19 +1809,19 @@ nsresult nsBidiPresUtils::ProcessTextFor > Mode aMode, > nscoord aX, > nscoord aY, > nsBidiPositionResolve* aPosResolve, > PRInt32 aPosResolveCount, > nscoord* aWidth) > { > nsIRenderingContextBidiProcessor processor(&aRenderingContext, &aTextRunConstructionContext, nsPoint(aX, aY)); >- >+ nsBidi bidiEngine; > return ProcessText(aText, aLength, aBaseDirection, aPresContext, processor, >- aMode, aPosResolve, aPosResolveCount, aWidth); >+ aMode, aPosResolve, aPosResolveCount, aWidth, &bidiEngine); > } > > /* static */ > void nsBidiPresUtils::WriteReverse(const PRUnichar* aSrc, > PRUint32 aSrcLength, > PRUnichar* aDest) > { > const PRUnichar* src = aSrc + aSrcLength; >@@ -1945,55 +1933,23 @@ void nsBidiPresUtils::CopyLogicalToVisua > // no need to use the converter -- just copy the string in reverse order > WriteReverse(fromBegin.get(), srcLength, toBegin.get()); > } else { > // if aOverride && aBaseDirection == NSBIDI_LTR, fall through to the > // simple copy > aDest.SetLength(0); > } > } else { >+ nsBidi bidiEngine; > if (!WriteLogicalToVisual(fromBegin.get(), srcLength, toBegin.get(), >- aBaseDirection, mBidiEngine)) { >+ aBaseDirection, &bidiEngine)) { > aDest.SetLength(0); > } > } > > if (aDest.IsEmpty()) { > // Either there was an error or the source is unidirectional > // left-to-right. In either case, just copy source to dest. > CopyUnicodeTo(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd), > aDest); > } > } >- >-PRUint32 nsBidiPresUtils::EstimateMemoryUsed() >-{ >- PRUint32 size = 0; >- >- size += sizeof(nsBidiPresUtils); >- size += mBuffer.Length() * sizeof(PRUnichar); >- size += moz_malloc_usable_size(mBidiEngine->mDirPropsMemory); >- size += moz_malloc_usable_size(mBidiEngine->mLevelsMemory); >- size += moz_malloc_usable_size(mBidiEngine->mRunsMemory); >- >- return size; >-} >- >-static PLDHashOperator >-TraverseKey(nsISupports *aKey, PRInt32 aData, void *aUserArg) >-{ >- nsCycleCollectionTraversalCallback *cb = >- static_cast<nsCycleCollectionTraversalCallback*>(aUserArg); >- NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, "mContentToFrameIndex key"); >- cb->NoteXPCOMChild(aKey); >- return PL_DHASH_NEXT; >-} >- >-void nsBidiPresUtils::Traverse(nsCycleCollectionTraversalCallback &cb) const >-{ >- mContentToFrameIndex.EnumerateRead(TraverseKey, &cb); >-} >- >-void nsBidiPresUtils::Unlink() >-{ >- mContentToFrameIndex.Clear(); >-} > #endif // IBMBIDI >diff --git a/layout/base/nsBidiPresUtils.h b/layout/base/nsBidiPresUtils.h >--- a/layout/base/nsBidiPresUtils.h >+++ b/layout/base/nsBidiPresUtils.h >@@ -50,16 +50,19 @@ > #include "nsDataHashtable.h" > #include "nsBlockFrame.h" > #include "nsTHashtable.h" > > #ifdef DrawText > #undef DrawText > #endif > >+struct BidiParagraphData; >+struct BidiLineData; >+ > /** > * A structure representing some continuation state for each frame on the line, > * used to determine the first and the last continuation frame for each > * continuation chain on the line. > */ > struct nsFrameContinuationState : public nsVoidPtrHashKey > { > nsFrameContinuationState(const void *aFrame) : nsVoidPtrHashKey(aFrame) {} >@@ -169,41 +172,43 @@ public: > /** > * Make Bidi engine calculate the embedding levels of the frames that are > * descendants of a given block frame. > * > * @param aBlockFrame The block frame > * > * @lina 06/18/2000 > */ >- nsresult Resolve(nsBlockFrame* aBlockFrame); >- void ResolveParagraph(nsBlockFrame* aBlockFrame); >- void ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame); >+ static nsresult Resolve(nsBlockFrame* aBlockFrame); >+ static nsresult ResolveParagraph(nsBlockFrame* aBlockFrame, >+ BidiParagraphData* aBpd); >+ static void ResolveParagraphWithinBlock(nsBlockFrame* aBlockFrame, >+ BidiParagraphData* aBpd); > > /** > * Reorder this line using Bidi engine. > * Update frame array, following the new visual sequence. > * > * @lina 05/02/2000 > */ >- void ReorderFrames(nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine); >+ static void ReorderFrames(nsIFrame* aFirstFrameOnLine, >+ PRInt32 aNumFramesOnLine); > > /** > * Format Unicode text, taking into account bidi capabilities > * of the platform. The formatting includes: reordering, Arabic shaping, > * symmetric and numeric swapping, removing control characters. > * > * @lina 06/18/2000 > */ >- nsresult FormatUnicodeText(nsPresContext* aPresContext, >- PRUnichar* aText, >- PRInt32& aTextLength, >- nsCharType aCharType, >- PRBool aIsOddLevel); >+ static nsresult FormatUnicodeText(nsPresContext* aPresContext, >+ PRUnichar* aText, >+ PRInt32& aTextLength, >+ nsCharType aCharType, >+ PRBool aIsOddLevel); > > /** > * Reorder plain text using the Unicode Bidi algorithm and send it to > * a rendering context for rendering. > * > * @param[in] aText the string to be rendered (in logical order) > * @param aLength the number of characters in the string > * @param aBaseDirection the base direction of the string >@@ -212,78 +217,78 @@ public: > * @param aPresContext the presentation context > * @param aRenderingContext the rendering context to render to > * @param aTextRunConstructionContext the rendering context to be used to construct the textrun (affects font hinting) > * @param aX the x-coordinate to render the string > * @param aY the y-coordinate to render the string > * @param[in,out] aPosResolve array of logical positions to resolve into visual positions; can be nsnull if this functionality is not required > * @param aPosResolveCount number of items in the aPosResolve array > */ >- nsresult RenderText(const PRUnichar* aText, >- PRInt32 aLength, >- nsBidiDirection aBaseDirection, >- nsPresContext* aPresContext, >- nsIRenderingContext& aRenderingContext, >- nsIRenderingContext& aTextRunConstructionContext, >- nscoord aX, >- nscoord aY, >- nsBidiPositionResolve* aPosResolve = nsnull, >- PRInt32 aPosResolveCount = 0) >+ static nsresult RenderText(const PRUnichar* aText, >+ PRInt32 aLength, >+ nsBidiDirection aBaseDirection, >+ nsPresContext* aPresContext, >+ nsIRenderingContext& aRenderingContext, >+ nsIRenderingContext& aTextRunConstructionContext, >+ nscoord aX, >+ nscoord aY, >+ nsBidiPositionResolve* aPosResolve = nsnull, >+ PRInt32 aPosResolveCount = 0) > { > return ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext, aRenderingContext, > aTextRunConstructionContext, MODE_DRAW, aX, aY, aPosResolve, aPosResolveCount, nsnull); > } > >- nscoord MeasureTextWidth(const PRUnichar* aText, >- PRInt32 aLength, >- nsBidiDirection aBaseDirection, >- nsPresContext* aPresContext, >- nsIRenderingContext& aRenderingContext) >+ static nscoord MeasureTextWidth(const PRUnichar* aText, >+ PRInt32 aLength, >+ nsBidiDirection aBaseDirection, >+ nsPresContext* aPresContext, >+ nsIRenderingContext& aRenderingContext) > { > nscoord length; > nsresult rv = ProcessTextForRenderingContext(aText, aLength, aBaseDirection, aPresContext, > aRenderingContext, aRenderingContext, > MODE_MEASURE, 0, 0, nsnull, 0, &length); > return NS_SUCCEEDED(rv) ? length : 0; > } > > /** > * Check if a line is reordered, i.e., if the child frames are not > * all laid out left-to-right. > * @param aFirstFrameOnLine : first frame of the line to be tested > * @param aNumFramesOnLine : number of frames on this line > * @param[out] aLeftMost : leftmost frame on this line > * @param[out] aRightMost : rightmost frame on this line > */ >- PRBool CheckLineOrder(nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine, >- nsIFrame** aLeftmost, >- nsIFrame** aRightmost); >+ static PRBool CheckLineOrder(nsIFrame* aFirstFrameOnLine, >+ PRInt32 aNumFramesOnLine, >+ nsIFrame** aLeftmost, >+ nsIFrame** aRightmost); > > /** > * Get the frame to the right of the given frame, on the same line. > * @param aFrame : We're looking for the frame to the right of this frame. > * If null, return the leftmost frame on the line. > * @param aFirstFrameOnLine : first frame of the line to be tested > * @param aNumFramesOnLine : number of frames on this line > */ >- nsIFrame* GetFrameToRightOf(const nsIFrame* aFrame, >- nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine); >+ static nsIFrame* GetFrameToRightOf(const nsIFrame* aFrame, >+ nsIFrame* aFirstFrameOnLine, >+ PRInt32 aNumFramesOnLine); > > /** > * Get the frame to the left of the given frame, on the same line. > * @param aFrame : We're looking for the frame to the left of this frame. > * If null, return the rightmost frame on the line. > * @param aFirstFrameOnLine : first frame of the line to be tested > * @param aNumFramesOnLine : number of frames on this line > */ >- nsIFrame* GetFrameToLeftOf(const nsIFrame* aFrame, >- nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine); >+ static nsIFrame* GetFrameToLeftOf(const nsIFrame* aFrame, >+ nsIFrame* aFirstFrameOnLine, >+ PRInt32 aNumFramesOnLine); > > /** > * Get the bidi embedding level of the given (inline) frame. > */ > static nsBidiLevel GetFrameEmbeddingLevel(nsIFrame* aFrame); > > /** > * Get the bidi base level of the given (inline) frame. >@@ -307,173 +312,150 @@ public: > * MODE_DRAW - invokes DrawText on the processor for each substring > * MODE_MEASURE - does not invoke DrawText on the processor > * Note that the string is always measured, regardless of mode > * @param[in,out] aPosResolve array of logical positions to resolve into > * visual positions; can be nsnull if this functionality is not required > * @param aPosResolveCount number of items in the aPosResolve array > * @param[out] aWidth Pointer to where the width will be stored (may be null) > */ >- nsresult ProcessText(const PRUnichar* aText, >- PRInt32 aLength, >- nsBidiDirection aBaseDirection, >- nsPresContext* aPresContext, >- BidiProcessor& aprocessor, >- Mode aMode, >- nsBidiPositionResolve* aPosResolve, >- PRInt32 aPosResolveCount, >- nscoord* aWidth); >+ static nsresult ProcessText(const PRUnichar* aText, >+ PRInt32 aLength, >+ nsBidiDirection aBaseDirection, >+ nsPresContext* aPresContext, >+ BidiProcessor& aprocessor, >+ Mode aMode, >+ nsBidiPositionResolve* aPosResolve, >+ PRInt32 aPosResolveCount, >+ nscoord* aWidth, >+ nsBidi* aBidiEngine); > > /** > * Make a copy of a string, converting from logical to visual order > * > * @param aSource the source string > * @param aDest the destination string > * @param aBaseDirection the base direction of the string > * (NSBIDI_LTR or NSBIDI_RTL to force the base direction; > * NSBIDI_DEFAULT_LTR or NSBIDI_DEFAULT_RTL to let the bidi engine > * determine the direction from rules P2 and P3 of the bidi algorithm. > * @see nsBidi::GetPara > * @param aOverride if TRUE, the text has a bidi override, according to > * the direction in aDir > */ >- void CopyLogicalToVisual(const nsAString& aSource, >- nsAString& aDest, >- nsBidiLevel aBaseDirection, >- PRBool aOverride); >- >- /** >- * Guess at how much memory is being used by this nsBidiPresUtils instance, >- * including memory used by nsBidi. >- */ >- PRUint32 EstimateMemoryUsed(); >- >- void Traverse(nsCycleCollectionTraversalCallback &cb) const; >- void Unlink(); >+ static void CopyLogicalToVisual(const nsAString& aSource, >+ nsAString& aDest, >+ nsBidiLevel aBaseDirection, >+ PRBool aOverride); > > private: >- nsresult ProcessTextForRenderingContext(const PRUnichar* aText, >- PRInt32 aLength, >- nsBidiDirection aBaseDirection, >- nsPresContext* aPresContext, >- nsIRenderingContext& aRenderingContext, >- nsIRenderingContext& aTextRunConstructionContext, >- Mode aMode, >- nscoord aX, // DRAW only >- nscoord aY, // DRAW only >- nsBidiPositionResolve* aPosResolve, /* may be null */ >- PRInt32 aPosResolveCount, >- nscoord* aWidth /* may be null */); >+ static nsresult ProcessTextForRenderingContext(const PRUnichar* aText, >+ PRInt32 aLength, >+ nsBidiDirection aBaseDirection, >+ nsPresContext* aPresContext, >+ nsIRenderingContext& aRenderingContext, >+ nsIRenderingContext& aTextRunConstructionContext, >+ Mode aMode, >+ nscoord aX, // DRAW only >+ nscoord aY, // DRAW only >+ nsBidiPositionResolve* aPosResolve, /* may be null */ >+ PRInt32 aPosResolveCount, >+ nscoord* aWidth /* may be null */); > > /** > * Traverse the child frames of the block element and: > * Set up an array of the frames in logical order > * Create a string containing the text content of all the frames > * If we encounter content that requires us to split the element into more > * than one paragraph for bidi resolution, resolve the paragraph up to that > * point. > */ >- void TraverseFrames(nsBlockFrame* aBlockFrame, nsIFrame* aCurrentFrame); >- >- /** >- * Initialize the logically-ordered array of frames >- * using the top-level frames of a single line >- */ >- void InitLogicalArrayFromLine(nsIFrame* aFirstFrameOnLine, >- PRInt32 aNumFramesOnLine); >- >- /** >- * Reorder the frame array from logical to visual order >- * >- * @param aReordered TRUE on return if the visual order is different from >- * the logical order >- * @param aHasRTLFrames TRUE on return if at least one of the frames is RTL >- * (and therefore might have reordered descendents) >- */ >- nsresult Reorder(PRBool& aReordered, PRBool& aHasRTLFrames); >+ static void TraverseFrames(nsBlockFrame* aBlockFrame, nsIFrame* aCurrentFrame, >+ BidiParagraphData *aBpd); > > /* > * Position aFrame and it's descendants to their visual places. Also if aFrame > * is not leaf, resize it to embrace it's children. > * > * @param aFrame The frame which itself and its children are going > * to be repositioned > * @param aIsOddLevel TRUE means the embedding level of this frame is odd > * @param[in,out] aLeft IN value is the starting position of aFrame(without > * considering its left margin) > * OUT value will be the ending position of aFrame(after > * adding its right margin) > * @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState > */ >- void RepositionFrame(nsIFrame* aFrame, >- PRBool aIsOddLevel, >- nscoord& aLeft, >- nsContinuationStates* aContinuationStates) const; >+ static void RepositionFrame(nsIFrame* aFrame, >+ PRBool aIsOddLevel, >+ nscoord& aLeft, >+ nsContinuationStates* aContinuationStates); > > /* > * Initialize the continuation state(nsFrameContinuationState) to > * (nsnull, 0) for aFrame and its descendants. > * > * @param aFrame The frame which itself and its descendants will > * be initialized > * @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState > */ >- void InitContinuationStates(nsIFrame* aFrame, >- nsContinuationStates* aContinuationStates) const; >+ static void InitContinuationStates(nsIFrame* aFrame, >+ nsContinuationStates* aContinuationStates); > > /* > * Determine if aFrame is leftmost or rightmost, and set aIsLeftMost and > * aIsRightMost values. Also set continuation states of aContinuationStates. > * > * A frame is leftmost if it's the first appearance of its continuation chain > * on the line and the chain is on its first line if it's LTR or the chain is > * on its last line if it's RTL. > * A frame is rightmost if it's the last appearance of its continuation chain > * on the line and the chain is on its first line if it's RTL or the chain is > * on its last line if it's LTR. > * > * @param aContinuationStates A map from nsIFrame* to nsFrameContinuationState > * @param[out] aIsLeftMost TRUE means aFrame is leftmost frame or continuation > * @param[out] aIsRightMost TRUE means aFrame is rightmost frame or continuation > */ >- void IsLeftOrRightMost(nsIFrame* aFrame, >- nsContinuationStates* aContinuationStates, >- PRBool& aIsLeftMost /* out */, >- PRBool& aIsRightMost /* out */) const; >+ static void IsLeftOrRightMost(nsIFrame* aFrame, >+ nsContinuationStates* aContinuationStates, >+ PRBool& aIsLeftMost /* out */, >+ PRBool& aIsRightMost /* out */); > > /** > * Adjust frame positions following their visual order > * > * @param aFirstChild the first kid > * > * @lina 04/11/2000 > */ >- void RepositionInlineFrames(nsIFrame* aFirstChild) const; >+ static void RepositionInlineFrames(BidiLineData *aBld, >+ nsIFrame* aFirstChild); > > /** > * Helper method for Resolve() > * Truncate a text frame to the end of a single-directional run and possibly > * create a continuation frame for the remainder of its content. > * > * @param aFrame the original frame > * @param aNewFrame [OUT] the new frame that was created > * @param aFrameIndex [IN/OUT] index of aFrame in mLogicalFrames > * @param aStart [IN] the start of the content mapped by aFrame (and > * any fluid continuations) > * @param aEnd [IN] the offset of the end of the single-directional > * text run. > * @see Resolve() > * @see RemoveBidiContinuation() > */ >- inline >- void EnsureBidiContinuation(nsIFrame* aFrame, >- nsIFrame** aNewFrame, >- PRInt32& aFrameIndex, >- PRInt32 aStart, >- PRInt32 aEnd); >+ static inline >+ nsresult EnsureBidiContinuation(nsIFrame* aFrame, >+ nsIFrame** aNewFrame, >+ PRInt32& aFrameIndex, >+ PRInt32 aStart, >+ PRInt32 aEnd); > > /** > * Helper method for Resolve() > * Convert one or more bidi continuation frames created in a previous reflow by > * EnsureBidiContinuation() into fluid continuations. > * @param aFrame the frame whose continuations are to be removed > * @param aFirstIndex index of aFrame in mLogicalFrames > * @param aLastIndex index of the last frame to be removed >@@ -481,54 +463,40 @@ private: > * directional frames have control characters > * corresponding to them in mBuffer, the pointers to > * mBuffer in Resolve() will need to be updated after > * deleting the frames. > * > * @see Resolve() > * @see EnsureBidiContinuation() > */ >- void RemoveBidiContinuation(nsIFrame* aFrame, >- PRInt32 aFirstIndex, >- PRInt32 aLastIndex, >- PRInt32& aOffset) const; >- void CalculateCharType(PRInt32& aOffset, >- PRInt32 aCharTypeLimit, >- PRInt32& aRunLimit, >- PRInt32& aRunLength, >- PRInt32& aRunCount, >- PRUint8& aCharType, >- PRUint8& aPrevCharType) const; >+ static void RemoveBidiContinuation(BidiParagraphData* aBpd, >+ nsIFrame* aFrame, >+ PRInt32 aFirstIndex, >+ PRInt32 aLastIndex, >+ PRInt32& aOffset); >+ static void CalculateCharType(nsBidi* aBidiEngine, >+ const PRUnichar* aText, >+ PRInt32& aOffset, >+ PRInt32 aCharTypeLimit, >+ PRInt32& aRunLimit, >+ PRInt32& aRunLength, >+ PRInt32& aRunCount, >+ PRUint8& aCharType, >+ PRUint8& aPrevCharType); > >- void StripBidiControlCharacters(PRUnichar* aText, >- PRInt32& aTextLength) const; >+ static void StripBidiControlCharacters(PRUnichar* aText, >+ PRInt32& aTextLength); > > static PRBool WriteLogicalToVisual(const PRUnichar* aSrc, > PRUint32 aSrcLength, > PRUnichar* aDest, > nsBidiLevel aBaseDirection, > nsBidi* aBidiEngine); > >- static void WriteReverse(const PRUnichar* aSrc, >- PRUint32 aSrcLength, >- PRUnichar* aDest); >- >- nsString mBuffer; >- nsTArray<PRUnichar> mEmbeddingStack; >- nsTArray<nsIFrame*> mLogicalFrames; >- nsTArray<nsIFrame*> mVisualFrames; >- nsDataHashtable<nsISupportsHashKey, PRInt32> mContentToFrameIndex; >- PRInt32 mArraySize; >- PRInt32* mIndexMap; >- PRUint8* mLevels; >- nsresult mSuccess; >- PRPackedBool mIsVisual; >- nsBidiLevel mParaLevel; >- nsIFrame* mPrevFrame; >- nsIContent* mPrevContent; >- >- nsAutoPtr<nsBlockInFlowLineIterator> mLineIter; >- nsBidi* mBidiEngine; >+ static void WriteReverse(const PRUnichar* aSrc, >+ PRUint32 aSrcLength, >+ PRUnichar* aDest); > }; > > #endif /* nsBidiPresUtils_h___ */ > > #endif // IBMBIDI >diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp >--- a/layout/base/nsLayoutUtils.cpp >+++ b/layout/base/nsLayoutUtils.cpp >@@ -2764,29 +2764,25 @@ nsLayoutUtils::DrawString(const nsIFrame > PRInt32 aLength, > nsPoint aPoint, > PRUint8 aDirection) > { > #ifdef IBMBIDI > nsresult rv = NS_ERROR_FAILURE; > nsPresContext* presContext = aFrame->PresContext(); > if (presContext->BidiEnabled()) { >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- >- if (bidiUtils) { >- if (aDirection == NS_STYLE_DIRECTION_INHERIT) { >- aDirection = aFrame->GetStyleVisibility()->mDirection; >- } >- nsBidiDirection direction = >- (NS_STYLE_DIRECTION_RTL == aDirection) ? >- NSBIDI_RTL : NSBIDI_LTR; >- rv = bidiUtils->RenderText(aString, aLength, direction, >- presContext, *aContext, *aContext, >- aPoint.x, aPoint.y); >+ if (aDirection == NS_STYLE_DIRECTION_INHERIT) { >+ aDirection = aFrame->GetStyleVisibility()->mDirection; > } >+ nsBidiDirection direction = >+ (NS_STYLE_DIRECTION_RTL == aDirection) ? >+ NSBIDI_RTL : NSBIDI_LTR; >+ rv = nsBidiPresUtils::RenderText(aString, aLength, direction, >+ presContext, *aContext, *aContext, >+ aPoint.x, aPoint.y); > } > if (NS_FAILED(rv)) > #endif // IBMBIDI > { > aContext->SetTextRunRTL(PR_FALSE); > aContext->DrawString(aString, aLength, aPoint.x, aPoint.y); > } > } >@@ -2795,26 +2791,22 @@ nscoord > nsLayoutUtils::GetStringWidth(const nsIFrame* aFrame, > nsIRenderingContext* aContext, > const PRUnichar* aString, > PRInt32 aLength) > { > #ifdef IBMBIDI > nsPresContext* presContext = aFrame->PresContext(); > if (presContext->BidiEnabled()) { >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- >- if (bidiUtils) { >- const nsStyleVisibility* vis = aFrame->GetStyleVisibility(); >- nsBidiDirection direction = >- (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? >- NSBIDI_RTL : NSBIDI_LTR; >- return bidiUtils->MeasureTextWidth(aString, aLength, >- direction, presContext, *aContext); >- } >+ const nsStyleVisibility* vis = aFrame->GetStyleVisibility(); >+ nsBidiDirection direction = >+ (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? >+ NSBIDI_RTL : NSBIDI_LTR; >+ return nsBidiPresUtils::MeasureTextWidth(aString, aLength, >+ direction, presContext, *aContext); > } > #endif // IBMBIDI > aContext->SetTextRunRTL(PR_FALSE); > nscoord width; > aContext->GetWidth(aString, aLength, width); > return width; > } > >diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp >--- a/layout/base/nsPresContext.cpp >+++ b/layout/base/nsPresContext.cpp >@@ -353,18 +353,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( > > for (PRUint32 i = 0; i < IMAGE_LOAD_TYPE_COUNT; ++i) > tmp->mImageLoaders[i].Enumerate(TraverseImageLoader, &cb); > > // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTheme); // a service > // NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLangService); // a service > NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrintSettings); > NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mPrefChangedTimer); >- if (tmp->mBidiUtils) >- tmp->mBidiUtils->Traverse(cb); > NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END > > NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsPresContext) > NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDocument); > NS_RELEASE(tmp->mDeviceContext); // worth bothering? > if (tmp->mEventManager) { > // unclear if these are needed, but can't hurt > tmp->mEventManager->NotifyDestroyPresContext(tmp); >@@ -379,18 +377,16 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns > // NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTheme); // a service > // NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mLangService); // a service > NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPrintSettings); > if (tmp->mPrefChangedTimer) > { > tmp->mPrefChangedTimer->Cancel(); > tmp->mPrefChangedTimer = nsnull; > } >- if (tmp->mBidiUtils) >- tmp->mBidiUtils->Unlink(); > NS_IMPL_CYCLE_COLLECTION_UNLINK_END > > > #define MAKE_FONT_PREF_KEY(_pref, _s0, _s1) \ > _pref.Assign(_s0); \ > _pref.Append(_s1); > > static const char* const kGenericFont[] = { >@@ -1430,25 +1426,16 @@ nsPresContext::SetBidiEnabled() const > if (mShell) { > nsIDocument *doc = mShell->GetDocument(); > if (doc) { > doc->SetBidiEnabled(); > } > } > } > >-nsBidiPresUtils* >-nsPresContext::GetBidiUtils() >-{ >- if (!mBidiUtils) >- mBidiUtils = new nsBidiPresUtils; >- >- return mBidiUtils; >-} >- > void > nsPresContext::SetBidi(PRUint32 aSource, PRBool aForceRestyle) > { > // Don't do all this stuff unless the options have changed. > if (aSource == GetBidi()) { > return; > } > >@@ -1481,25 +1468,16 @@ nsPresContext::SetBidi(PRUint32 aSource, > } > > PRUint32 > nsPresContext::GetBidi() const > { > return Document()->GetBidiOptions(); > } > >-PRUint32 >-nsPresContext::GetBidiMemoryUsed() >-{ >- if (!mBidiUtils) >- return 0; >- >- return mBidiUtils->EstimateMemoryUsed(); >-} >- > #endif //IBMBIDI > > PRBool > nsPresContext::IsTopLevelWindowInactive() > { > nsCOMPtr<nsIDocShellTreeItem> treeItem(do_QueryReferent(mContainer)); > if (!treeItem) > return PR_FALSE; >diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h >--- a/layout/base/nsPresContext.h >+++ b/layout/base/nsPresContext.h >@@ -742,36 +742,27 @@ public: > * > * @lina 05/02/2000 > */ > PRBool IsVisualMode() const { return mIsVisual; } > > //Mohamed > > /** >- * Get a Bidi presentation utilities object >- */ >- NS_HIDDEN_(nsBidiPresUtils*) GetBidiUtils(); >- >- /** > * Set the Bidi options for the presentation context > */ > NS_HIDDEN_(void) SetBidi(PRUint32 aBidiOptions, > PRBool aForceRestyle = PR_FALSE); > > /** > * Get the Bidi options for the presentation context > * Not inline so consumers of nsPresContext are not forced to > * include nsIDocument. > */ > NS_HIDDEN_(PRUint32) GetBidi() const; >- >- PRUint32 GetBidiMemoryUsed(); >-#else >- PRUint32 GetBidiMemoryUsed() { return 0; } > #endif // IBMBIDI > > /** > * Render only Selection > */ > void SetIsRenderingOnlySelection(PRBool aResult) > { > NS_ASSERTION(!(aResult & ~1), "Value must be true or false"); >@@ -989,17 +980,16 @@ public: > > PRBool MayHaveFixedBackgroundFrames() { return mMayHaveFixedBackgroundFrames; } > void SetHasFixedBackgroundFrame() { mMayHaveFixedBackgroundFrames = PR_TRUE; } > > PRUint32 EstimateMemoryUsed() { > PRUint32 result = 0; > > result += sizeof(nsPresContext); >- result += GetBidiMemoryUsed(); > > return result; > } > > PRBool IsRootContentDocument(); > > protected: > friend class nsRunnableMethod<nsPresContext>; >@@ -1073,20 +1063,16 @@ protected: > > PRInt32 mMinFontSize; // Min font size, defaults to 0 > float mTextZoom; // Text zoom, defaults to 1.0 > float mFullZoom; // Page zoom, defaults to 1.0 > > PRInt32 mCurAppUnitsPerDevPixel; > PRInt32 mAutoQualityMinFontSizePixelsPref; > >-#ifdef IBMBIDI >- nsAutoPtr<nsBidiPresUtils> mBidiUtils; >-#endif >- > nsCOMPtr<nsITheme> mTheme; > nsCOMPtr<nsILanguageAtomService> mLangService; > nsCOMPtr<nsIPrintSettings> mPrintSettings; > nsCOMPtr<nsITimer> mPrefChangedTimer; > > FramePropertyTable mPropertyTable; > > nsInvalidateRequestList mInvalidateRequests; >diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp >--- a/layout/base/nsPresShell.cpp >+++ b/layout/base/nsPresShell.cpp >@@ -1410,42 +1410,29 @@ public: > { > PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey()); > PRUint32 *val = (PRUint32*)userArg; > *val += aShell->EstimateMemoryUsed(); > *val += aShell->mPresContext->EstimateMemoryUsed(); > return PL_DHASH_NEXT; > } > >- static PLDHashOperator LiveShellBidiSizeEnumerator(PresShellPtrKey *aEntry, >- void *userArg) >- { >- PresShell *aShell = static_cast<PresShell*>(aEntry->GetKey()); >- PRUint32 *val = (PRUint32*)userArg; >- *val += aShell->mPresContext->GetBidiMemoryUsed(); >- return PL_DHASH_NEXT; >- } >- > static PRUint32 > EstimateShellsMemory(nsTHashtable<PresShellPtrKey>::Enumerator aEnumerator) > { > PRUint32 result = 0; > sLiveShells->EnumerateEntries(aEnumerator, &result); > return result; > } > > > static PRInt64 SizeOfLayoutMemoryReporter(void *) { > return EstimateShellsMemory(LiveShellSizeEnumerator); > } > >- static PRInt64 SizeOfBidiMemoryReporter(void *) { >- return EstimateShellsMemory(LiveShellBidiSizeEnumerator); >- } >- > protected: > void QueryIsActive(); > nsresult UpdateImageLockingState(); > }; > > class nsAutoCauseReflowNotifier > { > public: >@@ -1651,22 +1638,16 @@ NS_NewPresShell(nsIPresShell** aInstance > nsTHashtable<PresShell::PresShellPtrKey> *nsIPresShell::sLiveShells = 0; > > NS_MEMORY_REPORTER_IMPLEMENT(LayoutPresShell, > "layout/all", > "Memory in use by layout PresShell, PresContext, and other related areas.", > PresShell::SizeOfLayoutMemoryReporter, > nsnull) > >-NS_MEMORY_REPORTER_IMPLEMENT(LayoutBidi, >- "layout/bidi", >- "Memory in use by layout Bidi processor.", >- PresShell::SizeOfBidiMemoryReporter, >- nsnull) >- > PresShell::PresShell() > { > mSelection = nsnull; > #ifdef MOZ_REFLOW_PERF > mReflowCountMgr = new ReflowCountMgr(); > mReflowCountMgr->SetPresContext(mPresContext); > mReflowCountMgr->SetPresShell(this); > #endif >@@ -1684,17 +1665,16 @@ PresShell::PresShell() > mRenderFlags = 0; > mXResolution = 1.0; > mYResolution = 1.0; > mViewportOverridden = PR_FALSE; > > static bool registeredReporter = false; > if (!registeredReporter) { > NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(LayoutPresShell)); >- NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(LayoutBidi)); > registeredReporter = true; > } > > new (this) nsFrameManager(); > > sLiveShells->PutEntry(this); > } > >diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp >--- a/layout/generic/nsBlockFrame.cpp >+++ b/layout/generic/nsBlockFrame.cpp >@@ -4234,21 +4234,17 @@ nsBlockFrame::PlaceLine(nsBlockReflowSta > // RelativePositionFrames!!! > // XXXldb Is something here considering relatively positioned frames at > // other than their original positions? > #ifdef IBMBIDI > // XXXldb Why don't we do this earlier? > if (aState.mPresContext->BidiEnabled()) { > if (!aState.mPresContext->IsVisualMode() || > GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL) { >- nsBidiPresUtils* bidiUtils = aState.mPresContext->GetBidiUtils(); >- >- if (bidiUtils && bidiUtils->IsSuccessful() ) { >- bidiUtils->ReorderFrames(aLine->mFirstChild, aLine->GetChildCount()); >- } // bidiUtils >+ nsBidiPresUtils::ReorderFrames(aLine->mFirstChild, aLine->GetChildCount()); > } // not visual mode > } // bidi enabled > #endif // IBMBIDI > > // From here on, pfd->mBounds rectangles are incorrect because bidi > // might have moved frames around! > nsOverflowAreas overflowAreas; > aLineLayout.RelativePositionFrames(overflowAreas); >@@ -7173,21 +7169,17 @@ nsBlockFrame::ResolveBidi() > NS_ASSERTION(!GetPrevInFlow(), > "ResolveBidi called on non-first continuation"); > > nsPresContext* presContext = PresContext(); > if (!presContext->BidiEnabled()) { > return NS_OK; > } > >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- if (!bidiUtils) >- return NS_ERROR_NULL_POINTER; >- >- return bidiUtils->Resolve(this); >+ return nsBidiPresUtils::Resolve(this); > } > #endif > > #ifdef DEBUG > void > nsBlockFrame::VerifyLines(PRBool aFinalCheckOK) > { > if (!gVerifyLines) { >diff --git a/layout/generic/nsFrameList.cpp b/layout/generic/nsFrameList.cpp >--- a/layout/generic/nsFrameList.cpp >+++ b/layout/generic/nsFrameList.cpp >@@ -447,27 +447,26 @@ nsFrameList::GetPrevVisualFor(nsIFrame* > if (!mFirstChild) > return nsnull; > > nsIFrame* parent = mFirstChild->GetParent(); > if (!parent) > return aFrame ? aFrame->GetPrevSibling() : LastChild(); > > nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild); >- nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils(); > > nsAutoLineIterator iter = parent->GetLineIterator(); > if (!iter) { > // Parent is not a block Frame > if (parent->GetType() == nsGkAtoms::lineFrame) { > // Line frames are not bidi-splittable, so need to consider bidi reordering > if (baseLevel == NSBIDI_LTR) { >- return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1); >+ return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1); > } else { // RTL >- return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1); >+ return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1); > } > } else { > // Just get the next or prev sibling, depending on block and frame direction. > nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild); > if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) { > return aFrame ? aFrame->GetPrevSibling() : LastChild(); > } else { > return aFrame ? aFrame->GetNextSibling() : mFirstChild; >@@ -492,57 +491,56 @@ nsFrameList::GetPrevVisualFor(nsIFrame* > PRInt32 numFramesOnLine; > nsRect lineBounds; > PRUint32 lineFlags; > > if (aFrame) { > iter->GetLine(thisLine, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags); > > if (baseLevel == NSBIDI_LTR) { >- frame = bidiUtils->GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine); > } else { // RTL >- frame = bidiUtils->GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine); > } > } > > if (!frame && thisLine > 0) { > // Get the last frame of the previous line > iter->GetLine(thisLine - 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags); > > if (baseLevel == NSBIDI_LTR) { >- frame = bidiUtils->GetFrameToLeftOf(nsnull, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToLeftOf(nsnull, firstFrameOnLine, numFramesOnLine); > } else { // RTL >- frame = bidiUtils->GetFrameToRightOf(nsnull, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToRightOf(nsnull, firstFrameOnLine, numFramesOnLine); > } > } > return frame; > } > > nsIFrame* > nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const > { > if (!mFirstChild) > return nsnull; > > nsIFrame* parent = mFirstChild->GetParent(); > if (!parent) > return aFrame ? aFrame->GetPrevSibling() : mFirstChild; > > nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild); >- nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils(); > > nsAutoLineIterator iter = parent->GetLineIterator(); > if (!iter) { > // Parent is not a block Frame > if (parent->GetType() == nsGkAtoms::lineFrame) { > // Line frames are not bidi-splittable, so need to consider bidi reordering > if (baseLevel == NSBIDI_LTR) { >- return bidiUtils->GetFrameToRightOf(aFrame, mFirstChild, -1); >+ return nsBidiPresUtils::GetFrameToRightOf(aFrame, mFirstChild, -1); > } else { // RTL >- return bidiUtils->GetFrameToLeftOf(aFrame, mFirstChild, -1); >+ return nsBidiPresUtils::GetFrameToLeftOf(aFrame, mFirstChild, -1); > } > } else { > // Just get the next or prev sibling, depending on block and frame direction. > nsBidiLevel frameEmbeddingLevel = nsBidiPresUtils::GetFrameEmbeddingLevel(mFirstChild); > if ((frameEmbeddingLevel & 1) == (baseLevel & 1)) { > return aFrame ? aFrame->GetNextSibling() : mFirstChild; > } else { > return aFrame ? aFrame->GetPrevSibling() : LastChild(); >@@ -567,31 +565,31 @@ nsFrameList::GetNextVisualFor(nsIFrame* > PRInt32 numFramesOnLine; > nsRect lineBounds; > PRUint32 lineFlags; > > if (aFrame) { > iter->GetLine(thisLine, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags); > > if (baseLevel == NSBIDI_LTR) { >- frame = bidiUtils->GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToRightOf(aFrame, firstFrameOnLine, numFramesOnLine); > } else { // RTL >- frame = bidiUtils->GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToLeftOf(aFrame, firstFrameOnLine, numFramesOnLine); > } > } > > PRInt32 numLines = iter->GetNumLines(); > if (!frame && thisLine < numLines - 1) { > // Get the first frame of the next line > iter->GetLine(thisLine + 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags); > > if (baseLevel == NSBIDI_LTR) { >- frame = bidiUtils->GetFrameToRightOf(nsnull, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToRightOf(nsnull, firstFrameOnLine, numFramesOnLine); > } else { // RTL >- frame = bidiUtils->GetFrameToLeftOf(nsnull, firstFrameOnLine, numFramesOnLine); >+ frame = nsBidiPresUtils::GetFrameToLeftOf(nsnull, firstFrameOnLine, numFramesOnLine); > } > } > return frame; > } > #endif > > #ifdef DEBUG_FRAME_LIST > void >diff --git a/layout/generic/nsImageFrame.cpp b/layout/generic/nsImageFrame.cpp >--- a/layout/generic/nsImageFrame.cpp >+++ b/layout/generic/nsImageFrame.cpp >@@ -1002,31 +1002,27 @@ nsImageFrame::DisplayAltText(nsPresConte > PRUint32 maxFit; // number of characters that fit > nscoord strWidth = MeasureString(str, strLen, aRect.width, maxFit, > aRenderingContext); > > // Display the text > nsresult rv = NS_ERROR_FAILURE; > > if (aPresContext->BidiEnabled()) { >- nsBidiPresUtils* bidiUtils = aPresContext->GetBidiUtils(); >- >- if (bidiUtils) { >- const nsStyleVisibility* vis = GetStyleVisibility(); >- if (vis->mDirection == NS_STYLE_DIRECTION_RTL) >- rv = bidiUtils->RenderText(str, maxFit, NSBIDI_RTL, >- aPresContext, aRenderingContext, >- aRenderingContext, >- aRect.XMost() - strWidth, y + maxAscent); >- else >- rv = bidiUtils->RenderText(str, maxFit, NSBIDI_LTR, >- aPresContext, aRenderingContext, >- aRenderingContext, >- aRect.x, y + maxAscent); >- } >+ const nsStyleVisibility* vis = GetStyleVisibility(); >+ if (vis->mDirection == NS_STYLE_DIRECTION_RTL) >+ rv = nsBidiPresUtils::RenderText(str, maxFit, NSBIDI_RTL, >+ aPresContext, aRenderingContext, >+ aRenderingContext, >+ aRect.XMost() - strWidth, y + maxAscent); >+ else >+ rv = nsBidiPresUtils::RenderText(str, maxFit, NSBIDI_LTR, >+ aPresContext, aRenderingContext, >+ aRenderingContext, >+ aRect.x, y + maxAscent); > } > if (NS_FAILED(rv)) > aRenderingContext.DrawString(str, maxFit, aRect.x, y + maxAscent); > > // Move to the next line > str += maxFit; > strLen -= maxFit; > y += height; >diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp >--- a/layout/generic/nsLineBox.cpp >+++ b/layout/generic/nsLineBox.cpp >@@ -658,21 +658,19 @@ nsLineIterator::CheckLineOrder(PRInt32 > *aIsReordered = PR_FALSE; > *aFirstVisual = nsnull; > *aLastVisual = nsnull; > return NS_OK; > } > > nsPresContext* presContext = line->mFirstChild->PresContext(); > >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- > nsIFrame* leftmostFrame; > nsIFrame* rightmostFrame; >- *aIsReordered = bidiUtils->CheckLineOrder(line->mFirstChild, line->GetChildCount(), &leftmostFrame, &rightmostFrame); >+ *aIsReordered = nsBidiPresUtils::CheckLineOrder(line->mFirstChild, line->GetChildCount(), &leftmostFrame, &rightmostFrame); > > // map leftmost/rightmost to first/last according to paragraph direction > *aFirstVisual = mRightToLeft ? rightmostFrame : leftmostFrame; > *aLastVisual = mRightToLeft ? leftmostFrame : rightmostFrame; > > return NS_OK; > } > #endif // IBMBIDI >diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp >--- a/layout/generic/nsTextFrameThebes.cpp >+++ b/layout/generic/nsTextFrameThebes.cpp >@@ -103,17 +103,16 @@ > #include "nsILineIterator.h" > > #include "nsIServiceManager.h" > #ifdef ACCESSIBILITY > #include "nsAccessibilityService.h" > #endif > #include "nsAutoPtr.h" > >-#include "nsBidiPresUtils.h" > #include "nsBidiUtils.h" > > #include "nsIThebesFontMetrics.h" > #include "gfxFont.h" > #include "gfxContext.h" > #include "gfxTextRunWordCache.h" > #include "gfxImageSurface.h" > #include "mozilla/dom/Element.h" >diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp >--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp >+++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp >@@ -1525,58 +1525,55 @@ nsSVGGlyphFrame::EnsureTextRun(float *aD > double textRunSize; > if (mTextRun) { > textRunSize = mTextRun->GetFontGroup()->GetStyle()->size; > } else { > nsAutoString text; > if (!GetCharacterData(text)) > return PR_FALSE; > >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- if (bidiUtils) { >- nsAutoString visualText; >- >- /* >- * XXXsmontagu: The SVG spec says: >- * >- * http://www.w3.org/TR/SVG11/text.html#DirectionProperty >- * "For the 'direction' property to have any effect, the 'unicode-bidi' >- * property's value must be embed or bidi-override." >- * >- * The SVGTiny spec, on the other hand, says >- * >- * http://www.w3.org/TR/SVGTiny12/text.html#DirectionProperty >- * "For the 'direction' property to have any effect on an element that >- * does not by itself establish a new text chunk (such as the 'tspan' >- * element in SVG 1.2 Tiny), the 'unicode-bidi' property's value must >- * be embed or bidi-override." >- * >- * Note that this is different from HTML/CSS, where setting the 'dir' >- * attribute on an inline element automatically sets unicode-bidi: embed >- * >- * Our current implementation of bidi in SVG does not distinguish between >- * different text elements, but treats every text container frame as a >- * new text chunk, so we always set the base direction according to the >- * direction property >- * >- * See also XXXsmontagu comments in nsSVGTextFrame::UpdateGlyphPositioning >- */ >- >- // Get the unicodeBidi property from the parent, because it doesn't >- // inherit >- PRBool bidiOverride = (mParent->GetStyleTextReset()->mUnicodeBidi == >- NS_STYLE_UNICODE_BIDI_OVERRIDE); >- nsBidiLevel baseDirection = >- GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL ? >- NSBIDI_RTL : NSBIDI_LTR; >- bidiUtils->CopyLogicalToVisual(text, visualText, >- baseDirection, bidiOverride); >- if (!visualText.IsEmpty()) { >- text = visualText; >- } >+ nsAutoString visualText; >+ >+ /* >+ * XXXsmontagu: The SVG spec says: >+ * >+ * http://www.w3.org/TR/SVG11/text.html#DirectionProperty >+ * "For the 'direction' property to have any effect, the 'unicode-bidi' >+ * property's value must be embed or bidi-override." >+ * >+ * The SVGTiny spec, on the other hand, says >+ * >+ * http://www.w3.org/TR/SVGTiny12/text.html#DirectionProperty >+ * "For the 'direction' property to have any effect on an element that >+ * does not by itself establish a new text chunk (such as the 'tspan' >+ * element in SVG 1.2 Tiny), the 'unicode-bidi' property's value must >+ * be embed or bidi-override." >+ * >+ * Note that this is different from HTML/CSS, where setting the 'dir' >+ * attribute on an inline element automatically sets unicode-bidi: embed >+ * >+ * Our current implementation of bidi in SVG does not distinguish between >+ * different text elements, but treats every text container frame as a >+ * new text chunk, so we always set the base direction according to the >+ * direction property >+ * >+ * See also XXXsmontagu comments in nsSVGTextFrame::UpdateGlyphPositioning >+ */ >+ >+ // Get the unicodeBidi property from the parent, because it doesn't >+ // inherit >+ PRBool bidiOverride = (mParent->GetStyleTextReset()->mUnicodeBidi == >+ NS_STYLE_UNICODE_BIDI_OVERRIDE); >+ nsBidiLevel baseDirection = >+ GetStyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL ? >+ NSBIDI_RTL : NSBIDI_LTR; >+ nsBidiPresUtils::CopyLogicalToVisual(text, visualText, >+ baseDirection, bidiOverride); >+ if (!visualText.IsEmpty()) { >+ text = visualText; > } > > gfxMatrix m; > if (aForceGlobalTransform || > !(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) { > if (!GetGlobalTransform(&m)) > return PR_FALSE; > } >diff --git a/layout/xul/base/src/nsTextBoxFrame.cpp b/layout/xul/base/src/nsTextBoxFrame.cpp >--- a/layout/xul/base/src/nsTextBoxFrame.cpp >+++ b/layout/xul/base/src/nsTextBoxFrame.cpp >@@ -514,42 +514,38 @@ nsTextBoxFrame::DrawText(nsIRenderingCon > > aRenderingContext.SetColor(aOverrideColor ? *aOverrideColor : GetStyleColor()->mColor); > > #ifdef IBMBIDI > nsresult rv = NS_ERROR_FAILURE; > > if (mState & NS_FRAME_IS_BIDI) { > presContext->SetBidiEnabled(); >- nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils(); >- >- if (bidiUtils) { >- const nsStyleVisibility* vis = GetStyleVisibility(); >- nsBidiDirection direction = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? NSBIDI_RTL : NSBIDI_LTR; >- if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { >- // We let the RenderText function calculate the mnemonic's >- // underline position for us. >- nsBidiPositionResolve posResolve; >- posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex; >- rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, >- presContext, aRenderingContext, >- *refContext, >- aTextRect.x, baseline, >- &posResolve, >- 1); >- mAccessKeyInfo->mBeforeWidth = posResolve.visualLeftTwips; >- mAccessKeyInfo->mAccessWidth = posResolve.visualWidth; >- } >- else >- { >- rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, >- presContext, aRenderingContext, >- *refContext, >- aTextRect.x, baseline); >- } >+ const nsStyleVisibility* vis = GetStyleVisibility(); >+ nsBidiDirection direction = (NS_STYLE_DIRECTION_RTL == vis->mDirection) ? NSBIDI_RTL : NSBIDI_LTR; >+ if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { >+ // We let the RenderText function calculate the mnemonic's >+ // underline position for us. >+ nsBidiPositionResolve posResolve; >+ posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex; >+ rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, >+ presContext, aRenderingContext, >+ *refContext, >+ aTextRect.x, baseline, >+ &posResolve, >+ 1); >+ mAccessKeyInfo->mBeforeWidth = posResolve.visualLeftTwips; >+ mAccessKeyInfo->mAccessWidth = posResolve.visualWidth; >+ } >+ else >+ { >+ rv = nsBidiPresUtils::RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction, >+ presContext, aRenderingContext, >+ *refContext, >+ aTextRect.x, baseline); > } > } > if (NS_FAILED(rv) ) > #endif // IBMBIDI > { > aRenderingContext.SetTextRunRTL(PR_FALSE); > > if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) { >diff --git a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp >--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp >+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp >@@ -103,17 +103,17 @@ > #include "nsContentUtils.h" > #include "nsLayoutUtils.h" > #include "nsIScrollableFrame.h" > #include "nsEventDispatcher.h" > #include "nsDisplayList.h" > #include "nsTreeBoxObject.h" > > #ifdef IBMBIDI >-#include "nsBidiPresUtils.h" >+#include "nsBidiUtils.h" > #endif > > // Enumeration function that cancels all the image requests in our cache > static PLDHashOperator > CancelImageRequest(const nsAString& aKey, > nsTreeImageCacheEntry aEntry, void* aData) > { > aEntry.request->CancelAndForgetObserver(NS_BINDING_ABORTED);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Flags:
roc
: review+
Actions:
View
|
Diff
|
Review
Attachments on
bug 624798
:
519654
| 523097