Bug 174688. Don't apply top border-padding to block frames that aren't first in flow. Also, when a block is incomplete, ensure the frame extends to fill the entire available height. r+sr=dbaron,a=asa

This commit is contained in:
roc+%cs.cmu.edu 2005-04-26 02:26:12 +00:00
Родитель 70323cce41
Коммит d627fd1e59
3 изменённых файлов: 56 добавлений и 32 удалений

Просмотреть файл

@ -1349,32 +1349,43 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
// Compute final height
if (NS_UNCONSTRAINEDSIZE != aReflowState.mComputedHeight) {
if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
// Calculate the total unconstrained height including borders and padding. A continuation
// will have the same value as the first-in-flow, since the reflow state logic is based on
// style and doesn't alter mComputedHeight based on prev-in-flows.
aMetrics.height = borderPadding.top + aReflowState.mComputedHeight + borderPadding.bottom;
// Figure out how much of the computed height should be
// applied to this frame.
nscoord computedHeightLeftOver = aReflowState.mComputedHeight;
if (mPrevInFlow) {
// Reduce the height by the height of prev-in-flows. The last-in-flow will automatically
// pick up the bottom border/padding, since it was part of the original aMetrics.height.
// Reduce the height by the computed height of prev-in-flows.
for (nsIFrame* prev = mPrevInFlow; prev; prev = prev->GetPrevInFlow()) {
aMetrics.height -= prev->GetRect().height;
// XXX: All block level next-in-flows have borderPadding.top applied to them (bug 174688).
// The following should be removed when this gets fixed. bug 174688 prevents us from honoring
// a style height (exactly) and this hack at least compensates by increasing the height by the
// excessive borderPadding.top.
aMetrics.height += borderPadding.top;
nscoord contentHeight = prev->GetRect().height;
if (prev == mPrevInFlow) {
// subtract off the style top borderpadding to get the
// content height
contentHeight -= aReflowState.mComputedBorderPadding.top;
}
computedHeightLeftOver -= contentHeight;
}
aMetrics.height = PR_MAX(0, aMetrics.height);
// We may have stretched the frame beyond its computed height. Oh well.
computedHeightLeftOver = PR_MAX(0, computedHeightLeftOver);
}
if (aMetrics.height > aReflowState.availableHeight) {
// Take up the available height; continuations will take up the rest.
aMetrics.height = borderPadding.top + computedHeightLeftOver + borderPadding.bottom;
if (computedHeightLeftOver > 0 &&
aMetrics.height > aReflowState.availableHeight) {
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aMetrics.height = aReflowState.availableHeight;
aState.mReflowStatus = NS_FRAME_NOT_COMPLETE;
aState.mReflowStatus |= NS_FRAME_NOT_COMPLETE;
}
}
else {
// Use the current height; continuations will take up the rest.
aMetrics.height = aState.mY + nonCarriedOutVerticalMargin;
// Do extend the height to at least consume the available
// height, otherwise our left/right borders (for example) won't
// extend all the way to the break.
aMetrics.height = PR_MAX(aReflowState.availableHeight,
aState.mY + nonCarriedOutVerticalMargin);
}
// Don't carry out a bottom margin when our height is fixed.

Просмотреть файл

@ -70,6 +70,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mFlags(0),
mFloatBreakType(NS_STYLE_CLEAR_NONE)
{
SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nsnull);
const nsMargin& borderPadding = BorderPadding();
if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {

Просмотреть файл

@ -47,6 +47,19 @@
class nsBlockFrame;
// block reflow state flags
#define BRS_UNCONSTRAINEDWIDTH 0x00000001
#define BRS_UNCONSTRAINEDHEIGHT 0x00000002
#define BRS_SHRINKWRAPWIDTH 0x00000004
#define BRS_NEEDRESIZEREFLOW 0x00000008
#define BRS_ISTOPMARGINROOT 0x00000020 // Is this frame a root for top/bottom margin collapsing?
#define BRS_ISBOTTOMMARGINROOT 0x00000040
#define BRS_APPLYTOPMARGIN 0x00000080 // See ShouldApplyTopMargin
#define BRS_COMPUTEMAXELEMENTWIDTH 0x00000100
#define BRS_COMPUTEMAXWIDTH 0x00000200
#define BRS_ISFIRSTINFLOW 0x00000400
#define BRS_LASTFLAG BRS_ISFIRSTINFLOW
class nsBlockReflowState {
public:
nsBlockReflowState(const nsHTMLReflowState& aReflowState,
@ -91,13 +104,23 @@ public:
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType);
PRBool IsAdjacentWithTop() const {
return mY == mReflowState.mComputedBorderPadding.top;
return mY ==
((mFlags & BRS_ISFIRSTINFLOW) ? mReflowState.mComputedBorderPadding.top : 0);
}
const nsMargin& BorderPadding() const {
return mReflowState.mComputedBorderPadding;
/**
* Adjusts the border/padding to return 0 for the top if
* we are no the first in flow.
*/
nsMargin BorderPadding() const {
nsMargin result = mReflowState.mComputedBorderPadding;
if (!(mFlags & BRS_ISFIRSTINFLOW)) {
result.top = 0;
}
return result;
}
// XXX maybe we should do the same adjustment for continuations here
const nsMargin& Margin() const {
return mReflowState.mComputedMargin;
}
@ -230,18 +253,6 @@ public:
PRInt32 mLineNumber;
// block reflow state flags
#define BRS_UNCONSTRAINEDWIDTH 0x00000001
#define BRS_UNCONSTRAINEDHEIGHT 0x00000002
#define BRS_SHRINKWRAPWIDTH 0x00000004
#define BRS_NEEDRESIZEREFLOW 0x00000008
#define BRS_ISTOPMARGINROOT 0x00000020 // Is this frame a root for top/bottom margin collapsing?
#define BRS_ISBOTTOMMARGINROOT 0x00000040
#define BRS_APPLYTOPMARGIN 0x00000080 // See ShouldApplyTopMargin
#define BRS_COMPUTEMAXELEMENTWIDTH 0x00000100
#define BRS_COMPUTEMAXWIDTH 0x00000200
#define BRS_LASTFLAG BRS_COMPUTEMAXWIDTH
PRInt16 mFlags;
PRUint8 mFloatBreakType;