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