зеркало из https://github.com/mozilla/pjs.git
Bug 288560. Set mIsTopOfPage for each column in a column set. Also, make it possible to force floats to fit by relaxing the space manager's height constraint if necessary. r+sr=dbaron,a=chofmann
This commit is contained in:
Родитель
8e32ad6218
Коммит
907a58adbb
|
@ -79,10 +79,11 @@ nsBlockBandData::Init(nsSpaceManager* aSpaceManager,
|
|||
// available space is relative to our coordinate system (0,0) is our
|
||||
// upper left corner.
|
||||
nsresult
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
|
||||
nsBlockBandData::GetAvailableSpace(nscoord aY, PRBool aRelaxHeightConstraint,
|
||||
nsRect& aResult)
|
||||
{
|
||||
// Get the raw band data for the given Y coordinate
|
||||
nsresult rv = GetBandData(aY);
|
||||
nsresult rv = GetBandData(aY, aRelaxHeightConstraint);
|
||||
if (NS_FAILED(rv)) { return rv; }
|
||||
|
||||
// Compute the bounding rect of the available space, i.e. space
|
||||
|
@ -104,11 +105,15 @@ nsBlockBandData::GetAvailableSpace(nscoord aY, nsRect& aResult)
|
|||
* They should always call nsBlockBandData::GetBandData() instead.
|
||||
*/
|
||||
nsresult
|
||||
nsBlockBandData::GetBandData(nscoord aY)
|
||||
nsBlockBandData::GetBandData(nscoord aY, PRBool aRelaxHeightConstraint)
|
||||
{
|
||||
NS_ASSERTION(mSpaceManager, "bad state, no space manager");
|
||||
PRInt32 iterations =0;
|
||||
nsresult rv = mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
nsSize space = mSpace;
|
||||
if (aRelaxHeightConstraint) {
|
||||
space.height = NS_UNCONSTRAINEDSIZE;
|
||||
}
|
||||
nsresult rv = mSpaceManager->GetBandData(aY, space, *this);
|
||||
while (NS_FAILED(rv)) {
|
||||
iterations++;
|
||||
if (iterations>ERROR_TOO_MANY_ITERATIONS)
|
||||
|
@ -131,7 +136,7 @@ nsBlockBandData::GetBandData(nscoord aY)
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mSize = newSize;
|
||||
rv = mSpaceManager->GetBandData(aY, mSpace, *this);
|
||||
rv = mSpaceManager->GetBandData(aY, space, *this);
|
||||
}
|
||||
NS_POSTCONDITION(mCount<=mSize, "bad state, count > size");
|
||||
return NS_OK;
|
||||
|
|
|
@ -58,7 +58,8 @@ public:
|
|||
|
||||
// Get some available space. Note that aY is relative to the current
|
||||
// space manager translation.
|
||||
nsresult GetAvailableSpace(nscoord aY, nsRect& aResult);
|
||||
nsresult GetAvailableSpace(nscoord aY, PRBool aRelaxHeightConstraint,
|
||||
nsRect& aResult);
|
||||
|
||||
// Get the raw trapezoid count for this band.
|
||||
PRInt32 GetTrapezoidCount() const {
|
||||
|
@ -95,7 +96,7 @@ protected:
|
|||
* They should always call this method instead so data members
|
||||
* mTrapezoid, mCount, and mSize all get managed properly.
|
||||
*/
|
||||
nsresult GetBandData(nscoord aY);
|
||||
nsresult GetBandData(nscoord aY, PRBool aRelaxHeightConstraint);
|
||||
|
||||
// The spacemanager we are getting space from
|
||||
nsSpaceManager* mSpaceManager;
|
||||
|
|
|
@ -1999,7 +1999,7 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||
// XXXPerf: An optimization: if the line was and is completely
|
||||
// impacted by a float and the float hasn't changed size,
|
||||
// then we don't need to mark the line dirty.
|
||||
aState.GetAvailableSpace(aLine->mBounds.y + aDeltaY);
|
||||
aState.GetAvailableSpace(aLine->mBounds.y + aDeltaY, PR_FALSE);
|
||||
PRBool wasImpactedByFloat = aLine->IsImpactedByFloat();
|
||||
PRBool isImpactedByFloat = aState.IsImpactedByFloat();
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
|
@ -4507,6 +4507,9 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
// May be needed below
|
||||
PRBool wasAdjacentWIthTop = aState.IsAdjacentWithTop();
|
||||
|
||||
aState.mY = newY;
|
||||
|
||||
// If we're reflowing the line just to incrementally update the
|
||||
|
@ -4541,13 +4544,14 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
if (aState.mBelowCurrentLineFloats.NotEmpty()) {
|
||||
// Reflow the below-current-line floats, then add them to the
|
||||
// lines float list if there aren't any truncated floats.
|
||||
if (aState.PlaceBelowCurrentLineFloats(aState.mBelowCurrentLineFloats)) {
|
||||
if (aState.PlaceBelowCurrentLineFloats(aState.mBelowCurrentLineFloats,
|
||||
wasAdjacentWIthTop)) {
|
||||
aLine->AppendFloats(aState.mBelowCurrentLineFloats);
|
||||
}
|
||||
else {
|
||||
// At least one float is truncated, so fix up any placeholders that got split and
|
||||
// push the line. XXX It may be better to put the float on the next line, but this
|
||||
// is not common enough to justify the complexity.
|
||||
// is not common enough to justify the complexity. Or maybe it is now...
|
||||
|
||||
// If we just want to calculate the maximum width, then don't push the line.
|
||||
// We'll reflow it again and then it will get pushed if necessary.
|
||||
|
@ -5731,7 +5735,7 @@ nsBlockFrame::DeleteNextInFlowChild(nsPresContext* aPresContext,
|
|||
nsresult
|
||||
nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
||||
nsPlaceholderFrame* aPlaceholder,
|
||||
nsFloatCache* aFloatCache,
|
||||
nsFloatCache* aFloatCache,
|
||||
nsReflowStatus& aReflowStatus)
|
||||
{
|
||||
// Reflow the float.
|
||||
|
@ -6190,7 +6194,7 @@ nsBlockFrame::Paint(nsPresContext* aPresContext,
|
|||
nscoord y = 0;
|
||||
while (y < mRect.height) {
|
||||
nsRect availArea;
|
||||
band.GetAvailableSpace(y, availArea);
|
||||
band.GetAvailableSpace(y, PR_FALSE, availArea);
|
||||
|
||||
// Render a box and a diagonal line through the band
|
||||
aRenderingContext.SetColor(NS_RGB(0,255,0));
|
||||
|
|
|
@ -325,7 +325,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
}
|
||||
|
||||
void
|
||||
nsBlockReflowState::GetAvailableSpace(nscoord aY)
|
||||
nsBlockReflowState::GetAvailableSpace(nscoord aY, PRBool aRelaxHeightConstraint)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
// Verify that the caller setup the coordinate system properly
|
||||
|
@ -335,7 +335,8 @@ nsBlockReflowState::GetAvailableSpace(nscoord aY)
|
|||
"bad coord system");
|
||||
#endif
|
||||
|
||||
mBand.GetAvailableSpace(aY - BorderPadding().top, mAvailSpaceRect);
|
||||
mBand.GetAvailableSpace(aY - BorderPadding().top, aRelaxHeightConstraint,
|
||||
mAvailSpaceRect);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
|
@ -613,10 +614,15 @@ nsBlockReflowState::AddFloat(nsLineLayout& aLineLayout,
|
|||
|
||||
// And then place it
|
||||
PRBool isLeftFloat;
|
||||
placed = FlowAndPlaceFloat(fc, &isLeftFloat, aReflowStatus);
|
||||
// force it to fit if we're at the top of the block and we can't
|
||||
// break before this
|
||||
PRBool forceFit = IsAdjacentWithTop() && !aLineLayout.LineIsBreakable();
|
||||
placed = FlowAndPlaceFloat(fc, &isLeftFloat, aReflowStatus, forceFit);
|
||||
NS_ASSERTION(placed || !forceFit,
|
||||
"If we asked for force-fit, it should have been placed");
|
||||
if (placed) {
|
||||
// Pass on updated available space to the current inline reflow engine
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, forceFit);
|
||||
aLineLayout.UpdateBand(mAvailSpaceRect.x + BorderPadding().left, mY,
|
||||
GetFlag(BRS_UNCONSTRAINEDWIDTH) ? NS_UNCONSTRAINEDSIZE : mAvailSpaceRect.width,
|
||||
mAvailSpaceRect.height,
|
||||
|
@ -683,7 +689,7 @@ nsBlockReflowState::UpdateMaximumWidth(nscoord aMaximumWidth)
|
|||
|
||||
PRBool
|
||||
nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize,
|
||||
PRUint8 aFloats)
|
||||
PRUint8 aFloats, PRBool aForceFit)
|
||||
{
|
||||
// If the current Y coordinate is not impacted by any floats
|
||||
// then by definition the float fits.
|
||||
|
@ -748,7 +754,7 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize,
|
|||
}
|
||||
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, aForceFit);
|
||||
|
||||
if (0 == mBand.GetFloatCount()) {
|
||||
// Winner. This band has no floats on it, therefore
|
||||
|
@ -776,7 +782,7 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize,
|
|||
// Restore Y coordinate and available space information
|
||||
// regardless of the outcome.
|
||||
mY = saveY;
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, aForceFit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -786,7 +792,8 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize,
|
|||
PRBool
|
||||
nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
||||
PRBool* aIsLeftFloat,
|
||||
nsReflowStatus& aReflowStatus)
|
||||
nsReflowStatus& aReflowStatus,
|
||||
PRBool aForceFit)
|
||||
{
|
||||
aReflowStatus = NS_FRAME_COMPLETE;
|
||||
// Save away the Y coordinate before placing the float. We will
|
||||
|
@ -816,7 +823,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
|||
mY = ClearFloats(mY, floatDisplay->mBreakType);
|
||||
}
|
||||
// Get the band of available space
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, aForceFit);
|
||||
|
||||
NS_ASSERTION(floatFrame->GetParent() == mBlock,
|
||||
"Float frame has wrong parent");
|
||||
|
@ -851,7 +858,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
|||
// Can the float fit here?
|
||||
PRBool keepFloatOnSameLine = PR_FALSE;
|
||||
|
||||
while (! CanPlaceFloat(floatSize, floatDisplay->mFloats)) {
|
||||
while (!CanPlaceFloat(floatSize, floatDisplay->mFloats, aForceFit)) {
|
||||
if (mAvailSpaceRect.height <= 0) {
|
||||
// No space, nowhere to put anything.
|
||||
mY = saveY;
|
||||
|
@ -863,7 +870,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
|||
eCompatibility_NavQuirks != mPresContext->CompatibilityMode() ) {
|
||||
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, aForceFit);
|
||||
} else {
|
||||
// This quirk matches the one in nsBlockFrame::ReflowFloat
|
||||
// IE handles float tables in a very special way
|
||||
|
@ -904,7 +911,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
|||
|
||||
// the table does not fit anymore in this line so advance to next band
|
||||
mY += mAvailSpaceRect.height;
|
||||
GetAvailableSpace();
|
||||
GetAvailableSpace(mY, aForceFit);
|
||||
// reflow the float again now since we have more space
|
||||
mBlock->ReflowFloat(*this, placeholder, aFloatCache, aReflowStatus);
|
||||
// Get the floats bounding box and margin information
|
||||
|
@ -1068,7 +1075,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
|||
* Place below-current-line floats.
|
||||
*/
|
||||
PRBool
|
||||
nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheList& aList)
|
||||
nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheList& aList, PRBool aForceFit)
|
||||
{
|
||||
nsFloatCache* fc = aList.Head();
|
||||
while (fc) {
|
||||
|
@ -1083,11 +1090,12 @@ nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheList& aList)
|
|||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Place the float
|
||||
PRBool isLeftFloat;
|
||||
nsReflowStatus reflowStatus;
|
||||
PRBool placed = FlowAndPlaceFloat(fc, &isLeftFloat, reflowStatus);
|
||||
PRBool placed = FlowAndPlaceFloat(fc, &isLeftFloat, reflowStatus, aForceFit);
|
||||
NS_ASSERTION(placed || !aForceFit,
|
||||
"If we're in force-fit mode, we should have placed the float");
|
||||
|
||||
if (!placed || NS_FRAME_IS_TRUNCATED(reflowStatus)) {
|
||||
// return before processing all of the floats, since the line will be pushed.
|
||||
|
|
|
@ -75,11 +75,8 @@ public:
|
|||
* available space is relative to our coordinate system (0,0) is our
|
||||
* upper left corner.
|
||||
*/
|
||||
void GetAvailableSpace() {
|
||||
GetAvailableSpace(mY);
|
||||
}
|
||||
|
||||
void GetAvailableSpace(nscoord aY);
|
||||
void GetAvailableSpace() { GetAvailableSpace(mY, PR_FALSE); }
|
||||
void GetAvailableSpace(nscoord aY, PRBool aRelaxHeightConstraint);
|
||||
|
||||
/*
|
||||
* The following functions all return PR_TRUE if they were able to
|
||||
|
@ -93,11 +90,12 @@ public:
|
|||
nsPlaceholderFrame* aPlaceholderFrame,
|
||||
PRBool aInitialReflow,
|
||||
nsReflowStatus& aReflowStatus);
|
||||
PRBool CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats);
|
||||
PRBool FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
||||
PRBool CanPlaceFloat(const nsSize& aFloatSize, PRUint8 aFloats, PRBool aForceFit);
|
||||
PRBool FlowAndPlaceFloat(nsFloatCache* aFloatCache,
|
||||
PRBool* aIsLeftFloat,
|
||||
nsReflowStatus& aReflowStatus);
|
||||
PRBool PlaceBelowCurrentLineFloats(nsFloatCacheList& aFloats);
|
||||
nsReflowStatus& aReflowStatus,
|
||||
PRBool aForceFit);
|
||||
PRBool PlaceBelowCurrentLineFloats(nsFloatCacheList& aFloats, PRBool aForceFit);
|
||||
|
||||
// Returns the first coordinate >= aY that clears the
|
||||
// indicated floats.
|
||||
|
|
|
@ -448,7 +448,8 @@ nsColumnSetFrame::ReflowChildren(nsHTMLReflowMetrics& aDesiredSize,
|
|||
nsHTMLReflowState kidReflowState(GetPresContext(), aReflowState, child,
|
||||
availSize, availSize.width,
|
||||
aReflowState.mComputedHeight, tmpReason);
|
||||
|
||||
kidReflowState.mFlags.mIsTopOfPage = PR_TRUE;
|
||||
|
||||
#ifdef DEBUG_roc
|
||||
printf("*** Reflowing child #%d %p: reason = %d, availHeight=%d\n",
|
||||
columnCount, (void*)child, tmpReason, availSize.height);
|
||||
|
|
Загрузка…
Ссылка в новой задаче