From cfd8498ab180d6f1f4668e6bb6e2a822c4bd04f9 Mon Sep 17 00:00:00 2001 From: "kipp%netscape.com" Date: Tue, 12 Oct 1999 23:24:22 +0000 Subject: [PATCH] r=troy; Cleaned up line-box API (prep work for bug #12297; more coming); Support new line iterator API change (#16176) --- layout/generic/nsBlockFrame.cpp | 95 ++++++--------- layout/generic/nsBlockFrame.h | 2 +- layout/generic/nsBlockReflowState.cpp | 95 ++++++--------- layout/generic/nsBlockReflowState.h | 95 ++++++--------- layout/generic/nsLineBox.cpp | 48 ++++++-- layout/generic/nsLineBox.h | 127 +++++++++----------- layout/html/base/src/nsBlockFrame.cpp | 95 ++++++--------- layout/html/base/src/nsBlockFrame.h | 2 +- layout/html/base/src/nsBlockReflowState.cpp | 95 ++++++--------- layout/html/base/src/nsBlockReflowState.h | 95 ++++++--------- layout/html/base/src/nsLineBox.cpp | 48 ++++++-- layout/html/base/src/nsLineBox.h | 127 +++++++++----------- 12 files changed, 422 insertions(+), 502 deletions(-) diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index c6d94808cff..d6ba57bc076 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 12c283ebf0c..a09efc907e1 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -344,7 +344,7 @@ protected: PRBool FrameStartsCounterScope(nsIFrame* aFrame); - void UpdateBulletPosition(); + nsresult UpdateBulletPosition(); void ReflowBullet(nsBlockReflowState& aState, nsHTMLReflowMetrics& aMetrics); diff --git a/layout/generic/nsBlockReflowState.cpp b/layout/generic/nsBlockReflowState.cpp index c6d94808cff..d6ba57bc076 100644 --- a/layout/generic/nsBlockReflowState.cpp +++ b/layout/generic/nsBlockReflowState.cpp @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/generic/nsBlockReflowState.h b/layout/generic/nsBlockReflowState.h index c6d94808cff..d6ba57bc076 100644 --- a/layout/generic/nsBlockReflowState.h +++ b/layout/generic/nsBlockReflowState.h @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/generic/nsLineBox.cpp b/layout/generic/nsLineBox.cpp index b6521a3045c..876a63f1de1 100644 --- a/layout/generic/nsLineBox.cpp +++ b/layout/generic/nsLineBox.cpp @@ -29,18 +29,20 @@ MOZ_DECL_CTOR_COUNTER(nsLineBox); -nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags) +nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock) { MOZ_COUNT_CTOR(nsLineBox); mFirstChild = aFrame; mChildCount = aCount; - mState = LINE_IS_DIRTY | flags; + mAllFlags = 0; + MarkDirty(); + SetIsBlock(aIsBlock); mNext = nsnull; mBounds.SetRect(0,0,0,0); mCombinedArea.SetRect(0,0,0,0); //XXX mCarriedOutTopMargin = 0; mCarriedOutBottomMargin = 0; - mBreakType = NS_STYLE_CLEAR_NONE; + mFlags.mBreakType = NS_STYLE_CLEAR_NONE; mMaxElementWidth = 0; } @@ -81,9 +83,9 @@ char* nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const { PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]", - (mState & LINE_IS_DIRTY) ? "dirty" : "clean", - (mState & LINE_IS_BLOCK) ? "block" : "inline", - mState); + IsDirty() ? "dirty" : "clean", + IsBlock() ? "block" : "inline", + mAllFlags); return aBuf; } @@ -216,12 +218,18 @@ nsLineBox::CheckIsBlock() const #endif #ifdef DEBUG -void +PRBool nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { NS_PRECONDITION(aResult, "null OUT parameter pointer"); *aResult = sizeof(*this); + PRBool big = PR_TRUE; + if ((IsBlock() || mFloaters.IsEmpty()) && + (mBounds == mCombinedArea)) { + big = PR_FALSE; + } + // Add in the size needed for floaters associated with this line if (mFloaters.NotEmpty()) { PRUint32 floatersSize; @@ -231,6 +239,8 @@ nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const floatersSize -= sizeof(mFloaters); aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize); } + + return big; } #endif @@ -321,12 +331,13 @@ NS_IMETHODIMP nsLineIterator::GetLine(PRInt32 aLineNumber, nsIFrame** aFirstFrameOnLine, PRInt32* aNumFramesOnLine, - nsRect& aLineBounds) + nsRect& aLineBounds, + PRUint32* aLineFlags) { - NS_PRECONDITION(aFirstFrameOnLine && aNumFramesOnLine, "null OUT ptr"); - if (!aFirstFrameOnLine || !aNumFramesOnLine) { - return NS_ERROR_NULL_POINTER; - } + NS_ENSURE_ARG_POINTER(aFirstFrameOnLine); + NS_ENSURE_ARG_POINTER(aNumFramesOnLine); + NS_ENSURE_ARG_POINTER(aLineFlags); + if ((aLineNumber < 0) || (aLineNumber >= mNumLines)) { *aFirstFrameOnLine = nsnull; *aNumFramesOnLine = 0; @@ -337,6 +348,19 @@ nsLineIterator::GetLine(PRInt32 aLineNumber, *aFirstFrameOnLine = line->mFirstChild; *aNumFramesOnLine = line->mChildCount; aLineBounds = line->mBounds; + + PRUint32 flags = 0; + if (line->IsBlock()) { + flags |= NS_LINE_FLAG_IS_BLOCK; + } + else { + if (line->IsTrimmed()) + flags |= NS_LINE_FLAG_IS_TRIMMED; + if (line->HasBreak()) + flags |= NS_LINE_FLAG_ENDS_IN_BREAK; + } + *aLineFlags = flags; + return NS_OK; } diff --git a/layout/generic/nsLineBox.h b/layout/generic/nsLineBox.h index 027704cdee4..9d76dec19c2 100644 --- a/layout/generic/nsLineBox.h +++ b/layout/generic/nsLineBox.h @@ -24,15 +24,6 @@ #include "nsILineIterator.h" #include "nsISizeOfHandler.h" -// bits in nsLineBox.mState -#define LINE_IS_DIRTY 0x1 -#define LINE_IS_BLOCK 0x2 -#define LINE_IS_IMPACTED_BY_FLOATER 0x4 -#ifdef BLOCK_DOES_FIRST_LINE -#define LINE_IS_FIRST_LINE 0x8 -#endif -#define LINE_WAS_DIRTY 0x10 - class nsISpaceManager; class nsLineBox; @@ -151,6 +142,37 @@ protected: */ class nsLineBox { public: + nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock); + ~nsLineBox(); + + PRBool IsBlock() const { + return mFlags.mBlock; + } + + PRBool IsInline() const { + return 0 == mFlags.mBlock; + } + + // XXX Turn into a bit-field to simplify this code + void SetTrimmed(PRBool aOn) { + mFlags.mTrimmed = aOn; + } + + PRBool IsTrimmed() const { + return mFlags.mTrimmed; + } + + PRBool HasBreak() const { + return NS_STYLE_CLEAR_NONE != mFlags.mBreakType; + } + + void SetBreakType(PRUint8 aBreakType) { + mFlags.mBreakType = aBreakType; + } + + PRUint8 GetBreakType() const { + return mFlags.mBreakType; + } nscoord GetCarriedOutBottomMargin() const { return mCarriedOutBottomMargin; @@ -160,9 +182,7 @@ public: //---------------------------------------------------------------------- // XXX old junk - nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags); - ~nsLineBox(); static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine); @@ -181,77 +201,28 @@ public: PRBool IsLastChild(nsIFrame* aFrame) const; - PRBool IsBlock() const { - return 0 != (LINE_IS_BLOCK & mState); - } - - void SetIsBlock() { - mState |= LINE_IS_BLOCK; - } - - void ClearIsBlock() { - mState &= ~LINE_IS_BLOCK; - } - void SetIsBlock(PRBool aValue) { - if (aValue) { - SetIsBlock(); - } - else { - ClearIsBlock(); - } + mFlags.mBlock = aValue; } void SetLineIsImpactedByFloater(PRBool aValue) { - if (aValue) { - mState |= LINE_IS_IMPACTED_BY_FLOATER; - } - else { - mState &= ~LINE_IS_IMPACTED_BY_FLOATER; - } + mFlags.mImpactedByFloater = aValue; } PRBool IsImpactedByFloater() const { - return 0 != (LINE_IS_IMPACTED_BY_FLOATER & mState); + return mFlags.mImpactedByFloater; } -#ifdef BLOCK_DOES_FIRST_LINE - PRBool IsFirstLine() const { - return 0 != (LINE_IS_FIRST_LINE & mState); - } - - void SetIsFirstLine(PRBool aValue) { - if (aValue) { - mState |= LINE_IS_FIRST_LINE; - } - else { - mState &= ~LINE_IS_FIRST_LINE; - } - } -#endif - void MarkDirty() { - mState |= LINE_IS_DIRTY; + mFlags.mDirty = 1; } void ClearDirty() { - mState &= ~LINE_IS_DIRTY; + mFlags.mDirty = 0; } PRBool IsDirty() const { - return 0 != (LINE_IS_DIRTY & mState); - } - - void ClearWasDirty() { - mState &= ~LINE_WAS_DIRTY; - } - - void MarkWasDirty() { - mState |= LINE_WAS_DIRTY; - } - - PRBool WasDirty() const { - return 0 != (LINE_WAS_DIRTY & mState); + return mFlags.mDirty; } char* StateToString(char* aBuf, PRInt32 aBufSize) const; @@ -267,19 +238,34 @@ public: #endif #ifdef DEBUG - void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; + PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; #endif nsIFrame* mFirstChild; PRUint16 mChildCount; - PRUint8 mState; - PRUint8 mBreakType; nsRect mBounds; nsRect mCombinedArea; nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */ nsFloaterCacheList mFloaters; nsLineBox* mNext; nscoord mMaxElementWidth; // width part of max-element-size + + struct FlagBits { + PRUint32 mDirty : 1; + PRUint32 mBlock : 1; + PRUint32 mImpactedByFloater : 1; + PRUint32 mTrimmed : 1; + + PRUint32 reserved : 20; + + PRUint32 mBreakType : 8; + }; + +protected: + union { + PRUint32 mAllFlags; + FlagBits mFlags; + }; }; //---------------------------------------------------------------------- @@ -296,7 +282,8 @@ public: NS_IMETHOD GetLine(PRInt32 aLineNumber, nsIFrame** aFirstFrameOnLine, PRInt32* aNumFramesOnLine, - nsRect& aLineBounds); + nsRect& aLineBounds, + PRUint32* aLineFlags); NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult); NS_IMETHOD FindLineAt(nscoord aY, diff --git a/layout/html/base/src/nsBlockFrame.cpp b/layout/html/base/src/nsBlockFrame.cpp index c6d94808cff..d6ba57bc076 100644 --- a/layout/html/base/src/nsBlockFrame.cpp +++ b/layout/html/base/src/nsBlockFrame.cpp @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/html/base/src/nsBlockFrame.h b/layout/html/base/src/nsBlockFrame.h index 12c283ebf0c..a09efc907e1 100644 --- a/layout/html/base/src/nsBlockFrame.h +++ b/layout/html/base/src/nsBlockFrame.h @@ -344,7 +344,7 @@ protected: PRBool FrameStartsCounterScope(nsIFrame* aFrame); - void UpdateBulletPosition(); + nsresult UpdateBulletPosition(); void ReflowBullet(nsBlockReflowState& aState, nsHTMLReflowMetrics& aMetrics); diff --git a/layout/html/base/src/nsBlockReflowState.cpp b/layout/html/base/src/nsBlockReflowState.cpp index c6d94808cff..d6ba57bc076 100644 --- a/layout/html/base/src/nsBlockReflowState.cpp +++ b/layout/html/base/src/nsBlockReflowState.cpp @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/html/base/src/nsBlockReflowState.h b/layout/html/base/src/nsBlockReflowState.h index c6d94808cff..d6ba57bc076 100644 --- a/layout/html/base/src/nsBlockReflowState.h +++ b/layout/html/base/src/nsBlockReflowState.h @@ -90,10 +90,6 @@ // Debugging support code -#ifdef DEBUG -static PRBool gShowDirtyLines = PR_FALSE; -#endif - #ifdef NOISY_INCREMENTAL_REFLOW static PRInt32 gNoiseIndent; static const char* kReflowCommandType[] = { @@ -816,9 +812,9 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // The line may have clear before semantics. - if (aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { + if (aLine->IsBlock() && aLine->HasBreak()) { // Clear past floaters before the block if the clear style is not none - aApplyTopMargin = ClearPastFloaters(aLine->mBreakType); + aApplyTopMargin = ClearPastFloaters(aLine->GetBreakType()); #ifdef NOISY_VERTICAL_MARGINS nsFrame::ListTag(stdout, mBlock); printf(": RecoverStateFrom: y=%d child ", mY); @@ -924,12 +920,13 @@ nsBlockReflowState::RecoverStateFrom(nsLineBox* aLine, } // It's possible that the line has clear after semantics - if (!aLine->IsBlock() && (NS_STYLE_CLEAR_NONE != aLine->mBreakType)) { - switch (aLine->mBreakType) { + if (!aLine->IsBlock() && aLine->HasBreak()) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - ClearFloaters(mY, aLine->mBreakType); + ClearFloaters(mY, breakType); break; } } @@ -1437,16 +1434,6 @@ nsBlockFrame::Reflow(nsIPresContext& aPresContext, } } -#ifdef DEBUG - if (gShowDirtyLines && (eReflowReason_Resize == aReflowState.reason)) { - nsLineBox* line = mLines; - while (nsnull != line) { - line->ClearWasDirty(); - line = line->mNext; - } - } -#endif - #ifdef NOISY_FINAL_SIZE ListTag(stdout); printf(": availSize=%d,%d computed=%d,%d metrics=%d,%d carriedMargin=%d\n", @@ -1854,12 +1841,12 @@ nsBlockFrame::PrepareChildIncrementalReflow(nsBlockReflowState& aState) return NS_OK; } -void +nsresult nsBlockFrame::UpdateBulletPosition() { if (nsnull == mBullet) { // Don't bother if there is no bullet - return; + return NS_OK; } const nsStyleList* styleList; GetStyleData(eStyleStruct_List, (const nsStyleStruct*&) styleList); @@ -1906,12 +1893,13 @@ nsBlockFrame::UpdateBulletPosition() #ifdef DEBUG VerifyLines(PR_TRUE); #endif + return NS_OK; } nsresult nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) { - UpdateBulletPosition(); + nsresult rv = UpdateBulletPosition(); // Mark everything dirty nsLineBox* line = mLines; @@ -1919,7 +1907,7 @@ nsBlockFrame::PrepareStyleChangedReflow(nsBlockReflowState& aState) line->MarkDirty(); line = line->mNext; } - return NS_OK; + return rv; } nsresult @@ -1956,7 +1944,7 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState) // - there are no floaters associated with the line (reflowing the // placeholder frame causes the floater to be reflowed) if (line->IsBlock() || - (!aState.mNoWrap && line->mNext && (line->mBreakType == NS_STYLE_CLEAR_NONE)) || + (!aState.mNoWrap && line->mNext && !line->HasBreak()) || line->mFloaters.NotEmpty() || (line->mBounds.XMost() > newAvailWidth)) { @@ -2331,10 +2319,6 @@ nsBlockFrame::ReflowLine(nsBlockReflowState& aState, { nsresult rv = NS_OK; -#ifdef DEBUG - aLine->MarkWasDirty(); -#endif - // If the line is empty then first pull a frame into it so that we // know what kind of line it is (block or inline). if (0 == aLine->ChildCount()) { @@ -2913,9 +2897,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, } // Clear past floaters before the block if the clear style is not none - aLine->mBreakType = display->mBreakType; - if (NS_STYLE_CLEAR_NONE != aLine->mBreakType) { - PRBool alsoApplyTopMargin = aState.ClearPastFloaters(aLine->mBreakType); + PRUint8 breakType = display->mBreakType; + aLine->SetBreakType(breakType); + if (NS_STYLE_CLEAR_NONE != breakType) { + PRBool alsoApplyTopMargin = aState.ClearPastFloaters(breakType); if (alsoApplyTopMargin) { applyTopMargin = PR_TRUE; } @@ -2987,7 +2972,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState, // made one. if (madeContinuation) { frame->GetNextSibling(&frame); - nsLineBox* line = new nsLineBox(frame, 1, LINE_IS_BLOCK); + nsLineBox* line = new nsLineBox(frame, 1, PR_TRUE); if (nsnull == line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3388,7 +3373,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, // break-after-not-complete. There are two situations: we are a // block or we are an inline. This makes a total of 10 cases // (fortunately, there is some overlap). - aLine->mBreakType = NS_STYLE_CLEAR_NONE; + aLine->SetBreakType(NS_STYLE_CLEAR_NONE); if (NS_INLINE_IS_BREAK(frameReflowStatus)) { // Always abort the line reflow (because a line break is the // minimal amount of break we do). @@ -3419,7 +3404,7 @@ nsBlockFrame::ReflowInlineFrame(nsBlockReflowState& aState, } else { // Break-after cases - aLine->mBreakType = breakType; + aLine->SetBreakType(breakType); if (NS_FRAME_IS_NOT_COMPLETE(frameReflowStatus)) { // Create a continuation for the incomplete frame. Note that the // frame may already have a continuation. @@ -3548,7 +3533,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, // as it's continuation. This causes all sorts of bad side // effects so we don't allow it. if (0 != to->ChildCount()) { - nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, 0); + nsLineBox* insertedLine = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == insertedLine) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3561,7 +3546,7 @@ nsBlockFrame::SplitLine(nsBlockReflowState& aState, to->MarkDirty(); } } else { - to = new nsLineBox(aFrame, pushCount, 0); + to = new nsLineBox(aFrame, pushCount, PR_FALSE); if (nsnull == to) { return NS_ERROR_OUT_OF_MEMORY; } @@ -3629,7 +3614,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, nsresult rv = NS_OK; // Trim extra white-space from the line before placing the frames - aLineLayout.TrimTrailingWhiteSpace(); + PRBool trimmed = aLineLayout.TrimTrailingWhiteSpace(); + aLine->SetTrimmed(trimmed); // Vertically align the frames on this line. // @@ -3783,11 +3769,12 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState, } // Apply break-after clearing if necessary - switch (aLine->mBreakType) { + PRUint8 breakType = aLine->GetBreakType(); + switch (breakType) { case NS_STYLE_CLEAR_LEFT: case NS_STYLE_CLEAR_RIGHT: case NS_STYLE_CLEAR_LEFT_AND_RIGHT: - aState.ClearFloaters(aState.mY, aLine->mBreakType); + aState.ClearFloaters(aState.mY, breakType); break; } @@ -4242,7 +4229,7 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, PRInt32 rem = prevSibLine->mChildCount - prevSiblingIndex - 1; if (rem) { // Split the line in two where the frame(s) are being inserted. - nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, 0); + nsLineBox* line = new nsLineBox(prevSiblingNextFrame, rem, PR_FALSE); if (!line) { return NS_ERROR_OUT_OF_MEMORY; } @@ -4263,9 +4250,8 @@ nsBlockFrame::AddFrames(nsIPresContext* aPresContext, // structures to fit. nsIFrame* newFrame = aFrameList; while (newFrame) { - PRUint32 isBlock = nsLineLayout::TreatFrameAsBlock(newFrame) - ? LINE_IS_BLOCK - : 0; + PRBool isBlock = nsLineLayout::TreatFrameAsBlock(newFrame); + // If the frame is a block frame, or if there is no previous line // or if the previous line is a block line then make a new line. if (isBlock || !prevSibLine || prevSibLine->IsBlock()) { @@ -5459,14 +5445,6 @@ nsBlockFrame::PaintChildren(nsIPresContext& aPresContext, aWhichLayer); kid->GetNextSibling(&kid); } -#ifdef DEBUG - if (gShowDirtyLines) { - if (line->WasDirty()) { - aRenderingContext.SetColor(NS_RGB(128, 255, 128)); - aRenderingContext.DrawRect(line->mBounds); - } - } -#endif } #ifdef NOISY_DAMAGE_REPAIR else { @@ -5547,7 +5525,8 @@ nsBlockFrame::HandleEvent(nsIPresContext& aPresContext, //incase we hit another block frame. for (i = 0; i< countLines;i++) { - result = it->GetLine(i, &firstFrame, &lineFrameCount,rect); + PRUint32 flags; + result = it->GetLine(i, &firstFrame, &lineFrameCount,rect,&flags); if (NS_FAILED(result)) continue;//do not handle rect+=origin; @@ -5702,15 +5681,19 @@ nsBlockFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const nsLineBox* line = mLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } line = mOverflowLines; while (line) { PRUint32 lineBoxSize; - line->SizeOf(aHandler, &lineBoxSize); - aHandler->AddSize(nsLayoutAtoms::lineBox, lineBoxSize); + PRBool big = line->SizeOf(aHandler, &lineBoxSize); + aHandler->AddSize((big + ? nsLayoutAtoms::lineBoxBig + : nsLayoutAtoms::lineBoxSmall), lineBoxSize); line = line->mNext; } diff --git a/layout/html/base/src/nsLineBox.cpp b/layout/html/base/src/nsLineBox.cpp index b6521a3045c..876a63f1de1 100644 --- a/layout/html/base/src/nsLineBox.cpp +++ b/layout/html/base/src/nsLineBox.cpp @@ -29,18 +29,20 @@ MOZ_DECL_CTOR_COUNTER(nsLineBox); -nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags) +nsLineBox::nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock) { MOZ_COUNT_CTOR(nsLineBox); mFirstChild = aFrame; mChildCount = aCount; - mState = LINE_IS_DIRTY | flags; + mAllFlags = 0; + MarkDirty(); + SetIsBlock(aIsBlock); mNext = nsnull; mBounds.SetRect(0,0,0,0); mCombinedArea.SetRect(0,0,0,0); //XXX mCarriedOutTopMargin = 0; mCarriedOutBottomMargin = 0; - mBreakType = NS_STYLE_CLEAR_NONE; + mFlags.mBreakType = NS_STYLE_CLEAR_NONE; mMaxElementWidth = 0; } @@ -81,9 +83,9 @@ char* nsLineBox::StateToString(char* aBuf, PRInt32 aBufSize) const { PR_snprintf(aBuf, aBufSize, "%s,%s[0x%x]", - (mState & LINE_IS_DIRTY) ? "dirty" : "clean", - (mState & LINE_IS_BLOCK) ? "block" : "inline", - mState); + IsDirty() ? "dirty" : "clean", + IsBlock() ? "block" : "inline", + mAllFlags); return aBuf; } @@ -216,12 +218,18 @@ nsLineBox::CheckIsBlock() const #endif #ifdef DEBUG -void +PRBool nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const { NS_PRECONDITION(aResult, "null OUT parameter pointer"); *aResult = sizeof(*this); + PRBool big = PR_TRUE; + if ((IsBlock() || mFloaters.IsEmpty()) && + (mBounds == mCombinedArea)) { + big = PR_FALSE; + } + // Add in the size needed for floaters associated with this line if (mFloaters.NotEmpty()) { PRUint32 floatersSize; @@ -231,6 +239,8 @@ nsLineBox::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const floatersSize -= sizeof(mFloaters); aHandler->AddSize(nsLayoutAtoms::lineBoxFloaters, floatersSize); } + + return big; } #endif @@ -321,12 +331,13 @@ NS_IMETHODIMP nsLineIterator::GetLine(PRInt32 aLineNumber, nsIFrame** aFirstFrameOnLine, PRInt32* aNumFramesOnLine, - nsRect& aLineBounds) + nsRect& aLineBounds, + PRUint32* aLineFlags) { - NS_PRECONDITION(aFirstFrameOnLine && aNumFramesOnLine, "null OUT ptr"); - if (!aFirstFrameOnLine || !aNumFramesOnLine) { - return NS_ERROR_NULL_POINTER; - } + NS_ENSURE_ARG_POINTER(aFirstFrameOnLine); + NS_ENSURE_ARG_POINTER(aNumFramesOnLine); + NS_ENSURE_ARG_POINTER(aLineFlags); + if ((aLineNumber < 0) || (aLineNumber >= mNumLines)) { *aFirstFrameOnLine = nsnull; *aNumFramesOnLine = 0; @@ -337,6 +348,19 @@ nsLineIterator::GetLine(PRInt32 aLineNumber, *aFirstFrameOnLine = line->mFirstChild; *aNumFramesOnLine = line->mChildCount; aLineBounds = line->mBounds; + + PRUint32 flags = 0; + if (line->IsBlock()) { + flags |= NS_LINE_FLAG_IS_BLOCK; + } + else { + if (line->IsTrimmed()) + flags |= NS_LINE_FLAG_IS_TRIMMED; + if (line->HasBreak()) + flags |= NS_LINE_FLAG_ENDS_IN_BREAK; + } + *aLineFlags = flags; + return NS_OK; } diff --git a/layout/html/base/src/nsLineBox.h b/layout/html/base/src/nsLineBox.h index 027704cdee4..9d76dec19c2 100644 --- a/layout/html/base/src/nsLineBox.h +++ b/layout/html/base/src/nsLineBox.h @@ -24,15 +24,6 @@ #include "nsILineIterator.h" #include "nsISizeOfHandler.h" -// bits in nsLineBox.mState -#define LINE_IS_DIRTY 0x1 -#define LINE_IS_BLOCK 0x2 -#define LINE_IS_IMPACTED_BY_FLOATER 0x4 -#ifdef BLOCK_DOES_FIRST_LINE -#define LINE_IS_FIRST_LINE 0x8 -#endif -#define LINE_WAS_DIRTY 0x10 - class nsISpaceManager; class nsLineBox; @@ -151,6 +142,37 @@ protected: */ class nsLineBox { public: + nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRBool aIsBlock); + ~nsLineBox(); + + PRBool IsBlock() const { + return mFlags.mBlock; + } + + PRBool IsInline() const { + return 0 == mFlags.mBlock; + } + + // XXX Turn into a bit-field to simplify this code + void SetTrimmed(PRBool aOn) { + mFlags.mTrimmed = aOn; + } + + PRBool IsTrimmed() const { + return mFlags.mTrimmed; + } + + PRBool HasBreak() const { + return NS_STYLE_CLEAR_NONE != mFlags.mBreakType; + } + + void SetBreakType(PRUint8 aBreakType) { + mFlags.mBreakType = aBreakType; + } + + PRUint8 GetBreakType() const { + return mFlags.mBreakType; + } nscoord GetCarriedOutBottomMargin() const { return mCarriedOutBottomMargin; @@ -160,9 +182,7 @@ public: //---------------------------------------------------------------------- // XXX old junk - nsLineBox(nsIFrame* aFrame, PRInt32 aCount, PRUint16 flags); - ~nsLineBox(); static void DeleteLineList(nsIPresContext& aPresContext, nsLineBox* aLine); @@ -181,77 +201,28 @@ public: PRBool IsLastChild(nsIFrame* aFrame) const; - PRBool IsBlock() const { - return 0 != (LINE_IS_BLOCK & mState); - } - - void SetIsBlock() { - mState |= LINE_IS_BLOCK; - } - - void ClearIsBlock() { - mState &= ~LINE_IS_BLOCK; - } - void SetIsBlock(PRBool aValue) { - if (aValue) { - SetIsBlock(); - } - else { - ClearIsBlock(); - } + mFlags.mBlock = aValue; } void SetLineIsImpactedByFloater(PRBool aValue) { - if (aValue) { - mState |= LINE_IS_IMPACTED_BY_FLOATER; - } - else { - mState &= ~LINE_IS_IMPACTED_BY_FLOATER; - } + mFlags.mImpactedByFloater = aValue; } PRBool IsImpactedByFloater() const { - return 0 != (LINE_IS_IMPACTED_BY_FLOATER & mState); + return mFlags.mImpactedByFloater; } -#ifdef BLOCK_DOES_FIRST_LINE - PRBool IsFirstLine() const { - return 0 != (LINE_IS_FIRST_LINE & mState); - } - - void SetIsFirstLine(PRBool aValue) { - if (aValue) { - mState |= LINE_IS_FIRST_LINE; - } - else { - mState &= ~LINE_IS_FIRST_LINE; - } - } -#endif - void MarkDirty() { - mState |= LINE_IS_DIRTY; + mFlags.mDirty = 1; } void ClearDirty() { - mState &= ~LINE_IS_DIRTY; + mFlags.mDirty = 0; } PRBool IsDirty() const { - return 0 != (LINE_IS_DIRTY & mState); - } - - void ClearWasDirty() { - mState &= ~LINE_WAS_DIRTY; - } - - void MarkWasDirty() { - mState |= LINE_WAS_DIRTY; - } - - PRBool WasDirty() const { - return 0 != (LINE_WAS_DIRTY & mState); + return mFlags.mDirty; } char* StateToString(char* aBuf, PRInt32 aBufSize) const; @@ -267,19 +238,34 @@ public: #endif #ifdef DEBUG - void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; + PRBool SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const; #endif nsIFrame* mFirstChild; PRUint16 mChildCount; - PRUint8 mState; - PRUint8 mBreakType; nsRect mBounds; nsRect mCombinedArea; nscoord mCarriedOutBottomMargin;/* XXX switch to 16 bits */ nsFloaterCacheList mFloaters; nsLineBox* mNext; nscoord mMaxElementWidth; // width part of max-element-size + + struct FlagBits { + PRUint32 mDirty : 1; + PRUint32 mBlock : 1; + PRUint32 mImpactedByFloater : 1; + PRUint32 mTrimmed : 1; + + PRUint32 reserved : 20; + + PRUint32 mBreakType : 8; + }; + +protected: + union { + PRUint32 mAllFlags; + FlagBits mFlags; + }; }; //---------------------------------------------------------------------- @@ -296,7 +282,8 @@ public: NS_IMETHOD GetLine(PRInt32 aLineNumber, nsIFrame** aFirstFrameOnLine, PRInt32* aNumFramesOnLine, - nsRect& aLineBounds); + nsRect& aLineBounds, + PRUint32* aLineFlags); NS_IMETHOD FindLineContaining(nsIFrame* aFrame, PRInt32* aLineNumberResult); NS_IMETHOD FindLineAt(nscoord aY,