mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
bug 109043 - made percent tables without a computed height initiate a special 3rd pass reflow only when a table related frame up the chain has a fixed or percent height. Made row groups not allocate additional vertical space to percent rows in excess of the table height. sr=attinasi,r=alexsavulov
This commit is contained in:
parent
436e1ac49e
commit
5550862ce8
@ -984,6 +984,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
SetDesiredSize(aDesiredSize);
|
||||
|
||||
if (aReflowState.mFlags.mSpecialTableReflow) {
|
||||
aDesiredSize.height = mRect.height;
|
||||
SetNeedSpecialReflow(PR_FALSE);
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1840,30 @@ nsTableFrame::NotifyAncestorsOfSpecialReflow(const nsHTMLReflowState& aReflowSta
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSpecialNested(const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
// Walk up the reflow state tree until we find anything with a style height.
|
||||
// stop when we reach a table
|
||||
const nsHTMLReflowState* rs = aReflowState.parentReflowState;
|
||||
while (rs && rs->frame) {
|
||||
const nsStylePosition* position;
|
||||
rs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)position);
|
||||
if (eStyleUnit_Coord == position->mHeight.GetUnit()) {
|
||||
nscoord coordValue = position->mHeight.GetCoordValue();
|
||||
if (coordValue > 0) return PR_TRUE;
|
||||
}
|
||||
else if (eStyleUnit_Percent == position->mHeight.GetUnit()) {
|
||||
float percent = position->mHeight.GetPercentValue();
|
||||
if (percent > 0.0f) return PR_TRUE;
|
||||
}
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
rs->frame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableFrame == frameType.get()) break;
|
||||
rs = rs->parentReflowState;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* overview:
|
||||
if mFirstPassValid is false, this is our first time through since content was last changed
|
||||
do pass 1
|
||||
@ -1943,9 +1967,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// during an unconstrained reflow because another reflow will be processed later.
|
||||
if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
|
||||
if (!mPrevInFlow) {
|
||||
// see if an extra reflow will be necessary when there is a pct height but no height on the parent
|
||||
// see if an extra reflow will be necessary when the table is nested, there is a pct height,
|
||||
// no computed height, but a height on the containing table
|
||||
if ( ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) ||
|
||||
(0 == aReflowState.mComputedHeight)) && IsPctHeight(mStyleContext)) {
|
||||
(0 == aReflowState.mComputedHeight)) &&
|
||||
IsPctHeight(mStyleContext) && IsSpecialNested(aReflowState)) {
|
||||
NotifyAncestorsOfSpecialReflow(aReflowState);
|
||||
SetNeedSpecialReflow(PR_TRUE);
|
||||
}
|
||||
@ -1970,7 +1996,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialTableReflow = PR_TRUE;
|
||||
ReflowTable(aPresContext, aDesiredSize, aReflowState, aReflowState.availableHeight,
|
||||
nextReason, doCollapse, balanced, aStatus);
|
||||
haveDesiredHeight = PR_TRUE;;
|
||||
haveDesiredHeight = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (aReflowState.mFlags.mSpecialTableReflow) {
|
||||
@ -1988,7 +2014,6 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if (!haveDesiredHeight) {
|
||||
aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
if (IsRowInserted()) {
|
||||
ProcessRowInserted(aPresContext, *this, PR_TRUE, aDesiredSize.height);
|
||||
}
|
||||
|
@ -503,8 +503,11 @@ nsTableRowGroupFrame::GetFirstRow()
|
||||
|
||||
|
||||
struct RowInfo {
|
||||
unsigned height:30;
|
||||
RowInfo() { height = pctHeight = hasStyleHeight = hasPctHeight = isSpecial = 0; }
|
||||
unsigned height; // content height or fixed height, excluding pct height
|
||||
unsigned pctHeight:29; // pct height
|
||||
unsigned hasStyleHeight:1;
|
||||
unsigned hasPctHeight:1;
|
||||
unsigned isSpecial:1; // there is no cell originating in the row with rowspan=1 and there are at
|
||||
// least 2 cells spanning the row and there is no style height on the row
|
||||
};
|
||||
@ -577,20 +580,6 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
|
||||
// make sure that pct height rows do not exceed 100%
|
||||
nscoord pctTotal = 0;
|
||||
nsTableRowFrame* rowFrame;
|
||||
for (rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
|
||||
if (rowFrame->HasPctHeight()) {
|
||||
nscoord pctHeight = NSToCoordRound(rowFrame->GetPctHeight() * 100.0f);
|
||||
if ((pctHeight + pctTotal) > 100) {
|
||||
pctHeight = PR_MAX(0, NSToCoordRound(100.0f - (float)pctTotal));
|
||||
rowFrame->SetPctHeight((float)pctHeight / 100.0f, PR_TRUE);
|
||||
}
|
||||
pctTotal += pctHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// find the nearest row at or before aStartRowFrameIn that isn't spanned into.
|
||||
// If we have a computed height, then we can't compute the heights
|
||||
// incrementally from aStartRowFrameIn, and we must start at the first row.
|
||||
@ -637,9 +626,14 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// the style height of the row.
|
||||
nscoord pctHeightBasis = GetHeightBasis(aReflowState);
|
||||
PRInt32 rowIndex; // the index in rowInfo, not among the rows in the row group
|
||||
nsTableRowFrame* rowFrame;
|
||||
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
||||
UpdateHeights(rowInfo[rowIndex], nsTableFrame::RoundToPixel(rowFrame->GetHeight(pctHeightBasis), p2t),
|
||||
heightOfRows, heightOfUnStyledRows);
|
||||
if (rowFrame->HasPctHeight()) {
|
||||
rowInfo[rowIndex].hasPctHeight = PR_TRUE;
|
||||
rowInfo[rowIndex].pctHeight = nsTableFrame::RoundToPixel(rowFrame->GetHeight(pctHeightBasis), p2t);
|
||||
}
|
||||
nscoord nonPctHeight = PR_MAX(rowFrame->GetContentHeight(), rowFrame->GetFixedHeight());
|
||||
UpdateHeights(rowInfo[rowIndex], nonPctHeight, heightOfRows, heightOfUnStyledRows);
|
||||
rowInfo[rowIndex].hasStyleHeight = rowFrame->HasStyleHeight();
|
||||
|
||||
if (!rowInfo[rowIndex].hasStyleHeight) {
|
||||
@ -773,12 +767,23 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
} // while (rowFrame)
|
||||
}
|
||||
|
||||
// pct height rows have already got their content heights. Give them their pct heights up to pctHeightBasis
|
||||
nscoord extra = pctHeightBasis - heightOfRows;
|
||||
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame && (extra > 0); rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
||||
RowInfo& rInfo = rowInfo[rowIndex];
|
||||
if (rInfo.hasPctHeight) {
|
||||
nscoord rowExtra = PR_MAX(0, rInfo.pctHeight - rInfo.height);
|
||||
rowExtra = PR_MIN(rowExtra, extra);
|
||||
UpdateHeights(rInfo, rowExtra, heightOfRows, heightOfUnStyledRows);
|
||||
extra -= rowExtra;
|
||||
}
|
||||
}
|
||||
|
||||
nscoord rowGroupHeight = startRowGroupHeight + heightOfRows + ((numRows - 1) * cellSpacingY);
|
||||
nscoord extraComputedHeight = 0;
|
||||
// if we have a style height, allocate the extra height to unconstrained rows
|
||||
if ((aReflowState.mComputedHeight > rowGroupHeight) &&
|
||||
(NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight)) {
|
||||
extraComputedHeight = aReflowState.mComputedHeight - rowGroupHeight;
|
||||
nscoord extraComputedHeight = aReflowState.mComputedHeight - rowGroupHeight;
|
||||
nscoord extraUsed = 0;
|
||||
PRBool haveUnStyledRows = (heightOfUnStyledRows > 0);
|
||||
nscoord divisor = (haveUnStyledRows)
|
||||
|
@ -984,6 +984,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
|
||||
SetDesiredSize(aDesiredSize);
|
||||
|
||||
if (aReflowState.mFlags.mSpecialTableReflow) {
|
||||
aDesiredSize.height = mRect.height;
|
||||
SetNeedSpecialReflow(PR_FALSE);
|
||||
}
|
||||
|
||||
|
@ -1840,6 +1840,30 @@ nsTableFrame::NotifyAncestorsOfSpecialReflow(const nsHTMLReflowState& aReflowSta
|
||||
}
|
||||
}
|
||||
|
||||
static PRBool
|
||||
IsSpecialNested(const nsHTMLReflowState& aReflowState)
|
||||
{
|
||||
// Walk up the reflow state tree until we find anything with a style height.
|
||||
// stop when we reach a table
|
||||
const nsHTMLReflowState* rs = aReflowState.parentReflowState;
|
||||
while (rs && rs->frame) {
|
||||
const nsStylePosition* position;
|
||||
rs->frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)position);
|
||||
if (eStyleUnit_Coord == position->mHeight.GetUnit()) {
|
||||
nscoord coordValue = position->mHeight.GetCoordValue();
|
||||
if (coordValue > 0) return PR_TRUE;
|
||||
}
|
||||
else if (eStyleUnit_Percent == position->mHeight.GetUnit()) {
|
||||
float percent = position->mHeight.GetPercentValue();
|
||||
if (percent > 0.0f) return PR_TRUE;
|
||||
}
|
||||
nsCOMPtr<nsIAtom> frameType;
|
||||
rs->frame->GetFrameType(getter_AddRefs(frameType));
|
||||
if (nsLayoutAtoms::tableFrame == frameType.get()) break;
|
||||
rs = rs->parentReflowState;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
/* overview:
|
||||
if mFirstPassValid is false, this is our first time through since content was last changed
|
||||
do pass 1
|
||||
@ -1943,9 +1967,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
// during an unconstrained reflow because another reflow will be processed later.
|
||||
if (NeedsReflow(aReflowState) && (NS_UNCONSTRAINEDSIZE != aReflowState.availableWidth)) {
|
||||
if (!mPrevInFlow) {
|
||||
// see if an extra reflow will be necessary when there is a pct height but no height on the parent
|
||||
// see if an extra reflow will be necessary when the table is nested, there is a pct height,
|
||||
// no computed height, but a height on the containing table
|
||||
if ( ((NS_UNCONSTRAINEDSIZE == aReflowState.mComputedHeight) ||
|
||||
(0 == aReflowState.mComputedHeight)) && IsPctHeight(mStyleContext)) {
|
||||
(0 == aReflowState.mComputedHeight)) &&
|
||||
IsPctHeight(mStyleContext) && IsSpecialNested(aReflowState)) {
|
||||
NotifyAncestorsOfSpecialReflow(aReflowState);
|
||||
SetNeedSpecialReflow(PR_TRUE);
|
||||
}
|
||||
@ -1970,7 +1996,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
((nsHTMLReflowState::ReflowStateFlags&)aReflowState.mFlags).mSpecialTableReflow = PR_TRUE;
|
||||
ReflowTable(aPresContext, aDesiredSize, aReflowState, aReflowState.availableHeight,
|
||||
nextReason, doCollapse, balanced, aStatus);
|
||||
haveDesiredHeight = PR_TRUE;;
|
||||
haveDesiredHeight = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else if (aReflowState.mFlags.mSpecialTableReflow) {
|
||||
@ -1988,7 +2014,6 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
|
||||
if (!haveDesiredHeight) {
|
||||
aDesiredSize.height = CalcDesiredHeight(aPresContext, aReflowState);
|
||||
}
|
||||
|
||||
if (IsRowInserted()) {
|
||||
ProcessRowInserted(aPresContext, *this, PR_TRUE, aDesiredSize.height);
|
||||
}
|
||||
|
@ -503,8 +503,11 @@ nsTableRowGroupFrame::GetFirstRow()
|
||||
|
||||
|
||||
struct RowInfo {
|
||||
unsigned height:30;
|
||||
RowInfo() { height = pctHeight = hasStyleHeight = hasPctHeight = isSpecial = 0; }
|
||||
unsigned height; // content height or fixed height, excluding pct height
|
||||
unsigned pctHeight:29; // pct height
|
||||
unsigned hasStyleHeight:1;
|
||||
unsigned hasPctHeight:1;
|
||||
unsigned isSpecial:1; // there is no cell originating in the row with rowspan=1 and there are at
|
||||
// least 2 cells spanning the row and there is no style height on the row
|
||||
};
|
||||
@ -577,20 +580,6 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
float p2t;
|
||||
aPresContext->GetPixelsToTwips(&p2t);
|
||||
|
||||
// make sure that pct height rows do not exceed 100%
|
||||
nscoord pctTotal = 0;
|
||||
nsTableRowFrame* rowFrame;
|
||||
for (rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) {
|
||||
if (rowFrame->HasPctHeight()) {
|
||||
nscoord pctHeight = NSToCoordRound(rowFrame->GetPctHeight() * 100.0f);
|
||||
if ((pctHeight + pctTotal) > 100) {
|
||||
pctHeight = PR_MAX(0, NSToCoordRound(100.0f - (float)pctTotal));
|
||||
rowFrame->SetPctHeight((float)pctHeight / 100.0f, PR_TRUE);
|
||||
}
|
||||
pctTotal += pctHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// find the nearest row at or before aStartRowFrameIn that isn't spanned into.
|
||||
// If we have a computed height, then we can't compute the heights
|
||||
// incrementally from aStartRowFrameIn, and we must start at the first row.
|
||||
@ -637,9 +626,14 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
// the style height of the row.
|
||||
nscoord pctHeightBasis = GetHeightBasis(aReflowState);
|
||||
PRInt32 rowIndex; // the index in rowInfo, not among the rows in the row group
|
||||
nsTableRowFrame* rowFrame;
|
||||
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame; rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
||||
UpdateHeights(rowInfo[rowIndex], nsTableFrame::RoundToPixel(rowFrame->GetHeight(pctHeightBasis), p2t),
|
||||
heightOfRows, heightOfUnStyledRows);
|
||||
if (rowFrame->HasPctHeight()) {
|
||||
rowInfo[rowIndex].hasPctHeight = PR_TRUE;
|
||||
rowInfo[rowIndex].pctHeight = nsTableFrame::RoundToPixel(rowFrame->GetHeight(pctHeightBasis), p2t);
|
||||
}
|
||||
nscoord nonPctHeight = PR_MAX(rowFrame->GetContentHeight(), rowFrame->GetFixedHeight());
|
||||
UpdateHeights(rowInfo[rowIndex], nonPctHeight, heightOfRows, heightOfUnStyledRows);
|
||||
rowInfo[rowIndex].hasStyleHeight = rowFrame->HasStyleHeight();
|
||||
|
||||
if (!rowInfo[rowIndex].hasStyleHeight) {
|
||||
@ -773,12 +767,23 @@ nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
|
||||
} // while (rowFrame)
|
||||
}
|
||||
|
||||
// pct height rows have already got their content heights. Give them their pct heights up to pctHeightBasis
|
||||
nscoord extra = pctHeightBasis - heightOfRows;
|
||||
for (rowFrame = startRowFrame, rowIndex = 0; rowFrame && (extra > 0); rowFrame = rowFrame->GetNextRow(), rowIndex++) {
|
||||
RowInfo& rInfo = rowInfo[rowIndex];
|
||||
if (rInfo.hasPctHeight) {
|
||||
nscoord rowExtra = PR_MAX(0, rInfo.pctHeight - rInfo.height);
|
||||
rowExtra = PR_MIN(rowExtra, extra);
|
||||
UpdateHeights(rInfo, rowExtra, heightOfRows, heightOfUnStyledRows);
|
||||
extra -= rowExtra;
|
||||
}
|
||||
}
|
||||
|
||||
nscoord rowGroupHeight = startRowGroupHeight + heightOfRows + ((numRows - 1) * cellSpacingY);
|
||||
nscoord extraComputedHeight = 0;
|
||||
// if we have a style height, allocate the extra height to unconstrained rows
|
||||
if ((aReflowState.mComputedHeight > rowGroupHeight) &&
|
||||
(NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight)) {
|
||||
extraComputedHeight = aReflowState.mComputedHeight - rowGroupHeight;
|
||||
nscoord extraComputedHeight = aReflowState.mComputedHeight - rowGroupHeight;
|
||||
nscoord extraUsed = 0;
|
||||
PRBool haveUnStyledRows = (heightOfUnStyledRows > 0);
|
||||
nscoord divisor = (haveUnStyledRows)
|
||||
|
Loading…
Reference in New Issue
Block a user