Backed out 4 changesets (bug 1062963, bug 1079139) for failures in 427129-table-caption.html in b2g reftest-6 and Android 2.3 reftest-5

Backed out changeset a9672db96a5d (bug 1079139)
Backed out changeset 241c23570a62 (bug 1062963)
Backed out changeset 90172cc0b012 (bug 1062963)
Backed out changeset 71211c4a4acc (bug 1062963)
This commit is contained in:
Phil Ringnalda 2014-10-19 18:44:16 -07:00
parent 29c89dff4e
commit 8c0ffee828
14 changed files with 567 additions and 818 deletions

View File

@ -507,12 +507,6 @@ public:
aContainerWidth);
}
bool operator==(LogicalPoint aOther) const
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
return mPoint == aOther.mPoint;
}
LogicalPoint operator+(const LogicalPoint& aOther) const
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
@ -524,33 +518,6 @@ public:
mPoint.y + aOther.mPoint.y);
}
LogicalPoint& operator+=(const LogicalPoint& aOther)
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
I() += aOther.I();
B() += aOther.B();
return *this;
}
LogicalPoint operator-(const LogicalPoint& aOther) const
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
// In non-debug builds, LogicalPoint does not store the WritingMode,
// so the first parameter here (which will always be eUnknownWritingMode)
// is ignored.
return LogicalPoint(GetWritingMode(),
mPoint.x - aOther.mPoint.x,
mPoint.y - aOther.mPoint.y);
}
LogicalPoint& operator-=(const LogicalPoint& aOther)
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
I() -= aOther.I();
B() -= aOther.B();
return *this;
}
private:
friend class LogicalRect;
@ -1353,12 +1320,6 @@ public:
void SetEmpty() { mRect.SetEmpty(); }
bool IsEqualEdges(const LogicalRect aOther) const
{
CHECK_WRITING_MODE(aOther.GetWritingMode());
return mRect.IsEqualEdges(aOther.mRect);
}
/* XXX are these correct?
nscoord ILeft(WritingMode aWritingMode) const
{
@ -1471,17 +1432,17 @@ public:
}
}
#if 0 // XXX this would require aContainerWidth as well
/**
* Return a LogicalRect representing this rect in a different writing mode
*/
LogicalRect ConvertTo(WritingMode aToMode, WritingMode aFromMode,
nscoord aContainerWidth) const
LogicalRect ConvertTo(WritingMode aToMode, WritingMode aFromMode) const
{
CHECK_WRITING_MODE(aFromMode);
return aToMode == aFromMode ?
*this : LogicalRect(aToMode, GetPhysicalRect(aFromMode, aContainerWidth),
aContainerWidth);
*this : LogicalRect(aToMode, GetPhysicalRect(aFromMode));
}
#endif
private:
LogicalRect() MOZ_DELETE;

View File

@ -906,20 +906,17 @@ nsBlockFrame::GetPrefWidthTightBounds(nsRenderingContext* aRenderingContext,
}
static bool
AvailableSpaceShrunk(WritingMode aWM,
const LogicalRect& aOldAvailableSpace,
const LogicalRect& aNewAvailableSpace)
AvailableSpaceShrunk(const nsRect& aOldAvailableSpace,
const nsRect& aNewAvailableSpace)
{
if (aNewAvailableSpace.ISize(aWM) == 0) {
// Positions are not significant if the inline size is zero.
return aOldAvailableSpace.ISize(aWM) != 0;
if (aNewAvailableSpace.width == 0) {
// Positions are not significant if the width is zero.
return aOldAvailableSpace.width != 0;
}
NS_ASSERTION(aOldAvailableSpace.IStart(aWM) <=
aNewAvailableSpace.IStart(aWM) &&
aOldAvailableSpace.IEnd(aWM) >=
aNewAvailableSpace.IEnd(aWM),
NS_ASSERTION(aOldAvailableSpace.x <= aNewAvailableSpace.x &&
aOldAvailableSpace.XMost() >= aNewAvailableSpace.XMost(),
"available space should never grow");
return aOldAvailableSpace.ISize(aWM) != aNewAvailableSpace.ISize(aWM);
return aOldAvailableSpace.width != aNewAvailableSpace.width;
}
static LogicalSize
@ -1816,17 +1813,17 @@ nsBlockFrame::PrepareResizeReflow(nsBlockReflowState& aState)
* Propagate reflow "damage" from from earlier lines to the current
* line. The reflow damage comes from the following sources:
* 1. The regions of float damage remembered during reflow.
* 2. The combination of nonzero |aDeltaBCoord| and any impact by a
* float, either the previous reflow or now.
* 2. The combination of nonzero |aDeltaY| and any impact by a float,
* either the previous reflow or now.
*
* When entering this function, |aLine| is still at its old position and
* |aDeltaBCoord| indicates how much it will later be slid (assuming it
* |aDeltaY| indicates how much it will later be slid (assuming it
* doesn't get marked dirty and reflowed entirely).
*/
void
nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
nsLineBox* aLine,
nscoord aDeltaBCoord)
nscoord aDeltaY)
{
nsFloatManager *floatManager = aState.mReflowState.mFloatManager;
NS_ASSERTION((aState.mReflowState.parentReflowState &&
@ -1842,35 +1839,22 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
if (floatManager->HasFloatDamage()) {
// Need to check mBounds *and* mCombinedArea to find intersections
// with aLine's floats
nscoord lineBCoordBefore = aLine->BStart() + aDeltaBCoord;
nscoord lineBCoordAfter = lineBCoordBefore + aLine->BSize();
nscoord lineYA = aLine->BStart() + aDeltaY;
nscoord lineYB = lineYA + aLine->BSize();
// Scrollable overflow should be sufficient for things that affect
// layout.
WritingMode wm = aState.mReflowState.GetWritingMode();
nscoord containerWidth = aState.mContainerWidth;
LogicalRect overflow = aLine->GetOverflowArea(eScrollableOverflow, wm,
containerWidth);
nscoord lineBCoordCombinedBefore = overflow.BStart(wm) + aDeltaBCoord;
nscoord lineBCoordCombinedAfter = lineBCoordCombinedBefore +
overflow.BSize(wm);
// "Translate" the float manager with an offset of (0, 0) in order to
// set the origin to our writing mode
LogicalPoint oPt(wm);
WritingMode oldWM = floatManager->Translate(wm, oPt, containerWidth);
bool isDirty = floatManager->IntersectsDamage(wm, lineBCoordBefore,
lineBCoordAfter) ||
floatManager->IntersectsDamage(wm, lineBCoordCombinedBefore,
lineBCoordCombinedAfter);
floatManager->Untranslate(oldWM, oPt, containerWidth);
if (isDirty) {
nsRect overflow = aLine->GetOverflowArea(eScrollableOverflow);
nscoord lineYCombinedA = overflow.y + aDeltaY;
nscoord lineYCombinedB = lineYCombinedA + overflow.height;
if (floatManager->IntersectsDamage(lineYA, lineYB) ||
floatManager->IntersectsDamage(lineYCombinedA, lineYCombinedB)) {
aLine->MarkDirty();
return;
}
}
// Check if the line is moving relative to the float manager
if (aDeltaBCoord + aState.mReflowState.mBlockDelta != 0) {
if (aDeltaY + aState.mReflowState.mBlockDelta != 0) {
if (aLine->IsBlock()) {
// Unconditionally reflow sliding blocks; we only really need to reflow
// if there's a float impacting this block, but the current float manager
@ -1880,7 +1864,7 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
} else {
bool wasImpactedByFloat = aLine->IsImpactedByFloat();
nsFlowAreaRect floatAvailableSpace =
aState.GetFloatAvailableSpaceForBSize(aLine->BStart() + aDeltaBCoord,
aState.GetFloatAvailableSpaceForBSize(aLine->BStart() + aDeltaY,
aLine->BSize(),
nullptr);
@ -1927,7 +1911,7 @@ nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
}
static void DumpLine(const nsBlockReflowState& aState, nsLineBox* aLine,
nscoord aDeltaBCoord, int32_t aDeltaIndent) {
nscoord aDeltaY, int32_t aDeltaIndent) {
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsRect ovis(aLine->GetVisualOverflowArea());
@ -1940,7 +1924,7 @@ static void DumpLine(const nsBlockReflowState& aState, nsLineBox* aLine,
aLine->ISize(), aLine->BSize(),
ovis.x, ovis.y, ovis.width, ovis.height,
oscr.x, oscr.y, oscr.width, oscr.height,
aDeltaBCoord, aState.mPrevBEndMargin.get(), aLine->GetChildCount());
aDeltaY, aState.mPrevBEndMargin.get(), aLine->GetChildCount());
}
#endif
}
@ -3151,8 +3135,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
aLine.get(), floatAvailableSpace.mHasFloats?"true":"false");
#endif
aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
WritingMode wm = aState.mReflowState.GetWritingMode();
LogicalRect availSpace(wm);
nsRect availSpace;
aState.ComputeBlockAvailSpace(frame, display, floatAvailableSpace,
replacedBlock != nullptr, availSpace);
@ -3162,7 +3145,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// margins at the top of the page as we ought to, it wouldn't be
// needed.
if ((!aState.mReflowState.mFlags.mIsTopOfPage || clearedFloats) &&
availSpace.BSize(wm) < 0) {
availSpace.height < 0) {
// We know already that this child block won't fit on this
// page/column due to the top margin or the clearance. So we need
// to get out of here now. (If we don't, most blocks will handle
@ -3170,9 +3153,9 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// won't, and will thus make their parent overly-large and force
// *it* to be pushed in its entirety.)
// Doing this means that we also don't need to worry about the
// |availSpace.BSize(wm) += bStartMargin| below interacting with
// pushed floats (which force nscoord_MAX clearance) to cause a
// constrained block size to turn into an unconstrained one.
// |availSpace.height += bStartMargin| below interacting with pushed
// floats (which force nscoord_MAX clearance) to cause a
// constrained height to turn into an unconstrained one.
aState.mBCoord = startingBCoord;
aState.mPrevBEndMargin = incomingMargin;
*aKeepReflowGoing = false;
@ -3185,12 +3168,12 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
return;
}
// Now put the block-dir coordinate back to the start of the
// block-start-margin + clearance, and flow the block.
// Now put the Y coordinate back to the top of the top-margin +
// clearance, and flow the block.
aState.mBCoord -= bStartMargin;
availSpace.BStart(wm) -= bStartMargin;
if (NS_UNCONSTRAINEDSIZE != availSpace.BSize(wm)) {
availSpace.BSize(wm) += bStartMargin;
availSpace.y -= bStartMargin;
if (NS_UNCONSTRAINEDSIZE != availSpace.height) {
availSpace.height += bStartMargin;
}
// Reflow the block into the available space
@ -3198,11 +3181,10 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
// will initialize it
nsHTMLReflowState
blockHtmlRS(aState.mPresContext, aState.mReflowState, frame,
availSpace.Size(wm).ConvertTo(frame->GetWritingMode(), wm));
LogicalSize(frame->GetWritingMode(), availSpace.Size()));
blockHtmlRS.mFlags.mHasClearance = aLine->HasClearance();
nsFloatManager::SavedState
floatManagerState(aState.mReflowState.GetWritingMode());
nsFloatManager::SavedState floatManagerState;
if (mayNeedRetry) {
blockHtmlRS.mDiscoveredClearance = &clearanceFrame;
aState.mFloatManager->PushState(&floatManagerState);
@ -3467,8 +3449,7 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
int32_t forceBreakOffset = -1;
gfxBreakPriority forceBreakPriority = gfxBreakPriority::eNoBreak;
do {
nsFloatManager::SavedState
floatManagerState(aState.mReflowState.GetWritingMode());
nsFloatManager::SavedState floatManagerState;
aState.mReflowState.mFloatManager->PushState(&floatManagerState);
// Once upon a time we allocated the first 30 nsLineLayout objects
@ -3560,11 +3541,9 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
this, aFloatAvailableSpace.mHasFloats);
#endif
WritingMode outerWM = aState.mReflowState.GetWritingMode();
WritingMode lineWM = GetWritingMode(aLine->mFirstChild);
LogicalRect lineRect =
aFloatAvailableSpace.mRect.ConvertTo(lineWM, outerWM,
aState.mContainerWidth);
LogicalRect lineRect(lineWM, aFloatAvailableSpace.mRect,
aState.mContainerWidth);
nscoord iStart = lineRect.IStart(lineWM);
nscoord availISize = lineRect.ISize(lineWM);
@ -3701,12 +3680,11 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
//
// What we do is to advance past the first float we find and
// then reflow the line all over again.
NS_ASSERTION(NS_UNCONSTRAINEDSIZE !=
aFloatAvailableSpace.mRect.BSize(outerWM),
"unconstrained block size on totally empty line");
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aFloatAvailableSpace.mRect.height,
"unconstrained height on totally empty line");
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
if (aFloatAvailableSpace.mRect.BSize(outerWM) > 0) {
if (aFloatAvailableSpace.mRect.height > 0) {
NS_ASSERTION(aFloatAvailableSpace.mHasFloats,
"redo line on totally empty line with non-empty band...");
// We should never hit this case if we've placed floats on the
@ -3714,7 +3692,7 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
// and needs to happen after the caller pops the space manager
// state.
aState.mFloatManager->AssertStateMatches(aFloatStateBeforeLine);
aState.mBCoord += aFloatAvailableSpace.mRect.BSize(outerWM);
aState.mBCoord += aFloatAvailableSpace.mRect.height;
aFloatAvailableSpace = aState.GetFloatAvailableSpace();
} else {
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.AvailableBSize(),
@ -4133,7 +4111,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
nsFloatManager::SavedState *aFloatStateBeforeLine,
LogicalRect& aFloatAvailableSpace,
nsRect& aFloatAvailableSpace,
nscoord& aAvailableSpaceHeight,
bool* aKeepReflowGoing)
{
@ -4149,7 +4127,6 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// There are exactly two places a bullet can be placed: near the
// first or second line. It's only placed on the second line in a
// rare case: when the first line is empty.
WritingMode wm = aState.mReflowState.GetWritingMode();
bool addedBullet = false;
if (HasOutsideBullet() &&
((aLine == mLines.front() &&
@ -4160,7 +4137,8 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
nsHTMLReflowMetrics metrics(aState.mReflowState);
nsIFrame* bullet = GetOutsideBullet();
ReflowBullet(bullet, aState, metrics, aState.mBCoord);
NS_ASSERTION(!BulletIsEmpty() || metrics.BSize(wm) == 0,
NS_ASSERTION(!BulletIsEmpty() ||
metrics.BSize(aState.mReflowState.GetWritingMode()) == 0,
"empty bullet took up space");
aLineLayout.AddBulletFrame(bullet, metrics);
addedBullet = true;
@ -4172,7 +4150,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// 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).
LogicalRect oldFloatAvailableSpace(aFloatAvailableSpace);
nsRect oldFloatAvailableSpace(aFloatAvailableSpace);
// As we redo for floats, we can't reduce the amount of height we're
// checking.
aAvailableSpaceHeight = std::max(aAvailableSpaceHeight, aLine->BSize());
@ -4180,14 +4158,13 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
aState.GetFloatAvailableSpaceForBSize(aLine->BStart(),
aAvailableSpaceHeight,
aFloatStateBeforeLine).mRect;
NS_ASSERTION(aFloatAvailableSpace.BStart(wm) ==
oldFloatAvailableSpace.BStart(wm), "yikes");
NS_ASSERTION(aFloatAvailableSpace.y == oldFloatAvailableSpace.y, "yikes");
// Restore the height to the position of the next band.
aFloatAvailableSpace.BSize(wm) = oldFloatAvailableSpace.BSize(wm);
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(wm, oldFloatAvailableSpace, aFloatAvailableSpace)) {
if (AvailableSpaceShrunk(oldFloatAvailableSpace, aFloatAvailableSpace)) {
return false;
}
@ -5737,16 +5714,15 @@ nsBlockFrame::StyleTextForLineLayout()
////////////////////////////////////////////////////////////////////////
// Float support
LogicalRect
nsRect
nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
const LogicalRect& aFloatAvailableSpace,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFloatFrame)
{
// Compute the available inline size. By default, assume the inline
// size of the containing block.
// Compute the available width. By default, assume the width of the
// containing block.
nscoord availISize;
const nsStyleDisplay* floatDisplay = aFloatFrame->StyleDisplay();
WritingMode wm = aState.mReflowState.GetWritingMode();
if (NS_STYLE_DISPLAY_TABLE != floatDisplay->mDisplay ||
eCompatibility_NavQuirks != aState.mPresContext->CompatibilityMode() ) {
@ -5757,7 +5733,7 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
// give tables only the available space
// if they can shrink we may not be constrained to place
// them in the next line
availISize = aFloatAvailableSpace.ISize(wm);
availISize = aFloatAvailableSpace.width;
}
nscoord availBSize = NS_UNCONSTRAINEDSIZE == aState.ContentBSize()
@ -5775,37 +5751,39 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
}
#endif
return LogicalRect(wm, aState.ContentIStart(), aState.ContentBStart(),
availISize, availBSize);
WritingMode wm = aState.mReflowState.GetWritingMode();
LogicalRect availSpace(wm, aState.ContentIStart(), aState.ContentBStart(),
availISize, availBSize);
// for now return a physical rect
return availSpace.GetPhysicalRect(wm, aState.mContainerWidth);
}
nscoord
nsBlockFrame::ComputeFloatISize(nsBlockReflowState& aState,
const LogicalRect& aFloatAvailableSpace,
nsBlockFrame::ComputeFloatWidth(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFloat)
{
NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
"aFloat must be an out-of-flow frame");
// Reflow the float.
LogicalRect availSpace = AdjustFloatAvailableSpace(aState,
aFloatAvailableSpace,
aFloat);
nsRect availSpace = AdjustFloatAvailableSpace(aState, aFloatAvailableSpace,
aFloat);
WritingMode blockWM = aState.mReflowState.GetWritingMode();
WritingMode floatWM = aFloat->GetWritingMode();
nsHTMLReflowState
floatRS(aState.mPresContext, aState.mReflowState, aFloat,
availSpace.Size(blockWM).ConvertTo(floatWM, blockWM));
WritingMode wm = aFloat->GetWritingMode();
nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
LogicalSize(wm, availSpace.Size()));
return floatRS.ComputedSizeWithMarginBorderPadding(blockWM).ISize(blockWM);
return floatRS.ComputedWidth() + floatRS.ComputedPhysicalBorderPadding().LeftRight() +
floatRS.ComputedPhysicalMargin().LeftRight();
}
void
nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
const LogicalRect& aAdjustedAvailableSpace,
const nsRect& aAdjustedAvailableSpace,
nsIFrame* aFloat,
LogicalMargin& aFloatMargin,
LogicalMargin& aFloatOffsets,
nsMargin& aFloatMargin,
nsMargin& aFloatOffsets,
bool aFloatPushedDown,
nsReflowStatus& aReflowStatus)
{
@ -5814,19 +5792,18 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
// Reflow the float.
aReflowStatus = NS_FRAME_COMPLETE;
WritingMode wm = aState.mReflowState.GetWritingMode();
#ifdef NOISY_FLOAT
printf("Reflow Float %p in parent %p, availSpace(%d,%d,%d,%d)\n",
aFloat, this,
aFloatAvailableSpace.IStart(wm), aFloatAvailableSpace.BStart(wm),
aFloatAvailableSpace.ISize(wm), aFloatAvailableSpace.BSize(wm)
aFloat, this,
aFloatAvailableSpace.x, aFloatAvailableSpace.y,
aFloatAvailableSpace.width, aFloatAvailableSpace.height
);
#endif
nsHTMLReflowState
floatRS(aState.mPresContext, aState.mReflowState, aFloat,
aAdjustedAvailableSpace.Size(wm).ConvertTo(aFloat->GetWritingMode(),
wm));
LogicalSize(aFloat->GetWritingMode(),
aAdjustedAvailableSpace.Size()));
// Normally the mIsTopOfPage state is copied from the parent reflow
// state. However, when reflowing a float, if we've placed other
@ -5838,7 +5815,7 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
// about adjacency with the top, so it seems misleading.
if (floatRS.mFlags.mIsTopOfPage &&
(aFloatPushedDown ||
aAdjustedAvailableSpace.ISize(wm) != aState.ContentISize())) {
aAdjustedAvailableSpace.width != aState.ContentISize())) {
floatRS.mFlags.mIsTopOfPage = false;
}
@ -5876,9 +5853,9 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
ShouldAvoidBreakInside(floatRS)) {
aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
} else if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) {
// An incomplete reflow status means we should split the float
// if the height is constrained (bug 145305).
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) {
// An incomplete reflow status means we should split the float
// if the height is constrained (bug 145305).
aReflowStatus = NS_FRAME_COMPLETE;
}
@ -5895,11 +5872,8 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
}
// Capture the margin and offsets information for the caller
aFloatMargin =
// float margins don't collapse
floatRS.ComputedLogicalMargin().ConvertTo(wm, floatRS.GetWritingMode());
aFloatOffsets =
floatRS.ComputedLogicalOffsets().ConvertTo(wm, floatRS.GetWritingMode());
aFloatMargin = floatRS.ComputedPhysicalMargin(); // float margins don't collapse
aFloatOffsets = floatRS.ComputedPhysicalOffsets();
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
@ -5909,8 +5883,8 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
// we be doing this in nsBlockReflowState::FlowAndPlaceFloat after
// we've positioned the float, and shouldn't we be doing the equivalent
// of |PlaceFrameView| here?
WritingMode metricsWM = metrics.GetWritingMode();
aFloat->SetSize(metricsWM, metrics.Size(metricsWM));
WritingMode wm = metrics.GetWritingMode();
aFloat->SetSize(wm, metrics.Size(wm));
if (aFloat->HasView()) {
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, aFloat,
aFloat->GetView(),
@ -6010,15 +5984,14 @@ nsBlockFrame::ReflowPushedFloats(nsBlockReflowState& aState,
}
void
nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager, WritingMode aWM,
nscoord aContainerWidth)
nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager)
{
// Recover our own floats
nsIFrame* stop = nullptr; // Stop before we reach pushed floats that
// belong to our next-in-flow
for (nsIFrame* f = mFloats.FirstChild(); f && f != stop; f = f->GetNextSibling()) {
LogicalRect region = nsFloatManager::GetRegionFor(aWM, f, aContainerWidth);
aFloatManager.AddFloat(f, region, aWM, aContainerWidth);
nsRect region = nsFloatManager::GetRegionFor(f);
aFloatManager.AddFloat(f, region);
if (!stop && f->GetNextInFlow())
stop = f->GetNextInFlow();
}
@ -6026,22 +5999,20 @@ nsBlockFrame::RecoverFloats(nsFloatManager& aFloatManager, WritingMode aWM,
// Recurse into our overflow container children
for (nsIFrame* oc = GetFirstChild(kOverflowContainersList);
oc; oc = oc->GetNextSibling()) {
RecoverFloatsFor(oc, aFloatManager, aWM, aContainerWidth);
RecoverFloatsFor(oc, aFloatManager);
}
// Recurse into our normal children
for (nsBlockFrame::line_iterator line = begin_lines(); line != end_lines(); ++line) {
if (line->IsBlock()) {
RecoverFloatsFor(line->mFirstChild, aFloatManager, aWM, aContainerWidth);
RecoverFloatsFor(line->mFirstChild, aFloatManager);
}
}
}
void
nsBlockFrame::RecoverFloatsFor(nsIFrame* aFrame,
nsFloatManager& aFloatManager,
WritingMode aWM,
nscoord aContainerWidth)
nsFloatManager& aFloatManager)
{
NS_PRECONDITION(aFrame, "null frame");
// Only blocks have floats
@ -6053,10 +6024,10 @@ nsBlockFrame::RecoverFloatsFor(nsIFrame* aFrame,
// If the element is relatively positioned, then adjust x and y
// accordingly so that we consider relatively positioned frames
// at their original position.
LogicalPoint pos = block->GetLogicalNormalPosition(aWM, aContainerWidth);
WritingMode oldWM = aFloatManager.Translate(aWM, pos, aContainerWidth);
block->RecoverFloats(aFloatManager, aWM, aContainerWidth);
aFloatManager.Untranslate(oldWM, pos, aContainerWidth);
nsPoint pos = block->GetNormalPosition();
aFloatManager.Translate(pos.x, pos.y);
block->RecoverFloats(aFloatManager);
aFloatManager.Translate(-pos.x, -pos.y);
}
}
@ -6852,7 +6823,7 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
// the block.
// FIXME: aLineTop isn't actually set correctly by some callers, since
// they reposition the line.
LogicalRect floatAvailSpace =
nsRect floatAvailSpace =
aState.GetFloatAvailableSpaceWithState(aLineTop,
&aState.mFloatManagerStateBefore)
.mRect;
@ -6872,11 +6843,13 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
// in the current writing mode. Then we subtract out the start
// border/padding and the bullet's width and margin to offset the position.
WritingMode wm = rs.GetWritingMode();
nscoord containerWidth = floatAvailSpace.XMost();
LogicalRect logicalFAS(wm, floatAvailSpace, containerWidth);
// Get the bullet's margin, converted to our writing mode so that we can
// combine it with other logical values here.
LogicalMargin bulletMargin =
reflowState.ComputedLogicalMargin().ConvertTo(wm, bulletWM);
nscoord iStart = floatAvailSpace.IStart(wm) -
nscoord iStart = logicalFAS.IStart(wm) -
rs.ComputedLogicalBorderPadding().IStart(wm) -
bulletMargin.IEnd(wm) -
aMetrics.ISize(wm);
@ -6884,11 +6857,11 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
// Approximate the bullets position; vertical alignment will provide
// the final vertical location. We pass our writing-mode here, because
// it may be different from the bullet frame's mode.
nscoord bStart = floatAvailSpace.BStart(wm);
aBulletFrame->SetRect(wm, LogicalRect(wm, iStart, bStart,
aMetrics.ISize(wm),
aMetrics.BSize(wm)),
aState.mContainerWidth);
nscoord bStart = logicalFAS.BStart(wm);
aBulletFrame->SetRect(wm, LogicalRect(wm, LogicalPoint(wm, iStart, bStart),
LogicalSize(wm, aMetrics.ISize(wm),
aMetrics.BSize(wm))),
containerWidth);
aBulletFrame->DidReflow(aState.mPresContext, &aState.mReflowState,
nsDidReflowStatus::FINISHED);
}
@ -7041,22 +7014,20 @@ nsBlockFrame::BlockCanIntersectFloats(nsIFrame* aFrame)
// in the available space given, which means that variation shouldn't
// matter.
/* static */
nsBlockFrame::ReplacedElementISizeToClear
nsBlockFrame::ISizeToClearPastFloats(nsBlockReflowState& aState,
const LogicalRect& aFloatAvailableSpace,
nsBlockFrame::ReplacedElementWidthToClear
nsBlockFrame::WidthToClearPastFloats(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFrame)
{
nscoord inlineStartOffset, inlineEndOffset;
nscoord leftOffset, rightOffset;
WritingMode wm = aState.mReflowState.GetWritingMode();
nsCSSOffsetState offsetState(aFrame, aState.mReflowState.rendContext,
aState.mContentArea.Width(wm));
ReplacedElementISizeToClear result;
ReplacedElementWidthToClear result;
aState.ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
inlineStartOffset,
inlineEndOffset);
nscoord availISize = aState.mContentArea.ISize(wm) -
inlineStartOffset - inlineEndOffset;
leftOffset, rightOffset);
nscoord availWidth = aState.mContentArea.Width(wm) - leftOffset - rightOffset;
// We actually don't want the min width here; see bug 427782; we only
// want to displace if the width won't compute to a value small enough
@ -7064,19 +7035,16 @@ nsBlockFrame::ISizeToClearPastFloats(nsBlockReflowState& aState,
// All we really need here is the result of ComputeSize, and we
// could *almost* get that from an nsCSSOffsetState, except for the
// last argument.
WritingMode frWM = aFrame->GetWritingMode();
LogicalSize availSpace = LogicalSize(wm, availISize, NS_UNCONSTRAINEDSIZE).
ConvertTo(frWM, wm);
LogicalSize availSpace(aFrame->GetWritingMode(),
nsSize(availWidth, NS_UNCONSTRAINEDSIZE));
nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
aFrame, availSpace);
result.borderBoxISize =
reflowState.ComputedSizeWithBorderPadding().ConvertTo(wm, frWM).ISize(wm);
result.borderBoxWidth = reflowState.ComputedWidth() +
reflowState.ComputedPhysicalBorderPadding().LeftRight();
// Use the margins from offsetState rather than reflowState so that
// they aren't reduced by ignoring margins in overconstrained cases.
LogicalMargin computedMargin =
offsetState.ComputedLogicalMargin().ConvertTo(wm, frWM);
result.marginIStart = computedMargin.IStart(wm);
result.marginIEnd = computedMargin.IEnd(wm);
result.marginLeft = offsetState.ComputedPhysicalMargin().left;
result.marginRight = offsetState.ComputedPhysicalMargin().right;
return result;
}

View File

@ -314,19 +314,19 @@ public:
static bool BlockCanIntersectFloats(nsIFrame* aFrame);
/**
* Returns the inline size that needs to be cleared past floats for
* blocks that cannot intersect floats. aState must already have
* GetAvailableSpace called on it for the block-dir position that we
* care about (which need not be its current mBCoord)
* Returns the width that needs to be cleared past floats for blocks
* that cannot intersect floats. aState must already have
* GetAvailableSpace called on it for the vertical position that we
* care about (which need not be its current mY)
*/
struct ReplacedElementISizeToClear {
nscoord marginIStart, borderBoxISize, marginIEnd;
nscoord MarginBoxISize() const
{ return marginIStart + borderBoxISize + marginIEnd; }
struct ReplacedElementWidthToClear {
nscoord marginLeft, borderBoxWidth, marginRight;
nscoord MarginBoxWidth() const
{ return marginLeft + borderBoxWidth + marginRight; }
};
static ReplacedElementISizeToClear
ISizeToClearPastFloats(nsBlockReflowState& aState,
const mozilla::LogicalRect& aFloatAvailableSpace,
static ReplacedElementWidthToClear
WidthToClearPastFloats(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFrame);
/**
@ -476,10 +476,8 @@ public:
* assumes float manager is in aFrame's parent's coord system.
* Safe to call on non-blocks (does nothing).
*/
static void RecoverFloatsFor(nsIFrame* aFrame,
nsFloatManager& aFloatManager,
mozilla::WritingMode aWM,
nscoord aContainerWidth);
static void RecoverFloatsFor(nsIFrame* aFrame,
nsFloatManager& aFloatManager);
/**
* Determine if we have any pushed floats from a previous continuation.
@ -543,9 +541,7 @@ protected:
/** Load all our floats into the float manager (without reflowing them).
* Assumes float manager is in our own coordinate system.
*/
void RecoverFloats(nsFloatManager& aFloatManager,
mozilla::WritingMode aWM,
nscoord aContainerWidth);
void RecoverFloats(nsFloatManager& aFloatManager);
/** Reflow pushed floats
*/
@ -605,13 +601,13 @@ protected:
// Return false if it needs another reflow because of reduced space
// between floats that are next to it (but not next to its top), and
// return true otherwise.
bool PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
bool PlaceLine(nsBlockReflowState& aState,
nsLineLayout& aLineLayout,
line_iterator aLine,
nsFloatManager::SavedState* aFloatStateBeforeLine,
mozilla::LogicalRect& aFloatAvailableSpace, //in-out
nscoord& aAvailableSpaceHeight, // in-out
bool* aKeepReflowGoing);
nsRect& aFloatAvailableSpace, /* in-out */
nscoord& aAvailableSpaceHeight, /* in-out */
bool* aKeepReflowGoing);
/**
* If NS_BLOCK_LOOK_FOR_DIRTY_FRAMES is set, call MarkLineDirty
@ -669,29 +665,28 @@ protected:
nsIFrame* aFrame,
LineReflowStatus* aLineReflowStatus);
// Compute the available inline size for a float.
mozilla::LogicalRect AdjustFloatAvailableSpace(
nsBlockReflowState& aState,
const mozilla::LogicalRect& aFloatAvailableSpace,
nsIFrame* aFloatFrame);
// Computes the border-box inline size of the float
nscoord ComputeFloatISize(nsBlockReflowState& aState,
const mozilla::LogicalRect& aFloatAvailableSpace,
nsIFrame* aFloat);
// Compute the available width for a float.
nsRect AdjustFloatAvailableSpace(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFloatFrame);
// Computes the border-box width of the float
nscoord ComputeFloatWidth(nsBlockReflowState& aState,
const nsRect& aFloatAvailableSpace,
nsIFrame* aFloat);
// An incomplete aReflowStatus indicates the float should be split
// but only if the available height is constrained.
// aAdjustedAvailableSpace is the result of calling
// nsBlockFrame::AdjustFloatAvailableSpace.
void ReflowFloat(nsBlockReflowState& aState,
const mozilla::LogicalRect& aAdjustedAvailableSpace,
nsIFrame* aFloat,
mozilla::LogicalMargin& aFloatMargin,
mozilla::LogicalMargin& aFloatOffsets,
void ReflowFloat(nsBlockReflowState& aState,
const nsRect& aAdjustedAvailableSpace,
nsIFrame* aFloat,
nsMargin& aFloatMargin,
nsMargin& aFloatOffsets,
// Whether the float's position
// (aAdjustedAvailableSpace) has been pushed down
// due to the presence of other floats.
bool aFloatPushedDown,
nsReflowStatus& aReflowStatus);
bool aFloatPushedDown,
nsReflowStatus& aReflowStatus);
//----------------------------------------
// Methods for pushing/pulling lines/frames
@ -757,7 +752,7 @@ protected:
void PropagateFloatDamage(nsBlockReflowState& aState,
nsLineBox* aLine,
nscoord aDeltaBCoord);
nscoord aDeltaY);
void CheckFloats(nsBlockReflowState& aState);

View File

@ -214,7 +214,7 @@ nsBlockReflowContext::ComputeCollapsedBStartMargin(const nsHTMLReflowState& aRS,
}
void
nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
bool aApplyBStartMargin,
nsCollapsingMargin& aPrevMargin,
nscoord aClearance,
@ -227,7 +227,7 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
mFrame = aFrameRS.frame;
mWritingMode = aState.mReflowState.GetWritingMode();
mContainerWidth = aState.mContainerWidth;
mSpace = aSpace;
mSpace = LogicalRect(mWritingMode, aSpace, mContainerWidth);
if (!aIsAdjacentWithBStart) {
aFrameRS.mFlags.mIsTopOfPage = false; // make sure this is cleared
@ -250,7 +250,7 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
}
}
LogicalPoint tPt(mWritingMode);
nscoord tI = 0, tB = 0;
// The values of x and y do not matter for floats, so don't bother
// calculating them. Floats are guaranteed to have their own float
// manager, so tI and tB don't matter. mICoord and mBCoord don't
@ -262,12 +262,16 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
// reflow auto inline-start/end margins will have a zero value.
WritingMode frameWM = aFrameRS.GetWritingMode();
mICoord = tPt.I(mWritingMode) =
mICoord = tI =
mSpace.IStart(mWritingMode) +
aFrameRS.ComputedLogicalMargin().ConvertTo(mWritingMode,
frameWM).IStart(mWritingMode);
mBCoord = tPt.B(mWritingMode) = mSpace.BStart(mWritingMode) +
mBStartMargin.get() + aClearance;
mBCoord = tB = mSpace.BStart(mWritingMode) +
mBStartMargin.get() + aClearance;
//XXX temporary until nsFloatManager is logicalized
tI = aSpace.x + aFrameRS.ComputedPhysicalMargin().left;
tB = aSpace.y + mBStartMargin.get() + aClearance;
if ((mFrame->GetStateBits() & NS_BLOCK_FLOAT_MGR) == 0)
aFrameRS.mBlockDelta =
@ -282,11 +286,9 @@ nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
mMetrics.BSize(mWritingMode) = nscoord(0xdeadbeef);
#endif
WritingMode oldWM =
mOuterReflowState.mFloatManager->Translate(mWritingMode, tPt,
mContainerWidth);
mOuterReflowState.mFloatManager->Translate(tI, tB);
mFrame->Reflow(mPresContext, mMetrics, aFrameRS, aFrameReflowStatus);
mOuterReflowState.mFloatManager->Untranslate(oldWM, tPt, mContainerWidth);
mOuterReflowState.mFloatManager->Translate(-tI, -tB);
#ifdef DEBUG
if (!NS_INLINE_IS_BREAK_BEFORE(aFrameReflowStatus)) {

View File

@ -28,15 +28,15 @@ public:
const nsHTMLReflowState& aParentRS);
~nsBlockReflowContext() { }
void ReflowBlock(const mozilla::LogicalRect& aSpace,
bool aApplyBStartMargin,
nsCollapsingMargin& aPrevMargin,
nscoord aClearance,
bool aIsAdjacentWithBStart,
nsLineBox* aLine,
nsHTMLReflowState& aReflowState,
nsReflowStatus& aReflowStatus,
nsBlockReflowState& aState);
void ReflowBlock(const nsRect& aSpace,
bool aApplyBStartMargin,
nsCollapsingMargin& aPrevMargin,
nscoord aClearance,
bool aIsAdjacentWithBStart,
nsLineBox* aLine,
nsHTMLReflowState& aReflowState,
nsReflowStatus& aReflowStatus,
nsBlockReflowState& aState);
bool PlaceBlock(const nsHTMLReflowState& aReflowState,
bool aForceFit,

View File

@ -34,8 +34,6 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
: mBlock(aFrame),
mPresContext(aPresContext),
mReflowState(aReflowState),
mFloatManagerOrigin(aReflowState.GetWritingMode()),
mFloatManagerStateBefore(aReflowState.GetWritingMode()),
mContentArea(aReflowState.GetWritingMode()),
mPushedFloats(nullptr),
mOverflowTracker(nullptr),
@ -76,7 +74,7 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
"FloatManager should be set in nsBlockReflowState" );
if (mFloatManager) {
// Save the coordinate system origin for later.
mFloatManager->GetTranslation(mFloatManagerWM, mFloatManagerOrigin);
mFloatManager->GetTranslation(mFloatManagerX, mFloatManagerY);
mFloatManager->PushState(&mFloatManagerStateBefore); // never popped
}
@ -129,48 +127,44 @@ nsBlockReflowState::GetConsumedBSize()
}
void
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(
nsIFrame* aFrame,
const LogicalRect& aFloatAvailableSpace,
nscoord& aIStartResult,
nscoord& aIEndResult)
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const nsRect& aFloatAvailableSpace,
nscoord& aLeftResult,
nscoord& aRightResult)
{
WritingMode wm = mReflowState.GetWritingMode();
nsRect contentArea =
mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
// The frame is clueless about the float manager and therefore we
// only give it free space. An example is a table frame - the
// tables do not flow around floats.
// However, we can let its margins intersect floats.
NS_ASSERTION(aFloatAvailableSpace.IStart(wm) >= mContentArea.IStart(wm),
"bad avail space rect inline-coord");
NS_ASSERTION(aFloatAvailableSpace.ISize(wm) == 0 ||
aFloatAvailableSpace.IEnd(wm) <= mContentArea.IEnd(wm),
"bad avail space rect inline-size");
NS_ASSERTION(aFloatAvailableSpace.x >= contentArea.x, "bad avail space rect x");
NS_ASSERTION(aFloatAvailableSpace.width == 0 ||
aFloatAvailableSpace.XMost() <= contentArea.XMost(),
"bad avail space rect width");
nscoord iStartOffset, iEndOffset;
if (aFloatAvailableSpace.ISize(wm) == mContentArea.ISize(wm)) {
nscoord leftOffset, rightOffset;
if (aFloatAvailableSpace.width == contentArea.width) {
// We don't need to compute margins when there are no floats around.
iStartOffset = 0;
iEndOffset = 0;
leftOffset = 0;
rightOffset = 0;
} else {
LogicalMargin frameMargin(wm);
nsCSSOffsetState os(aFrame, mReflowState.rendContext,
mContentArea.ISize(wm));
frameMargin =
os.ComputedLogicalMargin().ConvertTo(wm, aFrame->GetWritingMode());
nsMargin frameMargin;
nsCSSOffsetState os(aFrame, mReflowState.rendContext, contentArea.width);
frameMargin = os.ComputedPhysicalMargin();
nscoord iStartFloatIOffset =
aFloatAvailableSpace.IStart(wm) - mContentArea.IStart(wm);
iStartOffset = std::max(iStartFloatIOffset, frameMargin.IStart(wm)) -
frameMargin.IStart(wm);
iStartOffset = std::max(iStartOffset, 0); // in case of negative margin
nscoord iEndFloatIOffset =
mContentArea.IEnd(wm) - aFloatAvailableSpace.IEnd(wm);
iEndOffset = std::max(iEndFloatIOffset, frameMargin.IEnd(wm)) -
frameMargin.IEnd(wm);
iEndOffset = std::max(iEndOffset, 0); // in case of negative margin
nscoord leftFloatXOffset = aFloatAvailableSpace.x - contentArea.x;
leftOffset = std::max(leftFloatXOffset, frameMargin.left) -
frameMargin.left;
leftOffset = std::max(leftOffset, 0); // in case of negative margin
nscoord rightFloatXOffset =
contentArea.XMost() - aFloatAvailableSpace.XMost();
rightOffset = std::max(rightFloatXOffset, frameMargin.right) -
frameMargin.right;
rightOffset = std::max(rightOffset, 0); // in case of negative margin
}
aIStartResult = iStartOffset;
aIEndResult = iEndOffset;
aLeftResult = leftOffset;
aRightResult = rightOffset;
}
static nscoord
@ -197,15 +191,19 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay,
const nsFlowAreaRect& aFloatAvailableSpace,
bool aBlockAvoidsFloats,
LogicalRect& aResult)
nsRect& aResult)
{
#ifdef REALLY_NOISY_REFLOW
printf("CBAS frame=%p has floats %d\n",
aFrame, aFloatAvailableSpace.mHasFloats);
#endif
WritingMode wm = mReflowState.GetWritingMode();
aResult.BStart(wm) = mBCoord;
aResult.BSize(wm) = GetFlag(BRS_UNCONSTRAINEDBSIZE)
LogicalRect result(wm);
LogicalRect floatAvailSpace = LogicalRect(wm,
aFloatAvailableSpace.mRect,
mContainerWidth); //??mReflowState.AvailableWidth());
result.BStart(wm) = mBCoord;
result.BSize(wm) = GetFlag(BRS_UNCONSTRAINEDBSIZE)
? NS_UNCONSTRAINEDSIZE
: mReflowState.AvailableBSize() - mBCoord
- GetBEndMarginClone(aFrame, mReflowState.rendContext, mContentArea, wm);
@ -222,7 +220,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
// applies to a specific set of frame classes and no new ones?
// If we did that, then for those frames where the condition below is
// true but nsBlockFrame::BlockCanIntersectFloats is false,
// nsBlockFrame::ISizeToClearPastFloats would need to use the
// nsBlockFrame::WidthToClearPastFloats would need to use the
// shrink-wrap formula, max(MIN_ISIZE, min(avail width, PREF_ISIZE))
// rather than just using MIN_ISIZE.
NS_ASSERTION(nsBlockFrame::BlockCanIntersectFloats(aFrame) ==
@ -238,15 +236,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
case NS_STYLE_FLOAT_EDGE_CONTENT: // content and only content does runaround of floats
// The child block will flow around the float. Therefore
// give it all of the available space.
aResult.IStart(wm) = mContentArea.IStart(wm);
aResult.ISize(wm) = mContentArea.ISize(wm);
result.IStart(wm) = ContentIStart();
result.ISize(wm) = ContentISize();
break;
case NS_STYLE_FLOAT_EDGE_MARGIN:
{
// The child block's margins should be placed adjacent to,
// but not overlap the float.
aResult.IStart(wm) = aFloatAvailableSpace.mRect.IStart(wm);
aResult.ISize(wm) = aFloatAvailableSpace.mRect.ISize(wm);
result.IStart(wm) = floatAvailSpace.IStart(wm);
result.ISize(wm) = floatAvailSpace.ISize(wm);
}
break;
}
@ -255,21 +253,24 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
// Since there are no floats present the float-edge property
// doesn't matter therefore give the block element all of the
// available space since it will flow around the float itself.
aResult.IStart(wm) = mContentArea.IStart(wm);
aResult.ISize(wm) = mContentArea.ISize(wm);
result.IStart(wm) = ContentIStart();
result.ISize(wm) = ContentISize();
}
aResult = result.GetPhysicalRect(wm, mContainerWidth);
}
else {
nscoord iStartOffset, iEndOffset;
aResult = result.GetPhysicalRect(wm, mContainerWidth);
nsRect contentArea =
mContentArea.GetPhysicalRect(wm, mContainerWidth);
nscoord leftOffset, rightOffset;
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
iStartOffset, iEndOffset);
aResult.IStart(wm) = mContentArea.IStart(wm) + iStartOffset;
aResult.ISize(wm) = mContentArea.ISize(wm) - iStartOffset - iEndOffset;
leftOffset, rightOffset);
aResult.x = contentArea.x + leftOffset;
aResult.width = contentArea.width - leftOffset - rightOffset;
}
#ifdef REALLY_NOISY_REFLOW
printf(" CBAS: result %d %d %d %d\n", aResult.IStart(wm), aResult.BStart(wm),
aResult.ISize(wm), aResult.BSize(wm));
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
#endif
}
@ -278,38 +279,31 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
nscoord aBCoord,
nsFloatManager::SavedState *aState) const
{
WritingMode wm = mReflowState.GetWritingMode();
#ifdef DEBUG
// Verify that the caller setup the coordinate system properly
WritingMode wWM;
LogicalPoint wPt(wWM);
mFloatManager->GetTranslation(wWM, wPt);
if (wWM == mFloatManagerWM) {
NS_ASSERTION(wPt == mFloatManagerOrigin, "bad coord system");
} else {
//XXX if the writing modes are different we can't easily assert that
// the origin is the same.
}
nscoord wx, wy;
mFloatManager->GetTranslation(wx, wy);
NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
"bad coord system");
#endif
nscoord blockSize = (mContentArea.BSize(wm) == nscoord_MAX)
? nscoord_MAX : std::max(mContentArea.BEnd(wm) - aBCoord, 0);
nsRect contentArea =
mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
nscoord height = (contentArea.height == nscoord_MAX)
? nscoord_MAX : std::max(contentArea.YMost() - aBCoord, 0);
nsFlowAreaRect result =
mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::BAND_FROM_POINT,
blockSize, mContentArea, aState,
mContainerWidth);
// Keep the inline size >= 0 for compatibility with nsSpaceManager.
if (result.mRect.ISize(wm) < 0) {
result.mRect.ISize(wm) = 0;
}
mFloatManager->GetFlowArea(aBCoord, nsFloatManager::BAND_FROM_POINT,
height, contentArea, 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("GetAvailableSpace: band=%d,%d,%d,%d hasfloats=%d\n",
result.mRect.IStart(wm), result.mRect.BStart(wm),
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
result.mRect.x, result.mRect.y, result.mRect.width,
result.mRect.height, result.mHasFloats);
}
#endif
return result;
@ -320,33 +314,28 @@ nsBlockReflowState::GetFloatAvailableSpaceForBSize(
nscoord aBCoord, nscoord aBSize,
nsFloatManager::SavedState *aState) const
{
WritingMode wm = mReflowState.GetWritingMode();
#ifdef DEBUG
// Verify that the caller setup the coordinate system properly
WritingMode wWM;
LogicalPoint wPt(wWM);
mFloatManager->GetTranslation(wWM, wPt);
if (wWM == mFloatManagerWM) {
NS_ASSERTION(wPt == mFloatManagerOrigin, "bad coord system");
} else {
//XXX if the writing modes are different we can't easily assert that
// the origin is the same.
}
nscoord wx, wy;
mFloatManager->GetTranslation(wx, wy);
NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
"bad coord system");
#endif
nsRect contentArea =
mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
nsFlowAreaRect result =
mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
aBSize, mContentArea, aState, mContainerWidth);
mFloatManager->GetFlowArea(aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
aBSize, contentArea, aState);
// Keep the width >= 0 for compatibility with nsSpaceManager.
if (result.mRect.ISize(wm) < 0) {
result.mRect.ISize(wm) = 0;
}
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.IStart(wm), result.mRect.BStart(wm),
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
result.mRect.x, result.mRect.y, result.mRect.width,
result.mRect.height, result.mHasFloats);
}
#endif
return result;
@ -430,7 +419,6 @@ void
nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
nscoord aDeltaBCoord)
{
WritingMode wm = mReflowState.GetWritingMode();
if (aLine->HasFloats()) {
// Place the floats into the space-manager again. Also slide
// them, just like the regular frames on the line.
@ -444,31 +432,23 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
}
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisyFloatManager) {
WritingMode tWM;
LogicalPoint tPt(tWM);
mFloatManager->GetTranslation(tWM, tPt);
nscoord tx, ty;
mFloatManager->GetTranslation(tx, ty);
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("RecoverFloats: txy=%d,%d (%d,%d) ",
tPt.I(tWM), tPt.B(tWM),
mFloatManagerOrigin.I(mFloatManagerWM),
mFloatManagerOrigin.B(mFloatManagerWM));
tx, ty, mFloatManagerX, mFloatManagerY);
nsFrame::ListTag(stdout, floatFrame);
LogicalRect region = nsFloatManager::GetRegionFor(wm, floatFrame,
mContainerWidth);
nsRect region = nsFloatManager::GetRegionFor(floatFrame);
printf(" aDeltaBCoord=%d region={%d,%d,%d,%d}\n",
aDeltaBCoord, region.IStart(wm), region.BStart(wm),
region.ISize(wm), region.BSize(wm));
aDeltaBCoord, region.x, region.y, region.width, region.height);
}
#endif
mFloatManager->AddFloat(floatFrame,
nsFloatManager::GetRegionFor(wm, floatFrame,
mContainerWidth),
wm, mContainerWidth);
nsFloatManager::GetRegionFor(floatFrame));
fc = fc->Next();
}
} else if (aLine->IsBlock()) {
nsBlockFrame::RecoverFloatsFor(aLine->mFirstChild, *mFloatManager, wm,
mContainerWidth);
nsBlockFrame::RecoverFloatsFor(aLine->mFirstChild, *mFloatManager);
}
}
@ -516,7 +496,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
bool
nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
nsIFrame* aFloat,
nscoord aAvailableISize)
nscoord aAvailableWidth)
{
NS_PRECONDITION(aLineLayout, "must have line layout");
NS_PRECONDITION(mBlock->end_lines() != mCurrentLine, "null ptr");
@ -555,10 +535,11 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
// that's a child of our block) we need to restore the space
// manager's translation to the space that the block resides in
// before placing the float.
WritingMode oldWM;
LogicalPoint oPt(oldWM);
mFloatManager->GetTranslation(oldWM, oPt);
mFloatManager->SetTranslation(mFloatManagerWM, mFloatManagerOrigin);
nscoord ox, oy;
mFloatManager->GetTranslation(ox, oy);
nscoord dx = ox - mFloatManagerX;
nscoord dy = oy - mFloatManagerY;
mFloatManager->Translate(-dx, -dy);
bool placed;
@ -567,21 +548,19 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
// If one or more floats has already been pushed to the next line,
// don't let this one go on the current line, since that would violate
// float ordering.
LogicalRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
nsRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
if (mBelowCurrentLineFloats.IsEmpty() &&
(aLineLayout->LineIsEmpty() ||
mBlock->ComputeFloatISize(*this, floatAvailableSpace, aFloat)
<= aAvailableISize)) {
mBlock->ComputeFloatWidth(*this, floatAvailableSpace, aFloat)
<= aAvailableWidth)) {
// And then place it
placed = FlowAndPlaceFloat(aFloat);
if (placed) {
// Pass on updated available space to the current inline reflow engine
WritingMode wm = mReflowState.GetWritingMode();
nsFlowAreaRect floatAvailSpace = GetFloatAvailableSpace(mBCoord);
LogicalRect availSpace(wm, floatAvailSpace.mRect.IStart(wm), mBCoord,
floatAvailSpace.mRect.ISize(wm),
floatAvailSpace.mRect.BSize(wm));
aLineLayout->UpdateBand(wm, availSpace, aFloat);
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x, mBCoord),
floatAvailSpace.mRect.Size());
aLineLayout->UpdateBand(availSpace, aFloat);
// Record this float in the current-line list
mCurrentLineFloats.Append(mFloatCacheFreeList.Alloc(aFloat));
} else {
@ -598,55 +577,48 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
}
// Restore coordinate system
mFloatManager->SetTranslation(oldWM, oPt);
mFloatManager->Translate(dx, dy);
return placed;
}
bool
nsBlockReflowState::CanPlaceFloat(nscoord aFloatISize,
nsBlockReflowState::CanPlaceFloat(nscoord aFloatWidth,
const nsFlowAreaRect& aFloatAvailableSpace)
{
// A float fits at a given block-dir position if there are no floats
// at its inline-dir position (no matter what its inline size) or if
// its inline size fits in the space remaining after prior floats have
// been placed.
// A float fits at a given vertical position if there are no floats at
// its horizontal position (no matter what its width) or if its width
// 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 ||
aFloatAvailableSpace.mRect.ISize(mReflowState.GetWritingMode()) >=
aFloatISize;
aFloatAvailableSpace.mRect.width >= aFloatWidth;
}
static nscoord
FloatMarginISize(const nsHTMLReflowState& aCBReflowState,
nscoord aFloatAvailableISize,
FloatMarginWidth(const nsHTMLReflowState& aCBReflowState,
nscoord aFloatAvailableWidth,
nsIFrame *aFloat,
const nsCSSOffsetState& aFloatOffsetState)
{
AutoMaybeDisableFontInflation an(aFloat);
WritingMode wm = aFloatOffsetState.GetWritingMode();
LogicalSize floatSize =
aFloat->ComputeSize(
aCBReflowState.rendContext,
wm,
aCBReflowState.ComputedSize(wm),
aFloatAvailableISize,
aFloatOffsetState.ComputedLogicalMargin().Size(wm),
aFloatOffsetState.ComputedLogicalBorderPadding().Size(wm) -
aFloatOffsetState.ComputedLogicalPadding().Size(wm),
aFloatOffsetState.ComputedLogicalPadding().Size(wm),
true);
return floatSize.ISize(wm) +
aFloatOffsetState.ComputedLogicalMargin().IStartEnd(wm) +
aFloatOffsetState.ComputedLogicalBorderPadding().IStartEnd(wm);
WritingMode fosWM = aFloatOffsetState.GetWritingMode();
return aFloat->ComputeSize(
aCBReflowState.rendContext,
fosWM,
aCBReflowState.ComputedSize(fosWM),
aFloatAvailableWidth,
aFloatOffsetState.ComputedLogicalMargin().Size(fosWM),
aFloatOffsetState.ComputedLogicalBorderPadding().Size(fosWM) -
aFloatOffsetState.ComputedLogicalPadding().Size(fosWM),
aFloatOffsetState.ComputedLogicalPadding().Size(fosWM),
true).Width(fosWM) +
aFloatOffsetState.ComputedPhysicalMargin().LeftRight() +
aFloatOffsetState.ComputedPhysicalBorderPadding().LeftRight();
}
bool
nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
{
WritingMode wm = mReflowState.GetWritingMode();
// Save away the Y coordinate before placing the float. We will
// restore mBCoord at the end after placing the float. This is
// necessary because any adjustments to mBCoord during the float
@ -660,17 +632,11 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
const nsStyleDisplay* floatDisplay = aFloat->StyleDisplay();
// The float's old region, so we can propagate damage.
LogicalRect oldRegion = nsFloatManager::GetRegionFor(wm, aFloat,
mContainerWidth);
nsRect oldRegion = nsFloatManager::GetRegionFor(aFloat);
// Enforce CSS2 9.5.1 rule [2], i.e., make sure that a float isn't
// ``above'' another float that preceded it in the flow.
// "Translate" the float manager with an offset of (0, 0) in order to
// set the origin to our writing mode
LogicalPoint oPt(wm);
WritingMode oldWM = mFloatManager->Translate(wm, oPt, mContainerWidth);
mBCoord = std::max(mFloatManager->GetLowestFloatTop(wm, mContainerWidth),
mBCoord);
mBCoord = std::max(mFloatManager->GetLowestFloatTop(), mBCoord);
// See if the float should clear any preceding floats...
// XXX We need to mark this float somehow so that it gets reflowed
@ -681,8 +647,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
}
// Get the band of available space
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
LogicalRect adjustedAvailableSpace =
mBlock->AdjustFloatAvailableSpace(*this, floatAvailableSpace.mRect, aFloat);
nsRect adjustedAvailableSpace = mBlock->AdjustFloatAvailableSpace(*this,
floatAvailableSpace.mRect, aFloat);
NS_ASSERTION(aFloat->GetParent() == mBlock,
"Float frame has wrong parent");
@ -690,12 +656,12 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
nsCSSOffsetState offsets(aFloat, mReflowState.rendContext,
mReflowState.ComputedWidth());
nscoord floatMarginISize = FloatMarginISize(mReflowState,
adjustedAvailableSpace.ISize(wm),
nscoord floatMarginWidth = FloatMarginWidth(mReflowState,
adjustedAvailableSpace.width,
aFloat, offsets);
LogicalMargin floatMargin(wm); // computed margin
LogicalMargin floatOffsets(wm);
nsMargin floatMargin; // computed margin
nsMargin floatOffsets;
nsReflowStatus reflowStatus;
// If it's a floating first-letter, we need to reflow it before we
@ -705,7 +671,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
if (isLetter) {
mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin,
floatOffsets, false, reflowStatus);
floatMarginISize = aFloat->ISize(wm) + floatMargin.IStartEnd(wm);
floatMarginWidth = aFloat->GetSize().width + floatMargin.LeftRight();
NS_ASSERTION(NS_FRAME_IS_COMPLETE(reflowStatus),
"letter frames shouldn't break, and if they do now, "
"then they're breaking at the wrong point");
@ -729,14 +695,14 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
for (;;) {
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE &&
floatAvailableSpace.mRect.BSize(wm) <= 0 &&
floatAvailableSpace.mRect.height <= 0 &&
!mustPlaceFloat) {
// No space, nowhere to put anything.
PushFloatPastBreak(aFloat);
return false;
}
if (CanPlaceFloat(floatMarginISize, floatAvailableSpace)) {
if (CanPlaceFloat(floatMarginWidth, floatAvailableSpace)) {
// We found an appropriate place.
break;
}
@ -745,9 +711,9 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
if (NS_STYLE_DISPLAY_TABLE != floatDisplay->mDisplay ||
eCompatibility_NavQuirks != mPresContext->CompatibilityMode() ) {
mBCoord += floatAvailableSpace.mRect.BSize(wm);
if (adjustedAvailableSpace.BSize(wm) != NS_UNCONSTRAINEDSIZE) {
adjustedAvailableSpace.BSize(wm) -= floatAvailableSpace.mRect.BSize(wm);
mBCoord += floatAvailableSpace.mRect.height;
if (adjustedAvailableSpace.height != NS_UNCONSTRAINEDSIZE) {
adjustedAvailableSpace.height -= floatAvailableSpace.mRect.height;
}
floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
} else {
@ -787,14 +753,14 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
}
// the table does not fit anymore in this line so advance to next band
mBCoord += floatAvailableSpace.mRect.BSize(wm);
mBCoord += floatAvailableSpace.mRect.height;
// To match nsBlockFrame::AdjustFloatAvailableSpace, we have to
// get a new width for the new band.
floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
adjustedAvailableSpace = mBlock->AdjustFloatAvailableSpace(*this,
floatAvailableSpace.mRect, aFloat);
floatMarginISize = FloatMarginISize(mReflowState,
adjustedAvailableSpace.ISize(wm),
floatMarginWidth = FloatMarginWidth(mReflowState,
adjustedAvailableSpace.width,
aFloat, offsets);
}
@ -806,20 +772,20 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// We don't worry about the geometry of the prev in flow, let the continuation
// place and size itself as required.
// Assign inline and block dir coordinates to the float.
LogicalPoint floatPos(wm);
if ((NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) == wm.IsBidiLTR()) {
floatPos.I(wm) = floatAvailableSpace.mRect.IStart(wm);
// Assign an x and y coordinate to the float.
nscoord floatX, floatY;
if (NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) {
floatX = floatAvailableSpace.mRect.x;
}
else {
if (!keepFloatOnSameLine) {
floatPos.I(wm) = floatAvailableSpace.mRect.IEnd(wm) - floatMarginISize;
}
floatX = floatAvailableSpace.mRect.XMost() - floatMarginWidth;
}
else {
// this is the IE quirk (see few lines above)
// the table is kept in the same line: don't let it overlap the
// previous float
floatPos.I(wm) = floatAvailableSpace.mRect.IStart(wm);
// previous float
floatX = floatAvailableSpace.mRect.x;
}
}
// CSS2 spec, 9.5.1 rule [4]: "A floating box's outer top may not
@ -827,7 +793,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// containing block is the content edge of the block box, this
// means the margin edge of the float can't be higher than the
// content edge of the block that contains it.)
floatPos.B(wm) = std::max(mBCoord, ContentBStart());
floatY = std::max(mBCoord, ContentBStart());
// Reflow the float after computing its vertical position so it knows
// where to break.
@ -837,9 +803,9 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
floatOffsets, pushedDown, reflowStatus);
}
if (aFloat->GetPrevInFlow())
floatMargin.BStart(wm) = 0;
floatMargin.top = 0;
if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus))
floatMargin.BEnd(wm) = 0;
floatMargin.bottom = 0;
// In the case that we're in columns and not splitting floats, we need
// to check here that the float's height fit, and if it didn't, bail.
@ -849,10 +815,10 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// its entirety to the next page (NS_FRAME_IS_TRUNCATED or
// NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
if ((ContentBSize() != NS_UNCONSTRAINEDSIZE &&
adjustedAvailableSpace.BSize(wm) == NS_UNCONSTRAINEDSIZE &&
adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE &&
!mustPlaceFloat &&
aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
ContentBEnd() - floatPos.B(wm)) ||
aFloat->GetSize().height + floatMargin.TopBottom() >
ContentBEnd() - floatY) ||
NS_FRAME_IS_TRUNCATED(reflowStatus) ||
NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
PushFloatPastBreak(aFloat);
@ -861,14 +827,13 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// We can't use aFloat->ShouldAvoidBreakInside(mReflowState) here since
// its mIsTopOfPage may be true even though the float isn't at the
// top when floatPos.B(wm) > 0.
// top when floatY > 0.
if (ContentBSize() != NS_UNCONSTRAINEDSIZE &&
!mustPlaceFloat &&
(!mReflowState.mFlags.mIsTopOfPage || floatPos.B(wm) > 0) &&
!mustPlaceFloat && (!mReflowState.mFlags.mIsTopOfPage || floatY > 0) &&
NS_STYLE_PAGE_BREAK_AVOID == aFloat->StyleDisplay()->mBreakInside &&
(!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) ||
aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
ContentBEnd() - floatPos.B(wm)) &&
aFloat->GetSize().height + floatMargin.TopBottom() >
ContentBEnd() - floatY) &&
!aFloat->GetPrevInFlow()) {
PushFloatPastBreak(aFloat);
return false;
@ -877,21 +842,11 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// Calculate the actual origin of the float frame's border rect
// relative to the parent block; the margin must be added in
// to get the border rect
//XXX temporary! ApplyRelativePositioning still uses physical margin and point
LogicalSize size = aFloat->GetLogicalSize(wm);
LogicalMargin margin = aFloat->GetLogicalUsedMargin(wm);
size.ISize(wm) += margin.IStartEnd(wm);
size.BSize(wm) += margin.BStartEnd(wm);
nsPoint physicalPos =
LogicalRect(wm, floatPos, size).GetPhysicalPosition(wm, mContainerWidth);
nsPoint origin(floatMargin.Left(wm) + physicalPos.x,
floatMargin.Top(wm) + physicalPos.y);
nsPoint origin(floatMargin.left + floatX,
floatMargin.top + floatY);
// If float is relatively positioned, factor that in as well
nsHTMLReflowState::ApplyRelativePositioning(aFloat,
floatOffsets.GetPhysicalMargin(wm),
&origin);
nsHTMLReflowState::ApplyRelativePositioning(aFloat, floatOffsets, &origin);
// Position the float and make sure and views are properly
// positioned. We need to explicitly position its child views as
@ -909,20 +864,17 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// Place the float in the float manager
// calculate region
LogicalRect region =
nsFloatManager::CalculateRegionFor(wm, aFloat, floatMargin,
mContainerWidth);
nsRect region = nsFloatManager::CalculateRegionFor(aFloat, floatMargin);
// if the float split, then take up all of the vertical height
if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus) &&
(NS_UNCONSTRAINEDSIZE != ContentBSize())) {
region.BSize(wm) = std::max(region.BSize(wm),
ContentBSize() - floatPos.B(wm));
region.height = std::max(region.height, ContentBSize() - floatY);
}
DebugOnly<nsresult> rv = mFloatManager->AddFloat(aFloat, region, wm,
mContainerWidth);
DebugOnly<nsresult> rv =
mFloatManager->AddFloat(aFloat, region);
NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv), "bad float placement");
// store region
nsFloatManager::StoreRegionFor(wm, aFloat, region, mContainerWidth);
nsFloatManager::StoreRegionFor(aFloat, region);
// If the float's dimensions have changed, note the damage in the
// float manager.
@ -931,9 +883,9 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// less damage; e.g., if only height has changed, then only note the
// area into which the float has grown or from which the float has
// shrunk.
nscoord blockStart = std::min(region.BStart(wm), oldRegion.BStart(wm));
nscoord blockEnd = std::max(region.BEnd(wm), oldRegion.BEnd(wm));
mFloatManager->IncludeInDamage(wm, blockStart, blockEnd);
nscoord top = std::min(region.y, oldRegion.y);
nscoord bottom = std::max(region.YMost(), oldRegion.YMost());
mFloatManager->IncludeInDamage(top, bottom);
}
if (!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus)) {
@ -941,16 +893,12 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
}
#ifdef NOISY_FLOATMANAGER
WritingMode tWM;
LogicalPoint tPt(wm);
mFloatManager->GetTranslation(tWM, tPt);
nscoord tx, ty;
mFloatManager->GetTranslation(tx, ty);
nsFrame::ListTag(stdout, mBlock);
printf(": FlowAndPlaceFloat: AddFloat: txy=%d,%d (%d,%d) {%d,%d,%d,%d}\n",
tPt.I(tWM), tPt.B(tWM),
mFloatManagerOrigin.I(mFloatManagerWM),
mFloatManagerOrigin.B(mFloatManagerWM),
region.IStart(wm), region.BStart(wm),
region.ISize(wm), region.BSize(wm));
tx, ty, mFloatManagerX, mFloatManagerY,
region.x, region.y, region.width, region.height);
#endif
#ifdef DEBUG
@ -963,8 +911,6 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
}
#endif
mFloatManager->Untranslate(oldWM, oPt, mContainerWidth);
return true;
}
@ -1049,8 +995,7 @@ nsBlockReflowState::ClearFloats(nscoord aBCoord, uint8_t aBreakType,
WritingMode wm = mReflowState.GetWritingMode();
if (aBreakType != NS_STYLE_CLEAR_NONE) {
newBCoord = mFloatManager->ClearFloats(wm, newBCoord, aBreakType,
mContainerWidth, aFlags);
newBCoord = mFloatManager->ClearFloats(newBCoord, aBreakType, aFlags);
}
if (aReplacedBlock) {
@ -1058,27 +1003,27 @@ nsBlockReflowState::ClearFloats(nscoord aBCoord, uint8_t aBreakType,
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
// We check this before calling WidthToClearPastFloats, which is
// somewhat expensive.
break;
}
nsBlockFrame::ReplacedElementISizeToClear replacedISize =
nsBlockFrame::ISizeToClearPastFloats(*this, floatAvailableSpace.mRect,
nsBlockFrame::ReplacedElementWidthToClear replacedWidth =
nsBlockFrame::WidthToClearPastFloats(*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 (std::max(floatAvailableSpace.mRect.x -
mContentArea.X(wm, mContainerWidth),
replacedWidth.marginLeft) +
replacedWidth.borderBoxWidth +
std::max(mContentArea.XMost(wm, mContainerWidth) -
floatAvailableSpace.mRect.XMost(),
replacedWidth.marginRight) <=
mContentArea.Width(wm)) {
break;
}
// See the analogous code for inlines in nsBlockFrame::DoReflowInlineFrames
if (floatAvailableSpace.mRect.BSize(wm) > 0) {
if (floatAvailableSpace.mRect.height > 0) {
// See if there's room in the next band.
newBCoord += floatAvailableSpace.mRect.BSize(wm);
newBCoord += floatAvailableSpace.mRect.height;
} else {
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) {
// Stop trying to clear here; we'll just get pushed to the

View File

@ -113,16 +113,16 @@ public:
// Caller must have called GetAvailableSpace for the correct position
// (which need not be the current mBCoord).
void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const mozilla::LogicalRect& aFloatAvailableSpace,
nscoord& aIStartResult,
nscoord& aIEndResult);
const nsRect& aFloatAvailableSpace,
nscoord& aLeftResult,
nscoord& aRightResult);
// Caller must have called GetAvailableSpace for the current mBCoord
void ComputeBlockAvailSpace(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay,
const nsFlowAreaRect& aFloatAvailableSpace,
bool aBlockAvoidsFloats,
mozilla::LogicalRect& aResult);
nsRect& aResult);
protected:
void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaBCoord);
@ -157,8 +157,7 @@ public:
// padding. This, therefore, represents the inner "content area" (in
// spacemanager coordinates) where child frames will be placed,
// including child blocks and floats.
mozilla::WritingMode mFloatManagerWM;
mozilla::LogicalPoint mFloatManagerOrigin;
nscoord mFloatManagerX, mFloatManagerY;
// XXX get rid of this
nsReflowStatus mReflowStatus;

View File

@ -1173,11 +1173,8 @@ nsContainerFrame::ReflowOverflowContainerChildren(nsPresContext* aPres
}
else {
tracker.Skip(frame, aStatus);
if (aReflowState.mFloatManager) {
nsBlockFrame::RecoverFloatsFor(frame, *aReflowState.mFloatManager,
aReflowState.GetWritingMode(),
aReflowState.ComputedWidth());
}
if (aReflowState.mFloatManager)
nsBlockFrame::RecoverFloatsFor(frame, *aReflowState.mFloatManager);
}
ConsiderChildOverflow(aOverflowRects, frame);
}

View File

@ -37,10 +37,8 @@ PSArenaFreeCB(size_t aSize, void* aPtr, void* aClosure)
/////////////////////////////////////////////////////////////////////////////
// nsFloatManager
nsFloatManager::nsFloatManager(nsIPresShell* aPresShell,
mozilla::WritingMode aWM)
: mWritingMode(aWM),
mOrigin(aWM),
nsFloatManager::nsFloatManager(nsIPresShell* aPresShell)
: mX(0), mY(0),
mFloatDamage(PSArenaAllocCB, PSArenaFreeCB, aPresShell),
mPushedLeftFloatPastBreak(false),
mPushedRightFloatPastBreak(false),
@ -112,20 +110,17 @@ void nsFloatManager::Shutdown()
}
nsFlowAreaRect
nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
BandInfoType aInfoType, nscoord aBSize,
LogicalRect aContentArea, SavedState* aState,
nscoord aContainerWidth) const
nsFloatManager::GetFlowArea(nscoord aYOffset, BandInfoType aInfoType,
nscoord aHeight, nsRect aContentArea,
SavedState* aState) const
{
NS_ASSERTION(aBSize >= 0, "unexpected max block size");
NS_ASSERTION(aContentArea.ISize(aWM) >= 0,
"unexpected content area inline size");
NS_ASSERTION(aHeight >= 0, "unexpected max height");
NS_ASSERTION(aContentArea.width >= 0, "unexpected content area width");
LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
nscoord blockStart = aBOffset + origin.B(aWM);
if (blockStart < nscoord_MIN) {
nscoord top = aYOffset + mY;
if (top < nscoord_MIN) {
NS_WARNING("bad value");
blockStart = nscoord_MIN;
top = nscoord_MIN;
}
// Determine the last float that we should consider.
@ -142,39 +137,39 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
// If there are no floats at all, or we're below the last one, return
// quickly.
if (floatCount == 0 ||
(mFloats[floatCount-1].mLeftBEnd <= blockStart &&
mFloats[floatCount-1].mRightBEnd <= blockStart)) {
return nsFlowAreaRect(aWM, aContentArea.IStart(aWM), aBOffset,
aContentArea.ISize(aWM), aBSize, false);
(mFloats[floatCount-1].mLeftYMost <= top &&
mFloats[floatCount-1].mRightYMost <= top)) {
return nsFlowAreaRect(aContentArea.x, aYOffset, aContentArea.width,
aHeight, false);
}
nscoord blockEnd;
if (aBSize == nscoord_MAX) {
nscoord bottom;
if (aHeight == nscoord_MAX) {
// This warning (and the two below) are possible to hit on pages
// with really large objects.
NS_WARN_IF_FALSE(aInfoType == BAND_FROM_POINT,
"bad height");
blockEnd = nscoord_MAX;
bottom = nscoord_MAX;
} else {
blockEnd = blockStart + aBSize;
if (blockEnd < blockStart || blockEnd > nscoord_MAX) {
bottom = top + aHeight;
if (bottom < top || bottom > nscoord_MAX) {
NS_WARNING("bad value");
blockEnd = nscoord_MAX;
bottom = nscoord_MAX;
}
}
nscoord inlineStart = origin.I(aWM) + aContentArea.IStart(aWM);
nscoord inlineEnd = origin.I(aWM) + aContentArea.IEnd(aWM);
if (inlineEnd < inlineStart) {
nscoord left = mX + aContentArea.x;
nscoord right = mX + aContentArea.XMost();
if (right < left) {
NS_WARNING("bad value");
inlineEnd = inlineStart;
right = left;
}
// Walk backwards through the floats until we either hit the front of
// the list or we're above |blockStart|.
// the list or we're above |top|.
bool haveFloats = false;
for (uint32_t i = floatCount; i > 0; --i) {
const FloatInfo &fi = mFloats[i-1];
if (fi.mLeftBEnd <= blockStart && fi.mRightBEnd <= blockStart) {
if (fi.mLeftYMost <= top && fi.mRightYMost <= top) {
// There aren't any more floats that could intersect this band.
break;
}
@ -184,39 +179,33 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
// future, though.)
continue;
}
LogicalRect rect = fi.mRect.ConvertTo(aWM, fi.mWritingMode,
aContainerWidth);
nscoord floatBStart = rect.BStart(aWM);
nscoord floatBEnd = rect.BEnd(aWM);
if (blockStart < floatBStart && aInfoType == BAND_FROM_POINT) {
nscoord floatTop = fi.mRect.y, floatBottom = fi.mRect.YMost();
if (top < floatTop && aInfoType == BAND_FROM_POINT) {
// This float is below our band. Shrink our band's height if needed.
if (floatBStart < blockEnd) {
blockEnd = floatBStart;
if (floatTop < bottom) {
bottom = floatTop;
}
}
// If blockStart == blockEnd (which happens only with WIDTH_WITHIN_HEIGHT),
// If top == bottom (which happens only with WIDTH_WITHIN_HEIGHT),
// we include floats that begin at our 0-height vertical area. We
// need to to this to satisfy the invariant that a
// WIDTH_WITHIN_HEIGHT call is at least as narrow on both sides as a
// BAND_WITHIN_POINT call beginning at its blockStart.
else if (blockStart < floatBEnd &&
(floatBStart < blockEnd ||
(floatBStart == blockEnd && blockStart == blockEnd))) {
// BAND_WITHIN_POINT call beginning at its top.
else if (top < floatBottom &&
(floatTop < bottom || (floatTop == bottom && top == bottom))) {
// This float is in our band.
// Shrink our band's height if needed.
if (floatBEnd < blockEnd && aInfoType == BAND_FROM_POINT) {
blockEnd = floatBEnd;
if (floatBottom < bottom && aInfoType == BAND_FROM_POINT) {
bottom = floatBottom;
}
// Shrink our band's width if needed.
if ((fi.mFrame->StyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) ==
aWM.IsBidiLTR()) {
// A left float in an ltr block or a right float in an rtl block
nscoord inlineEndEdge = rect.IEnd(aWM);
if (inlineEndEdge > inlineStart) {
inlineStart = inlineEndEdge;
if (fi.mFrame->StyleDisplay()->mFloats == NS_STYLE_FLOAT_LEFT) {
// A left float.
nscoord rightEdge = fi.mRect.XMost();
if (rightEdge > left) {
left = rightEdge;
// Only set haveFloats to true if the float is inside our
// containing block. This matches the spec for what some
// callers want and disagrees for other callers, so we should
@ -224,10 +213,10 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
haveFloats = true;
}
} else {
// A left float in an rtl block or a right float in an ltr block
nscoord inlineStartEdge = rect.IStart(aWM);
if (inlineStartEdge < inlineEnd) {
inlineEnd = inlineStartEdge;
// A right float.
nscoord leftEdge = fi.mRect.x;
if (leftEdge < right) {
right = leftEdge;
// See above.
haveFloats = true;
}
@ -235,40 +224,35 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
}
}
nscoord blockSize = (blockEnd == nscoord_MAX) ?
nscoord_MAX : (blockEnd - blockStart);
return nsFlowAreaRect(aWM,
inlineStart - origin.I(aWM), blockStart - origin.B(aWM),
inlineEnd - inlineStart, blockSize, haveFloats);
nscoord height = (bottom == nscoord_MAX) ? nscoord_MAX : (bottom - top);
return nsFlowAreaRect(left - mX, top - mY, right - left, height, haveFloats);
}
nsresult
nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const LogicalRect& aMarginRect,
WritingMode aWM, nscoord aContainerWidth)
nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const nsRect& aMarginRect)
{
NS_ASSERTION(aMarginRect.ISize(aWM) >= 0, "negative inline size!");
NS_ASSERTION(aMarginRect.BSize(aWM) >= 0, "negative block size!");
NS_ASSERTION(aMarginRect.width >= 0, "negative width!");
NS_ASSERTION(aMarginRect.height >= 0, "negative height!");
FloatInfo info(aFloatFrame, aWM, aMarginRect + mOrigin);
FloatInfo info(aFloatFrame, aMarginRect + nsPoint(mX, mY));
// Set mLeftBEnd and mRightBEnd.
// Set mLeftYMost and mRightYMost.
if (HasAnyFloats()) {
FloatInfo &tail = mFloats[mFloats.Length() - 1];
info.mLeftBEnd = tail.mLeftBEnd;
info.mRightBEnd = tail.mRightBEnd;
info.mLeftYMost = tail.mLeftYMost;
info.mRightYMost = tail.mRightYMost;
} else {
info.mLeftBEnd = nscoord_MIN;
info.mRightBEnd = nscoord_MIN;
info.mLeftYMost = nscoord_MIN;
info.mRightYMost = nscoord_MIN;
}
uint8_t floatStyle = aFloatFrame->StyleDisplay()->mFloats;
NS_ASSERTION(floatStyle == NS_STYLE_FLOAT_LEFT ||
floatStyle == NS_STYLE_FLOAT_RIGHT, "unexpected float");
nscoord& sideBEnd =
((floatStyle == NS_STYLE_FLOAT_LEFT) == aWM.IsBidiLTR()) ? info.mLeftBEnd
: info.mRightBEnd;
nscoord thisBEnd = info.mRect.BEnd(aWM);
if (thisBEnd > sideBEnd)
sideBEnd = thisBEnd;
nscoord& sideYMost = (floatStyle == NS_STYLE_FLOAT_LEFT) ? info.mLeftYMost
: info.mRightYMost;
nscoord thisYMost = info.mRect.YMost();
if (thisYMost > sideYMost)
sideYMost = thisYMost;
if (!mFloats.AppendElement(info))
return NS_ERROR_OUT_OF_MEMORY;
@ -276,61 +260,54 @@ nsFloatManager::AddFloat(nsIFrame* aFloatFrame, const LogicalRect& aMarginRect,
return NS_OK;
}
LogicalRect
nsFloatManager::CalculateRegionFor(WritingMode aWM,
nsIFrame* aFloat,
const LogicalMargin& aMargin,
nscoord aContainerWidth)
nsRect
nsFloatManager::CalculateRegionFor(nsIFrame* aFloat,
const nsMargin& aMargin)
{
// We consider relatively positioned frames at their original position.
LogicalRect region(aWM, nsRect(aFloat->GetNormalPosition(),
aFloat->GetSize()),
aContainerWidth);
nsRect region(aFloat->GetNormalPosition(), aFloat->GetSize());
// Float region includes its margin
region.Inflate(aWM, aMargin);
region.Inflate(aMargin);
// Don't store rectangles with negative margin-box width or height in
// the float manager; it can't deal with them.
if (region.ISize(aWM) < 0) {
if (region.width < 0) {
// Preserve the right margin-edge for left floats and the left
// margin-edge for right floats
const nsStyleDisplay* display = aFloat->StyleDisplay();
if ((NS_STYLE_FLOAT_LEFT == display->mFloats) == aWM.IsBidiLTR()) {
region.IStart(aWM) = region.IEnd(aWM);
if (NS_STYLE_FLOAT_LEFT == display->mFloats) {
region.x = region.XMost();
}
region.ISize(aWM) = 0;
region.width = 0;
}
if (region.BSize(aWM) < 0) {
region.BSize(aWM) = 0;
if (region.height < 0) {
region.height = 0;
}
return region;
}
NS_DECLARE_FRAME_PROPERTY(FloatRegionProperty, nsIFrame::DestroyMargin)
LogicalRect
nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat,
nscoord aContainerWidth)
nsRect
nsFloatManager::GetRegionFor(nsIFrame* aFloat)
{
LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerWidth);
nsRect region = aFloat->GetRect();
void* storedRegion = aFloat->Properties().Get(FloatRegionProperty());
if (storedRegion) {
nsMargin margin = *static_cast<nsMargin*>(storedRegion);
region.Inflate(aWM, LogicalMargin(aWM, margin));
region.Inflate(margin);
}
return region;
}
void
nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
const LogicalRect& aRegion,
nscoord aContainerWidth)
nsFloatManager::StoreRegionFor(nsIFrame* aFloat,
nsRect& aRegion)
{
nsRect region = aRegion.GetPhysicalRect(aWM, aContainerWidth);
nsRect rect = aFloat->GetRect();
FrameProperties props = aFloat->Properties();
if (region.IsEqualEdges(rect)) {
if (aRegion.IsEqualEdges(rect)) {
props.Delete(FloatRegionProperty());
}
else {
@ -340,7 +317,7 @@ nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
storedMargin = new nsMargin();
props.Set(FloatRegionProperty(), storedMargin);
}
*storedMargin = region - rect;
*storedMargin = aRegion - rect;
}
}
@ -401,8 +378,8 @@ nsFloatManager::PushState(SavedState* aState)
// reflow. In the typical case A and C will be the same, but not always.
// Allowing mFloatDamage to accumulate the damage incurred during both
// reflows ensures that nothing gets missed.
aState->mWritingMode = mWritingMode;
aState->mOrigin = mOrigin;
aState->mX = mX;
aState->mY = mY;
aState->mPushedLeftFloatPastBreak = mPushedLeftFloatPastBreak;
aState->mPushedRightFloatPastBreak = mPushedRightFloatPastBreak;
aState->mSplitLeftFloatAcrossBreak = mSplitLeftFloatAcrossBreak;
@ -415,8 +392,8 @@ nsFloatManager::PopState(SavedState* aState)
{
NS_PRECONDITION(aState, "No state to restore?");
mWritingMode = aState->mWritingMode;
mOrigin = aState->mOrigin;
mX = aState->mX;
mY = aState->mY;
mPushedLeftFloatPastBreak = aState->mPushedLeftFloatPastBreak;
mPushedRightFloatPastBreak = aState->mPushedRightFloatPastBreak;
mSplitLeftFloatAcrossBreak = aState->mSplitLeftFloatAcrossBreak;
@ -428,8 +405,7 @@ nsFloatManager::PopState(SavedState* aState)
}
nscoord
nsFloatManager::GetLowestFloatTop(WritingMode aWM,
nscoord aContainerWidth) const
nsFloatManager::GetLowestFloatTop() const
{
if (mPushedLeftFloatPastBreak || mPushedRightFloatPastBreak) {
return nscoord_MAX;
@ -437,11 +413,7 @@ nsFloatManager::GetLowestFloatTop(WritingMode aWM,
if (!HasAnyFloats()) {
return nscoord_MIN;
}
FloatInfo fi = mFloats[mFloats.Length() - 1];
LogicalRect rect = fi.mRect.ConvertTo(aWM, fi.mWritingMode, aContainerWidth);
LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
return rect.BStart(aWM) - origin.B(aWM);
return mFloats[mFloats.Length() - 1].mRect.y - mY;
}
#ifdef DEBUG_FRAME_DUMP
@ -461,53 +433,46 @@ nsFloatManager::List(FILE* out) const
const FloatInfo &fi = mFloats[i];
fprintf_stderr(out, "Float %u: frame=%p rect={%d,%d,%d,%d} ymost={l:%d, r:%d}\n",
i, static_cast<void*>(fi.mFrame),
fi.mRect.IStart(fi.mWritingMode),
fi.mRect.BStart(fi.mWritingMode),
fi.mRect.ISize(fi.mWritingMode),
fi.mRect.BSize(fi.mWritingMode),
fi.mLeftBEnd, fi.mRightBEnd);
fi.mRect.x, fi.mRect.y, fi.mRect.width, fi.mRect.height,
fi.mLeftYMost, fi.mRightYMost);
}
return NS_OK;
}
#endif
nscoord
nsFloatManager::ClearFloats(WritingMode aWM, nscoord aBCoord,
uint8_t aBreakType, nscoord aContainerWidth,
nsFloatManager::ClearFloats(nscoord aY, uint8_t aBreakType,
uint32_t aFlags) const
{
if (!(aFlags & DONT_CLEAR_PUSHED_FLOATS) && ClearContinues(aBreakType)) {
return nscoord_MAX;
}
if (!HasAnyFloats()) {
return aBCoord;
return aY;
}
LogicalPoint origin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
nscoord blockEnd = aBCoord + origin.B(aWM);
nscoord bottom = aY + mY;
const FloatInfo &tail = mFloats[mFloats.Length() - 1];
switch (aBreakType) {
case NS_STYLE_CLEAR_BOTH:
blockEnd = std::max(blockEnd, tail.mLeftBEnd);
blockEnd = std::max(blockEnd, tail.mRightBEnd);
bottom = std::max(bottom, tail.mLeftYMost);
bottom = std::max(bottom, tail.mRightYMost);
break;
case NS_STYLE_CLEAR_LEFT:
blockEnd = std::max(blockEnd, aWM.IsBidiLTR() ? tail.mLeftBEnd
: tail.mRightBEnd);
bottom = std::max(bottom, tail.mLeftYMost);
break;
case NS_STYLE_CLEAR_RIGHT:
blockEnd = std::max(blockEnd, aWM.IsBidiLTR() ? tail.mRightBEnd
: tail.mLeftBEnd);
bottom = std::max(bottom, tail.mRightYMost);
break;
default:
// Do nothing
break;
}
blockEnd -= origin.B(aWM);
bottom -= mY;
return blockEnd;
return bottom;
}
bool
@ -524,9 +489,8 @@ nsFloatManager::ClearContinues(uint8_t aBreakType) const
/////////////////////////////////////////////////////////////////////////////
// FloatInfo
nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, WritingMode aWM,
const LogicalRect& aRect)
: mFrame(aFrame), mRect(aRect), mWritingMode(aWM)
nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, const nsRect& aRect)
: mFrame(aFrame), mRect(aRect)
{
MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
}
@ -535,9 +499,8 @@ nsFloatManager::FloatInfo::FloatInfo(nsIFrame* aFrame, WritingMode aWM,
nsFloatManager::FloatInfo::FloatInfo(const FloatInfo& aOther)
: mFrame(aOther.mFrame),
mRect(aOther.mRect),
mWritingMode(aOther.mWritingMode),
mLeftBEnd(aOther.mLeftBEnd),
mRightBEnd(aOther.mRightBEnd)
mLeftYMost(aOther.mLeftYMost),
mRightYMost(aOther.mRightYMost)
{
MOZ_COUNT_CTOR(nsFloatManager::FloatInfo);
}
@ -578,8 +541,7 @@ nsAutoFloatManager::CreateFloatManager(nsPresContext *aPresContext)
// Create a new float manager and install it in the reflow
// state. `Remember' the old float manager so we can restore it
// later.
mNew = new nsFloatManager(aPresContext->PresShell(),
mReflowState.GetWritingMode());
mNew = new nsFloatManager(aPresContext->PresShell());
if (! mNew)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -13,7 +13,7 @@
#include "nsIntervalSet.h"
#include "nsCoord.h"
#include "WritingModes.h"
#include "nsRect.h"
#include "nsTArray.h"
#include "nsFrameList.h" // for DEBUG_FRAME_DUMP
@ -24,28 +24,25 @@ class nsPresContext;
/**
* 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.
* into a (vertical) sequence of rectangles. 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.
*/
struct nsFlowAreaRect {
mozilla::LogicalRect mRect;
nsRect mRect;
bool mHasFloats;
nsFlowAreaRect(mozilla::WritingMode aWritingMode,
nscoord aICoord, nscoord aBCoord,
nscoord aISize, nscoord aBSize,
nsFlowAreaRect(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight,
bool aHasFloats)
: mRect(aWritingMode, aICoord, aBCoord, aISize, aBSize)
, mHasFloats(aHasFloats) {}
: mRect(aX, aY, aWidth, aHeight), mHasFloats(aHasFloats) {}
};
#define NS_FLOAT_MANAGER_CACHE_SIZE 4
class nsFloatManager {
public:
explicit nsFloatManager(nsIPresShell* aPresShell, mozilla::WritingMode aWM);
explicit nsFloatManager(nsIPresShell* aPresShell);
~nsFloatManager();
void* operator new(size_t aSize) CPP_THROW_NEW;
@ -58,9 +55,7 @@ public:
* not there.) The float region is the area impacted by this float;
* the coordinates are relative to the containing block frame.
*/
static mozilla::LogicalRect GetRegionFor(mozilla::WritingMode aWM,
nsIFrame* aFloatFrame,
nscoord aContainerWidth);
static nsRect GetRegionFor(nsIFrame* aFloatFrame);
/**
* Calculate the float region for this frame using aMargin and the
* frame's mRect. The region includes the margins around the float,
@ -68,32 +63,23 @@ public:
* Note that if the frame is or has a continuation, aMargin's top
* and/or bottom must be zeroed by the caller.
*/
static mozilla::LogicalRect CalculateRegionFor(
mozilla::WritingMode aWM,
nsIFrame* aFloatFrame,
const mozilla::LogicalMargin& aMargin,
nscoord aContainerWidth);
static nsRect CalculateRegionFor(nsIFrame* aFloatFrame,
const nsMargin& aMargin);
/**
* Store the float region on the frame. The region is stored
* as a delta against the mRect, so repositioning the frame will
* also reposition the float region.
*/
static void StoreRegionFor(mozilla::WritingMode aWM,
nsIFrame* aFloat,
const mozilla::LogicalRect& aRegion,
nscoord aContainerWidth);
static void StoreRegionFor(nsIFrame* aFloat, nsRect& aRegion);
// Structure that stores the current state of a frame manager for
// Save/Restore purposes.
struct SavedState;
friend struct SavedState;
struct SavedState {
SavedState(mozilla::WritingMode aWM)
: mWritingMode(aWM)
, mOrigin(aWM)
{}
private:
uint32_t mFloatInfoCount;
mozilla::WritingMode mWritingMode;
mozilla::LogicalPoint mOrigin;
nscoord mX, mY;
bool mPushedLeftFloatPastBreak;
bool mPushedRightFloatPastBreak;
bool mSplitLeftFloatAcrossBreak;
@ -103,109 +89,69 @@ public:
};
/**
* Translate the current origin by the specified (dICoord, dBCoord). This
* Translate the current origin by the specified (dx, dy). This
* creates a new local coordinate space relative to the current
* coordinate space.
* @returns previous writing mode
*/
mozilla::WritingMode Translate(mozilla::WritingMode aWM,
mozilla::LogicalPoint aDOrigin,
nscoord aContainerWidth)
{
mozilla::WritingMode oldWM = mWritingMode;
mOrigin = mOrigin.ConvertTo(aWM, oldWM, aContainerWidth);
mWritingMode = aWM;
mOrigin += aDOrigin;
return oldWM;
}
/*
* Set the translation origin to a specified value instead of
* translating by a delta.
*/
void SetTranslation(mozilla::WritingMode aWM,
mozilla::LogicalPoint aOrigin)
{
mWritingMode = aWM;
mOrigin = aOrigin;
}
void Untranslate(mozilla::WritingMode aWM,
mozilla::LogicalPoint aDOrigin,
nscoord aContainerWidth)
{
mOrigin -= aDOrigin;
mOrigin = mOrigin.ConvertTo(aWM, mWritingMode, aContainerWidth);
mWritingMode = aWM;
}
void Translate(nscoord aDx, nscoord aDy) { mX += aDx; mY += aDy; }
/**
* Returns the current translation from local coordinate space to
* world coordinate space. This represents the accumulated calls to
* Translate().
*/
void GetTranslation(mozilla::WritingMode& aWM,
mozilla::LogicalPoint& aOrigin) const
{
aWM = mWritingMode;
aOrigin = mOrigin;
}
void GetTranslation(nscoord& aX, nscoord& aY) const { aX = mX; aY = mY; }
/**
* Get information about the area available to content that flows
* around floats. Two different types of space can be requested:
* BAND_FROM_POINT: returns the band containing block-dir coordinate
* |aBCoord| (though actually with the top truncated to begin at
* aBCoord), but up to at most |aBSize| (which may be nscoord_MAX).
* This will return the tallest rectangle whose block start is
* |aBCoord| and in which there are no changes in what floats are
* on the sides of that rectangle, but will limit the block size
* of the rectangle to |aBSize|. The inline start and end edges
* of the rectangle give the area available for line boxes in that
* space. The inline size of this resulting rectangle will not be
* negative.
* WIDTH_WITHIN_HEIGHT: This returns a rectangle whose block start
* is aBCoord and whose block size is exactly aBSize. Its inline
* start and end edges give the corresponding edges of the space
* that can be used for line boxes *throughout* that space. (It
* is possible that more inline space could be used in part of the
* space if a float begins or ends in it.) The inline size of the
* resulting rectangle can be negative.
* BAND_FROM_POINT: returns the band containing vertical coordinate
* |aY| (though actually with the top truncated to begin at aY),
* but up to at most |aHeight| (which may be nscoord_MAX).
* This will return the tallest rectangle whose top is |aY| and in
* which there are no changes in what floats are on the sides of
* that rectangle, but will limit the height of the rectangle to
* |aHeight|. The left and right edges of the rectangle give the
* area available for line boxes in that space. The width of this
* resulting rectangle will not be negative.
* WIDTH_WITHIN_HEIGHT: This returns a rectangle whose top is aY and
* whose height is exactly aHeight. Its left and right edges give
* the left and right edges of the space that can be used for line
* boxes *throughout* that space. (It is possible that more
* horizontal space could be used in part of the space if a float
* begins or ends in it.) The width of the resulting rectangle
* can be negative.
*
* @param aBCoord [in] block-dir coordinate for block start of
* available space desired
* @param aBSize [in] see above
* @param aY [in] vertical coordinate for top of available space
* desired
* @param aHeight [in] see above
* @param aContentArea [in] an nsRect representing the content area
* @param aState [in] If null, use the current state, otherwise, do
* computation based only on floats present in the given
* saved state.
* @return An nsFlowAreaRect whose:
* mRect is the resulting rectangle for line boxes. It will not
* extend beyond aContentArea's inline bounds, but may be
* extend beyond aContentArea's horizontal bounds, but may be
* narrower when floats are present.
* mBandHasFloats is whether there are floats at the sides of the
* return value including those that do not reduce the line box
* inline size at all (because they are entirely in the margins)
* width at all (because they are entirely in the margins)
*
* aBCoord and aAvailSpace are positioned relative to the current translation
* aY and aAvailSpace are positioned relative to the current translation
*/
enum BandInfoType { BAND_FROM_POINT, WIDTH_WITHIN_HEIGHT };
nsFlowAreaRect GetFlowArea(mozilla::WritingMode aWM,
nscoord aBCoord, BandInfoType aInfoType,
nscoord aBSize, mozilla::LogicalRect aContentArea,
SavedState* aState, nscoord mContainerWidth) const;
nsFlowAreaRect GetFlowArea(nscoord aY, BandInfoType aInfoType,
nscoord aHeight, nsRect aContentArea,
SavedState* aState) const;
/**
* Add a float that comes after all floats previously added. Its
* block start must be even with or below the top of all previous
* floats.
* Add a float that comes after all floats previously added. Its top
* must be even with or below the top of all previous floats.
*
* aMarginRect is relative to the current translation. The caller
* must ensure aMarginRect.height >= 0 and aMarginRect.width >= 0.
*/
nsresult AddFloat(nsIFrame* aFloatFrame,
const mozilla::LogicalRect& aMarginRect,
mozilla::WritingMode aWM, nscoord aContainerWidth);
nsresult AddFloat(nsIFrame* aFloatFrame, const nsRect& aMarginRect);
/**
* Notify that we tried to place a float that could not fit at all and
@ -254,18 +200,14 @@ public:
return !mFloatDamage.IsEmpty();
}
void IncludeInDamage(mozilla::WritingMode aWM,
nscoord aIntervalBegin, nscoord aIntervalEnd)
void IncludeInDamage(nscoord aIntervalBegin, nscoord aIntervalEnd)
{
mFloatDamage.IncludeInterval(aIntervalBegin + mOrigin.B(aWM),
aIntervalEnd + mOrigin.B(aWM));
mFloatDamage.IncludeInterval(aIntervalBegin + mY, aIntervalEnd + mY);
}
bool IntersectsDamage(mozilla::WritingMode aWM,
nscoord aIntervalBegin, nscoord aIntervalEnd) const
bool IntersectsDamage(nscoord aIntervalBegin, nscoord aIntervalEnd) const
{
return mFloatDamage.Intersects(aIntervalBegin + mOrigin.B(aWM),
aIntervalEnd + mOrigin.B(aWM));
return mFloatDamage.Intersects(aIntervalBegin + mY, aIntervalEnd + mY);
}
/**
@ -286,30 +228,26 @@ public:
void PopState(SavedState* aState);
/**
* Get the block start of the last float placed into the float
* manager, to enforce the rule that a float can't be above an earlier
* float. Returns the minimum nscoord value if there are no floats.
* Get the top of the last float placed into the float manager, to
* enforce the rule that a float can't be above an earlier float.
* Returns the minimum nscoord value if there are no floats.
*
* The result is relative to the current translation.
*/
nscoord GetLowestFloatTop(mozilla::WritingMode aWM,
nscoord aContainerWidth) const;
nscoord GetLowestFloatTop() const;
/**
* Return the coordinate of the lowest float matching aBreakType in
* this float manager. Returns aBCoord if there are no matching
* floats.
* Return the coordinate of the lowest float matching aBreakType in this
* float manager. Returns aY if there are no matching floats.
*
* Both aBCoord and the result are relative to the current translation.
* Both aY and the result are relative to the current translation.
*/
enum {
// Tell ClearFloats not to push to nscoord_MAX when floats have been
// pushed to the next page/column.
DONT_CLEAR_PUSHED_FLOATS = (1<<0)
};
nscoord ClearFloats(mozilla::WritingMode aWM, nscoord aBCoord,
uint8_t aBreakType, nscoord aContainerWidth,
uint32_t aFlags = 0) const;
nscoord ClearFloats(nscoord aY, uint8_t aBreakType, uint32_t aFlags = 0) const;
/**
* Checks if clear would pass into the floats' BFC's next-in-flow,
@ -319,8 +257,7 @@ public:
void AssertStateMatches(SavedState *aState) const
{
NS_ASSERTION(aState->mWritingMode == mWritingMode &&
aState->mOrigin == mOrigin &&
NS_ASSERTION(aState->mX == mX && aState->mY == mY &&
aState->mPushedLeftFloatPastBreak ==
mPushedLeftFloatPastBreak &&
aState->mPushedRightFloatPastBreak ==
@ -344,24 +281,18 @@ private:
struct FloatInfo {
nsIFrame *const mFrame;
mozilla::LogicalRect mRect;
mozilla::WritingMode mWritingMode;
// The lowest block-ends of left/right floats up to and including
// this one.
nscoord mLeftBEnd, mRightBEnd;
nsRect mRect;
// The lowest bottoms of left/right floats up to and including this one.
nscoord mLeftYMost, mRightYMost;
FloatInfo(nsIFrame* aFrame, mozilla::WritingMode aWM,
const mozilla::LogicalRect& aRect);
FloatInfo(nsIFrame* aFrame, const nsRect& aRect);
#ifdef NS_BUILD_REFCNT_LOGGING
FloatInfo(const FloatInfo& aOther);
~FloatInfo();
#endif
};
mozilla::WritingMode mWritingMode;
mozilla::LogicalPoint mOrigin; // translation from local to global
// coordinate space
nscoord mX, mY; // translation from local to global coordinate space
nsTArray<FloatInfo> mFloats;
nsIntervalSet mFloatDamage;

View File

@ -446,12 +446,6 @@ public:
// used for painting-related things, but should never be used for
// layout (except for handling of 'overflow').
void SetOverflowAreas(const nsOverflowAreas& aOverflowAreas);
mozilla::LogicalRect GetOverflowArea(nsOverflowType aType,
mozilla::WritingMode aWM,
nscoord aContainerWidth)
{
return mozilla::LogicalRect(aWM, GetOverflowArea(aType), aContainerWidth);
}
nsRect GetOverflowArea(nsOverflowType aType) {
return mData ? mData->mOverflowAreas.Overflow(aType) : GetPhysicalBounds();
}

View File

@ -93,7 +93,7 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext,
mLineNumber = 0;
mTotalPlacedFrames = 0;
mBStartEdge = 0;
mTrimmableISize = 0;
mTrimmableWidth = 0;
mInflationMinFontSize =
nsLayoutUtils::InflationMinFontSizeFor(aOuterReflowState->frame);
@ -270,17 +270,13 @@ nsLineLayout::EndLineReflow()
// per-span mIStart?
void
nsLineLayout::UpdateBand(WritingMode aWM,
const LogicalRect& aNewAvailSpace,
nsLineLayout::UpdateBand(const nsRect& aNewAvailSpace,
nsIFrame* aFloatFrame)
{
WritingMode lineWM = mRootSpan->mWritingMode;
// need to convert to our writing mode, because we might have a different
// mode from the caller due to dir: auto
LogicalRect availSpace = aNewAvailSpace.ConvertTo(lineWM, aWM,
mContainerWidth);
LogicalRect availSpace(lineWM, aNewAvailSpace, mContainerWidth);
#ifdef REALLY_NOISY_REFLOW
printf("nsLL::UpdateBand %d, %d, %d, %d, (converted to %d, %d, %d, %d); frame=%p\n will set mImpacted to true\n",
printf("nsLL::UpdateBand %d, %d, %d, %d, (logical %d, %d, %d, %d); frame=%p\n will set mImpacted to true\n",
aNewAvailSpace.x, aNewAvailSpace.y,
aNewAvailSpace.width, aNewAvailSpace.height,
availSpace.IStart(lineWM), availSpace.BStart(lineWM),
@ -304,22 +300,21 @@ nsLineLayout::UpdateBand(WritingMode aWM,
// Compute the difference between last times width and the new width
NS_WARN_IF_FALSE(mRootSpan->mIEnd != NS_UNCONSTRAINEDSIZE &&
availSpace.ISize(lineWM) != NS_UNCONSTRAINEDSIZE,
"have unconstrained inline size; this should only result "
"from very large sizes, not attempts at intrinsic width "
aNewAvailSpace.width != NS_UNCONSTRAINEDSIZE,
"have unconstrained width; this should only result from "
"very large sizes, not attempts at intrinsic width "
"calculation");
// The root span's mIStart moves to aICoord
nscoord deltaICoord = availSpace.IStart(lineWM) - mRootSpan->mIStart;
// The inline size of all spans changes by this much (the root span's
// mIEnd moves to aICoord + aISize, its new inline size is aISize)
// The width of all spans changes by this much (the root span's
// mIEnd moves to aICoord + aISize, its new width is aISize)
nscoord deltaISize = availSpace.ISize(lineWM) -
(mRootSpan->mIEnd - mRootSpan->mIStart);
#ifdef NOISY_REFLOW
nsFrame::ListTag(stdout, mBlockReflowState->frame);
printf(": UpdateBand: %d,%d,%d,%d deltaISize=%d deltaICoord=%d\n",
availSpace.IStart(lineWM), availSpace.BStart(lineWM),
availSpace.ISize(lineWM), availSpace.BSize(lineWM),
deltaISize, deltaICoord);
aNewAvailSpace.IStart(lineWM), aNewAvailSpace.BStart(lineWM),
aNewAvailSpace.ISize(lineWM), aNewAvailSpace.BSize(lineWM), deltaISize, deltaICoord);
#endif
// Update the root span position
@ -846,8 +841,10 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
metrics.ISize(lineWM) = nscoord(0xdeadbeef);
metrics.BSize(lineWM) = nscoord(0xdeadbeef);
#endif
LogicalPoint tPt = pfd->mBounds.Origin(lineWM);
WritingMode oldWM = mFloatManager->Translate(lineWM, tPt, mContainerWidth);
nsRect physicalBounds = pfd->mBounds.GetPhysicalRect(lineWM, mContainerWidth);
nscoord tx = physicalBounds.x;
nscoord ty = physicalBounds.y;
mFloatManager->Translate(tx, ty);
int32_t savedOptionalBreakOffset;
gfxBreakPriority savedOptionalBreakPriority;
@ -879,10 +876,10 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
pfd->SetFlag(PFD_SKIPWHENTRIMMINGWHITESPACE, true);
nsIFrame* outOfFlowFrame = nsLayoutUtils::GetFloatFromPlaceholder(aFrame);
if (outOfFlowFrame) {
// Add mTrimmableISize to the available width since if the line ends
// Add mTrimmableWidth to the available width since if the line ends
// here, the width of the inline content will be reduced by
// mTrimmableISize.
nscoord availableISize = psd->mIEnd - (psd->mICoord - mTrimmableISize);
// mTrimmableWidth.
nscoord availableWidth = psd->mIEnd - (psd->mICoord - mTrimmableWidth);
if (psd->mNoWrap) {
// If we place floats after inline content where there's
// no break opportunity, we don't know how much additional
@ -893,9 +890,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// but hopefully rare. Fixing it will require significant
// restructuring of line layout.
// We might as well allow zero-width floats to be placed, though.
availableISize = 0;
availableWidth = 0;
}
placedFloat = AddFloat(outOfFlowFrame, availableISize);
placedFloat = AddFloat(outOfFlowFrame, availableWidth);
NS_ASSERTION(!(outOfFlowFrame->GetType() == nsGkAtoms::letterFrame &&
GetFirstLetterStyleOK()),
"FirstLetterStyle set on line with floating first letter");
@ -932,7 +929,7 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
}
}
mFloatManager->Untranslate(oldWM, tPt, mContainerWidth);
mFloatManager->Translate(-tx, -ty);
NS_ASSERTION(metrics.ISize(lineWM) >= 0, "bad inline size");
NS_ASSERTION(metrics.BSize(lineWM) >= 0,"bad block size");
@ -1004,9 +1001,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
// runs (hence return false here) except for text frames and inline containers.
bool continuingTextRun = aFrame->CanContinueTextRun();
// Clear any residual mTrimmableISize if this isn't a text frame
// Clear any residual mTrimmableWidth if this isn't a text frame
if (!continuingTextRun && !pfd->GetFlag(PFD_SKIPWHENTRIMMINGWHITESPACE)) {
mTrimmableISize = 0;
mTrimmableWidth = 0;
}
// See if we can place the frame. If we can't fit it, then we
@ -1205,7 +1202,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd,
// Set outside to true if the result of the reflow leads to the
// frame sticking outside of our available area.
bool outside = pfd->mBounds.IEnd(lineWM) - mTrimmableISize + endMargin >
bool outside = pfd->mBounds.IEnd(lineWM) - mTrimmableWidth + endMargin >
psd->mIEnd;
if (!outside) {
// If it fits, it fits

View File

@ -62,8 +62,7 @@ public:
* space rectangle, relative to the containing block.
* @param aFloatFrame the float frame that was placed.
*/
void UpdateBand(mozilla::WritingMode aWM,
const mozilla::LogicalRect& aNewAvailableSpace,
void UpdateBand(const nsRect& aNewAvailableSpace,
nsIFrame* aFloatFrame);
void BeginSpan(nsIFrame* aFrame, const nsHTMLReflowState* aSpanReflowState,
@ -151,13 +150,13 @@ public:
//----------------------------------------
// Inform the line-layout about the presence of a floating frame
// XXX get rid of this: use get-frame-type?
bool AddFloat(nsIFrame* aFloat, nscoord aAvailableISize)
bool AddFloat(nsIFrame* aFloat, nscoord aAvailableWidth)
{
return mBlockRS->AddFloat(this, aFloat, aAvailableISize);
return mBlockRS->AddFloat(this, aFloat, aAvailableWidth);
}
void SetTrimmableISize(nscoord aTrimmableISize) {
mTrimmableISize = aTrimmableISize;
void SetTrimmableWidth(nscoord aTrimmableWidth) {
mTrimmableWidth = aTrimmableWidth;
}
//----------------------------------------
@ -505,9 +504,8 @@ protected:
// the block has been called.
nscoord mFinalLineBSize;
// Amount of trimmable whitespace inline size for the trailing text
// frame, if any
nscoord mTrimmableISize;
// Amount of trimmable whitespace width for the trailing text frame, if any
nscoord mTrimmableWidth;
nscoord mContainerWidth;

View File

@ -8313,7 +8313,7 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
// at most one space so there's no way for trimmable width from a previous
// frame to accumulate with trimmable width from this frame.)
if (transformedCharsFit > 0) {
aLineLayout.SetTrimmableISize(NSToCoordFloor(trimmableWidth));
aLineLayout.SetTrimmableWidth(NSToCoordFloor(trimmableWidth));
AddStateBits(TEXT_HAS_NONCOLLAPSED_CHARACTERS);
}
if (charsFit > 0 && charsFit == length &&