Bug 1463745 Part 2: Change nsFlowAreaRect to also track whether it may widen in the block direction. r=dbaron

MozReview-Commit-ID: FWKQEFDBFgr

--HG--
extra : rebase_source : d08e5b466dd6a7f0a61b5a3142eb756e17446473
This commit is contained in:
Brad Werth 2018-05-30 11:07:18 -07:00
Родитель 87348ed21e
Коммит 5cb7ed31be
4 изменённых файлов: 52 добавлений и 23 удалений

Просмотреть файл

@ -225,7 +225,7 @@ BlockReflowInput::ComputeBlockAvailSpace(nsIFrame* aFrame,
{
#ifdef REALLY_NOISY_REFLOW
printf("CBAS frame=%p has floats %d\n",
aFrame, aFloatAvailableSpace.mHasFloats);
aFrame, aFloatAvailableSpace.HasFloats());
#endif
WritingMode wm = mReflowInput.GetWritingMode();
aResult.BStart(wm) = mBCoord;
@ -253,7 +253,7 @@ BlockReflowInput::ComputeBlockAvailSpace(nsIFrame* aFrame,
!aBlockAvoidsFloats,
"unexpected replaced width");
if (!aBlockAvoidsFloats) {
if (aFloatAvailableSpace.mHasFloats) {
if (aFloatAvailableSpace.HasFloats()) {
// Use the float-edge property to determine how the child block
// will interact with the float.
const nsStyleBorder* borderStyle = aFrame->StyleBorder();
@ -301,7 +301,7 @@ bool
BlockReflowInput::ReplacedBlockFitsInAvailSpace(nsIFrame* aReplacedBlock,
const nsFlowAreaRect& aFloatAvailableSpace) const
{
if (!aFloatAvailableSpace.mHasFloats) {
if (!aFloatAvailableSpace.HasFloats()) {
// If there aren't any floats here, then we always fit.
// We check this before calling ISizeToClearPastFloats, which is
// somewhat expensive.
@ -355,7 +355,7 @@ BlockReflowInput::GetFloatAvailableSpaceWithState(
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("%s: band=%d,%d,%d,%d hasfloats=%d\n", __func__,
result.mRect.IStart(wm), result.mRect.BStart(wm),
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
result.mRect.ISize(wm), result.mRect.BSize(wm), result.HasFloats());
}
#endif
return result;
@ -390,7 +390,7 @@ BlockReflowInput::GetFloatAvailableSpaceForBSize(
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("%s: space=%d,%d,%d,%d hasfloats=%d\n", __func__,
result.mRect.IStart(wm), result.mRect.BStart(wm),
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
result.mRect.ISize(wm), result.mRect.BSize(wm), result.HasFloats());
}
#endif
return result;
@ -669,7 +669,7 @@ BlockReflowInput::CanPlaceFloat(nscoord aFloatISize,
// its inline size fits in the space remaining after prior floats have
// been placed.
// FIXME: We should allow overflow by up to half a pixel here (bug 21193).
return !aFloatAvailableSpace.mHasFloats ||
return !aFloatAvailableSpace.HasFloats() ||
aFloatAvailableSpace.mRect.ISize(mReflowInput.GetWritingMode()) >=
aFloatISize;
}

Просмотреть файл

@ -2070,13 +2070,13 @@ nsBlockFrame::PropagateFloatDamage(BlockReflowInput& aState,
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::PropagateFloatDamage %p was = %d, is=%d\n",
this, wasImpactedByFloat, floatAvailableSpace.mHasFloats);
this, wasImpactedByFloat, floatAvailableSpace.HasFloats());
#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 || floatAvailableSpace.mHasFloats) {
if (wasImpactedByFloat || floatAvailableSpace.HasFloats()) {
aLine->MarkDirty();
}
}
@ -2822,7 +2822,7 @@ nsBlockFrame::ReflowLine(BlockReflowInput& aState,
nsFlowAreaRect r = aState.GetFloatAvailableSpaceForBSize(aLine->BStart(),
aLine->BSize(),
nullptr);
if (r.mHasFloats) {
if (r.HasFloats()) {
LogicalRect so =
aLine->GetOverflowArea(eScrollableOverflow, wm, aLine->mContainerSize);
nscoord s = r.mRect.IStart(wm);
@ -3433,8 +3433,8 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& aState,
nsFloatManager::SavedState floatManagerState;
nsReflowStatus frameReflowStatus;
do {
if (floatAvailableSpace.mHasFloats) {
// Set if floatAvailableSpace.mHasFloats is true for any
if (floatAvailableSpace.HasFloats()) {
// Set if floatAvailableSpace.HasFloats() is true for any
// iteration of the loop.
aLine->SetLineIsImpactedByFloat(true);
}
@ -3600,7 +3600,7 @@ nsBlockFrame::ReflowBlockFrame(BlockReflowInput& 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.
bool forceFit = aState.IsAdjacentWithTop() && clearance <= 0 &&
!floatAvailableSpace.mHasFloats;
!floatAvailableSpace.HasFloats();
nsCollapsingMargin collapsedBEndMargin;
nsOverflowAreas overflowAreas;
*aKeepReflowGoing = brc.PlaceBlock(*blockHtmlRI, forceFit, aLine.get(),
@ -3890,11 +3890,11 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState,
// We need to set this flag on the line if any of our reflow passes
// are impacted by floats.
if (aFloatAvailableSpace.mHasFloats)
if (aFloatAvailableSpace.HasFloats())
aLine->SetLineIsImpactedByFloat(true);
#ifdef REALLY_NOISY_REFLOW
printf("nsBlockFrame::DoReflowInlineFrames %p impacted = %d\n",
this, aFloatAvailableSpace.mHasFloats);
this, aFloatAvailableSpace.HasFloats());
#endif
WritingMode outerWM = aState.mReflowInput.GetWritingMode();
@ -3920,7 +3920,7 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState,
aLineLayout.BeginLineReflow(iStart, aState.mBCoord,
availISize, availBSize,
aFloatAvailableSpace.mHasFloats,
aFloatAvailableSpace.HasFloats(),
false, /*XXX isTopOfPage*/
lineWM, aState.mContainerSize);
@ -3942,7 +3942,7 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState,
int32_t i;
nsIFrame* frame = aLine->mFirstChild;
if (aFloatAvailableSpace.mHasFloats) {
if (aFloatAvailableSpace.HasFloats()) {
// 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(
@ -4043,7 +4043,7 @@ nsBlockFrame::DoReflowInlineFrames(BlockReflowInput& aState,
// See the analogous code for blocks in BlockReflowInput::ClearFloats.
if (aFloatAvailableSpace.mRect.BSize(outerWM) > 0) {
NS_ASSERTION(aFloatAvailableSpace.mHasFloats,
NS_ASSERTION(aFloatAvailableSpace.HasFloats(),
"redo line on totally empty line with non-empty band...");
// We should never hit this case if we've placed floats on the
// line; if we have, then the GetFloatAvailableSpace call is wrong

Просмотреть файл

@ -144,7 +144,8 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBCoord, nscoord aBSize,
(mFloats[floatCount-1].mLeftBEnd <= blockStart &&
mFloats[floatCount-1].mRightBEnd <= blockStart)) {
return nsFlowAreaRect(aWM, aContentArea.IStart(aWM), aBCoord,
aContentArea.ISize(aWM), aBSize, false);
aContentArea.ISize(aWM), aBSize,
nsFlowAreaRectFlags::NO_FLAGS);
}
nscoord blockEnd;
@ -170,6 +171,7 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBCoord, nscoord aBSize,
// Walk backwards through the floats until we either hit the front of
// the list or we're above |blockStart|.
bool haveFloats = false;
bool mayWiden = false;
for (uint32_t i = floatCount; i > 0; --i) {
const FloatInfo &fi = mFloats[i-1];
if (fi.mLeftBEnd <= blockStart && fi.mRightBEnd <= blockStart) {
@ -218,6 +220,10 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBCoord, nscoord aBSize,
// callers want and disagrees for other callers, so we should
// probably provide better information at some point.
haveFloats = true;
// Our area may widen in the block direction if this float may
// narrow in the block direction.
mayWiden = mayWiden || fi.MayNarrowInBlockDirection(aShapeType);
}
} else {
// A right float
@ -227,6 +233,7 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBCoord, nscoord aBSize,
lineRight = lineLeftEdge;
// See above.
haveFloats = true;
mayWiden = mayWiden || fi.MayNarrowInBlockDirection(aShapeType);
}
}
@ -245,8 +252,12 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBCoord, nscoord aBSize,
: mLineLeft - lineRight +
LogicalSize(aWM, aContainerSize).ISize(aWM);
nsFlowAreaRectFlags flags =
(haveFloats ? nsFlowAreaRectFlags::HAS_FLOATS : nsFlowAreaRectFlags::NO_FLAGS) |
(mayWiden ? nsFlowAreaRectFlags::MAY_WIDEN : nsFlowAreaRectFlags::NO_FLAGS);
return nsFlowAreaRect(aWM, inlineStart, blockStart - mBlockStart,
lineRight - lineLeft, blockSize, haveFloats);
lineRight - lineLeft, blockSize, flags);
}
void

Просмотреть файл

@ -10,6 +10,7 @@
#define nsFloatManager_h_
#include "mozilla/Attributes.h"
#include "mozilla/TypedEnumBits.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/WritingModes.h"
#include "nsCoord.h"
@ -26,23 +27,40 @@ struct ReflowInput;
class StyleBasicShape;
} // namespace mozilla
enum class nsFlowAreaRectFlags : uint32_t {
NO_FLAGS = 0,
HAS_FLOATS = 1 << 0,
MAY_WIDEN = 1 << 1
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsFlowAreaRectFlags)
/**
* The available space for content not occupied by floats is divided
* into a sequence of rectangles in the block direction. 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.
* the content rectangle. If it has been reduced by floats, then we also
* track whether the flow area might widen as the floats narrow in the
* block direction.
*/
struct nsFlowAreaRect {
mozilla::LogicalRect mRect;
bool mHasFloats;
nsFlowAreaRectFlags mAreaFlags;
nsFlowAreaRect(mozilla::WritingMode aWritingMode,
nscoord aICoord, nscoord aBCoord,
nscoord aISize, nscoord aBSize,
bool aHasFloats)
nsFlowAreaRectFlags aAreaFlags)
: mRect(aWritingMode, aICoord, aBCoord, aISize, aBSize)
, mHasFloats(aHasFloats) {}
, mAreaFlags(aAreaFlags) {}
bool HasFloats() const {
return (bool)(mAreaFlags & nsFlowAreaRectFlags::HAS_FLOATS);
}
bool MayWiden() const {
return (bool)(mAreaFlags & nsFlowAreaRectFlags::MAY_WIDEN);
}
};
#define NS_FLOAT_MANAGER_CACHE_SIZE 64