зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
9acfc6bd28
Коммит
0000423887
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче