зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1079139: make nsFlowAreaRect.mRect a LogicalRect. r=jfkthame
This commit is contained in:
Родитель
3f0d7f2fcc
Коммит
3134a81fca
|
@ -906,17 +906,20 @@ nsBlockFrame::GetPrefWidthTightBounds(nsRenderingContext* aRenderingContext,
|
|||
}
|
||||
|
||||
static bool
|
||||
AvailableSpaceShrunk(const nsRect& aOldAvailableSpace,
|
||||
const nsRect& aNewAvailableSpace)
|
||||
AvailableSpaceShrunk(WritingMode aWM,
|
||||
const LogicalRect& aOldAvailableSpace,
|
||||
const LogicalRect& aNewAvailableSpace)
|
||||
{
|
||||
if (aNewAvailableSpace.width == 0) {
|
||||
// Positions are not significant if the width is zero.
|
||||
return aOldAvailableSpace.width != 0;
|
||||
if (aNewAvailableSpace.ISize(aWM) == 0) {
|
||||
// Positions are not significant if the inline size is zero.
|
||||
return aOldAvailableSpace.ISize(aWM) != 0;
|
||||
}
|
||||
NS_ASSERTION(aOldAvailableSpace.x <= aNewAvailableSpace.x &&
|
||||
aOldAvailableSpace.XMost() >= aNewAvailableSpace.XMost(),
|
||||
NS_ASSERTION(aOldAvailableSpace.IStart(aWM) <=
|
||||
aNewAvailableSpace.IStart(aWM) &&
|
||||
aOldAvailableSpace.IEnd(aWM) >=
|
||||
aNewAvailableSpace.IEnd(aWM),
|
||||
"available space should never grow");
|
||||
return aOldAvailableSpace.width != aNewAvailableSpace.width;
|
||||
return aOldAvailableSpace.ISize(aWM) != aNewAvailableSpace.ISize(aWM);
|
||||
}
|
||||
|
||||
static LogicalSize
|
||||
|
@ -1813,17 +1816,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 |aDeltaY| and any impact by a float,
|
||||
* either the previous reflow or now.
|
||||
* 2. The combination of nonzero |aDeltaBCoord| and any impact by a
|
||||
* float, either the previous reflow or now.
|
||||
*
|
||||
* When entering this function, |aLine| is still at its old position and
|
||||
* |aDeltaY| indicates how much it will later be slid (assuming it
|
||||
* |aDeltaBCoord| 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 aDeltaY)
|
||||
nscoord aDeltaBCoord)
|
||||
{
|
||||
nsFloatManager *floatManager = aState.mReflowState.mFloatManager;
|
||||
NS_ASSERTION((aState.mReflowState.parentReflowState &&
|
||||
|
@ -1839,23 +1842,35 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||
if (floatManager->HasFloatDamage()) {
|
||||
// Need to check mBounds *and* mCombinedArea to find intersections
|
||||
// with aLine's floats
|
||||
nscoord lineYA = aLine->BStart() + aDeltaY;
|
||||
nscoord lineYB = lineYA + aLine->BSize();
|
||||
nscoord lineBCoordBefore = aLine->BStart() + aDeltaBCoord;
|
||||
nscoord lineBCoordAfter = lineBCoordBefore + aLine->BSize();
|
||||
// Scrollable overflow should be sufficient for things that affect
|
||||
// layout.
|
||||
nsRect overflow = aLine->GetOverflowArea(eScrollableOverflow);
|
||||
nscoord lineYCombinedA = overflow.y + aDeltaY;
|
||||
nscoord lineYCombinedB = lineYCombinedA + overflow.height;
|
||||
WritingMode wm = aState.mReflowState.GetWritingMode();
|
||||
if (floatManager->IntersectsDamage(wm, lineYA, lineYB) ||
|
||||
floatManager->IntersectsDamage(wm, lineYCombinedA, lineYCombinedB)) {
|
||||
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) {
|
||||
aLine->MarkDirty();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the line is moving relative to the float manager
|
||||
if (aDeltaY + aState.mReflowState.mBlockDelta != 0) {
|
||||
if (aDeltaBCoord + 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
|
||||
|
@ -1865,7 +1880,7 @@ nsBlockFrame::PropagateFloatDamage(nsBlockReflowState& aState,
|
|||
} else {
|
||||
bool wasImpactedByFloat = aLine->IsImpactedByFloat();
|
||||
nsFlowAreaRect floatAvailableSpace =
|
||||
aState.GetFloatAvailableSpaceForBSize(aLine->BStart() + aDeltaY,
|
||||
aState.GetFloatAvailableSpaceForBSize(aLine->BStart() + aDeltaBCoord,
|
||||
aLine->BSize(),
|
||||
nullptr);
|
||||
|
||||
|
@ -1912,7 +1927,7 @@ nsBlockFrame::ReparentFloats(nsIFrame* aFirstFrame, nsBlockFrame* aOldParent,
|
|||
}
|
||||
|
||||
static void DumpLine(const nsBlockReflowState& aState, nsLineBox* aLine,
|
||||
nscoord aDeltaY, int32_t aDeltaIndent) {
|
||||
nscoord aDeltaBCoord, int32_t aDeltaIndent) {
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsRect ovis(aLine->GetVisualOverflowArea());
|
||||
|
@ -1925,7 +1940,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,
|
||||
aDeltaY, aState.mPrevBEndMargin.get(), aLine->GetChildCount());
|
||||
aDeltaBCoord, aState.mPrevBEndMargin.get(), aLine->GetChildCount());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -3136,7 +3151,8 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
aLine.get(), floatAvailableSpace.mHasFloats?"true":"false");
|
||||
#endif
|
||||
aLine->SetLineIsImpactedByFloat(floatAvailableSpace.mHasFloats);
|
||||
nsRect availSpace;
|
||||
WritingMode wm = aState.mReflowState.GetWritingMode();
|
||||
LogicalRect availSpace(wm);
|
||||
aState.ComputeBlockAvailSpace(frame, display, floatAvailableSpace,
|
||||
replacedBlock != nullptr, availSpace);
|
||||
|
||||
|
@ -3146,7 +3162,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.height < 0) {
|
||||
availSpace.BSize(wm) < 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
|
||||
|
@ -3154,9 +3170,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.height += bStartMargin| below interacting with pushed
|
||||
// floats (which force nscoord_MAX clearance) to cause a
|
||||
// constrained height to turn into an unconstrained one.
|
||||
// |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.
|
||||
aState.mBCoord = startingBCoord;
|
||||
aState.mPrevBEndMargin = incomingMargin;
|
||||
*aKeepReflowGoing = false;
|
||||
|
@ -3169,12 +3185,12 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
return;
|
||||
}
|
||||
|
||||
// Now put the Y coordinate back to the top of the top-margin +
|
||||
// clearance, and flow the block.
|
||||
// Now put the block-dir coordinate back to the start of the
|
||||
// block-start-margin + clearance, and flow the block.
|
||||
aState.mBCoord -= bStartMargin;
|
||||
availSpace.y -= bStartMargin;
|
||||
if (NS_UNCONSTRAINEDSIZE != availSpace.height) {
|
||||
availSpace.height += bStartMargin;
|
||||
availSpace.BStart(wm) -= bStartMargin;
|
||||
if (NS_UNCONSTRAINEDSIZE != availSpace.BSize(wm)) {
|
||||
availSpace.BSize(wm) += bStartMargin;
|
||||
}
|
||||
|
||||
// Reflow the block into the available space
|
||||
|
@ -3182,7 +3198,7 @@ nsBlockFrame::ReflowBlockFrame(nsBlockReflowState& aState,
|
|||
// will initialize it
|
||||
nsHTMLReflowState
|
||||
blockHtmlRS(aState.mPresContext, aState.mReflowState, frame,
|
||||
LogicalSize(frame->GetWritingMode(), availSpace.Size()));
|
||||
availSpace.Size(wm).ConvertTo(frame->GetWritingMode(), wm));
|
||||
blockHtmlRS.mFlags.mHasClearance = aLine->HasClearance();
|
||||
|
||||
nsFloatManager::SavedState
|
||||
|
@ -3544,9 +3560,11 @@ nsBlockFrame::DoReflowInlineFrames(nsBlockReflowState& aState,
|
|||
this, aFloatAvailableSpace.mHasFloats);
|
||||
#endif
|
||||
|
||||
WritingMode outerWM = aState.mReflowState.GetWritingMode();
|
||||
WritingMode lineWM = GetWritingMode(aLine->mFirstChild);
|
||||
LogicalRect lineRect(lineWM, aFloatAvailableSpace.mRect,
|
||||
aState.mContainerWidth);
|
||||
LogicalRect lineRect =
|
||||
aFloatAvailableSpace.mRect.ConvertTo(lineWM, outerWM,
|
||||
aState.mContainerWidth);
|
||||
|
||||
nscoord iStart = lineRect.IStart(lineWM);
|
||||
nscoord availISize = lineRect.ISize(lineWM);
|
||||
|
@ -3683,11 +3701,12 @@ 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.height,
|
||||
"unconstrained height on totally empty line");
|
||||
NS_ASSERTION(NS_UNCONSTRAINEDSIZE !=
|
||||
aFloatAvailableSpace.mRect.BSize(outerWM),
|
||||
"unconstrained block size on totally empty line");
|
||||
|
||||
// See the analogous code for blocks in nsBlockReflowState::ClearFloats.
|
||||
if (aFloatAvailableSpace.mRect.height > 0) {
|
||||
if (aFloatAvailableSpace.mRect.BSize(outerWM) > 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
|
||||
|
@ -3695,7 +3714,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.height;
|
||||
aState.mBCoord += aFloatAvailableSpace.mRect.BSize(outerWM);
|
||||
aFloatAvailableSpace = aState.GetFloatAvailableSpace();
|
||||
} else {
|
||||
NS_ASSERTION(NS_UNCONSTRAINEDSIZE != aState.mReflowState.AvailableBSize(),
|
||||
|
@ -4114,7 +4133,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
nsLineLayout& aLineLayout,
|
||||
line_iterator aLine,
|
||||
nsFloatManager::SavedState *aFloatStateBeforeLine,
|
||||
nsRect& aFloatAvailableSpace,
|
||||
LogicalRect& aFloatAvailableSpace,
|
||||
nscoord& aAvailableSpaceHeight,
|
||||
bool* aKeepReflowGoing)
|
||||
{
|
||||
|
@ -4130,6 +4149,7 @@ 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() &&
|
||||
|
@ -4140,8 +4160,7 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
nsHTMLReflowMetrics metrics(aState.mReflowState);
|
||||
nsIFrame* bullet = GetOutsideBullet();
|
||||
ReflowBullet(bullet, aState, metrics, aState.mBCoord);
|
||||
NS_ASSERTION(!BulletIsEmpty() ||
|
||||
metrics.BSize(aState.mReflowState.GetWritingMode()) == 0,
|
||||
NS_ASSERTION(!BulletIsEmpty() || metrics.BSize(wm) == 0,
|
||||
"empty bullet took up space");
|
||||
aLineLayout.AddBulletFrame(bullet, metrics);
|
||||
addedBullet = true;
|
||||
|
@ -4153,7 +4172,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).
|
||||
nsRect oldFloatAvailableSpace(aFloatAvailableSpace);
|
||||
LogicalRect oldFloatAvailableSpace(aFloatAvailableSpace);
|
||||
// As we redo for floats, we can't reduce the amount of height we're
|
||||
// checking.
|
||||
aAvailableSpaceHeight = std::max(aAvailableSpaceHeight, aLine->BSize());
|
||||
|
@ -4161,13 +4180,14 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
|
|||
aState.GetFloatAvailableSpaceForBSize(aLine->BStart(),
|
||||
aAvailableSpaceHeight,
|
||||
aFloatStateBeforeLine).mRect;
|
||||
NS_ASSERTION(aFloatAvailableSpace.y == oldFloatAvailableSpace.y, "yikes");
|
||||
NS_ASSERTION(aFloatAvailableSpace.BStart(wm) ==
|
||||
oldFloatAvailableSpace.BStart(wm), "yikes");
|
||||
// Restore the height to the position of the next band.
|
||||
aFloatAvailableSpace.height = oldFloatAvailableSpace.height;
|
||||
aFloatAvailableSpace.BSize(wm) = oldFloatAvailableSpace.BSize(wm);
|
||||
// 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(oldFloatAvailableSpace, aFloatAvailableSpace)) {
|
||||
if (AvailableSpaceShrunk(wm, oldFloatAvailableSpace, aFloatAvailableSpace)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -5717,15 +5737,16 @@ nsBlockFrame::StyleTextForLineLayout()
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
// Float support
|
||||
|
||||
nsRect
|
||||
LogicalRect
|
||||
nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
|
||||
const nsRect& aFloatAvailableSpace,
|
||||
const LogicalRect& aFloatAvailableSpace,
|
||||
nsIFrame* aFloatFrame)
|
||||
{
|
||||
// Compute the available width. By default, assume the width of the
|
||||
// containing block.
|
||||
// Compute the available inline size. By default, assume the inline
|
||||
// size 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() ) {
|
||||
|
@ -5736,7 +5757,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.width;
|
||||
availISize = aFloatAvailableSpace.ISize(wm);
|
||||
}
|
||||
|
||||
nscoord availBSize = NS_UNCONSTRAINEDSIZE == aState.ContentBSize()
|
||||
|
@ -5754,39 +5775,37 @@ nsBlockFrame::AdjustFloatAvailableSpace(nsBlockReflowState& aState,
|
|||
}
|
||||
#endif
|
||||
|
||||
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);
|
||||
return LogicalRect(wm, aState.ContentIStart(), aState.ContentBStart(),
|
||||
availISize, availBSize);
|
||||
}
|
||||
|
||||
nscoord
|
||||
nsBlockFrame::ComputeFloatWidth(nsBlockReflowState& aState,
|
||||
const nsRect& aFloatAvailableSpace,
|
||||
nsBlockFrame::ComputeFloatISize(nsBlockReflowState& aState,
|
||||
const LogicalRect& aFloatAvailableSpace,
|
||||
nsIFrame* aFloat)
|
||||
{
|
||||
NS_PRECONDITION(aFloat->GetStateBits() & NS_FRAME_OUT_OF_FLOW,
|
||||
"aFloat must be an out-of-flow frame");
|
||||
// Reflow the float.
|
||||
nsRect availSpace = AdjustFloatAvailableSpace(aState, aFloatAvailableSpace,
|
||||
aFloat);
|
||||
LogicalRect availSpace = AdjustFloatAvailableSpace(aState,
|
||||
aFloatAvailableSpace,
|
||||
aFloat);
|
||||
|
||||
WritingMode wm = aFloat->GetWritingMode();
|
||||
nsHTMLReflowState floatRS(aState.mPresContext, aState.mReflowState, aFloat,
|
||||
LogicalSize(wm, availSpace.Size()));
|
||||
WritingMode blockWM = aState.mReflowState.GetWritingMode();
|
||||
WritingMode floatWM = aFloat->GetWritingMode();
|
||||
nsHTMLReflowState
|
||||
floatRS(aState.mPresContext, aState.mReflowState, aFloat,
|
||||
availSpace.Size(blockWM).ConvertTo(floatWM, blockWM));
|
||||
|
||||
return floatRS.ComputedWidth() + floatRS.ComputedPhysicalBorderPadding().LeftRight() +
|
||||
floatRS.ComputedPhysicalMargin().LeftRight();
|
||||
return floatRS.ComputedSizeWithMarginBorderPadding(blockWM).ISize(blockWM);
|
||||
}
|
||||
|
||||
void
|
||||
nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
||||
const nsRect& aAdjustedAvailableSpace,
|
||||
const LogicalRect& aAdjustedAvailableSpace,
|
||||
nsIFrame* aFloat,
|
||||
nsMargin& aFloatMargin,
|
||||
nsMargin& aFloatOffsets,
|
||||
LogicalMargin& aFloatMargin,
|
||||
LogicalMargin& aFloatOffsets,
|
||||
bool aFloatPushedDown,
|
||||
nsReflowStatus& aReflowStatus)
|
||||
{
|
||||
|
@ -5795,18 +5814,19 @@ 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.x, aFloatAvailableSpace.y,
|
||||
aFloatAvailableSpace.width, aFloatAvailableSpace.height
|
||||
aFloat, this,
|
||||
aFloatAvailableSpace.IStart(wm), aFloatAvailableSpace.BStart(wm),
|
||||
aFloatAvailableSpace.ISize(wm), aFloatAvailableSpace.BSize(wm)
|
||||
);
|
||||
#endif
|
||||
|
||||
nsHTMLReflowState
|
||||
floatRS(aState.mPresContext, aState.mReflowState, aFloat,
|
||||
LogicalSize(aFloat->GetWritingMode(),
|
||||
aAdjustedAvailableSpace.Size()));
|
||||
aAdjustedAvailableSpace.Size(wm).ConvertTo(aFloat->GetWritingMode(),
|
||||
wm));
|
||||
|
||||
// Normally the mIsTopOfPage state is copied from the parent reflow
|
||||
// state. However, when reflowing a float, if we've placed other
|
||||
|
@ -5818,7 +5838,7 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
|||
// about adjacency with the top, so it seems misleading.
|
||||
if (floatRS.mFlags.mIsTopOfPage &&
|
||||
(aFloatPushedDown ||
|
||||
aAdjustedAvailableSpace.width != aState.ContentISize())) {
|
||||
aAdjustedAvailableSpace.ISize(wm) != aState.ContentISize())) {
|
||||
floatRS.mFlags.mIsTopOfPage = false;
|
||||
}
|
||||
|
||||
|
@ -5856,9 +5876,9 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
|||
ShouldAvoidBreakInside(floatRS)) {
|
||||
aReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
|
||||
} else if (NS_FRAME_IS_NOT_COMPLETE(aReflowStatus) &&
|
||||
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.height)) {
|
||||
// An incomplete reflow status means we should split the float
|
||||
// if the height is constrained (bug 145305).
|
||||
(NS_UNCONSTRAINEDSIZE == aAdjustedAvailableSpace.BSize(wm))) {
|
||||
// An incomplete reflow status means we should split the float
|
||||
// if the height is constrained (bug 145305).
|
||||
aReflowStatus = NS_FRAME_COMPLETE;
|
||||
}
|
||||
|
||||
|
@ -5875,8 +5895,11 @@ nsBlockFrame::ReflowFloat(nsBlockReflowState& aState,
|
|||
}
|
||||
|
||||
// Capture the margin and offsets information for the caller
|
||||
aFloatMargin = floatRS.ComputedPhysicalMargin(); // float margins don't collapse
|
||||
aFloatOffsets = floatRS.ComputedPhysicalOffsets();
|
||||
aFloatMargin =
|
||||
// float margins don't collapse
|
||||
floatRS.ComputedLogicalMargin().ConvertTo(wm, floatRS.GetWritingMode());
|
||||
aFloatOffsets =
|
||||
floatRS.ComputedLogicalOffsets().ConvertTo(wm, floatRS.GetWritingMode());
|
||||
|
||||
const nsHTMLReflowMetrics& metrics = brc.GetMetrics();
|
||||
|
||||
|
@ -5886,8 +5909,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 wm = metrics.GetWritingMode();
|
||||
aFloat->SetSize(wm, metrics.Size(wm));
|
||||
WritingMode metricsWM = metrics.GetWritingMode();
|
||||
aFloat->SetSize(metricsWM, metrics.Size(metricsWM));
|
||||
if (aFloat->HasView()) {
|
||||
nsContainerFrame::SyncFrameViewAfterReflow(aState.mPresContext, aFloat,
|
||||
aFloat->GetView(),
|
||||
|
@ -6829,7 +6852,7 @@ nsBlockFrame::ReflowBullet(nsIFrame* aBulletFrame,
|
|||
// the block.
|
||||
// FIXME: aLineTop isn't actually set correctly by some callers, since
|
||||
// they reposition the line.
|
||||
nsRect floatAvailSpace =
|
||||
LogicalRect floatAvailSpace =
|
||||
aState.GetFloatAvailableSpaceWithState(aLineTop,
|
||||
&aState.mFloatManagerStateBefore)
|
||||
.mRect;
|
||||
|
@ -6849,13 +6872,11 @@ 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 = logicalFAS.IStart(wm) -
|
||||
nscoord iStart = floatAvailSpace.IStart(wm) -
|
||||
rs.ComputedLogicalBorderPadding().IStart(wm) -
|
||||
bulletMargin.IEnd(wm) -
|
||||
aMetrics.ISize(wm);
|
||||
|
@ -6863,11 +6884,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 = logicalFAS.BStart(wm);
|
||||
aBulletFrame->SetRect(wm, LogicalRect(wm, LogicalPoint(wm, iStart, bStart),
|
||||
LogicalSize(wm, aMetrics.ISize(wm),
|
||||
aMetrics.BSize(wm))),
|
||||
containerWidth);
|
||||
nscoord bStart = floatAvailSpace.BStart(wm);
|
||||
aBulletFrame->SetRect(wm, LogicalRect(wm, iStart, bStart,
|
||||
aMetrics.ISize(wm),
|
||||
aMetrics.BSize(wm)),
|
||||
aState.mContainerWidth);
|
||||
aBulletFrame->DidReflow(aState.mPresContext, &aState.mReflowState,
|
||||
nsDidReflowStatus::FINISHED);
|
||||
}
|
||||
|
@ -7020,20 +7041,22 @@ nsBlockFrame::BlockCanIntersectFloats(nsIFrame* aFrame)
|
|||
// in the available space given, which means that variation shouldn't
|
||||
// matter.
|
||||
/* static */
|
||||
nsBlockFrame::ReplacedElementWidthToClear
|
||||
nsBlockFrame::WidthToClearPastFloats(nsBlockReflowState& aState,
|
||||
const nsRect& aFloatAvailableSpace,
|
||||
nsBlockFrame::ReplacedElementISizeToClear
|
||||
nsBlockFrame::ISizeToClearPastFloats(nsBlockReflowState& aState,
|
||||
const LogicalRect& aFloatAvailableSpace,
|
||||
nsIFrame* aFrame)
|
||||
{
|
||||
nscoord leftOffset, rightOffset;
|
||||
nscoord inlineStartOffset, inlineEndOffset;
|
||||
WritingMode wm = aState.mReflowState.GetWritingMode();
|
||||
nsCSSOffsetState offsetState(aFrame, aState.mReflowState.rendContext,
|
||||
aState.mContentArea.Width(wm));
|
||||
|
||||
ReplacedElementWidthToClear result;
|
||||
ReplacedElementISizeToClear result;
|
||||
aState.ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace,
|
||||
leftOffset, rightOffset);
|
||||
nscoord availWidth = aState.mContentArea.Width(wm) - leftOffset - rightOffset;
|
||||
inlineStartOffset,
|
||||
inlineEndOffset);
|
||||
nscoord availISize = aState.mContentArea.ISize(wm) -
|
||||
inlineStartOffset - inlineEndOffset;
|
||||
|
||||
// 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
|
||||
|
@ -7041,16 +7064,19 @@ nsBlockFrame::WidthToClearPastFloats(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.
|
||||
LogicalSize availSpace(aFrame->GetWritingMode(),
|
||||
nsSize(availWidth, NS_UNCONSTRAINEDSIZE));
|
||||
WritingMode frWM = aFrame->GetWritingMode();
|
||||
LogicalSize availSpace = LogicalSize(wm, availISize, NS_UNCONSTRAINEDSIZE).
|
||||
ConvertTo(frWM, wm);
|
||||
nsHTMLReflowState reflowState(aState.mPresContext, aState.mReflowState,
|
||||
aFrame, availSpace);
|
||||
result.borderBoxWidth = reflowState.ComputedWidth() +
|
||||
reflowState.ComputedPhysicalBorderPadding().LeftRight();
|
||||
result.borderBoxISize =
|
||||
reflowState.ComputedSizeWithBorderPadding().ConvertTo(wm, frWM).ISize(wm);
|
||||
// Use the margins from offsetState rather than reflowState so that
|
||||
// they aren't reduced by ignoring margins in overconstrained cases.
|
||||
result.marginLeft = offsetState.ComputedPhysicalMargin().left;
|
||||
result.marginRight = offsetState.ComputedPhysicalMargin().right;
|
||||
LogicalMargin computedMargin =
|
||||
offsetState.ComputedLogicalMargin().ConvertTo(wm, frWM);
|
||||
result.marginIStart = computedMargin.IStart(wm);
|
||||
result.marginIEnd = computedMargin.IEnd(wm);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -314,19 +314,19 @@ public:
|
|||
static bool BlockCanIntersectFloats(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* 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)
|
||||
*/
|
||||
struct ReplacedElementWidthToClear {
|
||||
nscoord marginLeft, borderBoxWidth, marginRight;
|
||||
nscoord MarginBoxWidth() const
|
||||
{ return marginLeft + borderBoxWidth + marginRight; }
|
||||
struct ReplacedElementISizeToClear {
|
||||
nscoord marginIStart, borderBoxISize, marginIEnd;
|
||||
nscoord MarginBoxISize() const
|
||||
{ return marginIStart + borderBoxISize + marginIEnd; }
|
||||
};
|
||||
static ReplacedElementWidthToClear
|
||||
WidthToClearPastFloats(nsBlockReflowState& aState,
|
||||
const nsRect& aFloatAvailableSpace,
|
||||
static ReplacedElementISizeToClear
|
||||
ISizeToClearPastFloats(nsBlockReflowState& aState,
|
||||
const mozilla::LogicalRect& aFloatAvailableSpace,
|
||||
nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
|
@ -605,13 +605,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,
|
||||
nsRect& aFloatAvailableSpace, /* in-out */
|
||||
nscoord& aAvailableSpaceHeight, /* in-out */
|
||||
bool* aKeepReflowGoing);
|
||||
mozilla::LogicalRect& aFloatAvailableSpace, //in-out
|
||||
nscoord& aAvailableSpaceHeight, // in-out
|
||||
bool* aKeepReflowGoing);
|
||||
|
||||
/**
|
||||
* If NS_BLOCK_LOOK_FOR_DIRTY_FRAMES is set, call MarkLineDirty
|
||||
|
@ -669,28 +669,29 @@ protected:
|
|||
nsIFrame* aFrame,
|
||||
LineReflowStatus* aLineReflowStatus);
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
// 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 nsRect& aAdjustedAvailableSpace,
|
||||
nsIFrame* aFloat,
|
||||
nsMargin& aFloatMargin,
|
||||
nsMargin& aFloatOffsets,
|
||||
void ReflowFloat(nsBlockReflowState& aState,
|
||||
const mozilla::LogicalRect& aAdjustedAvailableSpace,
|
||||
nsIFrame* aFloat,
|
||||
mozilla::LogicalMargin& aFloatMargin,
|
||||
mozilla::LogicalMargin& 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
|
||||
|
@ -756,7 +757,7 @@ protected:
|
|||
|
||||
void PropagateFloatDamage(nsBlockReflowState& aState,
|
||||
nsLineBox* aLine,
|
||||
nscoord aDeltaY);
|
||||
nscoord aDeltaBCoord);
|
||||
|
||||
void CheckFloats(nsBlockReflowState& aState);
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ nsBlockReflowContext::ComputeCollapsedBStartMargin(const nsHTMLReflowState& aRS,
|
|||
}
|
||||
|
||||
void
|
||||
nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
||||
nsBlockReflowContext::ReflowBlock(const LogicalRect& aSpace,
|
||||
bool aApplyBStartMargin,
|
||||
nsCollapsingMargin& aPrevMargin,
|
||||
nscoord aClearance,
|
||||
|
@ -227,7 +227,7 @@ nsBlockReflowContext::ReflowBlock(const nsRect& aSpace,
|
|||
mFrame = aFrameRS.frame;
|
||||
mWritingMode = aState.mReflowState.GetWritingMode();
|
||||
mContainerWidth = aState.mContainerWidth;
|
||||
mSpace = LogicalRect(mWritingMode, aSpace, mContainerWidth);
|
||||
mSpace = aSpace;
|
||||
|
||||
if (!aIsAdjacentWithBStart) {
|
||||
aFrameRS.mFlags.mIsTopOfPage = false; // make sure this is cleared
|
||||
|
|
|
@ -28,15 +28,15 @@ public:
|
|||
const nsHTMLReflowState& aParentRS);
|
||||
~nsBlockReflowContext() { }
|
||||
|
||||
void ReflowBlock(const nsRect& aSpace,
|
||||
bool aApplyBStartMargin,
|
||||
nsCollapsingMargin& aPrevMargin,
|
||||
nscoord aClearance,
|
||||
bool aIsAdjacentWithBStart,
|
||||
nsLineBox* aLine,
|
||||
nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aReflowStatus,
|
||||
nsBlockReflowState& aState);
|
||||
void ReflowBlock(const mozilla::LogicalRect& aSpace,
|
||||
bool aApplyBStartMargin,
|
||||
nsCollapsingMargin& aPrevMargin,
|
||||
nscoord aClearance,
|
||||
bool aIsAdjacentWithBStart,
|
||||
nsLineBox* aLine,
|
||||
nsHTMLReflowState& aReflowState,
|
||||
nsReflowStatus& aReflowStatus,
|
||||
nsBlockReflowState& aState);
|
||||
|
||||
bool PlaceBlock(const nsHTMLReflowState& aReflowState,
|
||||
bool aForceFit,
|
||||
|
|
|
@ -129,44 +129,48 @@ nsBlockReflowState::GetConsumedBSize()
|
|||
}
|
||||
|
||||
void
|
||||
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
|
||||
const nsRect& aFloatAvailableSpace,
|
||||
nscoord& aLeftResult,
|
||||
nscoord& aRightResult)
|
||||
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(
|
||||
nsIFrame* aFrame,
|
||||
const LogicalRect& aFloatAvailableSpace,
|
||||
nscoord& aIStartResult,
|
||||
nscoord& aIEndResult)
|
||||
{
|
||||
nsRect contentArea =
|
||||
mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
|
||||
WritingMode wm = mReflowState.GetWritingMode();
|
||||
// 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.x >= contentArea.x, "bad avail space rect x");
|
||||
NS_ASSERTION(aFloatAvailableSpace.width == 0 ||
|
||||
aFloatAvailableSpace.XMost() <= contentArea.XMost(),
|
||||
"bad avail space rect width");
|
||||
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");
|
||||
|
||||
nscoord leftOffset, rightOffset;
|
||||
if (aFloatAvailableSpace.width == contentArea.width) {
|
||||
nscoord iStartOffset, iEndOffset;
|
||||
if (aFloatAvailableSpace.ISize(wm) == mContentArea.ISize(wm)) {
|
||||
// We don't need to compute margins when there are no floats around.
|
||||
leftOffset = 0;
|
||||
rightOffset = 0;
|
||||
iStartOffset = 0;
|
||||
iEndOffset = 0;
|
||||
} else {
|
||||
nsMargin frameMargin;
|
||||
nsCSSOffsetState os(aFrame, mReflowState.rendContext, contentArea.width);
|
||||
frameMargin = os.ComputedPhysicalMargin();
|
||||
LogicalMargin frameMargin(wm);
|
||||
nsCSSOffsetState os(aFrame, mReflowState.rendContext,
|
||||
mContentArea.ISize(wm));
|
||||
frameMargin =
|
||||
os.ComputedLogicalMargin().ConvertTo(wm, aFrame->GetWritingMode());
|
||||
|
||||
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
|
||||
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
|
||||
}
|
||||
aLeftResult = leftOffset;
|
||||
aRightResult = rightOffset;
|
||||
aIStartResult = iStartOffset;
|
||||
aIEndResult = iEndOffset;
|
||||
}
|
||||
|
||||
static nscoord
|
||||
|
@ -193,19 +197,15 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
|
|||
const nsStyleDisplay* aDisplay,
|
||||
const nsFlowAreaRect& aFloatAvailableSpace,
|
||||
bool aBlockAvoidsFloats,
|
||||
nsRect& aResult)
|
||||
LogicalRect& aResult)
|
||||
{
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("CBAS frame=%p has floats %d\n",
|
||||
aFrame, aFloatAvailableSpace.mHasFloats);
|
||||
#endif
|
||||
WritingMode wm = mReflowState.GetWritingMode();
|
||||
LogicalRect result(wm);
|
||||
LogicalRect floatAvailSpace = LogicalRect(wm,
|
||||
aFloatAvailableSpace.mRect,
|
||||
mContainerWidth); //??mReflowState.AvailableWidth());
|
||||
result.BStart(wm) = mBCoord;
|
||||
result.BSize(wm) = GetFlag(BRS_UNCONSTRAINEDBSIZE)
|
||||
aResult.BStart(wm) = mBCoord;
|
||||
aResult.BSize(wm) = GetFlag(BRS_UNCONSTRAINEDBSIZE)
|
||||
? NS_UNCONSTRAINEDSIZE
|
||||
: mReflowState.AvailableBSize() - mBCoord
|
||||
- GetBEndMarginClone(aFrame, mReflowState.rendContext, mContentArea, wm);
|
||||
|
@ -222,7 +222,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::WidthToClearPastFloats would need to use the
|
||||
// nsBlockFrame::ISizeToClearPastFloats 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 +238,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.
|
||||
result.IStart(wm) = ContentIStart();
|
||||
result.ISize(wm) = ContentISize();
|
||||
aResult.IStart(wm) = mContentArea.IStart(wm);
|
||||
aResult.ISize(wm) = mContentArea.ISize(wm);
|
||||
break;
|
||||
case NS_STYLE_FLOAT_EDGE_MARGIN:
|
||||
{
|
||||
// The child block's margins should be placed adjacent to,
|
||||
// but not overlap the float.
|
||||
result.IStart(wm) = floatAvailSpace.IStart(wm);
|
||||
result.ISize(wm) = floatAvailSpace.ISize(wm);
|
||||
aResult.IStart(wm) = aFloatAvailableSpace.mRect.IStart(wm);
|
||||
aResult.ISize(wm) = aFloatAvailableSpace.mRect.ISize(wm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -255,24 +255,21 @@ 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.
|
||||
result.IStart(wm) = ContentIStart();
|
||||
result.ISize(wm) = ContentISize();
|
||||
aResult.IStart(wm) = mContentArea.IStart(wm);
|
||||
aResult.ISize(wm) = mContentArea.ISize(wm);
|
||||
}
|
||||
aResult = result.GetPhysicalRect(wm, mContainerWidth);
|
||||
}
|
||||
else {
|
||||
aResult = result.GetPhysicalRect(wm, mContainerWidth);
|
||||
nsRect contentArea =
|
||||
mContentArea.GetPhysicalRect(wm, mContainerWidth);
|
||||
nscoord leftOffset, rightOffset;
|
||||
nscoord iStartOffset, iEndOffset;
|
||||
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
|
||||
leftOffset, rightOffset);
|
||||
aResult.x = contentArea.x + leftOffset;
|
||||
aResult.width = contentArea.width - leftOffset - rightOffset;
|
||||
iStartOffset, iEndOffset);
|
||||
aResult.IStart(wm) = mContentArea.IStart(wm) + iStartOffset;
|
||||
aResult.ISize(wm) = mContentArea.ISize(wm) - iStartOffset - iEndOffset;
|
||||
}
|
||||
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.x, aResult.y, aResult.width, aResult.height);
|
||||
printf(" CBAS: result %d %d %d %d\n", aResult.IStart(wm), aResult.BStart(wm),
|
||||
aResult.ISize(wm), aResult.BSize(wm));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -302,16 +299,17 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
|
|||
mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::BAND_FROM_POINT,
|
||||
blockSize, mContentArea, aState,
|
||||
mContainerWidth);
|
||||
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.width < 0)
|
||||
result.mRect.width = 0;
|
||||
// Keep the inline size >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.ISize(wm) < 0) {
|
||||
result.mRect.ISize(wm) = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("GetAvailableSpace: band=%d,%d,%d,%d hasfloats=%d\n",
|
||||
result.mRect.x, result.mRect.y, result.mRect.width,
|
||||
result.mRect.height, result.mHasFloats);
|
||||
result.mRect.IStart(wm), result.mRect.BStart(wm),
|
||||
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
|
@ -339,15 +337,16 @@ nsBlockReflowState::GetFloatAvailableSpaceForBSize(
|
|||
mFloatManager->GetFlowArea(wm, aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
|
||||
aBSize, mContentArea, aState, mContainerWidth);
|
||||
// Keep the width >= 0 for compatibility with nsSpaceManager.
|
||||
if (result.mRect.width < 0)
|
||||
result.mRect.width = 0;
|
||||
if (result.mRect.ISize(wm) < 0) {
|
||||
result.mRect.ISize(wm) = 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (nsBlockFrame::gNoisyReflow) {
|
||||
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
|
||||
printf("GetAvailableSpaceForHeight: space=%d,%d,%d,%d hasfloats=%d\n",
|
||||
result.mRect.x, result.mRect.y, result.mRect.width,
|
||||
result.mRect.height, result.mHasFloats);
|
||||
result.mRect.IStart(wm), result.mRect.BStart(wm),
|
||||
result.mRect.ISize(wm), result.mRect.BSize(wm), result.mHasFloats);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
|
@ -517,7 +516,7 @@ nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
|
|||
bool
|
||||
nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
|
||||
nsIFrame* aFloat,
|
||||
nscoord aAvailableWidth)
|
||||
nscoord aAvailableISize)
|
||||
{
|
||||
NS_PRECONDITION(aLineLayout, "must have line layout");
|
||||
NS_PRECONDITION(mBlock->end_lines() != mCurrentLine, "null ptr");
|
||||
|
@ -568,19 +567,21 @@ 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.
|
||||
nsRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
|
||||
LogicalRect floatAvailableSpace = GetFloatAvailableSpace().mRect;
|
||||
if (mBelowCurrentLineFloats.IsEmpty() &&
|
||||
(aLineLayout->LineIsEmpty() ||
|
||||
mBlock->ComputeFloatWidth(*this, floatAvailableSpace, aFloat)
|
||||
<= aAvailableWidth)) {
|
||||
mBlock->ComputeFloatISize(*this, floatAvailableSpace, aFloat)
|
||||
<= aAvailableISize)) {
|
||||
// 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);
|
||||
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x, mBCoord),
|
||||
floatAvailSpace.mRect.Size());
|
||||
aLineLayout->UpdateBand(availSpace, aFloat);
|
||||
LogicalRect availSpace(wm, floatAvailSpace.mRect.IStart(wm), mBCoord,
|
||||
floatAvailSpace.mRect.ISize(wm),
|
||||
floatAvailSpace.mRect.BSize(wm));
|
||||
aLineLayout->UpdateBand(wm, availSpace, aFloat);
|
||||
// Record this float in the current-line list
|
||||
mCurrentLineFloats.Append(mFloatCacheFreeList.Alloc(aFloat));
|
||||
} else {
|
||||
|
@ -603,37 +604,43 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
|
|||
}
|
||||
|
||||
bool
|
||||
nsBlockReflowState::CanPlaceFloat(nscoord aFloatWidth,
|
||||
nsBlockReflowState::CanPlaceFloat(nscoord aFloatISize,
|
||||
const nsFlowAreaRect& aFloatAvailableSpace)
|
||||
{
|
||||
// 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.
|
||||
// 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.
|
||||
// FIXME: We should allow overflow by up to half a pixel here (bug 21193).
|
||||
return !aFloatAvailableSpace.mHasFloats ||
|
||||
aFloatAvailableSpace.mRect.width >= aFloatWidth;
|
||||
aFloatAvailableSpace.mRect.ISize(mReflowState.GetWritingMode()) >=
|
||||
aFloatISize;
|
||||
}
|
||||
|
||||
static nscoord
|
||||
FloatMarginWidth(const nsHTMLReflowState& aCBReflowState,
|
||||
nscoord aFloatAvailableWidth,
|
||||
FloatMarginISize(const nsHTMLReflowState& aCBReflowState,
|
||||
nscoord aFloatAvailableISize,
|
||||
nsIFrame *aFloat,
|
||||
const nsCSSOffsetState& aFloatOffsetState)
|
||||
{
|
||||
AutoMaybeDisableFontInflation an(aFloat);
|
||||
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();
|
||||
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);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -674,8 +681,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
}
|
||||
// Get the band of available space
|
||||
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
|
||||
nsRect adjustedAvailableSpace = mBlock->AdjustFloatAvailableSpace(*this,
|
||||
floatAvailableSpace.mRect, aFloat);
|
||||
LogicalRect adjustedAvailableSpace =
|
||||
mBlock->AdjustFloatAvailableSpace(*this, floatAvailableSpace.mRect, aFloat);
|
||||
|
||||
NS_ASSERTION(aFloat->GetParent() == mBlock,
|
||||
"Float frame has wrong parent");
|
||||
|
@ -683,12 +690,12 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
nsCSSOffsetState offsets(aFloat, mReflowState.rendContext,
|
||||
mReflowState.ComputedWidth());
|
||||
|
||||
nscoord floatMarginWidth = FloatMarginWidth(mReflowState,
|
||||
adjustedAvailableSpace.width,
|
||||
nscoord floatMarginISize = FloatMarginISize(mReflowState,
|
||||
adjustedAvailableSpace.ISize(wm),
|
||||
aFloat, offsets);
|
||||
|
||||
nsMargin floatMargin; // computed margin
|
||||
nsMargin floatOffsets;
|
||||
LogicalMargin floatMargin(wm); // computed margin
|
||||
LogicalMargin floatOffsets(wm);
|
||||
nsReflowStatus reflowStatus;
|
||||
|
||||
// If it's a floating first-letter, we need to reflow it before we
|
||||
|
@ -698,7 +705,7 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
if (isLetter) {
|
||||
mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin,
|
||||
floatOffsets, false, reflowStatus);
|
||||
floatMarginWidth = aFloat->GetSize().width + floatMargin.LeftRight();
|
||||
floatMarginISize = aFloat->ISize(wm) + floatMargin.IStartEnd(wm);
|
||||
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");
|
||||
|
@ -722,14 +729,14 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
|
||||
for (;;) {
|
||||
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE &&
|
||||
floatAvailableSpace.mRect.height <= 0 &&
|
||||
floatAvailableSpace.mRect.BSize(wm) <= 0 &&
|
||||
!mustPlaceFloat) {
|
||||
// No space, nowhere to put anything.
|
||||
PushFloatPastBreak(aFloat);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CanPlaceFloat(floatMarginWidth, floatAvailableSpace)) {
|
||||
if (CanPlaceFloat(floatMarginISize, floatAvailableSpace)) {
|
||||
// We found an appropriate place.
|
||||
break;
|
||||
}
|
||||
|
@ -738,9 +745,9 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
if (NS_STYLE_DISPLAY_TABLE != floatDisplay->mDisplay ||
|
||||
eCompatibility_NavQuirks != mPresContext->CompatibilityMode() ) {
|
||||
|
||||
mBCoord += floatAvailableSpace.mRect.height;
|
||||
if (adjustedAvailableSpace.height != NS_UNCONSTRAINEDSIZE) {
|
||||
adjustedAvailableSpace.height -= floatAvailableSpace.mRect.height;
|
||||
mBCoord += floatAvailableSpace.mRect.BSize(wm);
|
||||
if (adjustedAvailableSpace.BSize(wm) != NS_UNCONSTRAINEDSIZE) {
|
||||
adjustedAvailableSpace.BSize(wm) -= floatAvailableSpace.mRect.BSize(wm);
|
||||
}
|
||||
floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
|
||||
} else {
|
||||
|
@ -780,14 +787,14 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
}
|
||||
|
||||
// the table does not fit anymore in this line so advance to next band
|
||||
mBCoord += floatAvailableSpace.mRect.height;
|
||||
mBCoord += floatAvailableSpace.mRect.BSize(wm);
|
||||
// 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);
|
||||
floatMarginWidth = FloatMarginWidth(mReflowState,
|
||||
adjustedAvailableSpace.width,
|
||||
floatMarginISize = FloatMarginISize(mReflowState,
|
||||
adjustedAvailableSpace.ISize(wm),
|
||||
aFloat, offsets);
|
||||
}
|
||||
|
||||
|
@ -799,20 +806,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 an x and y coordinate to the float.
|
||||
nscoord floatX, floatY;
|
||||
if (NS_STYLE_FLOAT_LEFT == floatDisplay->mFloats) {
|
||||
floatX = floatAvailableSpace.mRect.x;
|
||||
// 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);
|
||||
}
|
||||
else {
|
||||
if (!keepFloatOnSameLine) {
|
||||
floatX = floatAvailableSpace.mRect.XMost() - floatMarginWidth;
|
||||
}
|
||||
floatPos.I(wm) = floatAvailableSpace.mRect.IEnd(wm) - floatMarginISize;
|
||||
}
|
||||
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
|
||||
floatX = floatAvailableSpace.mRect.x;
|
||||
// previous float
|
||||
floatPos.I(wm) = floatAvailableSpace.mRect.IStart(wm);
|
||||
}
|
||||
}
|
||||
// CSS2 spec, 9.5.1 rule [4]: "A floating box's outer top may not
|
||||
|
@ -820,7 +827,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.)
|
||||
floatY = std::max(mBCoord, ContentBStart());
|
||||
floatPos.B(wm) = std::max(mBCoord, ContentBStart());
|
||||
|
||||
// Reflow the float after computing its vertical position so it knows
|
||||
// where to break.
|
||||
|
@ -830,9 +837,9 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
floatOffsets, pushedDown, reflowStatus);
|
||||
}
|
||||
if (aFloat->GetPrevInFlow())
|
||||
floatMargin.top = 0;
|
||||
floatMargin.BStart(wm) = 0;
|
||||
if (NS_FRAME_IS_NOT_COMPLETE(reflowStatus))
|
||||
floatMargin.bottom = 0;
|
||||
floatMargin.BEnd(wm) = 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.
|
||||
|
@ -842,10 +849,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.height == NS_UNCONSTRAINEDSIZE &&
|
||||
adjustedAvailableSpace.BSize(wm) == NS_UNCONSTRAINEDSIZE &&
|
||||
!mustPlaceFloat &&
|
||||
aFloat->GetSize().height + floatMargin.TopBottom() >
|
||||
ContentBEnd() - floatY) ||
|
||||
aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
|
||||
ContentBEnd() - floatPos.B(wm)) ||
|
||||
NS_FRAME_IS_TRUNCATED(reflowStatus) ||
|
||||
NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
|
||||
PushFloatPastBreak(aFloat);
|
||||
|
@ -854,13 +861,14 @@ 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 floatY > 0.
|
||||
// top when floatPos.B(wm) > 0.
|
||||
if (ContentBSize() != NS_UNCONSTRAINEDSIZE &&
|
||||
!mustPlaceFloat && (!mReflowState.mFlags.mIsTopOfPage || floatY > 0) &&
|
||||
!mustPlaceFloat &&
|
||||
(!mReflowState.mFlags.mIsTopOfPage || floatPos.B(wm) > 0) &&
|
||||
NS_STYLE_PAGE_BREAK_AVOID == aFloat->StyleDisplay()->mBreakInside &&
|
||||
(!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) ||
|
||||
aFloat->GetSize().height + floatMargin.TopBottom() >
|
||||
ContentBEnd() - floatY) &&
|
||||
aFloat->BSize(wm) + floatMargin.BStartEnd(wm) >
|
||||
ContentBEnd() - floatPos.B(wm)) &&
|
||||
!aFloat->GetPrevInFlow()) {
|
||||
PushFloatPastBreak(aFloat);
|
||||
return false;
|
||||
|
@ -869,11 +877,21 @@ 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
|
||||
nsPoint origin(floatMargin.left + floatX,
|
||||
floatMargin.top + floatY);
|
||||
|
||||
//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);
|
||||
|
||||
// If float is relatively positioned, factor that in as well
|
||||
nsHTMLReflowState::ApplyRelativePositioning(aFloat, floatOffsets, &origin);
|
||||
nsHTMLReflowState::ApplyRelativePositioning(aFloat,
|
||||
floatOffsets.GetPhysicalMargin(wm),
|
||||
&origin);
|
||||
|
||||
// Position the float and make sure and views are properly
|
||||
// positioned. We need to explicitly position its child views as
|
||||
|
@ -892,13 +910,13 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
|
|||
// Place the float in the float manager
|
||||
// calculate region
|
||||
LogicalRect region =
|
||||
nsFloatManager::CalculateRegionFor(wm, aFloat,
|
||||
LogicalMargin(wm, floatMargin),
|
||||
nsFloatManager::CalculateRegionFor(wm, aFloat, floatMargin,
|
||||
mContainerWidth);
|
||||
// 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() - floatY);
|
||||
region.BSize(wm) = std::max(region.BSize(wm),
|
||||
ContentBSize() - floatPos.B(wm));
|
||||
}
|
||||
DebugOnly<nsresult> rv = mFloatManager->AddFloat(aFloat, region, wm,
|
||||
mContainerWidth);
|
||||
|
@ -1040,27 +1058,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 WidthToClearPastFloats, which is
|
||||
// We check this before calling ISizeToClearPastFloats, which is
|
||||
// somewhat expensive.
|
||||
break;
|
||||
}
|
||||
nsBlockFrame::ReplacedElementWidthToClear replacedWidth =
|
||||
nsBlockFrame::WidthToClearPastFloats(*this, floatAvailableSpace.mRect,
|
||||
nsBlockFrame::ReplacedElementISizeToClear replacedISize =
|
||||
nsBlockFrame::ISizeToClearPastFloats(*this, floatAvailableSpace.mRect,
|
||||
aReplacedBlock);
|
||||
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)) {
|
||||
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)) {
|
||||
break;
|
||||
}
|
||||
// See the analogous code for inlines in nsBlockFrame::DoReflowInlineFrames
|
||||
if (floatAvailableSpace.mRect.height > 0) {
|
||||
if (floatAvailableSpace.mRect.BSize(wm) > 0) {
|
||||
// See if there's room in the next band.
|
||||
newBCoord += floatAvailableSpace.mRect.height;
|
||||
newBCoord += floatAvailableSpace.mRect.BSize(wm);
|
||||
} 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 nsRect& aFloatAvailableSpace,
|
||||
nscoord& aLeftResult,
|
||||
nscoord& aRightResult);
|
||||
const mozilla::LogicalRect& aFloatAvailableSpace,
|
||||
nscoord& aIStartResult,
|
||||
nscoord& aIEndResult);
|
||||
|
||||
// Caller must have called GetAvailableSpace for the current mBCoord
|
||||
void ComputeBlockAvailSpace(nsIFrame* aFrame,
|
||||
const nsStyleDisplay* aDisplay,
|
||||
const nsFlowAreaRect& aFloatAvailableSpace,
|
||||
bool aBlockAvoidsFloats,
|
||||
nsRect& aResult);
|
||||
mozilla::LogicalRect& aResult);
|
||||
|
||||
protected:
|
||||
void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaBCoord);
|
||||
|
|
|
@ -144,11 +144,8 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
|
|||
if (floatCount == 0 ||
|
||||
(mFloats[floatCount-1].mLeftBEnd <= blockStart &&
|
||||
mFloats[floatCount-1].mRightBEnd <= blockStart)) {
|
||||
//XXX temporary!
|
||||
LogicalRect rect(aWM, aContentArea.IStart(aWM), aBOffset,
|
||||
aContentArea.ISize(aWM), aBSize);
|
||||
nsRect phys = rect.GetPhysicalRect(aWM, aContainerWidth);
|
||||
return nsFlowAreaRect(phys.x, phys.y, phys.width, phys.height, false);
|
||||
return nsFlowAreaRect(aWM, aContentArea.IStart(aWM), aBOffset,
|
||||
aContentArea.ISize(aWM), aBSize, false);
|
||||
}
|
||||
|
||||
nscoord blockEnd;
|
||||
|
@ -238,14 +235,11 @@ nsFloatManager::GetFlowArea(WritingMode aWM, nscoord aBOffset,
|
|||
}
|
||||
}
|
||||
|
||||
nscoord height = (blockEnd == nscoord_MAX) ?
|
||||
nscoord_MAX : (blockEnd - blockStart);
|
||||
//XXX temporary!
|
||||
LogicalRect rect(aWM,
|
||||
inlineStart - origin.I(aWM), blockStart - origin.B(aWM),
|
||||
inlineEnd - inlineStart, height);
|
||||
nsRect phys = rect.GetPhysicalRect(aWM, aContainerWidth);
|
||||
return nsFlowAreaRect(phys.x, phys.y, phys.width, phys.height, haveFloats);
|
||||
nscoord blockSize = (blockEnd == nscoord_MAX) ?
|
||||
nscoord_MAX : (blockEnd - blockStart);
|
||||
return nsFlowAreaRect(aWM,
|
||||
inlineStart - origin.I(aWM), blockStart - origin.B(aWM),
|
||||
inlineEnd - inlineStart, blockSize, haveFloats);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -30,13 +30,15 @@ class nsPresContext;
|
|||
* the content rectangle.
|
||||
*/
|
||||
struct nsFlowAreaRect {
|
||||
nsRect mRect;
|
||||
mozilla::LogicalRect mRect;
|
||||
bool mHasFloats;
|
||||
|
||||
nsFlowAreaRect(nscoord aICoord, nscoord aBCoord,
|
||||
nsFlowAreaRect(mozilla::WritingMode aWritingMode,
|
||||
nscoord aICoord, nscoord aBCoord,
|
||||
nscoord aISize, nscoord aBSize,
|
||||
bool aHasFloats)
|
||||
: mRect(aICoord, aBCoord, aISize, aBSize), mHasFloats(aHasFloats) {}
|
||||
: mRect(aWritingMode, aICoord, aBCoord, aISize, aBSize)
|
||||
, mHasFloats(aHasFloats) {}
|
||||
};
|
||||
|
||||
#define NS_FLOAT_MANAGER_CACHE_SIZE 4
|
||||
|
|
|
@ -446,6 +446,12 @@ 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();
|
||||
}
|
||||
|
|
|
@ -270,13 +270,17 @@ nsLineLayout::EndLineReflow()
|
|||
// per-span mIStart?
|
||||
|
||||
void
|
||||
nsLineLayout::UpdateBand(const nsRect& aNewAvailSpace,
|
||||
nsLineLayout::UpdateBand(WritingMode aWM,
|
||||
const LogicalRect& aNewAvailSpace,
|
||||
nsIFrame* aFloatFrame)
|
||||
{
|
||||
WritingMode lineWM = mRootSpan->mWritingMode;
|
||||
LogicalRect availSpace(lineWM, aNewAvailSpace, mContainerWidth);
|
||||
// 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);
|
||||
#ifdef REALLY_NOISY_REFLOW
|
||||
printf("nsLL::UpdateBand %d, %d, %d, %d, (logical %d, %d, %d, %d); frame=%p\n will set mImpacted to true\n",
|
||||
printf("nsLL::UpdateBand %d, %d, %d, %d, (converted to %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),
|
||||
|
@ -300,21 +304,22 @@ nsLineLayout::UpdateBand(const nsRect& aNewAvailSpace,
|
|||
|
||||
// Compute the difference between last times width and the new width
|
||||
NS_WARN_IF_FALSE(mRootSpan->mIEnd != NS_UNCONSTRAINEDSIZE &&
|
||||
aNewAvailSpace.width != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained width; this should only result from "
|
||||
"very large sizes, not attempts at intrinsic width "
|
||||
availSpace.ISize(lineWM) != NS_UNCONSTRAINEDSIZE,
|
||||
"have unconstrained inline size; 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 width of all spans changes by this much (the root span's
|
||||
// mIEnd moves to aICoord + aISize, its new width is aISize)
|
||||
// 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)
|
||||
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",
|
||||
aNewAvailSpace.IStart(lineWM), aNewAvailSpace.BStart(lineWM),
|
||||
aNewAvailSpace.ISize(lineWM), aNewAvailSpace.BSize(lineWM), deltaISize, deltaICoord);
|
||||
availSpace.IStart(lineWM), availSpace.BStart(lineWM),
|
||||
availSpace.ISize(lineWM), availSpace.BSize(lineWM),
|
||||
deltaISize, deltaICoord);
|
||||
#endif
|
||||
|
||||
// Update the root span position
|
||||
|
|
|
@ -62,7 +62,8 @@ public:
|
|||
* space rectangle, relative to the containing block.
|
||||
* @param aFloatFrame the float frame that was placed.
|
||||
*/
|
||||
void UpdateBand(const nsRect& aNewAvailableSpace,
|
||||
void UpdateBand(mozilla::WritingMode aWM,
|
||||
const mozilla::LogicalRect& aNewAvailableSpace,
|
||||
nsIFrame* aFloatFrame);
|
||||
|
||||
void BeginSpan(nsIFrame* aFrame, const nsHTMLReflowState* aSpanReflowState,
|
||||
|
@ -150,9 +151,9 @@ 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 aAvailableWidth)
|
||||
bool AddFloat(nsIFrame* aFloat, nscoord aAvailableISize)
|
||||
{
|
||||
return mBlockRS->AddFloat(this, aFloat, aAvailableWidth);
|
||||
return mBlockRS->AddFloat(this, aFloat, aAvailableISize);
|
||||
}
|
||||
|
||||
void SetTrimmableISize(nscoord aTrimmableISize) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче