diff --git a/accessible/src/html/nsHyperTextAccessible.cpp b/accessible/src/html/nsHyperTextAccessible.cpp index 3e00ebe8e727..a82158be650c 100644 --- a/accessible/src/html/nsHyperTextAccessible.cpp +++ b/accessible/src/html/nsHyperTextAccessible.cpp @@ -1685,7 +1685,7 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber() NS_ENSURE_TRUE(caretFrame, -1); PRInt32 lineNumber = 1; - nsAutoLineIterator lineIterForCaret; + nsCOMPtr lineIterForCaret; nsCOMPtr hyperTextContent = do_QueryInterface(mDOMNode); while (caretFrame) { if (hyperTextContent == caretFrame->GetContent()) { @@ -1698,10 +1698,11 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber() // Add lines for the sibling frames before the caret nsIFrame *sibling = parentFrame->GetFirstChild(nsnull); while (sibling && sibling != caretFrame) { - nsAutoLineIterator lineIterForSibling = sibling->GetLineIterator(); + nsCOMPtr lineIterForSibling = do_QueryInterface(sibling); if (lineIterForSibling) { + PRInt32 addLines; // For the frames before that grab all the lines - PRInt32 addLines = lineIterForSibling->GetNumLines(); + lineIterForSibling->GetNumLines(&addLines); lineNumber += addLines; } sibling = sibling->GetNextSibling(); @@ -1709,10 +1710,11 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber() // Get the line number relative to the container with lines if (!lineIterForCaret) { // Add the caret line just once - lineIterForCaret = parentFrame->GetLineIterator(); + lineIterForCaret = do_QueryInterface(parentFrame); if (lineIterForCaret) { // Ancestor of caret - PRInt32 addLines = lineIterForCaret->FindLineContaining(caretFrame); + PRInt32 addLines; + lineIterForCaret->FindLineContaining(caretFrame, &addLines); lineNumber += addLines; } } diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 3d79680d9f2a..921bafd49ab0 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -3801,9 +3801,11 @@ UnionRectForClosestScrolledView(nsIFrame* aFrame, f && frameType == nsGkAtoms::blockFrame) { // find the line containing aFrame and increase the top of |offset|. - nsAutoLineIterator lines = f->GetLineIterator(); + nsCOMPtr lines(do_QueryInterface(f)); + if (lines) { - PRInt32 index = lines->FindLineContaining(prevFrame); + PRInt32 index = -1; + lines->FindLineContaining(prevFrame, &index); if (index >= 0) { nsIFrame *trash1; PRInt32 trash2; diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index 170d9118e4f4..10f2df7b75fa 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -315,22 +315,6 @@ nsBlockFrame::Destroy() nsBlockFrameSuper::Destroy(); } -/* virtual */ nsILineIterator* -nsBlockFrame::GetLineIterator() -{ - nsLineIterator* it = new nsLineIterator; - if (!it) - return nsnull; - - const nsStyleVisibility* visibility = GetStyleVisibility(); - nsresult rv = it->Init(mLines, visibility->mDirection == NS_STYLE_DIRECTION_RTL); - if (NS_FAILED(rv)) { - delete it; - return nsnull; - } - return it; -} - NS_IMETHODIMP nsBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -340,6 +324,26 @@ nsBlockFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) *aInstancePtr = static_cast(static_cast(this)); return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsILineIterator)) || + aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) { + nsLineIterator* it = new nsLineIterator; + if (!it) { + *aInstancePtr = nsnull; + return NS_ERROR_OUT_OF_MEMORY; + } + NS_ADDREF(it); // reference passed to caller + const nsStyleVisibility* visibility = GetStyleVisibility(); + nsresult rv = it->Init(mLines, + visibility->mDirection == NS_STYLE_DIRECTION_RTL); + if (NS_FAILED(rv)) { + *aInstancePtr = nsnull; + NS_RELEASE(it); + return rv; + } + *aInstancePtr = static_cast(it); + return NS_OK; + } + return nsBlockFrameSuper::QueryInterface(aIID, aInstancePtr); } diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 30587207e675..0d2507a20a4f 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -74,6 +74,7 @@ class nsBlockInFlowLineIterator; class nsBulletFrame; class nsLineBox; class nsFirstLineFrame; +class nsILineIterator; class nsIntervalSet; /** * Child list name indices @@ -597,8 +598,6 @@ protected: //---------------------------------------- - virtual nsILineIterator* GetLineIterator(); - public: nsLineList* GetOverflowLines() const; protected: diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index b7c6cdf76c8c..635b1cd56614 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4558,8 +4558,6 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext, PRInt8 aOutSideLimit ) { - nsresult result; - //magic numbers aLineStart will be -1 for end of block 0 will be start of block if (!aBlockFrame || !aPos) return NS_ERROR_NULL_POINTER; @@ -4568,11 +4566,14 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext, aPos->mResultContent = nsnull; aPos->mAttachForward = (aPos->mDirection == eDirNext); - nsAutoLineIterator it = aBlockFrame->GetLineIterator(); - if (!it) - return NS_ERROR_FAILURE; + nsresult result; + nsCOMPtr it; + result = aBlockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it)); + if (NS_FAILED(result) || !it) + return result; PRInt32 searchingLine = aLineStart; - PRInt32 countLines = it->GetNumLines(); + PRInt32 countLines; + result = it->GetNumLines(&countLines); if (aOutSideLimit > 0) //start at end searchingLine = countLines; else if (aOutSideLimit <0)//start at beginning @@ -4640,9 +4641,10 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext, if (NS_SUCCEEDED(result) && resultFrame) { + nsCOMPtr newIt; //check to see if this is ANOTHER blockframe inside the other one if so then call into its lines - nsAutoLineIterator newIt = resultFrame->GetLineIterator(); - if (newIt) + result = resultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(newIt)); + if (NS_SUCCEEDED(result) && newIt) { aPos->mResultFrame = resultFrame; return NS_OK; @@ -5085,16 +5087,15 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) } case eSelectLine : { - nsAutoLineIterator iter; + nsCOMPtr iter; nsIFrame *blockFrame = this; while (NS_FAILED(result)){ PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame); if (thisLine < 0) return NS_ERROR_FAILURE; - iter = blockFrame->GetLineIterator(); - NS_ASSERTION(iter, "GetLineNumber() succeeded but no block frame?"); - result = NS_OK; + result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(iter)); + NS_ASSERTION(NS_SUCCEEDED(result) && iter, "GetLineNumber() succeeded but no block frame?"); int edgeCase = 0;//no edge case. this should look at thisLine @@ -5138,23 +5139,20 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) //got the table frame now while(frame) //ok time to drill down to find iterator { - iter = frame->GetLineIterator(); - if (iter) + result = frame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator), + getter_AddRefs(iter)); + if (NS_SUCCEEDED(result)) { aPos->mResultFrame = frame; searchTableBool = PR_TRUE; - result = NS_OK; break; //while(frame) } - result = NS_ERROR_FAILURE; frame = frame->GetFirstChild(nsnull); } } - - if (!searchTableBool) { - iter = aPos->mResultFrame->GetLineIterator(); - result = iter ? NS_OK : NS_ERROR_FAILURE; - } + if (!searchTableBool) + result = aPos->mResultFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator), + getter_AddRefs(iter)); if (NS_SUCCEEDED(result) && iter)//we've struck another block element! { doneLooping = PR_FALSE; @@ -5184,13 +5182,14 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) case eSelectBeginLine: case eSelectEndLine: { + nsCOMPtr it; // Adjusted so that the caret can't get confused when content changes nsIFrame* blockFrame = AdjustFrameForSelectionStyles(this); PRInt32 thisLine = nsFrame::GetLineNumber(blockFrame, aPos->mScrollViewStop, &blockFrame); if (thisLine < 0) return NS_ERROR_FAILURE; - nsAutoLineIterator it = blockFrame->GetLineIterator(); - NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?"); + result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it)); + NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?"); PRInt32 lineFrameCount; nsIFrame *firstFrame; @@ -5201,7 +5200,8 @@ nsIFrame::PeekOffset(nsPeekOffsetStruct* aPos) #ifdef IBMBIDI if (aPos->mVisual && PresContext()->BidiEnabled()) { - PRBool lineIsRTL = it->GetDirection(); + PRBool lineIsRTL; + it->GetDirection(&lineIsRTL); PRBool isReordered; nsIFrame *lastFrame; result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame); @@ -5357,7 +5357,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain nsIFrame *blockFrame = aFrame; nsIFrame *thisBlock; PRInt32 thisLine; - nsAutoLineIterator it; + nsCOMPtr it; nsresult result = NS_ERROR_FAILURE; while (NS_FAILED(result) && blockFrame) { @@ -5378,7 +5378,7 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain if (blockFrame) { if (aLockScroll && blockFrame->GetType() == nsGkAtoms::scrollFrame) return -1; - it = blockFrame->GetLineIterator(); + result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it)); } } if (!blockFrame || !it) @@ -5386,16 +5386,17 @@ nsFrame::GetLineNumber(nsIFrame *aFrame, PRBool aLockScroll, nsIFrame** aContain if (aContainingBlock) *aContainingBlock = blockFrame; - return it->FindLineContaining(thisBlock); + result = it->FindLineContaining(thisBlock, &thisLine); + if (NS_FAILED(result)) + return -1; + return thisLine; } nsresult nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual, PRBool aJumpLines, PRBool aScrollViewStop, nsIFrame** aOutFrame, PRInt32* aOutOffset, PRBool* aOutJumpedLine) -{ - nsresult result; - +{ if (!aOutFrame || !aOutOffset || !aOutJumpedLine) return NS_ERROR_NULL_POINTER; @@ -5409,20 +5410,21 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, PRBool aVisual, nsIFrame *traversedFrame = this; while (!selectable) { nsIFrame *blockFrame; + nsCOMPtr it; PRInt32 thisLine = nsFrame::GetLineNumber(traversedFrame, aScrollViewStop, &blockFrame); if (thisLine < 0) return NS_ERROR_FAILURE; - - nsAutoLineIterator it = blockFrame->GetLineIterator(); - NS_ASSERTION(it, "GetLineNumber() succeeded but no block frame?"); + nsresult result = blockFrame->QueryInterface(NS_GET_IID(nsILineIteratorNavigator),getter_AddRefs(it)); + NS_ASSERTION(NS_SUCCEEDED(result) && it, "GetLineNumber() succeeded but no block frame?"); PRBool atLineEdge; nsIFrame *firstFrame; nsIFrame *lastFrame; #ifdef IBMBIDI if (aVisual && presContext->BidiEnabled()) { - PRBool lineIsRTL = it->GetDirection(); + PRBool lineIsRTL; + it->GetDirection(&lineIsRTL); PRBool isReordered; result = it->CheckLineOrder(thisLine, &isReordered, &firstFrame, &lastFrame); nsIFrame** framePtr = aDirection == eDirPrevious ? &firstFrame : &lastFrame; @@ -6210,7 +6212,7 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState) metrics->mBlockMinSize.height = 0; // ok we need the max ascent of the items on the line. So to do this // ask the block for its line iterator. Get the max ascent. - nsAutoLineIterator lines = GetLineIterator(); + nsCOMPtr lines = do_QueryInterface(static_cast(this)); if (lines) { metrics->mBlockMinSize.height = 0; @@ -6253,12 +6255,6 @@ nsFrame::RefreshSizeCache(nsBoxLayoutState& aState) return rv; } -/* virtual */ nsILineIterator* -nsFrame::GetLineIterator() -{ - return nsnull; -} - nsSize nsFrame::GetPrefSize(nsBoxLayoutState& aState) { diff --git a/layout/generic/nsFrame.h b/layout/generic/nsFrame.h index 334ddd0f1b9a..cf557c570c6c 100644 --- a/layout/generic/nsFrame.h +++ b/layout/generic/nsFrame.h @@ -621,8 +621,6 @@ private: NS_IMETHODIMP RefreshSizeCache(nsBoxLayoutState& aState); - virtual nsILineIterator* GetLineIterator(); - protected: NS_IMETHOD_(nsrefcnt) AddRef(void); NS_IMETHOD_(nsrefcnt) Release(void); diff --git a/layout/generic/nsFrameList.cpp b/layout/generic/nsFrameList.cpp index 4c230850c1fa..9556f30ce52e 100644 --- a/layout/generic/nsFrameList.cpp +++ b/layout/generic/nsFrameList.cpp @@ -427,6 +427,8 @@ nsFrameList::List(FILE* out) const nsIFrame* nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const { + nsCOMPtr iter; + if (!mFirstChild) return nsnull; @@ -437,8 +439,8 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild); nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils(); - nsAutoLineIterator iter = parent->GetLineIterator(); - if (!iter) { + nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter)); + if (NS_FAILED(result) || !iter) { // Parent is not a block Frame if (parent->GetType() == nsGkAtoms::lineFrame) { // Line frames are not bidi-splittable, so need to consider bidi reordering @@ -463,11 +465,11 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const PRInt32 thisLine; if (aFrame) { - thisLine = iter->FindLineContaining(aFrame); - if (thisLine < 0) + result = iter->FindLineContaining(aFrame, &thisLine); + if (NS_FAILED(result) || thisLine < 0) return nsnull; } else { - thisLine = iter->GetNumLines(); + iter->GetNumLines(&thisLine); } nsIFrame* frame = nsnull; @@ -502,6 +504,8 @@ nsFrameList::GetPrevVisualFor(nsIFrame* aFrame) const nsIFrame* nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const { + nsCOMPtr iter; + if (!mFirstChild) return nsnull; @@ -512,8 +516,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const nsBidiLevel baseLevel = nsBidiPresUtils::GetFrameBaseLevel(mFirstChild); nsBidiPresUtils* bidiUtils = mFirstChild->PresContext()->GetBidiUtils(); - nsAutoLineIterator iter = parent->GetLineIterator(); - if (!iter) { + nsresult result = parent->QueryInterface(NS_GET_IID(nsILineIterator), getter_AddRefs(iter)); + if (NS_FAILED(result) || !iter) { // Parent is not a block Frame if (parent->GetType() == nsGkAtoms::lineFrame) { // Line frames are not bidi-splittable, so need to consider bidi reordering @@ -538,8 +542,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const PRInt32 thisLine; if (aFrame) { - thisLine = iter->FindLineContaining(aFrame); - if (thisLine < 0) + result = iter->FindLineContaining(aFrame, &thisLine); + if (NS_FAILED(result) || thisLine < 0) return nsnull; } else { thisLine = -1; @@ -561,7 +565,8 @@ nsFrameList::GetNextVisualFor(nsIFrame* aFrame) const } } - PRInt32 numLines = iter->GetNumLines(); + PRInt32 numLines; + iter->GetNumLines(&numLines); if (!frame && thisLine < numLines - 1) { // Get the first frame of the next line iter->GetLine(thisLine + 1, &firstFrameOnLine, &numFramesOnLine, lineBounds, &lineFlags); diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index feb01085c7b3..8bdf1735c0ef 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -85,7 +85,6 @@ class nsIDOMRange; class nsISelectionController; class nsBoxLayoutState; class nsIBoxLayout; -class nsILineIterator; #ifdef ACCESSIBILITY class nsIAccessible; #endif @@ -2225,14 +2224,6 @@ NS_PTR_TO_INT32(frame->GetProperty(nsGkAtoms::embeddingLevel)) const nsRect& aOldOverflowRect, const nsSize& aNewDesiredSize); - /** - * Get a line iterator for this frame, if supported. - * - * @return nsnull if no line iterator is supported. - * @note dispose the line iterator using nsILineIterator::DisposeLineIterator - */ - virtual nsILineIterator* GetLineIterator() = 0; - protected: // Members nsRect mRect; diff --git a/layout/generic/nsILineIterator.h b/layout/generic/nsILineIterator.h index 54803262141e..391343011fca 100644 --- a/layout/generic/nsILineIterator.h +++ b/layout/generic/nsILineIterator.h @@ -37,11 +37,26 @@ #ifndef nsILineIterator_h___ #define nsILineIterator_h___ -#include "nscore.h" -#include "nsCoord.h" +#include "nsISupports.h" -class nsIFrame; -struct nsRect; +/* a6cf90ff-15b3-11d2-932e-00805f8add32 */ +#define NS_ILINE_ITERATOR_IID \ + { 0xa6cf90ff, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} + +/* {80AA3D7A-E0BF-4e18-8A82-2110397D7BC4}*/ +#define NS_ILINE_ITERATOR_NAV_IID \ + { 0x80aa3d7a, 0xe0bf, 0x4e18,{0x8a, 0x82, 0x21, 0x10, 0x39, 0x7d, 0x7b, 0xc4}} + +// Line iterator API. +// +// Lines are numbered from 0 to N, where 0 is the top line and N is +// the bottom line. +// +// NOTE: while you can get this interface by doing a slezy hacky +// QueryInterface on block frames, it isn't like a normal com +// interface: it's not reflexive (you can't query back to the block +// frame) and unlike other frames, it *IS* reference counted so don't +// forget to NS_RELEASE it when you are done with it! // Line Flags (see GetLine below) @@ -52,36 +67,17 @@ struct nsRect; // This bit is set when the line ends in some sort of break. #define NS_LINE_FLAG_ENDS_IN_BREAK 0x4 -/** - * Line iterator API. - * - * Lines are numbered from 0 to N, where 0 is the top line and N is - * the bottom line. - * - * Obtain this interface from frames via nsIFrame::GetLineIterator. - * When you are finished using the iterator, call DisposeLineIterator() - * to destroy the iterator if appropriate. - */ -class nsILineIterator -{ -protected: - ~nsILineIterator() { } - +class nsILineIterator : public nsISupports { public: - virtual void DisposeLineIterator() = 0; + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_IID) - /** - * The number of lines in the block - */ - virtual PRInt32 GetNumLines() = 0; + // Return the number of lines in the block. + NS_IMETHOD GetNumLines(PRInt32* aResult) = 0; - /** - * The prevailing direction of lines. - * - * @return PR_TRUE if the CSS direction property for the block is - * "rtl", otherwise PR_FALSE - */ - virtual PRBool GetDirection() = 0; + // Return the prevailing direction for the line. aIsRightToLeft will + // be set to PR_TRUE if the CSS direction property for the block is + // "rtl", otherwise aIsRightToLeft will be set to PR_FALSE. + NS_IMETHOD GetDirection(PRBool* aIsRightToLeft) = 0; // Return structural information about a line. aFirstFrameOnLine is // the first frame on the line and aNumFramesOnLine is the number of @@ -102,20 +98,19 @@ public: nsRect& aLineBounds, PRUint32* aLineFlags) = 0; - /** - * Given a frame that's a child of the block, find which line its on - * and return that line index. Returns -1 if the frame cannot be found. - */ - virtual PRInt32 FindLineContaining(nsIFrame* aFrame) = 0; + // Given a frame that's a child of the block, find which line its on + // and return that line index into aIndexResult. aIndexResult will + // be set to -1 if the frame cannot be found. + NS_IMETHOD FindLineContaining(nsIFrame* aFrame, + PRInt32* aLineNumberResult) = 0; - /** - * Given a Y coordinate relative to the block that provided this - * line iterator, return the line that contains the Y - * coordinate. Returns -1 in aLineNumberResult if the Y coordinate - * is above the first line. Returns N (where N is the number of - * lines) if the Y coordinate is below the last line. - */ - virtual PRInt32 FindLineAt(nscoord aY) = 0; + // Given a Y coordinate relative to the block that provided this + // line iterator, find the line that contains the Y + // coordinate. Returns -1 in aLineNumberResult if the Y coordinate + // is above the first line. Returns N (where N is the number of + // lines) if the Y coordinate is below the last line. + NS_IMETHOD FindLineAt(nscoord aY, + PRInt32* aLineNumberResult) = 0; // Given a line number and an X coordinate, find the frame on the // line that is nearest to the X coordinate. The @@ -141,30 +136,15 @@ public: #endif }; -class nsAutoLineIterator -{ +NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIterator, NS_ILINE_ITERATOR_IID) + +//special line iterator for keyboard navigation +class nsILineIteratorNavigator : public nsILineIterator { public: - nsAutoLineIterator() : mRawPtr(nsnull) { } - nsAutoLineIterator(nsILineIterator *i) : mRawPtr(i) { } - - ~nsAutoLineIterator() { - if (mRawPtr) - mRawPtr->DisposeLineIterator(); - } - - operator nsILineIterator*() { return mRawPtr; } - nsILineIterator* operator->() { return mRawPtr; } - - nsILineIterator* operator=(nsILineIterator* i) { - if (mRawPtr) - mRawPtr->DisposeLineIterator(); - - mRawPtr = i; - return i; - } - -private: - nsILineIterator* mRawPtr; + NS_DECLARE_STATIC_IID_ACCESSOR(NS_ILINE_ITERATOR_NAV_IID) }; +NS_DEFINE_STATIC_IID_ACCESSOR(nsILineIteratorNavigator, + NS_ILINE_ITERATOR_NAV_IID) + #endif /* nsILineIterator_h___ */ diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp index 566a50a5b6d0..047598dcf3f2 100644 --- a/layout/generic/nsLineBox.cpp +++ b/layout/generic/nsLineBox.cpp @@ -543,11 +543,7 @@ nsLineIterator::~nsLineIterator() } } -/* virtual */ void -nsLineIterator::DisposeLineIterator() -{ - delete this; -} +NS_IMPL_ISUPPORTS2(nsLineIterator, nsILineIterator, nsILineIteratorNavigator) nsresult nsLineIterator::Init(nsLineList& aLines, PRBool aRightToLeft) @@ -582,16 +578,26 @@ nsLineIterator::Init(nsLineList& aLines, PRBool aRightToLeft) return NS_OK; } -PRInt32 -nsLineIterator::GetNumLines() +NS_IMETHODIMP +nsLineIterator::GetNumLines(PRInt32* aResult) { - return mNumLines; + NS_PRECONDITION(aResult, "null OUT ptr"); + if (!aResult) { + return NS_ERROR_NULL_POINTER; + } + *aResult = mNumLines; + return NS_OK; } -PRBool -nsLineIterator::GetDirection() +NS_IMETHODIMP +nsLineIterator::GetDirection(PRBool* aIsRightToLeft) { - return mRightToLeft; + NS_PRECONDITION(aIsRightToLeft, "null OUT ptr"); + if (!aIsRightToLeft) { + return NS_ERROR_NULL_POINTER; + } + *aIsRightToLeft = mRightToLeft; + return NS_OK; } NS_IMETHODIMP @@ -629,35 +635,42 @@ nsLineIterator::GetLine(PRInt32 aLineNumber, return NS_OK; } -PRInt32 -nsLineIterator::FindLineContaining(nsIFrame* aFrame) +NS_IMETHODIMP +nsLineIterator::FindLineContaining(nsIFrame* aFrame, + PRInt32* aLineNumberResult) { nsLineBox* line = mLines[0]; PRInt32 lineNumber = 0; while (lineNumber != mNumLines) { if (line->Contains(aFrame)) { - return lineNumber; + *aLineNumberResult = lineNumber; + return NS_OK; } line = mLines[++lineNumber]; } - return -1; + *aLineNumberResult = -1; + return NS_OK; } -/* virtual */ PRInt32 -nsLineIterator::FindLineAt(nscoord aY) +NS_IMETHODIMP +nsLineIterator::FindLineAt(nscoord aY, + PRInt32* aLineNumberResult) { nsLineBox* line = mLines[0]; if (!line || (aY < line->mBounds.y)) { - return -1; + *aLineNumberResult = -1; + return NS_OK; } PRInt32 lineNumber = 0; while (lineNumber != mNumLines) { if ((aY >= line->mBounds.y) && (aY < line->mBounds.YMost())) { - return lineNumber; + *aLineNumberResult = lineNumber; + return NS_OK; } line = mLines[++lineNumber]; } - return mNumLines; + *aLineNumberResult = mNumLines; + return NS_OK; } #ifdef IBMBIDI diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h index fb1230b2841c..0ed5fb5c7306 100644 --- a/layout/generic/nsLineBox.h +++ b/layout/generic/nsLineBox.h @@ -1508,23 +1508,24 @@ nsLineList_const_reverse_iterator::operator=(const nsLineList_const_reverse_iter //---------------------------------------------------------------------- -class NS_FINAL_CLASS nsLineIterator : public nsILineIterator -{ +class nsLineIterator : public nsILineIteratorNavigator { public: nsLineIterator(); - ~nsLineIterator(); + virtual ~nsLineIterator(); - virtual void DisposeLineIterator(); + NS_DECL_ISUPPORTS - virtual PRInt32 GetNumLines(); - virtual PRBool GetDirection(); + NS_IMETHOD GetNumLines(PRInt32* aResult); + NS_IMETHOD GetDirection(PRBool* aIsRightToLeft); NS_IMETHOD GetLine(PRInt32 aLineNumber, nsIFrame** aFirstFrameOnLine, PRInt32* aNumFramesOnLine, nsRect& aLineBounds, PRUint32* aLineFlags); - virtual PRInt32 FindLineContaining(nsIFrame* aFrame); - virtual PRInt32 FindLineAt(nscoord aY); + NS_IMETHOD FindLineContaining(nsIFrame* aFrame, + PRInt32* aLineNumberResult); + NS_IMETHOD FindLineAt(nscoord aY, + PRInt32* aLineNumberResult); NS_IMETHOD FindFrameAt(PRInt32 aLineNumber, nscoord aX, nsIFrame** aFrameFound, @@ -1540,7 +1541,15 @@ public: #endif nsresult Init(nsLineList& aLines, PRBool aRightToLeft); -private: +protected: + PRInt32 NumLines() const { + return mNumLines; + } + + nsLineBox* CurrentLine() { + return mLines[mIndex]; + } + nsLineBox* PrevLine() { if (0 == mIndex) { return nsnull; diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp index 2108a6373153..69f9abd9b206 100644 --- a/layout/tables/nsTableRowGroupFrame.cpp +++ b/layout/tables/nsTableRowGroupFrame.cpp @@ -64,6 +64,17 @@ nsTableRowGroupFrame::~nsTableRowGroupFrame() { } +/* ----------- nsTableRowGroupFrame ---------- */ +nsrefcnt nsTableRowGroupFrame::AddRef(void) +{ + return 1;//implementation of nsLineIterator +} + +nsrefcnt nsTableRowGroupFrame::Release(void) +{ + return 1;//implementation of nsLineIterator +} + NS_IMETHODIMP nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) { @@ -74,6 +85,14 @@ nsTableRowGroupFrame::QueryInterface(const nsIID& aIID, void** aInstancePtr) *aInstancePtr = (void*)this; return NS_OK; } + if (aIID.Equals(NS_GET_IID(nsILineIteratorNavigator))) { + *aInstancePtr = static_cast(this); + return NS_OK; + } + if (aIID.Equals(NS_GET_IID(nsILineIterator))) { + *aInstancePtr = static_cast(this); + return NS_OK; + } return nsHTMLContainerFrame::QueryInterface(aIID, aInstancePtr); } @@ -1634,18 +1653,23 @@ void nsTableRowGroupFrame::SetContinuousBCBorderWidth(PRUint8 aForSide, } //nsILineIterator methods -PRInt32 -nsTableRowGroupFrame::GetNumLines() +NS_IMETHODIMP +nsTableRowGroupFrame::GetNumLines(PRInt32* aResult) { - return GetRowCount(); + NS_ENSURE_ARG_POINTER(aResult); + *aResult = GetRowCount(); + return NS_OK; } -PRBool -nsTableRowGroupFrame::GetDirection() +NS_IMETHODIMP +nsTableRowGroupFrame::GetDirection(PRBool* aIsRightToLeft) { + NS_ENSURE_ARG_POINTER(aIsRightToLeft); + // rtl is table wide @see nsTableIterator nsTableFrame* table = nsTableFrame::GetTableFrame(this); - return (NS_STYLE_DIRECTION_RTL == - table->GetStyleVisibility()->mDirection); + *aIsRightToLeft = (NS_STYLE_DIRECTION_RTL == + table->GetStyleVisibility()->mDirection); + return NS_OK; } NS_IMETHODIMP @@ -1690,25 +1714,28 @@ nsTableRowGroupFrame::GetLine(PRInt32 aLineNumber, return NS_ERROR_FAILURE; } -PRInt32 -nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame) +NS_IMETHODIMP +nsTableRowGroupFrame::FindLineContaining(nsIFrame* aFrame, + PRInt32* aLineNumberResult) { NS_ENSURE_ARG_POINTER(aFrame); + NS_ENSURE_ARG_POINTER(aLineNumberResult); NS_ASSERTION((aFrame->GetType() == nsGkAtoms::tableRowFrame), "RowGroup contains a frame that is not a row"); nsTableRowFrame* rowFrame = (nsTableRowFrame*)aFrame; - return rowFrame->GetRowIndex() - GetStartRowIndex(); + *aLineNumberResult = rowFrame->GetRowIndex() - GetStartRowIndex(); + + return NS_OK; } -PRInt32 -nsTableRowGroupFrame::FindLineAt(nscoord aY) +NS_IMETHODIMP +nsTableRowGroupFrame::FindLineAt(nscoord aY, + PRInt32* aLineNumberResult) { - NS_NOTREACHED("Not implemented"); return NS_ERROR_NOT_IMPLEMENTED; } - #ifdef IBMBIDI NS_IMETHODIMP nsTableRowGroupFrame::CheckLineOrder(PRInt32 aLine, diff --git a/layout/tables/nsTableRowGroupFrame.h b/layout/tables/nsTableRowGroupFrame.h index 5319bf2e11a0..b35298814970 100644 --- a/layout/tables/nsTableRowGroupFrame.h +++ b/layout/tables/nsTableRowGroupFrame.h @@ -96,12 +96,11 @@ struct nsRowGroupReflowState { * @see nsTableFrame * @see nsTableRowFrame */ -class nsTableRowGroupFrame - : public nsHTMLContainerFrame - , public nsILineIterator +class nsTableRowGroupFrame : public nsHTMLContainerFrame, public nsILineIteratorNavigator { public: - NS_IMETHOD QueryInterface(const nsIID &aIID, void **aInstancePtr); + // nsISupports + NS_DECL_ISUPPORTS_INHERITED /** instantiate a new instance of nsTableRowFrame. * @param aPresShell the pres shell for this frame @@ -228,8 +227,6 @@ public: // nsILineIterator methods public: - virtual void DisposeLineIterator() { } - // The table row is the equivalent to a line in block layout. // The nsILineIterator assumes that a line resides in a block, this role is // fullfilled by the row group. Rows in table are counted relative to the @@ -238,14 +235,14 @@ public: // row index of the first row in the row group. /** Get the number of rows in a row group - * @return the number of lines in a row group + * @param aResult - pointer that holds the number of lines in a row group */ - virtual PRInt32 GetNumLines(); + NS_IMETHOD GetNumLines(PRInt32* aResult); /** @see nsILineIterator.h GetDirection - * @return true if the table is rtl + * @param aIsRightToLeft - true if the table is rtl */ - virtual PRBool GetDirection(); + NS_IMETHOD GetDirection(PRBool* aIsRightToLeft); /** Return structural information about a line. * @param aLineNumber - the index of the row relative to the row group @@ -267,15 +264,16 @@ public: /** Given a frame that's a child of the rowgroup, find which line its on. * @param aFrame - frame, should be a row - * @return row index relative to the row group if this a row - * frame. -1 if the frame cannot be found. + * @param aIndexResult - row index relative to the row group if this a row + * frame. aIndexResult will be set to -1 if the frame + * cannot be found. */ - virtual PRInt32 FindLineContaining(nsIFrame* aFrame); + NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult); /** not implemented * the function is also not called in our tree */ - virtual PRInt32 FindLineAt(nscoord aY); + NS_IMETHOD FindLineAt(nscoord aY, PRInt32* aLineNumberResult); /** Find the orginating cell frame on a row that is the nearest to the * coordinate X. @@ -375,8 +373,6 @@ public: GetStyleDisplay()->mOverflowY == NS_STYLE_OVERFLOW_CLIP; } - virtual nsILineIterator* GetLineIterator() { return this; } - protected: nsTableRowGroupFrame(nsStyleContext* aContext);