Bug 538194 patch 1 - Refactor some code dealing with fitting block formatting contexts around floats into separate functions. r=roc

This commit is contained in:
L. David Baron 2015-08-02 21:03:09 -07:00
parent 3f1d8f48ce
commit 554d404844
4 changed files with 59 additions and 33 deletions

View File

@ -7205,7 +7205,7 @@ nsBlockFrame::BlockCanIntersectFloats(nsIFrame* aFrame)
// matter.
/* static */
nsBlockFrame::ReplacedElementISizeToClear
nsBlockFrame::ISizeToClearPastFloats(nsBlockReflowState& aState,
nsBlockFrame::ISizeToClearPastFloats(const nsBlockReflowState& aState,
const LogicalRect& aFloatAvailableSpace,
nsIFrame* aFrame)
{

View File

@ -324,7 +324,7 @@ public:
{ return marginIStart + borderBoxISize + marginIEnd; }
};
static ReplacedElementISizeToClear
ISizeToClearPastFloats(nsBlockReflowState& aState,
ISizeToClearPastFloats(const nsBlockReflowState& aState,
const mozilla::LogicalRect& aFloatAvailableSpace,
nsIFrame* aFrame);

View File

@ -161,7 +161,7 @@ nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(
nsIFrame* aFrame,
const LogicalRect& aFloatAvailableSpace,
nscoord& aIStartResult,
nscoord& aIEndResult)
nscoord& aIEndResult) const
{
WritingMode wm = mReflowState.GetWritingMode();
// The frame is clueless about the float manager and therefore we
@ -302,6 +302,30 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
#endif
}
bool
nsBlockReflowState::ReplacedBlockFitsInAvailSpace(nsIFrame* aReplacedBlock,
const nsFlowAreaRect& aFloatAvailableSpace) const
{
if (!aFloatAvailableSpace.mHasFloats) {
// If there aren't any floats here, then we always fit.
// We check this before calling ISizeToClearPastFloats, which is
// somewhat expensive.
return true;
}
WritingMode wm = mReflowState.GetWritingMode();
nsBlockFrame::ReplacedElementISizeToClear replacedISize =
nsBlockFrame::ISizeToClearPastFloats(*this, aFloatAvailableSpace.mRect,
aReplacedBlock);
return std::max(aFloatAvailableSpace.mRect.IStart(wm) -
mContentArea.IStart(wm),
replacedISize.marginIStart) +
replacedISize.borderBoxISize +
std::max(mContentArea.IEnd(wm) -
aFloatAvailableSpace.mRect.IEnd(wm),
replacedISize.marginIEnd) <=
mContentArea.ISize(wm);
}
nsFlowAreaRect
nsBlockReflowState::GetFloatAvailableSpaceWithState(
nscoord aBCoord,
@ -1078,7 +1102,6 @@ nsBlockReflowState::ClearFloats(nscoord aBCoord, uint8_t aBreakType,
}
nscoord newBCoord = aBCoord;
WritingMode wm = mReflowState.GetWritingMode();
if (aBreakType != NS_STYLE_CLEAR_NONE) {
newBCoord = mFloatManager->ClearFloats(newBCoord, aBreakType, aFlags);
@ -1087,37 +1110,14 @@ nsBlockReflowState::ClearFloats(nscoord aBCoord, uint8_t aBreakType,
if (aReplacedBlock) {
for (;;) {
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(newBCoord);
if (!floatAvailableSpace.mHasFloats) {
// If there aren't any floats here, then we always fit.
// We check this before calling ISizeToClearPastFloats, which is
// somewhat expensive.
break;
}
nsBlockFrame::ReplacedElementISizeToClear replacedISize =
nsBlockFrame::ISizeToClearPastFloats(*this, floatAvailableSpace.mRect,
aReplacedBlock);
if (std::max(floatAvailableSpace.mRect.IStart(wm) -
mContentArea.IStart(wm),
replacedISize.marginIStart) +
replacedISize.borderBoxISize +
std::max(mContentArea.IEnd(wm) -
floatAvailableSpace.mRect.IEnd(wm),
replacedISize.marginIEnd) <=
mContentArea.ISize(wm)) {
if (ReplacedBlockFitsInAvailSpace(aReplacedBlock, floatAvailableSpace)) {
break;
}
// See the analogous code for inlines in nsBlockFrame::DoReflowInlineFrames
if (floatAvailableSpace.mRect.BSize(wm) > 0) {
// See if there's room in the next band.
newBCoord += floatAvailableSpace.mRect.BSize(wm);
} else {
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) {
// Stop trying to clear here; we'll just get pushed to the
// next column or page and try again there.
break;
}
NS_NOTREACHED("avail space rect with zero height!");
newBCoord += 1;
if (!AdvanceToNextBand(floatAvailableSpace.mRect, &newBCoord)) {
// Stop trying to clear here; we'll just get pushed to the
// next column or page and try again there.
break;
}
}
}

View File

@ -93,6 +93,32 @@ public:
nsIFrame *aReplacedBlock = nullptr,
uint32_t aFlags = 0);
// Advances to the next band, i.e., the next horizontal stripe in
// which there is a different set of floats.
// Return false if it did not advance, which only happens for
// constrained heights (and means that we should get pushed to the
// next column/page).
bool AdvanceToNextBand(const mozilla::LogicalRect& aFloatAvailableSpace,
nscoord *aBCoord) const {
mozilla::WritingMode wm = mReflowState.GetWritingMode();
if (aFloatAvailableSpace.BSize(wm) > 0) {
// See if there's room in the next band.
*aBCoord += aFloatAvailableSpace.BSize(wm);
} else {
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) {
// Stop trying to clear here; we'll just get pushed to the
// next column or page and try again there.
return false;
}
NS_NOTREACHED("avail space rect with zero height!");
*aBCoord += 1;
}
return true;
}
bool ReplacedBlockFitsInAvailSpace(nsIFrame* aReplacedBlock,
const nsFlowAreaRect& aFloatAvailableSpace) const;
bool IsAdjacentWithTop() const {
return mBCoord == mBorderPadding.BStart(mReflowState.GetWritingMode());
}
@ -117,7 +143,7 @@ public:
void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const mozilla::LogicalRect& aFloatAvailableSpace,
nscoord& aIStartResult,
nscoord& aIEndResult);
nscoord& aIEndResult) const;
// Caller must have called GetAvailableSpace for the current mBCoord
void ComputeBlockAvailSpace(nsIFrame* aFrame,