mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Fix bug 25888 for inline frames other than bullets: redo line reflow when the line's height pushes it into the way of other floats. (Bug 25888) r+sr=roc
This commit is contained in:
parent
bedec9616e
commit
7c71744210
6
layout/generic/crashtests/25888-1.html
Normal file
6
layout/generic/crashtests/25888-1.html
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<title>Hang while developing patch for bug 25888</title>
|
||||||
|
|
||||||
|
<div style="width:500px">
|
||||||
|
<div style="float:left;width:600px;height:30px"></div>
|
||||||
|
Hello
|
||||||
|
</div>
|
8
layout/generic/crashtests/25888-2.html
Normal file
8
layout/generic/crashtests/25888-2.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<!DOCTYPE HTML>
|
||||||
|
<title>Testcase for hang while developing bug 25888 (hit on www.flightaware.com)</title>
|
||||||
|
|
||||||
|
<div style="border: solid 1em; width: 500px; height: 500px">
|
||||||
|
<div style="float:right; width: 300px; height: 3px;background:yellow;"></div>
|
||||||
|
<div style="float:left; width: 220px; height: 100px;background:aqua;"></div>
|
||||||
|
hi
|
||||||
|
</div>
|
@ -1,3 +1,5 @@
|
|||||||
|
load 25888-1.html
|
||||||
|
load 25888-2.html
|
||||||
load 37757-1.html
|
load 37757-1.html
|
||||||
load 225868-1.html
|
load 225868-1.html
|
||||||
load 264937-1.html
|
load 264937-1.html
|
||||||
|
@ -783,6 +783,20 @@ nsBlockFrame::ComputeTightBounds(gfxContext* aContext) const
|
|||||||
return ComputeSimpleTightBounds(aContext);
|
return ComputeSimpleTightBounds(aContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PRBool
|
||||||
|
AvailableSpaceShrunk(const nsRect& aOldAvailableSpace,
|
||||||
|
const nsRect& aNewAvailableSpace)
|
||||||
|
{
|
||||||
|
if (aNewAvailableSpace.width == 0) {
|
||||||
|
// Positions are not significant if the width is zero.
|
||||||
|
return aOldAvailableSpace.width != 0;
|
||||||
|
}
|
||||||
|
NS_ASSERTION(aOldAvailableSpace.x <= aNewAvailableSpace.x &&
|
||||||
|
aOldAvailableSpace.XMost() >= aNewAvailableSpace.XMost(),
|
||||||
|
"available space should never grow");
|
||||||
|
return aOldAvailableSpace.width != aNewAvailableSpace.width;
|
||||||
|
}
|
||||||
|
|
||||||
static nsSize
|
static nsSize
|
||||||
CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
CalculateContainingBlockSizeForAbsolutes(const nsHTMLReflowState& aReflowState,
|
||||||
nsSize aFrameSize)
|
nsSize aFrameSize)
|
||||||
@ -1663,11 +1677,11 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||||||
// decide what it needs to reflow.
|
// decide what it needs to reflow.
|
||||||
aLine->MarkDirty();
|
aLine->MarkDirty();
|
||||||
} else {
|
} else {
|
||||||
// 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();
|
PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
|
||||||
nsFlowAreaRect floatAvailableSpace =
|
nsFlowAreaRect floatAvailableSpace =
|
||||||
aState.GetFloatAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
|
aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y + aDeltaY,
|
||||||
|
aLine->mBounds.height,
|
||||||
|
nsnull);
|
||||||
|
|
||||||
#ifdef REALLY_NOISY_REFLOW
|
#ifdef REALLY_NOISY_REFLOW
|
||||||
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n",
|
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n",
|
||||||
@ -3320,11 +3334,19 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
*aKeepReflowGoing = PR_TRUE;
|
*aKeepReflowGoing = PR_TRUE;
|
||||||
|
|
||||||
|
aLine->SetLineIsImpactedByFloat(PR_FALSE);
|
||||||
|
|
||||||
|
// Setup initial coordinate system for reflowing the inline frames
|
||||||
|
// into. Apply a previous block frame's bottom margin first.
|
||||||
|
if (ShouldApplyTopMargin(aState, aLine)) {
|
||||||
|
aState.mY += aState.mPrevBottomMargin.get();
|
||||||
|
}
|
||||||
|
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRInt32 spins = 0;
|
PRInt32 spins = 0;
|
||||||
#endif
|
#endif
|
||||||
LineReflowStatus lineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND;
|
LineReflowStatus lineReflowStatus = LINE_REFLOW_REDO_NEXT_BAND;
|
||||||
PRBool movedPastFloat = PR_FALSE;
|
|
||||||
do {
|
do {
|
||||||
PRBool allowPullUp = PR_TRUE;
|
PRBool allowPullUp = PR_TRUE;
|
||||||
nsIContent* forceBreakInContent = nsnull;
|
nsIContent* forceBreakInContent = nsnull;
|
||||||
@ -3349,11 +3371,13 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
lineLayout.ForceBreakAtPosition(forceBreakInContent, forceBreakOffset);
|
lineLayout.ForceBreakAtPosition(forceBreakInContent, forceBreakOffset);
|
||||||
}
|
}
|
||||||
rv = DoReflowInlineFrames(aState, lineLayout, aLine,
|
rv = DoReflowInlineFrames(aState, lineLayout, aLine,
|
||||||
|
floatAvailableSpace, &floatManagerState,
|
||||||
aKeepReflowGoing, &lineReflowStatus,
|
aKeepReflowGoing, &lineReflowStatus,
|
||||||
allowPullUp);
|
allowPullUp);
|
||||||
lineLayout.EndLineReflow();
|
lineLayout.EndLineReflow();
|
||||||
|
|
||||||
if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus ||
|
if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus ||
|
||||||
|
LINE_REFLOW_REDO_MORE_FLOATS == lineReflowStatus ||
|
||||||
LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) {
|
LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) {
|
||||||
if (lineLayout.NeedsBackup()) {
|
if (lineLayout.NeedsBackup()) {
|
||||||
NS_ASSERTION(!forceBreakInContent, "Backing up twice; this should never be necessary");
|
NS_ASSERTION(!forceBreakInContent, "Backing up twice; this should never be necessary");
|
||||||
@ -3383,17 +3407,9 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
// Don't allow pullup on a subsequent LINE_REFLOW_REDO_NO_PULL pass
|
// Don't allow pullup on a subsequent LINE_REFLOW_REDO_NO_PULL pass
|
||||||
allowPullUp = PR_FALSE;
|
allowPullUp = PR_FALSE;
|
||||||
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NO_PULL == lineReflowStatus);
|
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NO_PULL == lineReflowStatus);
|
||||||
|
} while (NS_SUCCEEDED(rv) &&
|
||||||
if (LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus) {
|
(LINE_REFLOW_REDO_MORE_FLOATS == lineReflowStatus ||
|
||||||
movedPastFloat = PR_TRUE;
|
LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus));
|
||||||
}
|
|
||||||
} while (NS_SUCCEEDED(rv) && LINE_REFLOW_REDO_NEXT_BAND == lineReflowStatus);
|
|
||||||
|
|
||||||
// If we did at least one REDO_FOR_FLOAT, then the line did not fit next to some float.
|
|
||||||
// Mark it as impacted by a float, even if it no longer is next to a float.
|
|
||||||
if (movedPastFloat) {
|
|
||||||
aLine->SetLineIsImpactedByFloat(PR_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -3417,6 +3433,7 @@ nsBlockFrame::PushTruncatedPlaceholderLine(nsBlockReflowState& aState,
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static const char* LineReflowStatusNames[] = {
|
static const char* LineReflowStatusNames[] = {
|
||||||
"LINE_REFLOW_OK", "LINE_REFLOW_STOP", "LINE_REFLOW_REDO_NO_PULL",
|
"LINE_REFLOW_OK", "LINE_REFLOW_STOP", "LINE_REFLOW_REDO_NO_PULL",
|
||||||
|
"LINE_REFLOW_REDO_MORE_FLOATS",
|
||||||
"LINE_REFLOW_REDO_NEXT_BAND", "LINE_REFLOW_TRUNCATED"
|
"LINE_REFLOW_REDO_NEXT_BAND", "LINE_REFLOW_TRUNCATED"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
@ -3425,6 +3442,9 @@ nsresult
|
|||||||
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||||
nsLineLayout& aLineLayout,
|
nsLineLayout& aLineLayout,
|
||||||
line_iterator aLine,
|
line_iterator aLine,
|
||||||
|
nsFlowAreaRect& aFloatAvailableSpace,
|
||||||
|
nsFloatManager::SavedState*
|
||||||
|
aFloatStateBeforeLine,
|
||||||
PRBool* aKeepReflowGoing,
|
PRBool* aKeepReflowGoing,
|
||||||
LineReflowStatus* aLineReflowStatus,
|
LineReflowStatus* aLineReflowStatus,
|
||||||
PRBool aAllowPullUp)
|
PRBool aAllowPullUp)
|
||||||
@ -3433,28 +3453,25 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
aLine->FreeFloats(aState.mFloatCacheFreeList);
|
aLine->FreeFloats(aState.mFloatCacheFreeList);
|
||||||
aState.mFloatCombinedArea.SetRect(0, 0, 0, 0);
|
aState.mFloatCombinedArea.SetRect(0, 0, 0, 0);
|
||||||
|
|
||||||
// Setup initial coordinate system for reflowing the inline frames
|
// We need to set this flag on the line if any of our reflow passes
|
||||||
// into. Apply a previous block frame's bottom margin first.
|
// are impacted by floats.
|
||||||
if (ShouldApplyTopMargin(aState, aLine)) {
|
if (aFloatAvailableSpace.mHasFloats)
|
||||||
aState.mY += aState.mPrevBottomMargin.get();
|
aLine->SetLineIsImpactedByFloat(PR_TRUE);
|
||||||
}
|
|
||||||
nsFlowAreaRect floatAvailableSpace = aState.GetFloatAvailableSpace();
|
|
||||||
aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
|
|
||||||
#ifdef REALLY_NOISY_REFLOW
|
#ifdef REALLY_NOISY_REFLOW
|
||||||
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
|
||||||
this, floatAvailableSpace.mHasFloats);
|
this, aFloatAvailableSpace.mHasFloats);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const nsMargin& borderPadding = aState.BorderPadding();
|
const nsMargin& borderPadding = aState.BorderPadding();
|
||||||
nscoord x = floatAvailableSpace.mRect.x + borderPadding.left;
|
nscoord x = aFloatAvailableSpace.mRect.x + borderPadding.left;
|
||||||
nscoord availWidth = floatAvailableSpace.mRect.width;
|
nscoord availWidth = aFloatAvailableSpace.mRect.width;
|
||||||
nscoord availHeight;
|
nscoord availHeight;
|
||||||
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
|
if (aState.GetFlag(BRS_UNCONSTRAINEDHEIGHT)) {
|
||||||
availHeight = NS_UNCONSTRAINEDSIZE;
|
availHeight = NS_UNCONSTRAINEDSIZE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* XXX get the height right! */
|
/* XXX get the height right! */
|
||||||
availHeight = floatAvailableSpace.mRect.height;
|
availHeight = aFloatAvailableSpace.mRect.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure to enable resize optimization before we call BeginLineReflow
|
// Make sure to enable resize optimization before we call BeginLineReflow
|
||||||
@ -3463,7 +3480,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
|
|
||||||
aLineLayout.BeginLineReflow(x, aState.mY,
|
aLineLayout.BeginLineReflow(x, aState.mY,
|
||||||
availWidth, availHeight,
|
availWidth, availHeight,
|
||||||
floatAvailableSpace.mHasFloats,
|
aFloatAvailableSpace.mHasFloats,
|
||||||
PR_FALSE /*XXX isTopOfPage*/);
|
PR_FALSE /*XXX isTopOfPage*/);
|
||||||
|
|
||||||
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, PR_FALSE);
|
aState.SetFlag(BRS_LINE_LAYOUT_EMPTY, PR_FALSE);
|
||||||
@ -3486,7 +3503,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
// continuations
|
// continuations
|
||||||
PRBool isContinuingPlaceholders = PR_FALSE;
|
PRBool isContinuingPlaceholders = PR_FALSE;
|
||||||
|
|
||||||
if (floatAvailableSpace.mHasFloats) {
|
if (aFloatAvailableSpace.mHasFloats) {
|
||||||
// There is a soft break opportunity at the start of the line, because
|
// There is a soft break opportunity at the start of the line, because
|
||||||
// we can always move this line down below float(s).
|
// we can always move this line down below float(s).
|
||||||
if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0, PR_TRUE, eNormalBreak)) {
|
if (aLineLayout.NotifyOptionalBreakPosition(frame->GetContent(), 0, PR_TRUE, eNormalBreak)) {
|
||||||
@ -3591,20 +3608,32 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
//
|
//
|
||||||
// What we do is to advance past the first float we find and
|
// What we do is to advance past the first float we find and
|
||||||
// then reflow the line all over again.
|
// then reflow the line all over again.
|
||||||
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != floatAvailableSpace.mRect.height,
|
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aFloatAvailableSpace.mRect.height,
|
||||||
"unconstrained height on totally empty line");
|
"unconstrained height on totally empty line");
|
||||||
|
|
||||||
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
|
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
|
||||||
if (floatAvailableSpace.mRect.height > 0) {
|
if (aFloatAvailableSpace.mRect.height > 0) {
|
||||||
NS_ASSERTION(floatAvailableSpace.mHasFloats,
|
NS_ASSERTION(aFloatAvailableSpace.mHasFloats,
|
||||||
"redo line on totally empty line with non-empty band...");
|
"redo line on totally empty line with non-empty band...");
|
||||||
aState.mY += floatAvailableSpace.mRect.height;
|
// We should never hit this case if we've placed floats on the
|
||||||
|
// line; if we have, then the GetFloatAvailableSpace call is wrong
|
||||||
|
// and needs to happen after the caller pops the space manager
|
||||||
|
// state.
|
||||||
|
aState.mFloatManager->AssertStateMatches(aFloatStateBeforeLine);
|
||||||
|
aState.mY += aFloatAvailableSpace.mRect.height;
|
||||||
|
aFloatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||||
} else {
|
} else {
|
||||||
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight,
|
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.availableHeight,
|
||||||
"We shouldn't be running out of height here");
|
"We shouldn't be running out of height here");
|
||||||
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableHeight) {
|
if (NS_UNCONSTRAINEDSIZE == aState.mReflowState.availableHeight) {
|
||||||
// just move it down a bit to try to get out of this mess
|
// just move it down a bit to try to get out of this mess
|
||||||
aState.mY += 1;
|
aState.mY += 1;
|
||||||
|
// We should never hit this case if we've placed floats on the
|
||||||
|
// line; if we have, then the GetFloatAvailableSpace call is wrong
|
||||||
|
// and needs to happen after the caller pops the space manager
|
||||||
|
// state.
|
||||||
|
aState.mFloatManager->AssertStateMatches(aFloatStateBeforeLine);
|
||||||
|
aFloatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||||
} else {
|
} else {
|
||||||
// There's nowhere to retry placing the line. Just treat it as if
|
// There's nowhere to retry placing the line. Just treat it as if
|
||||||
// we placed the float but it was truncated so we need this line
|
// we placed the float but it was truncated so we need this line
|
||||||
@ -3614,30 +3643,22 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||||||
PushTruncatedPlaceholderLine(aState, aLine, *aKeepReflowGoing);
|
PushTruncatedPlaceholderLine(aState, aLine, *aKeepReflowGoing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We don't want to advance by the bottom margin anymore (we did it
|
|
||||||
// once at the beginning of this function, which will just be called
|
|
||||||
// again), and we certainly don't want to go back if it's negative
|
|
||||||
// (infinite loop, bug 153429).
|
|
||||||
aState.mPrevBottomMargin.Zero();
|
|
||||||
|
|
||||||
// XXX: a small optimization can be done here when paginating:
|
// XXX: a small optimization can be done here when paginating:
|
||||||
// if the new Y coordinate is past the end of the block then
|
// if the new Y coordinate is past the end of the block then
|
||||||
// push the line and return now instead of later on after we are
|
// push the line and return now instead of later on after we are
|
||||||
// past the float.
|
// past the float.
|
||||||
}
|
}
|
||||||
else if (LINE_REFLOW_REDO_NO_PULL == lineReflowStatus) {
|
else if (LINE_REFLOW_TRUNCATED != lineReflowStatus &&
|
||||||
// We don't want to advance by the bottom margin anymore (we did it
|
LINE_REFLOW_REDO_NO_PULL != lineReflowStatus) {
|
||||||
// once at the beginning of this function, which will just be called
|
|
||||||
// again), and we certainly don't want to go back if it's negative
|
|
||||||
// (infinite loop, bug 153429).
|
|
||||||
aState.mPrevBottomMargin.Zero();
|
|
||||||
}
|
|
||||||
else if (LINE_REFLOW_TRUNCATED != lineReflowStatus) {
|
|
||||||
// If we are propagating out a break-before status then there is
|
// If we are propagating out a break-before status then there is
|
||||||
// no point in placing the line.
|
// no point in placing the line.
|
||||||
if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) {
|
if (!NS_INLINE_IS_BREAK_BEFORE(aState.mReflowStatus)) {
|
||||||
PlaceLine(aState, aLineLayout, aLine, aKeepReflowGoing);
|
if (!PlaceLine(aState, aLineLayout, aLine, aFloatStateBeforeLine,
|
||||||
|
aFloatAvailableSpace.mRect, aKeepReflowGoing)) {
|
||||||
|
lineReflowStatus = LINE_REFLOW_REDO_MORE_FLOATS;
|
||||||
|
// PlaceLine already called GetAvailableSpaceForHeight for us.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -4017,10 +4038,12 @@ nsBlockFrame::ShouldJustifyLine(nsBlockReflowState& aState,
|
|||||||
return PR_FALSE;
|
return PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
PRBool
|
||||||
nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
||||||
nsLineLayout& aLineLayout,
|
nsLineLayout& aLineLayout,
|
||||||
line_iterator aLine,
|
line_iterator aLine,
|
||||||
|
nsFloatManager::SavedState *aFloatStateBeforeLine,
|
||||||
|
nsRect& aFloatAvailableSpace,
|
||||||
PRBool* aKeepReflowGoing)
|
PRBool* aKeepReflowGoing)
|
||||||
{
|
{
|
||||||
// Trim extra white-space from the line before placing the frames
|
// Trim extra white-space from the line before placing the frames
|
||||||
@ -4049,6 +4072,26 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
}
|
}
|
||||||
aLineLayout.VerticalAlignLine();
|
aLineLayout.VerticalAlignLine();
|
||||||
|
|
||||||
|
// We want to compare to the available space that we would have had in
|
||||||
|
// the line's height *before* we placed any floats in the line itself.
|
||||||
|
// Floats that are in the line are handled during line reflow (and may
|
||||||
|
// result in floats being pushed to below the line or (I HOPE???) in a
|
||||||
|
// reflow with a forced break position).
|
||||||
|
nsRect oldFloatAvailableSpace(aFloatAvailableSpace);
|
||||||
|
aFloatAvailableSpace =
|
||||||
|
aState.GetFloatAvailableSpaceForHeight(aLine->mBounds.y,
|
||||||
|
aLine->mBounds.height,
|
||||||
|
aFloatStateBeforeLine).mRect;
|
||||||
|
NS_ASSERTION(aFloatAvailableSpace.y == oldFloatAvailableSpace.y, "yikes");
|
||||||
|
// Restore the height to the position of the next band.
|
||||||
|
aFloatAvailableSpace.height = oldFloatAvailableSpace.height;
|
||||||
|
// If the available space between the floats is smaller now that we
|
||||||
|
// know the height, return false (and cause another pass with
|
||||||
|
// LINE_REFLOW_REDO_MORE_FLOATS).
|
||||||
|
if (AvailableSpaceShrunk(oldFloatAvailableSpace, aFloatAvailableSpace)) {
|
||||||
|
return PR_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
{
|
{
|
||||||
static nscoord lastHeight = 0;
|
static nscoord lastHeight = 0;
|
||||||
@ -4143,7 +4186,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
|
||||||
*aKeepReflowGoing = PR_FALSE;
|
*aKeepReflowGoing = PR_FALSE;
|
||||||
}
|
}
|
||||||
return;
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// May be needed below
|
// May be needed below
|
||||||
@ -4200,6 +4243,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||||||
if (aLine->HasFloatBreakAfter()) {
|
if (aLine->HasFloatBreakAfter()) {
|
||||||
aState.mY = aState.ClearFloats(aState.mY, aLine->GetBreakTypeAfter());
|
aState.mY = aState.ClearFloats(aState.mY, aLine->GetBreakTypeAfter());
|
||||||
}
|
}
|
||||||
|
return PR_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "nsLineBox.h"
|
#include "nsLineBox.h"
|
||||||
#include "nsCSSPseudoElements.h"
|
#include "nsCSSPseudoElements.h"
|
||||||
#include "nsStyleSet.h"
|
#include "nsStyleSet.h"
|
||||||
|
#include "nsFloatManager.h"
|
||||||
|
|
||||||
enum LineReflowStatus {
|
enum LineReflowStatus {
|
||||||
// The line was completely reflowed and fit in available width, and we should
|
// The line was completely reflowed and fit in available width, and we should
|
||||||
@ -61,6 +62,10 @@ enum LineReflowStatus {
|
|||||||
// We need to reflow the line again at its current vertical position. The
|
// We need to reflow the line again at its current vertical position. The
|
||||||
// new reflow should not try to pull up any frames from the next line.
|
// new reflow should not try to pull up any frames from the next line.
|
||||||
LINE_REFLOW_REDO_NO_PULL,
|
LINE_REFLOW_REDO_NO_PULL,
|
||||||
|
// We need to reflow the line again using the floats from its height
|
||||||
|
// this reflow, since its height made it hit floats that were not
|
||||||
|
// adjacent to its top.
|
||||||
|
LINE_REFLOW_REDO_MORE_FLOATS,
|
||||||
// We need to reflow the line again at a lower vertical postion where there
|
// We need to reflow the line again at a lower vertical postion where there
|
||||||
// may be more horizontal space due to different float configuration.
|
// may be more horizontal space due to different float configuration.
|
||||||
LINE_REFLOW_REDO_NEXT_BAND,
|
LINE_REFLOW_REDO_NEXT_BAND,
|
||||||
@ -479,11 +484,15 @@ protected:
|
|||||||
line_iterator aLine,
|
line_iterator aLine,
|
||||||
PRBool* aKeepReflowGoing);
|
PRBool* aKeepReflowGoing);
|
||||||
|
|
||||||
// Return PR_TRUE if aLine gets pushed.
|
// Return false if it needs another reflow because of reduced space
|
||||||
void PlaceLine(nsBlockReflowState& aState,
|
// between floats that are next to it (but not next to its top), and
|
||||||
nsLineLayout& aLineLayout,
|
// return true otherwise.
|
||||||
line_iterator aLine,
|
PRBool PlaceLine(nsBlockReflowState& aState,
|
||||||
PRBool* aKeepReflowGoing);
|
nsLineLayout& aLineLayout,
|
||||||
|
line_iterator aLine,
|
||||||
|
nsFloatManager::SavedState* aFloatStateBeforeLine,
|
||||||
|
nsRect& aFloatAvailableSpace, /* in-out */
|
||||||
|
PRBool* aKeepReflowGoing);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark |aLine| dirty, and, if necessary because of possible
|
* Mark |aLine| dirty, and, if necessary because of possible
|
||||||
@ -522,6 +531,9 @@ protected:
|
|||||||
nsresult DoReflowInlineFrames(nsBlockReflowState& aState,
|
nsresult DoReflowInlineFrames(nsBlockReflowState& aState,
|
||||||
nsLineLayout& aLineLayout,
|
nsLineLayout& aLineLayout,
|
||||||
line_iterator aLine,
|
line_iterator aLine,
|
||||||
|
nsFlowAreaRect& aFloatAvailableSpace,
|
||||||
|
nsFloatManager::SavedState*
|
||||||
|
aFloatStateBeforeLine,
|
||||||
PRBool* aKeepReflowGoing,
|
PRBool* aKeepReflowGoing,
|
||||||
LineReflowStatus* aLineReflowStatus,
|
LineReflowStatus* aLineReflowStatus,
|
||||||
PRBool aAllowPullUp);
|
PRBool aAllowPullUp);
|
||||||
|
@ -366,6 +366,38 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsFlowAreaRect
|
||||||
|
nsBlockReflowState::GetFloatAvailableSpaceForHeight(
|
||||||
|
nscoord aY, nscoord aHeight,
|
||||||
|
nsFloatManager::SavedState *aState) const
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
// Verify that the caller setup the coordinate system properly
|
||||||
|
nscoord wx, wy;
|
||||||
|
mFloatManager->GetTranslation(wx, wy);
|
||||||
|
NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
|
||||||
|
"bad coord system");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
nsFlowAreaRect result =
|
||||||
|
mFloatManager->GetFlowArea(aY - BorderPadding().top,
|
||||||
|
nsFloatManager::WIDTH_WITHIN_HEIGHT,
|
||||||
|
aHeight, mContentArea.width, aState);
|
||||||
|
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||||
|
if (result.mRect.width < 0)
|
||||||
|
result.mRect.width = 0;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
if (nsBlockFrame::gNoisyReflow) {
|
||||||
|
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||||
|
printf("GetAvailableSpaceForHeight: space=%d,%d,%d,%d hasfloats=%d\n",
|
||||||
|
result.mRect.x, result.mRect.y, result.mRect.width,
|
||||||
|
result.mRect.height, result.mHasFloats);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reconstruct the vertical margin before the line |aLine| in order to
|
* Reconstruct the vertical margin before the line |aLine| in order to
|
||||||
* do an incremental reflow that begins with |aLine| without reflowing
|
* do an incremental reflow that begins with |aLine| without reflowing
|
||||||
|
@ -100,6 +100,9 @@ public:
|
|||||||
nsFlowAreaRect
|
nsFlowAreaRect
|
||||||
GetFloatAvailableSpaceWithState(nscoord aY, PRBool aRelaxHeightConstraint,
|
GetFloatAvailableSpaceWithState(nscoord aY, PRBool aRelaxHeightConstraint,
|
||||||
nsFloatManager::SavedState *aState) const;
|
nsFloatManager::SavedState *aState) const;
|
||||||
|
nsFlowAreaRect
|
||||||
|
GetFloatAvailableSpaceForHeight(nscoord aY, nscoord aHeight,
|
||||||
|
nsFloatManager::SavedState *aState) const;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following functions all return PR_TRUE if they were able to
|
* The following functions all return PR_TRUE if they were able to
|
||||||
|
@ -227,6 +227,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType) const;
|
nscoord ClearFloats(nscoord aY, PRUint8 aBreakType) const;
|
||||||
|
|
||||||
|
void AssertStateMatches(SavedState *aState) const
|
||||||
|
{
|
||||||
|
NS_ASSERTION(aState->mX == mX && aState->mY == mY &&
|
||||||
|
aState->mFloatInfoCount == mFloats.Length(),
|
||||||
|
"float manager state should match saved state");
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/**
|
/**
|
||||||
* Dump the state of the float manager out to a file.
|
* Dump the state of the float manager out to a file.
|
||||||
|
@ -36,14 +36,14 @@
|
|||||||
== 23604-1.html 23604-1-ref.html
|
== 23604-1.html 23604-1-ref.html
|
||||||
== 23604-2.html 23604-2-ref.html
|
== 23604-2.html 23604-2-ref.html
|
||||||
!= 24998-1.html 24998-1-ref.html
|
!= 24998-1.html 24998-1-ref.html
|
||||||
fails == 25888-1l.html 25888-1l-ref.html # bug 25888
|
== 25888-1l.html 25888-1l-ref.html
|
||||||
fails != 25888-1l.html 25888-1l-notref.html # bug 25888
|
!= 25888-1l.html 25888-1l-notref.html
|
||||||
fails == 25888-1r.html 25888-1r-ref.html # bug 25888
|
== 25888-1r.html 25888-1r-ref.html
|
||||||
fails != 25888-1r.html 25888-1r-notref.html # bug 25888
|
!= 25888-1r.html 25888-1r-notref.html
|
||||||
fails == 25888-2l.html 25888-2l-ref.html # bug 25888
|
== 25888-2l.html 25888-2l-ref.html
|
||||||
fails == 25888-2r.html 25888-2r-ref.html # bug 25888
|
== 25888-2r.html 25888-2r-ref.html
|
||||||
fails == 25888-3l.html 25888-3l-ref.html # bug 25888
|
== 25888-3l.html 25888-3l-ref.html
|
||||||
fails == 25888-3r.html 25888-3r-ref.html # bug 25888
|
== 25888-3r.html 25888-3r-ref.html
|
||||||
== 28811-1a.html 28811-1-ref.html
|
== 28811-1a.html 28811-1-ref.html
|
||||||
== 28811-1b.html 28811-1-ref.html
|
== 28811-1b.html 28811-1-ref.html
|
||||||
== 28811-2a.html 28811-2-ref.html
|
== 28811-2a.html 28811-2-ref.html
|
||||||
|
9
layout/reftests/floats/345369-1-ref.html
Normal file
9
layout/reftests/floats/345369-1-ref.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; position: absolute">
|
||||||
|
<div style="position: absolute; top: 0; left: 0; height: 0.5em; width: 1em; background: blue"></div>
|
||||||
|
<div style="position: absolute; top: 0.5em; left: 0; height: 2em; width: 10em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="position: absolute; top: 2.5em; left: 0; height: 1em; width: 4em; background: maroon;"></span>
|
||||||
|
|
||||||
|
</div>
|
9
layout/reftests/floats/345369-1.html
Normal file
9
layout/reftests/floats/345369-1.html
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; line-height: 1; font-family: sans-serif;">
|
||||||
|
<div style="float: left; height: 0.5em; width: 1em; background: blue"></div>
|
||||||
|
<div style="float: left; height: 2em; width: 10em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="display:inline-block; height: 1em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-2-ref.html
Normal file
10
layout/reftests/floats/345369-2-ref.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; position: relative">
|
||||||
|
<div style="position: absolute; top: 0; left: 0; height: 2em; width: 1em; background: blue"></div>
|
||||||
|
<div style="position: absolute; top: 2em; left: 0; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="position: absolute; top: 0; left: 1em; height: 1em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="position: absolute; top: 1em; left: 5em; height: 3em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
12
layout/reftests/floats/345369-2.html
Normal file
12
layout/reftests/floats/345369-2.html
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; line-height: 1; font-family: sans-serif;">
|
||||||
|
<div style="float: left; height: 2em; width: 1em; background: blue"></div>
|
||||||
|
<div style="float: left; clear: left; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<!-- small <span style="font-size: 3em">big</span> -->
|
||||||
|
|
||||||
|
<span style="display:inline-block; height: 1em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="display:inline-block; height: 3em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-3-ref.html
Normal file
10
layout/reftests/floats/345369-3-ref.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; position: relative">
|
||||||
|
<div style="position: absolute; top: 0; left: 0; height: 2em; width: 1em; background: blue"></div>
|
||||||
|
<div style="position: absolute; top: 2em; left: 0; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="position: absolute; top: 0; left: 1em; height: 1em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="position: absolute; top: 4em; left: 0; height: 3em; width: 6em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-3.html
Normal file
10
layout/reftests/floats/345369-3.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; line-height: 1; font-family: sans-serif;">
|
||||||
|
<div style="float: left; height: 2em; width: 1em; background: blue"></div>
|
||||||
|
<div style="float: left; clear: left; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="display:inline-block; height: 1em; width: 4em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="display:inline-block; height: 3em; width: 6em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-4-ref.html
Normal file
10
layout/reftests/floats/345369-4-ref.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; position: relative">
|
||||||
|
<div style="position: absolute; top: 0; left: 0; height: 2em; width: 2em; background: blue"></div>
|
||||||
|
<div style="position: absolute; top: 2em; left: 0; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="position: absolute; top: 0; left: 2em; height: 1em; width: 3em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="position: absolute; top: 1em; left: 5em; height: 3em; width: 5em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-4.html
Normal file
10
layout/reftests/floats/345369-4.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; line-height: 1; font-family: sans-serif;">
|
||||||
|
<div style="float: left; height: 2em; width: 2em; background: blue"></div>
|
||||||
|
<div style="float: left; clear: left; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="display:inline-block; height: 1em; width: 3em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="display:inline-block; height: 3em; width: 5em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-5-ref.html
Normal file
10
layout/reftests/floats/345369-5-ref.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; position: relative">
|
||||||
|
<div style="position: absolute; top: 0; left: 0; height: 2em; width: 2em; background: blue"></div>
|
||||||
|
<div style="position: absolute; top: 2em; left: 0; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="position: absolute; top: 0; left: 2em; height: 1em; width: 2em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="position: absolute; top: 4em; left: 0; height: 3em; width: 6em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
10
layout/reftests/floats/345369-5.html
Normal file
10
layout/reftests/floats/345369-5.html
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<title>Ambiguous line width</title>
|
||||||
|
|
||||||
|
<div style="background: yellow; width: 10em; height: 10em; line-height: 1; font-family: sans-serif;">
|
||||||
|
<div style="float: left; height: 2em; width: 2em; background: blue"></div>
|
||||||
|
<div style="float: left; clear: left; height: 2em; width: 5em; background: aqua"></div>
|
||||||
|
|
||||||
|
<span style="display:inline-block; height: 1em; width: 2em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
<span style="display:inline-block; height: 3em; width: 6em; background: maroon; vertical-align: bottom"></span>
|
||||||
|
|
||||||
|
</div>
|
@ -7,5 +7,10 @@ fails == other-float-outside-rule-3-right-2.html other-float-outside-rule-3-righ
|
|||||||
fails == other-float-outside-rule-7-left.html other-float-outside-rule-7-left-ref.html
|
fails == other-float-outside-rule-7-left.html other-float-outside-rule-7-left-ref.html
|
||||||
fails == other-float-outside-rule-7-right.html other-float-outside-rule-7-right-ref.html
|
fails == other-float-outside-rule-7-right.html other-float-outside-rule-7-right-ref.html
|
||||||
== float-outside-block-push.html float-outside-block-push-ref.html
|
== float-outside-block-push.html float-outside-block-push-ref.html
|
||||||
fails == zero-height-float-base.html zero-height-float-ref.html
|
== zero-height-float-base.html zero-height-float-ref.html
|
||||||
fails == zero-height-float.html zero-height-float-ref.html
|
fails == zero-height-float.html zero-height-float-ref.html
|
||||||
|
fails == 345369-1.html 345369-1-ref.html
|
||||||
|
fails == 345369-2.html 345369-2-ref.html
|
||||||
|
== 345369-3.html 345369-3-ref.html
|
||||||
|
== 345369-4.html 345369-4-ref.html
|
||||||
|
== 345369-5.html 345369-5-ref.html
|
||||||
|
Loading…
Reference in New Issue
Block a user