Use a struct containing a rectangle and a boolean for float available space rather than passing them around separately. (Bug 25888) r+sr=roc

This commit is contained in:
L. David Baron 2009-04-08 13:52:37 -07:00
parent 9acfc6bd28
commit 0000423887
5 changed files with 127 additions and 126 deletions

View File

@ -1658,20 +1658,18 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
// Note that this check will become incorrect once bug 25888 is fixed
// because we are only checking the top of the line
PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
nsRect floatAvailableSpace;
PRBool isImpactedByFloat =
aState.GetFloatAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE,
floatAvailableSpace);
nsFlowAreaRect floatAvailableSpace =
aState.GetFloatAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n",
this, wasImpactedByFloat, isImpactedByFloat);
this, wasImpactedByFloat, floatAvailableSpace.mHasFloats);
#endif
// Mark the line dirty if it was or is affected by a float
// We actually only really need to reflow if the amount of impact
// changes, but that's not straightforward to check
if (wasImpactedByFloat || isImpactedByFloat) {
if (wasImpactedByFloat || floatAvailableSpace.mHasFloats) {
aLine->MarkDirty();
}
}
@ -2953,16 +2951,14 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// Here aState.mY is the top border-edge of the block.
// Compute the available space for the block
nsRect floatAvailableSpace;
PRBool isImpacted = aState.GetFloatAvailableSpace(floatAvailableSpace);
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
#ifdef REALLY_NOISY_REFLOW
printf("setting line %p isImpacted to %s\n",
aLine.get(), isImpacted?"true":"false");
aLine.get(), floatAvailableSpace.mHasFloats?"true":"false");
#endif
aLine->SetLineIsImpactedByFloat(isImpacted);
aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
nsRect availSpace;
aState.ComputeBlockAvailSpace(frame, display,
isImpacted, floatAvailableSpace,
aState.ComputeBlockAvailSpace(frame, display, floatAvailableSpace,
replacedBlock != nsnull, availSpace);
// Now put the Y coordinate back to the top of the top-margin +
@ -3043,7 +3039,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// then pushing it to the next page would give it more room. Note that
// isImpacted doesn't include impact from the block's own floats.
PRBool forceFit = aState.IsAdjacentWithTop() && clearance <= 0 &&
!isImpacted;
!floatAvailableSpace.mHasFloats;
nsCollapsingMargin collapsedBottomMargin;
nsRect combinedArea(0,0,0,0);
*aKeepReflowGoing = brc.PlaceBlock(blockHtmlRS, forceFit, aLine.get(),
@ -3351,24 +3347,23 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
if (ShouldApplyTopMargin(aState, aLine)) {
aState.mY += aState.mPrevBottomMargin.get();
}
nsRect floatAvailableSpace;
PRBool impactedByFloats = aState.GetFloatAvailableSpace(floatAvailableSpace);
aLine->SetLineIsImpactedByFloat(impactedByFloats);
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
this, impactedByFloats);
this, floatAvailableSpace.mHasFloats);
#endif
const nsMargin& borderPadding = aState.BorderPadding();
nscoord x = floatAvailableSpace.x + borderPadding.left;
nscoord availWidth = floatAvailableSpace.width;
nscoord x = floatAvailableSpace.mRect.x + borderPadding.left;
nscoord availWidth = floatAvailableSpace.mRect.width;
nscoord availHeight;
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
availHeight = NS_UNCONSTRAINEDSIZE;
}
else {
/* XXX get the height right! */
availHeight = floatAvailableSpace.height;
availHeight = floatAvailableSpace.mRect.height;
}
// Make sure to enable resize optimization before we call BeginLineReflow
@ -3377,7 +3372,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
aLineLayout.BeginLineReflow(x, aState.mY,
availWidth, availHeight,
impactedByFloats,
floatAvailableSpace.mHasFloats,
PR_FALSE /*XXX isTopOfPage*/);
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, PR_FALSE);
@ -3400,7 +3395,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
// continuations
PRBool isContinuingPlaceholders = PR_FALSE;
if (impactedByFloats) {
if (floatAvailableSpace.mHasFloats) {
// There is a soft break opportunity at the start of the line, because
// we can always move this line down below float(s).
if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0, PR_TRUE, eNormalBreak)) {
@ -3505,14 +3500,14 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
//
// What we do is to advance past the first float we find and
// then reflow the line all over again.
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != floatAvailableSpace.height,
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != floatAvailableSpace.mRect.height,
"unconstrained height on totally empty line");
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
if (floatAvailableSpace.height > 0) {
NS_ASSERTION(impactedByFloats,
if (floatAvailableSpace.mRect.height > 0) {
NS_ASSERTION(floatAvailableSpace.mHasFloats,
"redo line on totally empty line with non-empty band...");
aState.mY += floatAvailableSpace.height;
aState.mY += floatAvailableSpace.mRect.height;
} else {
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight,
"We shouldn't be running out of height here");
@ -6664,10 +6659,10 @@ nsBlockFrame::ReflowBullet(nsBlockReflowState& aState,
// the block.
// FIXME: aLineTop isn't actually set correctly by some callers, since
// they reposition the line.
nsRect floatAvailSpace;
aState.GetFloatAvailableSpaceWithState(aLineTop, PR_FALSE,
&aState.mFloatManagerStateBefore,
floatAvailSpace);
nsRect floatAvailSpace =
aState.GetFloatAvailableSpaceWithState(aLineTop, PR_FALSE,
&aState.mFloatManagerStateBefore)
.mRect;
// FIXME (bug 25888): need to check the entire region that the first
// line overlaps, not just the top pixel.

View File

@ -245,13 +245,13 @@ nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
void
nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay,
PRBool aBandHasFloats,
const nsRect& aFloatAvailableSpace,
const nsFlowAreaRect& aFloatAvailableSpace,
PRBool aBlockAvoidsFloats,
nsRect& aResult)
{
#ifdef REALLY_NOISY_REFLOW
printf("CBAS frame=%p has floats %d\n", aFrame, aBandHasFloats);
printf("CBAS frame=%p has floats %d\n",
aFrame, aFloatAvailableSpace.mHasFloats);
#endif
aResult.y = mY;
aResult.height = GetFlag(BRS_UNCONSTRAINEDHEIGHT)
@ -279,7 +279,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
!aBlockAvoidsFloats,
"unexpected replaced width");
if (!aBlockAvoidsFloats) {
if (aBandHasFloats) {
if (aFloatAvailableSpace.mHasFloats) {
// Use the float-edge property to determine how the child block
// will interact with the float.
const nsStyleBorder* borderStyle = aFrame->GetStyleBorder();
@ -295,8 +295,8 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
{
// The child block's margins should be placed adjacent to,
// but not overlap the float.
aResult.x = aFloatAvailableSpace.x + borderPadding.left;
aResult.width = aFloatAvailableSpace.width;
aResult.x = aFloatAvailableSpace.mRect.x + borderPadding.left;
aResult.width = aFloatAvailableSpace.mRect.width;
}
break;
}
@ -315,12 +315,12 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
if (aFrame->GetType() == nsGkAtoms::tableOuterFrame) {
replacedWidth = &replacedWidthStruct;
replacedWidthStruct =
nsBlockFrame::WidthToClearPastFloats(*this, aFloatAvailableSpace,
nsBlockFrame::WidthToClearPastFloats(*this, aFloatAvailableSpace.mRect,
aFrame);
}
nscoord leftOffset, rightOffset;
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
leftOffset, rightOffset,
replacedWidth);
aResult.x = borderPadding.left + leftOffset;
@ -332,11 +332,10 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
#endif
}
PRBool
nsFlowAreaRect
nsBlockReflowState::GetFloatAvailableSpaceWithState(
nscoord aY, PRBool aRelaxHeightConstraint,
nsFloatManager::SavedState *aState,
nsRect& aResult) const
nsFloatManager::SavedState *aState) const
{
#ifdef DEBUG
// Verify that the caller setup the coordinate system properly
@ -346,24 +345,24 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
"bad coord system");
#endif
PRBool hasFloats;
aResult =
nsFlowAreaRect result =
mFloatManager->GetBand(aY - BorderPadding().top,
aRelaxHeightConstraint ? nscoord_MAX
: mContentArea.height,
mContentArea.width, aState, &hasFloats);
mContentArea.width, aState);
// Keep the width >= 0 for compatibility with nsSpaceManager.
if (aResult.width < 0)
aResult.width = 0;
if (result.mRect.width < 0)
result.mRect.width = 0;
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("GetAvailableSpace: band=%d,%d,%d,%d hasfloats=%d\n",
aResult.x, aResult.y, aResult.width, aResult.height, hasFloats);
result.mRect.x, result.mRect.y, result.mRect.width,
result.mRect.height, result.mHasFloats);
}
#endif
return hasFloats;
return result;
}
/*
@ -580,8 +579,7 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
// If one or more floats has already been pushed to the next line,
// don't let this one go on the current line, since that would violate
// float ordering.
nsRect floatAvailableSpace;
GetFloatAvailableSpace(floatAvailableSpace);
nsRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
if (mBelowCurrentLineFloats.IsEmpty() &&
(aLineLayout.LineIsEmpty() ||
mBlock->ComputeFloatWidth(*this, floatAvailableSpace, aPlaceholder) <=
@ -596,10 +594,11 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
"If we asked for force-fit, it should have been placed");
if (forceFit || (placed && !NS_FRAME_IS_TRUNCATED(aReflowStatus))) {
// Pass on updated available space to the current inline reflow engine
nsRect floatAvailSpace;
GetFloatAvailableSpace(mY, forceFit, floatAvailSpace);
nsRect availSpace(nsPoint(floatAvailSpace.x + BorderPadding().left, mY),
floatAvailSpace.Size());
nsFlowAreaRect floatAvailSpace =
GetFloatAvailableSpace(mY, forceFit);
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x + BorderPadding().left,
mY),
floatAvailSpace.mRect.Size());
aLineLayout.UpdateBand(availSpace, isLeftFloat,
aPlaceholder->GetOutOfFlowFrame());
@ -653,15 +652,15 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
PRBool
nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
const nsRect& aFloatAvailableSpace,
PRBool aBandHasFloats, PRBool aForceFit)
const nsFlowAreaRect& aFloatAvailableSpace,
PRBool aForceFit)
{
// If the current Y coordinate is not impacted by any floats
// then by definition the float fits.
PRBool result = PR_TRUE;
if (aBandHasFloats) {
if (aFloatAvailableSpace.mHasFloats) {
// XXX We should allow overflow by up to half a pixel here (bug 21193).
if (aFloatAvailableSpace.width < aFloatSize.width) {
if (aFloatAvailableSpace.mRect.width < aFloatSize.width) {
// The available width is too narrow (and its been impacted by a
// prior float)
result = PR_FALSE;
@ -674,7 +673,8 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
// At this point we know that there is enough horizontal space for
// the float (somewhere). Lets see if there is enough vertical
// space.
if (NSCoordGreaterThan(aFloatSize.height, aFloatAvailableSpace.height)) {
if (NSCoordGreaterThan(aFloatSize.height,
aFloatAvailableSpace.mRect.height)) {
// The available height is too short. However, its possible that
// there is enough open space below which is not impacted by a
// float.
@ -685,16 +685,16 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
// here.
nscoord xa;
if (NS_STYLE_FLOAT_LEFT == aFloats) {
xa = aFloatAvailableSpace.x;
xa = aFloatAvailableSpace.mRect.x;
}
else {
xa = aFloatAvailableSpace.XMost() - aFloatSize.width;
xa = aFloatAvailableSpace.mRect.XMost() - aFloatSize.width;
// In case the float is too big, don't go past the left edge
// XXXldb This seems wrong, but we might want to fix bug 6976
// first.
if (xa < aFloatAvailableSpace.x) {
xa = aFloatAvailableSpace.x;
if (xa < aFloatAvailableSpace.mRect.x) {
xa = aFloatAvailableSpace.mRect.x;
}
}
nscoord xb = xa + aFloatSize.width;
@ -714,22 +714,21 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
nscoord yb = ya + aFloatSize.height;
nscoord saveY = mY;
nsRect floatAvailableSpace(aFloatAvailableSpace);
nsFlowAreaRect floatAvailableSpace(aFloatAvailableSpace);
for (;;) {
// Get the available space at the new Y coordinate
if (floatAvailableSpace.height <= 0) {
if (floatAvailableSpace.mRect.height <= 0) {
// there is no more available space. We lose.
result = PR_FALSE;
break;
}
mY += floatAvailableSpace.height;
PRBool bandHasFloats =
GetFloatAvailableSpace(mY, aForceFit, floatAvailableSpace);
mY += floatAvailableSpace.mRect.height;
floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
if (bandHasFloats) {
if (xa < floatAvailableSpace.x ||
xb > floatAvailableSpace.XMost()) {
if (floatAvailableSpace.mHasFloats) {
if (xa < floatAvailableSpace.mRect.x ||
xb > floatAvailableSpace.mRect.XMost()) {
// The float can't go here.
result = PR_FALSE;
break;
@ -737,7 +736,7 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
}
// See if there is now enough height for the float.
if (yb <= mY + floatAvailableSpace.height) {
if (yb <= mY + floatAvailableSpace.mRect.height) {
// Winner. The bottom Y coordinate of the float is in
// this band.
break;
@ -786,16 +785,14 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
mY = ClearFloats(mY, floatDisplay->mBreakType);
}
// Get the band of available space
nsRect floatAvailableSpace;
PRBool bandHasFloats =
GetFloatAvailableSpace(mY, aForceFit, floatAvailableSpace);
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
NS_ASSERTION(floatFrame->GetParent() == mBlock,
"Float frame has wrong parent");
// Reflow the float
nsMargin floatMargin;
mBlock->ReflowFloat(*this, floatAvailableSpace, placeholder,
mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, placeholder,
floatMargin, aReflowStatus);
#ifdef DEBUG
@ -823,8 +820,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
PRBool keepFloatOnSameLine = PR_FALSE;
while (!CanPlaceFloat(floatSize, floatDisplay->mFloats, floatAvailableSpace,
bandHasFloats, aForceFit)) {
if (floatAvailableSpace.height <= 0) {
aForceFit)) {
if (floatAvailableSpace.mRect.height <= 0) {
// No space, nowhere to put anything.
mY = saveY;
return PR_FALSE;
@ -834,9 +831,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
if (NS_STYLE_DISPLAY_TABLE != floatDisplay->mDisplay ||
eCompatibility_NavQuirks != mPresContext->CompatibilityMode() ) {
mY += floatAvailableSpace.height;
bandHasFloats =
GetFloatAvailableSpace(mY, aForceFit, floatAvailableSpace);
mY += floatAvailableSpace.mRect.height;
floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
} else {
// This quirk matches the one in nsBlockFrame::ReflowFloat
// IE handles float tables in a very special way
@ -874,14 +870,13 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
}
// the table does not fit anymore in this line so advance to next band
mY += floatAvailableSpace.height;
bandHasFloats =
GetFloatAvailableSpace(mY, aForceFit, floatAvailableSpace);
mY += floatAvailableSpace.mRect.height;
floatAvailableSpace = GetFloatAvailableSpace(mY, aForceFit);
// reflow the float again now since we have more space
// XXXldb We really don't need to Reflow in a loop, we just need
// to ComputeSize in a loop (once ComputeSize depends on
// availableWidth, which should make this work again).
mBlock->ReflowFloat(*this, floatAvailableSpace, placeholder,
mBlock->ReflowFloat(*this, floatAvailableSpace.mRect, placeholder,
floatMargin, aReflowStatus);
// Get the floats bounding box and margin information
floatSize = floatFrame->GetSize() +
@ -901,18 +896,18 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
nscoord floatX, floatY;
if (NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) {
isLeftFloat = PR_TRUE;
floatX = floatAvailableSpace.x;
floatX = floatAvailableSpace.mRect.x;
}
else {
isLeftFloat = PR_FALSE;
if (!keepFloatOnSameLine) {
floatX = floatAvailableSpace.XMost() - floatSize.width;
floatX = floatAvailableSpace.mRect.XMost() - floatSize.width;
}
else {
// this is the IE quirk (see few lines above)
// the table is kept in the same line: don't let it overlap the
// previous float
floatX = floatAvailableSpace.x;
floatX = floatAvailableSpace.mRect.x;
}
}
*aIsLeftFloat = isLeftFloat;
@ -1106,25 +1101,25 @@ nsBlockReflowState::ClearFloats(nscoord aY, PRUint8 aBreakType,
if (aReplacedBlock) {
for (;;) {
nsRect floatAvailableSpace;
PRBool bandHasFloats =
GetFloatAvailableSpace(newY, PR_FALSE, floatAvailableSpace);
nsFlowAreaRect floatAvailableSpace =
GetFloatAvailableSpace(newY, PR_FALSE);
nsBlockFrame::ReplacedElementWidthToClear replacedWidth =
nsBlockFrame::WidthToClearPastFloats(*this, floatAvailableSpace,
nsBlockFrame::WidthToClearPastFloats(*this, floatAvailableSpace.mRect,
aReplacedBlock);
if (!bandHasFloats ||
PR_MAX(floatAvailableSpace.x, replacedWidth.marginLeft) +
if (!floatAvailableSpace.mHasFloats ||
PR_MAX(floatAvailableSpace.mRect.x, replacedWidth.marginLeft) +
replacedWidth.borderBoxWidth +
PR_MAX(mContentArea.width -
PR_MIN(mContentArea.width, floatAvailableSpace.XMost()),
PR_MIN(mContentArea.width,
floatAvailableSpace.mRect.XMost()),
replacedWidth.marginRight) <=
mContentArea.width) {
break;
}
// See the analogous code for inlines in nsBlockFrame::DoReflowInlineFrames
if (floatAvailableSpace.height > 0) {
if (floatAvailableSpace.mRect.height > 0) {
// See if there's room in the next band.
newY += floatAvailableSpace.height;
newY += floatAvailableSpace.mRect.height;
} else {
if (mReflowState.availableHeight != NS_UNCONSTRAINEDSIZE) {
// Stop trying to clear here; we'll just get pushed to the

View File

@ -91,16 +91,15 @@ public:
* Returns whether there are floats present at the given vertical
* coordinate and within the width of the content rect.
*/
PRBool GetFloatAvailableSpace(nsRect& aResult) const
{ return GetFloatAvailableSpace(mY, PR_FALSE, aResult); }
PRBool GetFloatAvailableSpace(nscoord aY, PRBool aRelaxHeightConstraint,
nsRect& aResult) const
nsFlowAreaRect GetFloatAvailableSpace() const
{ return GetFloatAvailableSpace(mY, PR_FALSE); }
nsFlowAreaRect GetFloatAvailableSpace(nscoord aY,
PRBool aRelaxHeightConstraint) const
{ return GetFloatAvailableSpaceWithState(aY, aRelaxHeightConstraint,
nsnull, aResult); }
PRBool GetFloatAvailableSpaceWithState(nscoord aY,
PRBool aRelaxHeightConstraint,
nsFloatManager::SavedState *aState,
nsRect& aResult) const;
nsnull); }
nsFlowAreaRect
GetFloatAvailableSpaceWithState(nscoord aY, PRBool aRelaxHeightConstraint,
nsFloatManager::SavedState *aState) const;
/*
* The following functions all return PR_TRUE if they were able to
@ -117,8 +116,8 @@ public:
nscoord aAvailableWidth,
nsReflowStatus& aReflowStatus);
PRBool CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats,
const nsRect& aFloatAvailableSpace,
PRBool aBandHasFloats, PRBool aForceFit);
const nsFlowAreaRect& aFloatAvailableSpace,
PRBool aForceFit);
PRBool FlowAndPlaceFloat(nsFloatCache* aFloatCache,
PRBool* aIsLeftFloat,
nsReflowStatus& aReflowStatus,
@ -172,8 +171,7 @@ public:
// Caller must have called GetAvailableSpace for the current mY
void ComputeBlockAvailSpace(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay,
PRBool aBandHasFloats,
const nsRect& aFloatAvailableSpace,
const nsFlowAreaRect& aFloatAvailableSpace,
PRBool aBlockAvoidsFloats,
nsRect& aResult);

View File

@ -135,12 +135,11 @@ void nsFloatManager::Shutdown()
sCachedFloatManagerCount = -1;
}
nsRect
nsFlowAreaRect
nsFloatManager::GetBand(nscoord aYOffset,
nscoord aMaxHeight,
nscoord aContentAreaWidth,
SavedState* aState,
PRBool* aHasFloats) const
SavedState* aState) const
{
NS_ASSERTION(aMaxHeight >= 0, "unexpected max height");
NS_ASSERTION(aContentAreaWidth >= 0, "unexpected content area width");
@ -167,8 +166,7 @@ nsFloatManager::GetBand(nscoord aYOffset,
if (floatCount == 0 ||
(mFloats[floatCount-1].mLeftYMost <= top &&
mFloats[floatCount-1].mRightYMost <= top)) {
*aHasFloats = PR_FALSE;
return nsRect(0, aYOffset, aContentAreaWidth, aMaxHeight);
return nsFlowAreaRect(0, aYOffset, aContentAreaWidth, aMaxHeight, PR_FALSE);
}
nscoord bottom;
@ -241,9 +239,8 @@ nsFloatManager::GetBand(nscoord aYOffset,
}
}
*aHasFloats = haveFloats;
nscoord height = (bottom == nscoord_MAX) ? nscoord_MAX : (bottom - top);
return nsRect(left - mX, top - mY, right - left, height);
return nsFlowAreaRect(left - mX, top - mY, right - left, height, haveFloats);
}
nsresult

View File

@ -52,6 +52,22 @@ class nsIFrame;
struct nsHTMLReflowState;
class nsPresContext;
/**
* The available space for content not occupied by floats is divided
* into a (vertical) sequence of rectangles. However, we need to know
* not only the rectangle, but also whether it was reduced (from the
* content rectangle) by floats that actually intruded into the content
* rectangle.
*/
struct nsFlowAreaRect {
nsRect mRect;
PRPackedBool mHasFloats;
nsFlowAreaRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
PRBool aHasFloats)
: mRect(aX, aY, aWidth, aHeight), mHasFloats(aHasFloats) {}
};
#define NS_FLOAT_MANAGER_CACHE_SIZE 4
class nsFloatManager {
@ -107,18 +123,18 @@ public:
* @param aState [in] If null, use the current state, otherwise, do
* computation based only on floats present in the given
* saved state.
* @param aHasFloats [out] whether there are floats at the sides of
* the return value including those that do not
* reduce the line box width at all (because they
* are entirely in the margins)
* @return the resulting rectangle for line boxes. It will not go
* left of 0, nor right of aContentAreaWidth, but will be
* narrower when floats are present.
* @return An nsFlowAreaRect whose:
* mRect is the resulting rectangle for line boxes. It will not go
* left of 0, nor right of aContentAreaWidth, but will be
* narrower when floats are present.
* mBandHasFloats is whether there are floats at the sides of the
* return value including those that do not reduce the line box
* width at all (because they are entirely in the margins)
*
* aY and aAvailSpace are positioned relative to the current translation
*/
nsRect GetBand(nscoord aY, nscoord aMaxHeight, nscoord aContentAreaWidth,
SavedState* aState, PRBool* aHasFloats) const;
nsFlowAreaRect GetBand(nscoord aY, nscoord aMaxHeight,
nscoord aContentAreaWidth, SavedState* aState) const;
/**
* Add a float that comes after all floats previously added. Its top