From 300e242585f51b265979e880b07ea9be220e514c Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Wed, 28 Nov 2001 00:50:08 +0000 Subject: [PATCH] bug 111872 - Keep track of pct height content that overflows a cell on the 3rd pass reflow and Hide it. sr=attinasi, r=alexsavulov git-svn-id: svn://10.0.0.236/trunk@109073 18797224-902f-48f8-a5cc-f745e15eee43 --- .../content/shared/public/nsLayoutAtomList.h | 1 + mozilla/layout/base/nsLayoutAtomList.h | 1 + .../html/table/src/nsTableCellFrame.cpp | 104 ++++++++++++++---- .../layout/html/table/src/nsTableCellFrame.h | 23 ++++ mozilla/layout/tables/nsTableCellFrame.cpp | 104 ++++++++++++++---- mozilla/layout/tables/nsTableCellFrame.h | 23 ++++ 6 files changed, 212 insertions(+), 44 deletions(-) diff --git a/mozilla/content/shared/public/nsLayoutAtomList.h b/mozilla/content/shared/public/nsLayoutAtomList.h index 38ffba7f214..33a2782c050 100644 --- a/mozilla/content/shared/public/nsLayoutAtomList.h +++ b/mozilla/content/shared/public/nsLayoutAtomList.h @@ -132,6 +132,7 @@ LAYOUT_ATOM(textFrame, "TextFrame") LAYOUT_ATOM(viewportFrame, "ViewportFrame") // Alphabetical list of frame property names +LAYOUT_ATOM(cellPctOverHeightProperty, "CellPctOverHeightProperty") // nscoord* LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint* LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize* diff --git a/mozilla/layout/base/nsLayoutAtomList.h b/mozilla/layout/base/nsLayoutAtomList.h index 38ffba7f214..33a2782c050 100644 --- a/mozilla/layout/base/nsLayoutAtomList.h +++ b/mozilla/layout/base/nsLayoutAtomList.h @@ -132,6 +132,7 @@ LAYOUT_ATOM(textFrame, "TextFrame") LAYOUT_ATOM(viewportFrame, "ViewportFrame") // Alphabetical list of frame property names +LAYOUT_ATOM(cellPctOverHeightProperty, "CellPctOverHeightProperty") // nscoord* LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint* LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize* diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index cd0075061b3..fa30fab77a5 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -431,7 +431,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, nsClipCombine_kIntersect, clipState); } else{ - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { const nsStylePadding* myPadding = (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsMargin padding; @@ -449,7 +449,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PopState(clipState); } else { - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { aRenderingContext.PopState(clipState); } } @@ -806,8 +806,10 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, ((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset; DISPLAY_REFLOW_CHANGE(); } - nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, - availSize); + else { + SetHasPctOverHeight(PR_FALSE); + } + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, availSize); // If it was a style change targeted at us, then reflow the child using // the special reflow reason @@ -846,6 +848,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, if (isStyleChanged) { Invalidate(aPresContext, mRect); } + #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState, &kidSize, aStatus); #endif @@ -986,13 +989,31 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->width = nsTableFrame::RoundToPixel(aDesiredSize.maxElementSize->width, p2t); } } - // remember my desired size for this reflow - SetDesiredSize(aDesiredSize); if (aReflowState.mFlags.mSpecialTableReflow) { + if (aDesiredSize.height > mRect.height) { + // set a bit and frame property indicating that the pct height contents exceeded + // the height that they could honor in the pass 2 reflow + SetHasPctOverHeight(PR_TRUE); + SetPctOverHeightValue(aPresContext, aDesiredSize.height); + } aDesiredSize.height = mRect.height; SetNeedSpecialReflow(PR_FALSE); } + else if ((eReflowReason_Incremental == aReflowState.reason) && HasPctOverHeight()) { + nscoord overValue; + GetPctOverHeightValue(aPresContext, overValue); + // if the pct over height value hasn't changed, use the last height of the cell, otherwise ignore it + if (aDesiredSize.height == overValue) { + aDesiredSize.height = mRect.height; + } + else { + SetHasPctOverHeight(PR_FALSE); + } + } + + // remember the desired size for this reflow + SetDesiredSize(aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); @@ -1322,6 +1343,16 @@ nsTableCellFrame::GetFrameName(nsAString& aResult) const } #endif +// Destructor function for the pct over height frame property +static void +DestroyCoordFunc(nsIPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue) +{ + delete (nscoord*)aPropertyValue; +} + // Destructor function for the collapse offset frame property static void DestroyPointFunc(nsIPresContext* aPresContext, @@ -1332,10 +1363,11 @@ DestroyPointFunc(nsIPresContext* aPresContext, delete (nsPoint*)aPropertyValue; } -static nsPoint* -GetCollapseOffsetProperty(nsIPresContext* aPresContext, - nsIFrame* aFrame, - PRBool aCreateIfNecessary = PR_FALSE) +static void* +GetCellProperty(nsIPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRBool aCreateIfNecessary = PR_FALSE) { nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); @@ -1347,20 +1379,27 @@ GetCollapseOffsetProperty(nsIPresContext* aPresContext, if (frameManager) { void* value; - frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::collapseOffsetProperty, - 0, &value); + frameManager->GetFrameProperty(aFrame, aPropertyName, 0, &value); if (value) { return (nsPoint*)value; // the property already exists } else if (aCreateIfNecessary) { - // The property isn't set yet, so allocate a new point, set the property, - // and return the newly allocated point - nsPoint* offset = new nsPoint(0, 0); - if (!offset) return nsnull; + // The property isn't set yet, so allocate a new value, set the property, + // and return the newly allocated value + void* value; + NSFMPropertyDtorFunc dtorFunc; + if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) { + value = new nsPoint(0, 0); + dtorFunc = DestroyPointFunc; + } + else if (aPropertyName == nsLayoutAtoms::cellPctOverHeightProperty) { + value = new nscoord; + dtorFunc = DestroyCoordFunc; + } + if (!value) return nsnull; - frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::collapseOffsetProperty, - offset, DestroyPointFunc); - return offset; + frameManager->SetFrameProperty(aFrame, aPropertyName, value, dtorFunc); + return value; } } } @@ -1372,7 +1411,7 @@ void nsTableCellFrame::SetCollapseOffsetX(nsIPresContext* aPresContext, nscoord aXOffset) { // Get the frame property (creating a point struct if necessary) - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this, PR_TRUE); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty, PR_TRUE); if (offset) { offset->x = aXOffset; @@ -1383,7 +1422,7 @@ void nsTableCellFrame::SetCollapseOffsetY(nsIPresContext* aPresContext, nscoord aYOffset) { // Get the property (creating a point struct if necessary) - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this, PR_TRUE); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty, PR_TRUE); if (offset) { offset->y = aYOffset; @@ -1394,7 +1433,7 @@ void nsTableCellFrame::GetCollapseOffset(nsIPresContext* aPresContext, nsPoint& aOffset) { // See if the property is set - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty); if (offset) { aOffset = *offset; @@ -1403,6 +1442,27 @@ void nsTableCellFrame::GetCollapseOffset(nsIPresContext* aPresContext, } } +void nsTableCellFrame::SetPctOverHeightValue(nsIPresContext* aPresContext, + nscoord aValue) +{ + // Get the property + nscoord* value = (nscoord*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::cellPctOverHeightProperty, PR_TRUE); + if (value) { + *value = aValue; + } +} + +void nsTableCellFrame::GetPctOverHeightValue(nsIPresContext* aPresContext, + nscoord& aValue) +{ + aValue = 0; + // See if the property is set + nscoord* value = (nscoord*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::cellPctOverHeightProperty); + if (value) { + aValue = *value; + } +} + #ifdef DEBUG NS_IMETHODIMP nsTableCellFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.h b/mozilla/layout/html/table/src/nsTableCellFrame.h index 42289f6f254..d62412810d0 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.h +++ b/mozilla/layout/html/table/src/nsTableCellFrame.h @@ -51,6 +51,7 @@ class nsHTMLValue; */ #define NS_TABLE_CELL_CONTENT_EMPTY 0x80000000 #define NS_TABLE_CELL_NEED_SPECIAL_REFLOW 0x40000000 +#define NS_TABLE_CELL_PCT_OVER_HEIGHT 0x20000000 /** * nsTableCellFrame @@ -243,11 +244,17 @@ public: PRBool NeedSpecialReflow(); void SetNeedSpecialReflow(PRBool aContentEmpty); + PRBool HasPctOverHeight(); + void SetHasPctOverHeight(PRBool aValue); + // The collapse offset is (0,0) except for cells originating in a row/col which is collapsed void SetCollapseOffsetX(nsIPresContext* aPresContext, nscoord aXOffset); void SetCollapseOffsetY(nsIPresContext* aPresContext, nscoord aYOffset); void GetCollapseOffset(nsIPresContext* aPresContext, nsPoint& aOffset); + void SetPctOverHeightValue(nsIPresContext* aPresContext, nscoord aValue); + void GetPctOverHeightValue(nsIPresContext* aPresContext, nscoord& aValue); + nsTableCellFrame* GetNextCell() const; protected: @@ -365,6 +372,22 @@ inline void nsTableCellFrame::SetNeedSpecialReflow(PRBool aValue) mState &= ~NS_TABLE_CELL_NEED_SPECIAL_REFLOW; } } + +inline PRBool nsTableCellFrame::HasPctOverHeight() +{ + return (mState & NS_TABLE_CELL_PCT_OVER_HEIGHT) == + NS_TABLE_CELL_PCT_OVER_HEIGHT; +} + +inline void nsTableCellFrame::SetHasPctOverHeight(PRBool aValue) +{ + if (aValue) { + mState |= NS_TABLE_CELL_PCT_OVER_HEIGHT; + } else { + mState &= ~NS_TABLE_CELL_PCT_OVER_HEIGHT; + } +} + #endif diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index cd0075061b3..fa30fab77a5 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -431,7 +431,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, nsClipCombine_kIntersect, clipState); } else{ - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { const nsStylePadding* myPadding = (const nsStylePadding*)mStyleContext->GetStyleData(eStyleStruct_Padding); nsMargin padding; @@ -449,7 +449,7 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PopState(clipState); } else { - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { aRenderingContext.PopState(clipState); } } @@ -806,8 +806,10 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, ((nsHTMLReflowState&)aReflowState).mComputedHeight = mRect.height - topInset - bottomInset; DISPLAY_REFLOW_CHANGE(); } - nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, - availSize); + else { + SetHasPctOverHeight(PR_FALSE); + } + nsHTMLReflowState kidReflowState(aPresContext, aReflowState, firstKid, availSize); // If it was a style change targeted at us, then reflow the child using // the special reflow reason @@ -846,6 +848,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, if (isStyleChanged) { Invalidate(aPresContext, mRect); } + #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(firstKid, (nsHTMLReflowState&)kidReflowState, &kidSize, aStatus); #endif @@ -986,13 +989,31 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.maxElementSize->width = nsTableFrame::RoundToPixel(aDesiredSize.maxElementSize->width, p2t); } } - // remember my desired size for this reflow - SetDesiredSize(aDesiredSize); if (aReflowState.mFlags.mSpecialTableReflow) { + if (aDesiredSize.height > mRect.height) { + // set a bit and frame property indicating that the pct height contents exceeded + // the height that they could honor in the pass 2 reflow + SetHasPctOverHeight(PR_TRUE); + SetPctOverHeightValue(aPresContext, aDesiredSize.height); + } aDesiredSize.height = mRect.height; SetNeedSpecialReflow(PR_FALSE); } + else if ((eReflowReason_Incremental == aReflowState.reason) && HasPctOverHeight()) { + nscoord overValue; + GetPctOverHeightValue(aPresContext, overValue); + // if the pct over height value hasn't changed, use the last height of the cell, otherwise ignore it + if (aDesiredSize.height == overValue) { + aDesiredSize.height = mRect.height; + } + else { + SetHasPctOverHeight(PR_FALSE); + } + } + + // remember the desired size for this reflow + SetDesiredSize(aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); @@ -1322,6 +1343,16 @@ nsTableCellFrame::GetFrameName(nsAString& aResult) const } #endif +// Destructor function for the pct over height frame property +static void +DestroyCoordFunc(nsIPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + void* aPropertyValue) +{ + delete (nscoord*)aPropertyValue; +} + // Destructor function for the collapse offset frame property static void DestroyPointFunc(nsIPresContext* aPresContext, @@ -1332,10 +1363,11 @@ DestroyPointFunc(nsIPresContext* aPresContext, delete (nsPoint*)aPropertyValue; } -static nsPoint* -GetCollapseOffsetProperty(nsIPresContext* aPresContext, - nsIFrame* aFrame, - PRBool aCreateIfNecessary = PR_FALSE) +static void* +GetCellProperty(nsIPresContext* aPresContext, + nsIFrame* aFrame, + nsIAtom* aPropertyName, + PRBool aCreateIfNecessary = PR_FALSE) { nsCOMPtr presShell; aPresContext->GetShell(getter_AddRefs(presShell)); @@ -1347,20 +1379,27 @@ GetCollapseOffsetProperty(nsIPresContext* aPresContext, if (frameManager) { void* value; - frameManager->GetFrameProperty(aFrame, nsLayoutAtoms::collapseOffsetProperty, - 0, &value); + frameManager->GetFrameProperty(aFrame, aPropertyName, 0, &value); if (value) { return (nsPoint*)value; // the property already exists } else if (aCreateIfNecessary) { - // The property isn't set yet, so allocate a new point, set the property, - // and return the newly allocated point - nsPoint* offset = new nsPoint(0, 0); - if (!offset) return nsnull; + // The property isn't set yet, so allocate a new value, set the property, + // and return the newly allocated value + void* value; + NSFMPropertyDtorFunc dtorFunc; + if (aPropertyName == nsLayoutAtoms::collapseOffsetProperty) { + value = new nsPoint(0, 0); + dtorFunc = DestroyPointFunc; + } + else if (aPropertyName == nsLayoutAtoms::cellPctOverHeightProperty) { + value = new nscoord; + dtorFunc = DestroyCoordFunc; + } + if (!value) return nsnull; - frameManager->SetFrameProperty(aFrame, nsLayoutAtoms::collapseOffsetProperty, - offset, DestroyPointFunc); - return offset; + frameManager->SetFrameProperty(aFrame, aPropertyName, value, dtorFunc); + return value; } } } @@ -1372,7 +1411,7 @@ void nsTableCellFrame::SetCollapseOffsetX(nsIPresContext* aPresContext, nscoord aXOffset) { // Get the frame property (creating a point struct if necessary) - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this, PR_TRUE); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty, PR_TRUE); if (offset) { offset->x = aXOffset; @@ -1383,7 +1422,7 @@ void nsTableCellFrame::SetCollapseOffsetY(nsIPresContext* aPresContext, nscoord aYOffset) { // Get the property (creating a point struct if necessary) - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this, PR_TRUE); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty, PR_TRUE); if (offset) { offset->y = aYOffset; @@ -1394,7 +1433,7 @@ void nsTableCellFrame::GetCollapseOffset(nsIPresContext* aPresContext, nsPoint& aOffset) { // See if the property is set - nsPoint* offset = ::GetCollapseOffsetProperty(aPresContext, this); + nsPoint* offset = (nsPoint*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::collapseOffsetProperty); if (offset) { aOffset = *offset; @@ -1403,6 +1442,27 @@ void nsTableCellFrame::GetCollapseOffset(nsIPresContext* aPresContext, } } +void nsTableCellFrame::SetPctOverHeightValue(nsIPresContext* aPresContext, + nscoord aValue) +{ + // Get the property + nscoord* value = (nscoord*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::cellPctOverHeightProperty, PR_TRUE); + if (value) { + *value = aValue; + } +} + +void nsTableCellFrame::GetPctOverHeightValue(nsIPresContext* aPresContext, + nscoord& aValue) +{ + aValue = 0; + // See if the property is set + nscoord* value = (nscoord*)::GetCellProperty(aPresContext, this, nsLayoutAtoms::cellPctOverHeightProperty); + if (value) { + aValue = *value; + } +} + #ifdef DEBUG NS_IMETHODIMP nsTableCellFrame::SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const diff --git a/mozilla/layout/tables/nsTableCellFrame.h b/mozilla/layout/tables/nsTableCellFrame.h index 42289f6f254..d62412810d0 100644 --- a/mozilla/layout/tables/nsTableCellFrame.h +++ b/mozilla/layout/tables/nsTableCellFrame.h @@ -51,6 +51,7 @@ class nsHTMLValue; */ #define NS_TABLE_CELL_CONTENT_EMPTY 0x80000000 #define NS_TABLE_CELL_NEED_SPECIAL_REFLOW 0x40000000 +#define NS_TABLE_CELL_PCT_OVER_HEIGHT 0x20000000 /** * nsTableCellFrame @@ -243,11 +244,17 @@ public: PRBool NeedSpecialReflow(); void SetNeedSpecialReflow(PRBool aContentEmpty); + PRBool HasPctOverHeight(); + void SetHasPctOverHeight(PRBool aValue); + // The collapse offset is (0,0) except for cells originating in a row/col which is collapsed void SetCollapseOffsetX(nsIPresContext* aPresContext, nscoord aXOffset); void SetCollapseOffsetY(nsIPresContext* aPresContext, nscoord aYOffset); void GetCollapseOffset(nsIPresContext* aPresContext, nsPoint& aOffset); + void SetPctOverHeightValue(nsIPresContext* aPresContext, nscoord aValue); + void GetPctOverHeightValue(nsIPresContext* aPresContext, nscoord& aValue); + nsTableCellFrame* GetNextCell() const; protected: @@ -365,6 +372,22 @@ inline void nsTableCellFrame::SetNeedSpecialReflow(PRBool aValue) mState &= ~NS_TABLE_CELL_NEED_SPECIAL_REFLOW; } } + +inline PRBool nsTableCellFrame::HasPctOverHeight() +{ + return (mState & NS_TABLE_CELL_PCT_OVER_HEIGHT) == + NS_TABLE_CELL_PCT_OVER_HEIGHT; +} + +inline void nsTableCellFrame::SetHasPctOverHeight(PRBool aValue) +{ + if (aValue) { + mState |= NS_TABLE_CELL_PCT_OVER_HEIGHT; + } else { + mState &= ~NS_TABLE_CELL_PCT_OVER_HEIGHT; + } +} + #endif