зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d37beb9414
Коммит
b2eb743d9b
|
@ -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;
|
||||
|
|
|
@ -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,7 +5853,7 @@ 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))) {
|
||||
(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче