Bug 789096 patch 8: use logical coordinates in nsBlockReflowState. r=jfkthame

This commit is contained in:
Simon Montagu 2014-06-20 02:55:35 -07:00
parent 50badd6444
commit 82f2df73ba
13 changed files with 638 additions and 560 deletions

File diff suppressed because it is too large Load Diff

View File

@ -232,36 +232,34 @@ public:
virtual nscoord GetPrefWidth(nsRenderingContext *aRenderingContext) MOZ_OVERRIDE;
virtual nsRect ComputeTightBounds(gfxContext* aContext) const MOZ_OVERRIDE;
virtual nsresult GetPrefWidthTightBounds(nsRenderingContext* aContext,
nscoord* aX,
nscoord* aXMost) MOZ_OVERRIDE;
/**
* Compute the final height of this frame.
* Compute the final block size of this frame.
*
* @param aReflowState Data structure passed from parent during reflow.
* @param aReflowStatus A pointed to the reflow status for when we're finished
* doing reflow. this will get set appropriately if the height causes
* us to exceed the current available (page) height.
* @param aContentHeight The height of content, precomputed outside of this
* function. The final height that is used in aMetrics will be set to
* either this or the available height, whichever is larger, in the
* case where our available height is constrained, and we overflow that
* available height.
* @param aReflowStatus A pointer to the reflow status for when we're finished
* doing reflow. this will get set appropriately if the block-size
* causes us to exceed the current available (page) block-size.
* @param aContentBSize The block-size of content, precomputed outside of this
* function. The final block-size that is used in aMetrics will be set
* to either this or the available block-size, whichever is larger, in
* the case where our available block-size is constrained, and we
* overflow that available block-size.
* @param aBorderPadding The margins representing the border padding for block
* frames. Can be 0.
* @param aMetrics Out parameter for final height. Taken as an
* nsHTMLReflowMetrics object so that aMetrics can be passed in
* directly during reflow.
* @param aConsumed The height already consumed by our previous-in-flows.
* @param aFinalSize Out parameter for final block-size.
* @param aConsumed The block-size already consumed by our previous-in-flows.
*/
void ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentHeight,
const nsMargin& aBorderPadding,
nsHTMLReflowMetrics& aMetrics,
nscoord aConsumed);
void ComputeFinalBSize(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentBSize,
const mozilla::LogicalMargin& aBorderPadding,
mozilla::LogicalSize& aFinalSize,
nscoord aConsumed);
virtual void Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
@ -297,14 +295,14 @@ public:
* line includes the margin-top of a line with clearance (in which
* case we must avoid collapsing that margin with our bottom margin)
*/
bool CheckForCollapsedBottomMarginFromClearanceLine();
bool CheckForCollapsedBEndMarginFromClearanceLine();
static nsresult GetCurrentLine(nsBlockReflowState *aState, nsLineBox **aOutCurrentLine);
/**
* Determine if this block is a margin root at the top/bottom edges.
*/
void IsMarginRoot(bool* aTopMarginRoot, bool* aBottomMarginRoot);
void IsMarginRoot(bool* aBStartMarginRoot, bool* aBEndMarginRoot);
static bool BlockNeedsFloatManager(nsIFrame* aBlock);
@ -638,8 +636,8 @@ protected:
//----------------------------------------
// Methods for individual frame reflow
bool ShouldApplyTopMargin(nsBlockReflowState& aState,
nsLineBox* aLine);
bool ShouldApplyBStartMargin(nsBlockReflowState& aState,
nsLineBox* aLine);
void ReflowBlockFrame(nsBlockReflowState& aState,
line_iterator aLine,

View File

@ -27,37 +27,41 @@ using namespace mozilla::layout;
nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
nsPresContext* aPresContext,
nsBlockFrame* aFrame,
bool aTopMarginRoot,
bool aBottomMarginRoot,
bool aBStartMarginRoot,
bool aBEndMarginRoot,
bool aBlockNeedsFloatManager,
nscoord aConsumedHeight)
nscoord aConsumedBSize)
: mBlock(aFrame),
mPresContext(aPresContext),
mReflowState(aReflowState),
mContentArea(aReflowState.GetWritingMode()),
mPushedFloats(nullptr),
mOverflowTracker(nullptr),
mPrevBottomMargin(),
mBorderPadding(mReflowState.ComputedLogicalBorderPadding()),
mPrevBEndMargin(),
mLineNumber(0),
mFlags(0),
mFloatBreakType(NS_STYLE_CLEAR_NONE),
mConsumedHeight(aConsumedHeight)
mConsumedBSize(aConsumedBSize)
{
WritingMode wm = aReflowState.GetWritingMode();
SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nullptr);
SetFlag(BRS_ISOVERFLOWCONTAINER,
IS_TRUE_OVERFLOW_CONTAINER(aFrame));
mBorderPadding = mReflowState.ComputedPhysicalBorderPadding();
aFrame->ApplySkipSides(mBorderPadding, &aReflowState);
mContainerWidth = aReflowState.ComputedWidth() + mBorderPadding.LeftRight();
aFrame->ApplyLogicalSkipSides(mBorderPadding, &aReflowState);
if (aTopMarginRoot || 0 != mBorderPadding.top) {
SetFlag(BRS_ISTOPMARGINROOT, true);
// Note that mContainerWidth is the physical width!
mContainerWidth = aReflowState.ComputedWidth() + mBorderPadding.LeftRight(wm);
if (aBStartMarginRoot || 0 != mBorderPadding.BStart(wm)) {
SetFlag(BRS_ISBSTARTMARGINROOT, true);
}
if (aBottomMarginRoot || 0 != mBorderPadding.bottom) {
SetFlag(BRS_ISBOTTOMMARGINROOT, true);
if (aBEndMarginRoot || 0 != mBorderPadding.BEnd(wm)) {
SetFlag(BRS_ISBENDMARGINROOT, true);
}
if (GetFlag(BRS_ISTOPMARGINROOT)) {
SetFlag(BRS_APPLYTOPMARGIN, true);
if (GetFlag(BRS_ISBSTARTMARGINROOT)) {
SetFlag(BRS_APPLYBSTARTMARGIN, true);
}
if (aBlockNeedsFloatManager) {
SetFlag(BRS_FLOAT_MGR, true);
@ -77,11 +81,11 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mNextInFlow = static_cast<nsBlockFrame*>(mBlock->GetNextInFlow());
NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedWidth(),
NS_WARN_IF_FALSE(NS_UNCONSTRAINEDSIZE != aReflowState.ComputedISize(),
"have unconstrained width; this should only result from "
"very large sizes, not attempts at intrinsic width "
"calculation");
mContentArea.width = aReflowState.ComputedWidth();
mContentArea.ISize(wm) = aReflowState.ComputedISize();
// Compute content area height. Unlike the width, if we have a
// specified style height we ignore it since extra content is
@ -89,21 +93,21 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
// specified style height then we may end up limiting our height if
// the availableHeight is constrained (this situation occurs when we
// are paginated).
if (NS_UNCONSTRAINEDSIZE != aReflowState.AvailableHeight()) {
if (NS_UNCONSTRAINEDSIZE != aReflowState.AvailableBSize()) {
// We are in a paginated situation. The bottom edge is just inside
// the bottom border and padding. The content area height doesn't
// include either border or padding edge.
mBottomEdge = aReflowState.AvailableHeight() - mBorderPadding.bottom;
mContentArea.height = std::max(0, mBottomEdge - mBorderPadding.top);
mBEndEdge = aReflowState.AvailableBSize() - mBorderPadding.BEnd(wm);
mContentArea.BSize(wm) = std::max(0, mBEndEdge - mBorderPadding.BStart(wm));
}
else {
// When we are not in a paginated situation then we always use
// an constrained height.
SetFlag(BRS_UNCONSTRAINEDHEIGHT, true);
mContentArea.height = mBottomEdge = NS_UNCONSTRAINEDSIZE;
SetFlag(BRS_UNCONSTRAINEDBSIZE, true);
mContentArea.BSize(wm) = mBEndEdge = NS_UNCONSTRAINEDSIZE;
}
mContentArea.x = mBorderPadding.left;
mY = mContentArea.y = mBorderPadding.top;
mContentArea.IStart(wm) = mBorderPadding.IStart(wm);
mBCoord = mContentArea.BStart(wm) = mBorderPadding.BStart(wm);
mPrevChild = nullptr;
mCurrentLine = aFrame->end_lines();
@ -112,13 +116,13 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
}
nscoord
nsBlockReflowState::GetConsumedHeight()
nsBlockReflowState::GetConsumedBSize()
{
if (mConsumedHeight == NS_INTRINSICSIZE) {
mConsumedHeight = mBlock->GetConsumedHeight();
if (mConsumedBSize == NS_INTRINSICSIZE) {
mConsumedBSize = mBlock->GetConsumedBSize();
}
return mConsumedHeight;
return mConsumedBSize;
}
void
@ -127,31 +131,33 @@ nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
nscoord& aLeftResult,
nscoord& aRightResult)
{
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.x >= mContentArea.x, "bad avail space rect x");
NS_ASSERTION(aFloatAvailableSpace.x >= contentArea.x, "bad avail space rect x");
NS_ASSERTION(aFloatAvailableSpace.width == 0 ||
aFloatAvailableSpace.XMost() <= mContentArea.XMost(),
aFloatAvailableSpace.XMost() <= contentArea.XMost(),
"bad avail space rect width");
nscoord leftOffset, rightOffset;
if (aFloatAvailableSpace.width == mContentArea.width) {
if (aFloatAvailableSpace.width == contentArea.width) {
// We don't need to compute margins when there are no floats around.
leftOffset = 0;
rightOffset = 0;
} else {
nsMargin frameMargin;
nsCSSOffsetState os(aFrame, mReflowState.rendContext, mContentArea.width);
nsCSSOffsetState os(aFrame, mReflowState.rendContext, contentArea.width);
frameMargin = os.ComputedPhysicalMargin();
nscoord leftFloatXOffset = aFloatAvailableSpace.x - mContentArea.x;
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 =
mContentArea.XMost() - aFloatAvailableSpace.XMost();
contentArea.XMost() - aFloatAvailableSpace.XMost();
rightOffset = std::max(rightFloatXOffset, frameMargin.right) -
frameMargin.right;
rightOffset = std::max(rightOffset, 0); // in case of negative margin
@ -174,11 +180,16 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
printf("CBAS frame=%p has floats %d\n",
aFrame, aFloatAvailableSpace.mHasFloats);
#endif
aResult.y = mY;
aResult.height = GetFlag(BRS_UNCONSTRAINEDHEIGHT)
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)
? NS_UNCONSTRAINEDSIZE
: mReflowState.AvailableHeight() - mY;
// mY might be greater than mBottomEdge if the block's top margin pushes
: mReflowState.AvailableBSize() - mBCoord;
// mBCoord might be greater than mBEndEdge if the block's top margin pushes
// it off the page/column. Negative available height can confuse other code
// and is nonsense in principle.
@ -207,15 +218,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.x = mContentArea.x;
aResult.width = mContentArea.width;
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.x = aFloatAvailableSpace.mRect.x;
aResult.width = aFloatAvailableSpace.mRect.width;
result.IStart(wm) = floatAvailSpace.IStart(wm);
result.ISize(wm) = floatAvailSpace.ISize(wm);
}
break;
}
@ -224,16 +235,20 @@ 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.x = mContentArea.x;
aResult.width = mContentArea.width;
result.IStart(wm) = ContentIStart();
result.ISize(wm) = ContentISize();
}
aResult = result.GetPhysicalRect(wm, mContainerWidth);
}
else {
aResult = result.GetPhysicalRect(wm, mContainerWidth);
nsRect contentArea =
mContentArea.GetPhysicalRect(wm, mContainerWidth);
nscoord leftOffset, rightOffset;
ComputeReplacedBlockOffsetsForFloats(aFrame, aFloatAvailableSpace.mRect,
leftOffset, rightOffset);
aResult.x = mContentArea.x + leftOffset;
aResult.width = mContentArea.width - leftOffset - rightOffset;
aResult.x = contentArea.x + leftOffset;
aResult.width = contentArea.width - leftOffset - rightOffset;
}
#ifdef REALLY_NOISY_REFLOW
@ -243,7 +258,7 @@ nsBlockReflowState::ComputeBlockAvailSpace(nsIFrame* aFrame,
nsFlowAreaRect
nsBlockReflowState::GetFloatAvailableSpaceWithState(
nscoord aY,
nscoord aBCoord,
nsFloatManager::SavedState *aState) const
{
#ifdef DEBUG
@ -254,11 +269,13 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
"bad coord system");
#endif
nscoord height = (mContentArea.height == nscoord_MAX)
? nscoord_MAX : std::max(mContentArea.YMost() - aY, 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(aY, nsFloatManager::BAND_FROM_POINT,
height, mContentArea, aState);
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;
@ -275,8 +292,8 @@ nsBlockReflowState::GetFloatAvailableSpaceWithState(
}
nsFlowAreaRect
nsBlockReflowState::GetFloatAvailableSpaceForHeight(
nscoord aY, nscoord aHeight,
nsBlockReflowState::GetFloatAvailableSpaceForBSize(
nscoord aBCoord, nscoord aBSize,
nsFloatManager::SavedState *aState) const
{
#ifdef DEBUG
@ -286,10 +303,11 @@ nsBlockReflowState::GetFloatAvailableSpaceForHeight(
NS_ASSERTION((wx == mFloatManagerX) && (wy == mFloatManagerY),
"bad coord system");
#endif
nsRect contentArea =
mContentArea.GetPhysicalRect(mReflowState.GetWritingMode(), mContainerWidth);
nsFlowAreaRect result =
mFloatManager->GetFlowArea(aY, nsFloatManager::WIDTH_WITHIN_HEIGHT,
aHeight, mContentArea, aState);
mFloatManager->GetFlowArea(aBCoord, nsFloatManager::WIDTH_WITHIN_HEIGHT,
aBSize, contentArea, aState);
// Keep the width >= 0 for compatibility with nsSpaceManager.
if (result.mRect.width < 0)
result.mRect.width = 0;
@ -314,21 +332,21 @@ nsBlockReflowState::GetFloatAvailableSpaceForHeight(
*
* The reconstruction involves walking backward through the line list to
* find any collapsed margins preceding the line that would have been in
* the reflow state's |mPrevBottomMargin| when we reflowed that line in
* the reflow state's |mPrevBEndMargin| when we reflowed that line in
* a full reflow (under the rule in CSS2 that all adjacent vertical
* margins of blocks collapse).
*/
void
nsBlockReflowState::ReconstructMarginAbove(nsLineList::iterator aLine)
nsBlockReflowState::ReconstructMarginBefore(nsLineList::iterator aLine)
{
mPrevBottomMargin.Zero();
mPrevBEndMargin.Zero();
nsBlockFrame *block = mBlock;
nsLineList::iterator firstLine = block->begin_lines();
for (;;) {
--aLine;
if (aLine->IsBlock()) {
mPrevBottomMargin = aLine->GetCarriedOutBottomMargin();
mPrevBEndMargin = aLine->GetCarriedOutBEndMargin();
break;
}
if (!aLine->IsEmpty()) {
@ -337,8 +355,8 @@ nsBlockReflowState::ReconstructMarginAbove(nsLineList::iterator aLine)
if (aLine == firstLine) {
// If the top margin was carried out (and thus already applied),
// set it to zero. Either way, we're done.
if (!GetFlag(BRS_ISTOPMARGINROOT)) {
mPrevBottomMargin.Zero();
if (!GetFlag(BRS_ISBSTARTMARGINROOT)) {
mPrevBEndMargin.Zero();
}
break;
}
@ -374,14 +392,14 @@ nsBlockReflowState::AppendPushedFloat(nsIFrame* aFloatCont)
/**
* Restore information about floats into the float manager for an
* incremental reflow, and simultaneously push the floats by
* |aDeltaY|, which is the amount |aLine| was pushed relative to its
* |aDeltaBCoord|, which is the amount |aLine| was pushed relative to its
* parent. The recovery of state is one of the things that makes
* incremental reflow O(N^2) and this state should really be kept
* around, attached to the frame tree.
*/
void
nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
nscoord aDeltaY)
nscoord aDeltaBCoord)
{
if (aLine->HasFloats()) {
// Place the floats into the space-manager again. Also slide
@ -389,8 +407,8 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
nsFloatCache* fc = aLine->GetFirstFloat();
while (fc) {
nsIFrame* floatFrame = fc->mFloat;
if (aDeltaY != 0) {
floatFrame->MovePositionBy(nsPoint(0, aDeltaY));
if (aDeltaBCoord != 0) {
floatFrame->MovePositionBy(nsPoint(0, aDeltaBCoord));
nsContainerFrame::PositionFrameView(floatFrame);
nsContainerFrame::PositionChildViews(floatFrame);
}
@ -403,8 +421,8 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
tx, ty, mFloatManagerX, mFloatManagerY);
nsFrame::ListTag(stdout, floatFrame);
nsRect region = nsFloatManager::GetRegionFor(floatFrame);
printf(" aDeltaY=%d region={%d,%d,%d,%d}\n",
aDeltaY, region.x, region.y, region.width, region.height);
printf(" aDeltaBCoord=%d region={%d,%d,%d,%d}\n",
aDeltaBCoord, region.x, region.y, region.width, region.height);
}
#endif
mFloatManager->AddFloat(floatFrame,
@ -421,7 +439,7 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
* reflow so it is O(N*M) where M is the number of incremental reflow
* passes. That's bad. Don't do stuff here.
*
* When this function is called, |aLine| has just been slid by |aDeltaY|
* When this function is called, |aLine| has just been slid by |aDeltaBCoord|
* and the purpose of RecoverStateFrom is to ensure that the
* nsBlockReflowState is in the same state that it would have been in
* had the line just been reflowed.
@ -430,14 +448,14 @@ nsBlockReflowState::RecoverFloats(nsLineList::iterator aLine,
*/
void
nsBlockReflowState::RecoverStateFrom(nsLineList::iterator aLine,
nscoord aDeltaY)
nscoord aDeltaBCoord)
{
// Make the line being recovered the current line
mCurrentLine = aLine;
// Place floats for this line into the float manager
if (aLine->HasFloats() || aLine->IsBlock()) {
RecoverFloats(aLine, aDeltaY);
RecoverFloats(aLine, aDeltaBCoord);
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow || nsBlockFrame::gNoisyFloatManager) {
@ -521,8 +539,8 @@ nsBlockReflowState::AddFloat(nsLineLayout* aLineLayout,
placed = FlowAndPlaceFloat(aFloat);
if (placed) {
// Pass on updated available space to the current inline reflow engine
nsFlowAreaRect floatAvailSpace = GetFloatAvailableSpace(mY);
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x, mY),
nsFlowAreaRect floatAvailSpace = GetFloatAvailableSpace(mBCoord);
nsRect availSpace(nsPoint(floatAvailSpace.mRect.x, mBCoord),
floatAvailSpace.mRect.Size());
aLineLayout->UpdateBand(availSpace, aFloat);
// Record this float in the current-line list
@ -587,13 +605,13 @@ bool
nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
{
// Save away the Y coordinate before placing the float. We will
// restore mY at the end after placing the float. This is
// necessary because any adjustments to mY during the float
// restore mBCoord at the end after placing the float. This is
// necessary because any adjustments to mBCoord during the float
// placement are for the float only, not for any non-floating
// content.
AutoRestore<nscoord> restoreY(mY);
AutoRestore<nscoord> restoreBCoord(mBCoord);
// FIXME: Should give AutoRestore a getter for the value to avoid this.
const nscoord saveY = mY;
const nscoord saveBCoord = mBCoord;
// Grab the float's display information
const nsStyleDisplay* floatDisplay = aFloat->StyleDisplay();
@ -603,17 +621,17 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* 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.
mY = std::max(mFloatManager->GetLowestFloatTop(), mY);
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
// when floats are inserted before it.
if (NS_STYLE_CLEAR_NONE != floatDisplay->mBreakType) {
// XXXldb Does this handle vertical margins correctly?
mY = ClearFloats(mY, floatDisplay->mBreakType);
mBCoord = ClearFloats(mBCoord, floatDisplay->mBreakType);
}
// Get the band of available space
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mY);
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
nsRect adjustedAvailableSpace = mBlock->AdjustFloatAvailableSpace(*this,
floatAvailableSpace.mRect, aFloat);
@ -678,11 +696,11 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
if (NS_STYLE_DISPLAY_TABLE != floatDisplay->mDisplay ||
eCompatibility_NavQuirks != mPresContext->CompatibilityMode() ) {
mY += floatAvailableSpace.mRect.height;
mBCoord += floatAvailableSpace.mRect.height;
if (adjustedAvailableSpace.height != NS_UNCONSTRAINEDSIZE) {
adjustedAvailableSpace.height -= floatAvailableSpace.mRect.height;
}
floatAvailableSpace = GetFloatAvailableSpace(mY);
floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
} else {
// This quirk matches the one in nsBlockFrame::AdjustFloatAvailableSpace
// IE handles float tables in a very special way
@ -720,10 +738,10 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
}
// the table does not fit anymore in this line so advance to next band
mY += floatAvailableSpace.mRect.height;
mBCoord += floatAvailableSpace.mRect.height;
// To match nsBlockFrame::AdjustFloatAvailableSpace, we have to
// get a new width for the new band.
floatAvailableSpace = GetFloatAvailableSpace(mY);
floatAvailableSpace = GetFloatAvailableSpace(mBCoord);
adjustedAvailableSpace = mBlock->AdjustFloatAvailableSpace(*this,
floatAvailableSpace.mRect, aFloat);
floatMarginWidth = FloatMarginWidth(mReflowState,
@ -760,12 +778,12 @@ 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(mY, mContentArea.y);
floatY = std::max(mBCoord, ContentBStart());
// Reflow the float after computing its vertical position so it knows
// where to break.
if (!isLetter) {
bool pushedDown = mY != saveY;
bool pushedDown = mBCoord != saveBCoord;
mBlock->ReflowFloat(*this, adjustedAvailableSpace, aFloat, floatMargin,
floatOffsets, pushedDown, reflowStatus);
}
@ -781,11 +799,11 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
// Likewise, if none of the float fit, and it needs to be pushed in
// its entirety to the next page (NS_FRAME_IS_TRUNCATED or
// NS_INLINE_IS_BREAK_BEFORE), we need to do the same.
if ((mContentArea.height != NS_UNCONSTRAINEDSIZE &&
if ((ContentBSize() != NS_UNCONSTRAINEDSIZE &&
adjustedAvailableSpace.height == NS_UNCONSTRAINEDSIZE &&
!mustPlaceFloat &&
aFloat->GetSize().height + floatMargin.TopBottom() >
mContentArea.YMost() - floatY) ||
ContentBEnd() - floatY) ||
NS_FRAME_IS_TRUNCATED(reflowStatus) ||
NS_INLINE_IS_BREAK_BEFORE(reflowStatus)) {
PushFloatPastBreak(aFloat);
@ -795,12 +813,12 @@ 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.
if (mContentArea.height != NS_UNCONSTRAINEDSIZE &&
if (ContentBSize() != NS_UNCONSTRAINEDSIZE &&
!mustPlaceFloat && (!mReflowState.mFlags.mIsTopOfPage || floatY > 0) &&
NS_STYLE_PAGE_BREAK_AVOID == aFloat->StyleDisplay()->mBreakInside &&
(!NS_FRAME_IS_FULLY_COMPLETE(reflowStatus) ||
aFloat->GetSize().height + floatMargin.TopBottom() >
mContentArea.YMost() - floatY) &&
ContentBEnd() - floatY) &&
!aFloat->GetPrevInFlow()) {
PushFloatPastBreak(aFloat);
return false;
@ -834,8 +852,8 @@ nsBlockReflowState::FlowAndPlaceFloat(nsIFrame* aFloat)
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 != mContentArea.height)) {
region.height = std::max(region.height, mContentArea.height - floatY);
(NS_UNCONSTRAINEDSIZE != ContentBSize())) {
region.height = std::max(region.height, ContentBSize() - floatY);
}
DebugOnly<nsresult> rv =
mFloatManager->AddFloat(aFloat, region);
@ -937,36 +955,36 @@ nsBlockReflowState::PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aList,
}
nscoord
nsBlockReflowState::ClearFloats(nscoord aY, uint8_t aBreakType,
nsBlockReflowState::ClearFloats(nscoord aBCoord, uint8_t aBreakType,
nsIFrame *aReplacedBlock,
uint32_t aFlags)
{
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("clear floats: in: aY=%d\n", aY);
printf("clear floats: in: aBCoord=%d\n", aBCoord);
}
#endif
#ifdef NOISY_FLOAT_CLEARING
printf("nsBlockReflowState::ClearFloats: aY=%d breakType=%d\n",
aY, aBreakType);
printf("nsBlockReflowState::ClearFloats: aBCoord=%d breakType=%d\n",
aBCoord, aBreakType);
mFloatManager->List(stdout);
#endif
if (!mFloatManager->HasAnyFloats()) {
return aY;
return aBCoord;
}
nscoord newY = aY;
nscoord newBCoord = aBCoord;
if (aBreakType != NS_STYLE_CLEAR_NONE) {
newY = mFloatManager->ClearFloats(newY, aBreakType, aFlags);
newBCoord = mFloatManager->ClearFloats(newBCoord, aBreakType, aFlags);
}
if (aReplacedBlock) {
for (;;) {
nsFlowAreaRect floatAvailableSpace = GetFloatAvailableSpace(newY);
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
@ -976,18 +994,18 @@ nsBlockReflowState::ClearFloats(nscoord aY, uint8_t aBreakType,
nsBlockFrame::ReplacedElementWidthToClear replacedWidth =
nsBlockFrame::WidthToClearPastFloats(*this, floatAvailableSpace.mRect,
aReplacedBlock);
if (std::max(floatAvailableSpace.mRect.x - mContentArea.x,
if (std::max(floatAvailableSpace.mRect.x - ContentIStart(),
replacedWidth.marginLeft) +
replacedWidth.borderBoxWidth +
std::max(mContentArea.XMost() - floatAvailableSpace.mRect.XMost(),
std::max(ContentIEnd() - floatAvailableSpace.mRect.XMost(),
replacedWidth.marginRight) <=
mContentArea.width) {
ContentISize()) {
break;
}
// See the analogous code for inlines in nsBlockFrame::DoReflowInlineFrames
if (floatAvailableSpace.mRect.height > 0) {
// See if there's room in the next band.
newY += floatAvailableSpace.mRect.height;
newBCoord += floatAvailableSpace.mRect.height;
} else {
if (mReflowState.AvailableHeight() != NS_UNCONSTRAINEDSIZE) {
// Stop trying to clear here; we'll just get pushed to the
@ -995,7 +1013,7 @@ nsBlockReflowState::ClearFloats(nscoord aY, uint8_t aBreakType,
break;
}
NS_NOTREACHED("avail space rect with zero height!");
newY += 1;
newBCoord += 1;
}
}
}
@ -1003,10 +1021,10 @@ nsBlockReflowState::ClearFloats(nscoord aY, uint8_t aBreakType,
#ifdef DEBUG
if (nsBlockFrame::gNoisyReflow) {
nsFrame::IndentBy(stdout, nsBlockFrame::gNoiseIndent);
printf("clear floats: out: y=%d\n", newY);
printf("clear floats: out: y=%d\n", newBCoord);
}
#endif
return newY;
return newBCoord;
}

View File

@ -17,10 +17,10 @@ class nsFrameList;
class nsOverflowContinuationTracker;
// block reflow state flags
#define BRS_UNCONSTRAINEDHEIGHT 0x00000001
#define BRS_ISTOPMARGINROOT 0x00000002 // Is this frame a root for top/bottom margin collapsing?
#define BRS_ISBOTTOMMARGINROOT 0x00000004
#define BRS_APPLYTOPMARGIN 0x00000008 // See ShouldApplyTopMargin
#define BRS_UNCONSTRAINEDBSIZE 0x00000001
#define BRS_ISBSTARTMARGINROOT 0x00000002 // Is this frame a root for block
#define BRS_ISBENDMARGINROOT 0x00000004 // direction start/end margin collapsing?
#define BRS_APPLYBSTARTMARGIN 0x00000008 // See ShouldApplyTopMargin
#define BRS_ISFIRSTINFLOW 0x00000010
// Set when mLineAdjacentToTop is valid
#define BRS_HAVELINEADJACENTTOTOP 0x00000020
@ -39,9 +39,9 @@ public:
nsBlockReflowState(const nsHTMLReflowState& aReflowState,
nsPresContext* aPresContext,
nsBlockFrame* aFrame,
bool aTopMarginRoot, bool aBottomMarginRoot,
bool aBStartMarginRoot, bool aBEndMarginRoot,
bool aBlockNeedsFloatManager,
nscoord aConsumedHeight = NS_INTRINSICSIZE);
nscoord aConsumedBSize = NS_INTRINSICSIZE);
/**
* Get the available reflow space (the area not occupied by floats)
@ -49,19 +49,19 @@ public:
* our coordinate system, which is the content box, with (0, 0) in the
* upper left.
*
* Returns whether there are floats present at the given vertical
* coordinate and within the width of the content rect.
* Returns whether there are floats present at the given block-direction
* coordinate and within the inline size of the content rect.
*/
nsFlowAreaRect GetFloatAvailableSpace() const
{ return GetFloatAvailableSpace(mY); }
nsFlowAreaRect GetFloatAvailableSpace(nscoord aY) const
{ return GetFloatAvailableSpaceWithState(aY, nullptr); }
{ return GetFloatAvailableSpace(mBCoord); }
nsFlowAreaRect GetFloatAvailableSpace(nscoord aBCoord) const
{ return GetFloatAvailableSpaceWithState(aBCoord, nullptr); }
nsFlowAreaRect
GetFloatAvailableSpaceWithState(nscoord aY,
GetFloatAvailableSpaceWithState(nscoord aBCoord,
nsFloatManager::SavedState *aState) const;
nsFlowAreaRect
GetFloatAvailableSpaceForHeight(nscoord aY, nscoord aHeight,
nsFloatManager::SavedState *aState) const;
GetFloatAvailableSpaceForBSize(nscoord aBCoord, nscoord aBSize,
nsFloatManager::SavedState *aState) const;
/*
* The following functions all return true if they were able to
@ -71,11 +71,11 @@ public:
* they are not associated with a line box).
*/
bool AddFloat(nsLineLayout* aLineLayout,
nsIFrame* aFloat,
nscoord aAvailableWidth);
nsIFrame* aFloat,
nscoord aAvailableISize);
private:
bool CanPlaceFloat(nscoord aFloatWidth,
const nsFlowAreaRect& aFloatAvailableSpace);
bool CanPlaceFloat(nscoord aFloatISize,
const nsFlowAreaRect& aFloatAvailableSpace);
public:
bool FlowAndPlaceFloat(nsIFrame* aFloat);
private:
@ -84,40 +84,40 @@ public:
void PlaceBelowCurrentLineFloats(nsFloatCacheFreeList& aFloats,
nsLineBox* aLine);
// Returns the first coordinate >= aY that clears the
// floats indicated by aBreakType and has enough width between floats
// Returns the first coordinate >= aBCoord that clears the
// floats indicated by aBreakType and has enough inline size between floats
// (or no floats remaining) to accomodate aReplacedBlock.
nscoord ClearFloats(nscoord aY, uint8_t aBreakType,
nscoord ClearFloats(nscoord aBCoord, uint8_t aBreakType,
nsIFrame *aReplacedBlock = nullptr,
uint32_t aFlags = 0);
bool IsAdjacentWithTop() const {
return mY == mBorderPadding.top;
return mBCoord == mBorderPadding.BStart(mReflowState.GetWritingMode());
}
/**
* Return mBlock's computed physical border+padding with GetSkipSides applied.
*/
const nsMargin& BorderPadding() const {
const mozilla::LogicalMargin& BorderPadding() const {
return mBorderPadding;
}
/**
* Retrieve the height "consumed" by any previous-in-flows.
* Retrieve the block-direction size "consumed" by any previous-in-flows.
*/
nscoord GetConsumedHeight();
nscoord GetConsumedBSize();
// Reconstruct the previous bottom margin that goes above |aLine|.
void ReconstructMarginAbove(nsLineList::iterator aLine);
// Reconstruct the previous block-end margin that goes before |aLine|.
void ReconstructMarginBefore(nsLineList::iterator aLine);
// Caller must have called GetAvailableSpace for the correct position
// (which need not be the current mY).
// (which need not be the current mBCoord).
void ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const nsRect& aFloatAvailableSpace,
nscoord& aLeftResult,
nscoord& aRightResult);
// Caller must have called GetAvailableSpace for the current mY
// Caller must have called GetAvailableSpace for the current mBCoord
void ComputeBlockAvailSpace(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay,
const nsFlowAreaRect& aFloatAvailableSpace,
@ -125,10 +125,10 @@ public:
nsRect& aResult);
protected:
void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaY);
void RecoverFloats(nsLineList::iterator aLine, nscoord aDeltaBCoord);
public:
void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaY);
void RecoverStateFrom(nsLineList::iterator aLine, nscoord aDeltaBCoord);
void AdvanceToNextLine() {
if (GetFlag(BRS_LINE_LAYOUT_EMPTY)) {
@ -168,17 +168,36 @@ public:
// block, not floats inside of it.
nsFloatManager::SavedState mFloatManagerStateBefore;
nscoord mBottomEdge;
nscoord mBEndEdge;
// The content area to reflow child frames within. This is within
// this frame's coordinate system, which means mContentArea.x ==
// BorderPadding().left and mContentArea.y == BorderPadding().top.
// The height may be NS_UNCONSTRAINEDSIZE, which indicates that there
// this frame's coordinate system and writing mode, which means
// mContentArea.IStart == BorderPadding().IStart and
// mContentArea.BStart == BorderPadding().BStart.
// The block size may be NS_UNCONSTRAINEDSIZE, which indicates that there
// is no page/column boundary below (the common case).
// mContentArea.YMost() should only be called after checking that
// mContentArea.height is not NS_UNCONSTRAINEDSIZE; otherwise
// mContentArea.BEnd() should only be called after checking that
// mContentArea.BSize is not NS_UNCONSTRAINEDSIZE; otherwise
// coordinate overflow may occur.
nsRect mContentArea;
mozilla::LogicalRect mContentArea;
nscoord ContentIStart() {
return mContentArea.IStart(mReflowState.GetWritingMode());
}
nscoord ContentISize() {
return mContentArea.ISize(mReflowState.GetWritingMode());
}
nscoord ContentIEnd() {
return mContentArea.IEnd(mReflowState.GetWritingMode());
}
nscoord ContentBStart() {
return mContentArea.BStart(mReflowState.GetWritingMode());
}
nscoord ContentBSize() {
return mContentArea.BSize(mReflowState.GetWritingMode());
}
nscoord ContentBEnd() {
return mContentArea.BEnd(mReflowState.GetWritingMode());
}
nscoord mContainerWidth;
// Continuation out-of-flow float frames that need to move to our
@ -210,11 +229,11 @@ public:
// always before the current line.
nsLineList::iterator mLineAdjacentToTop;
// The current Y coordinate in the block
nscoord mY;
// The current block-direction coordinate in the block
nscoord mBCoord;
// mBlock's computed physical border+padding with GetSkipSides applied.
nsMargin mBorderPadding;
mozilla::LogicalMargin mBorderPadding;
// The overflow areas of all floats placed so far
nsOverflowAreas mFloatOverflowAreas;
@ -226,7 +245,7 @@ public:
nsIFrame* mPrevChild;
// The previous child frames collapsed bottom margin value.
nsCollapsingMargin mPrevBottomMargin;
nsCollapsingMargin mPrevBEndMargin;
// The current next-in-flow for the block. When lines are pulled
// from a next-in-flow, this is used to know which next-in-flow to
@ -258,8 +277,8 @@ public:
uint8_t mFloatBreakType;
// The amount of computed height "consumed" by previous-in-flows.
nscoord mConsumedHeight;
// The amount of computed block-direction size "consumed" by previous-in-flows.
nscoord mConsumedBSize;
void SetFlag(uint32_t aFlag, bool aValue)
{

View File

@ -177,13 +177,13 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
availContentWidth = aReflowState.ComputedWidth();
}
nscoord consumedHeight = GetConsumedHeight();
nscoord consumedBSize = GetConsumedBSize();
// The effective computed height is the height of the current continuation
// of the column set frame. This should be the same as the computed height
// if we have an unconstrained available height.
nscoord computedHeight = GetEffectiveComputedHeight(aReflowState,
consumedHeight);
nscoord computedBSize = GetEffectiveComputedBSize(aReflowState,
consumedBSize);
nscoord colHeight = GetAvailableContentHeight(aReflowState);
if (aReflowState.ComputedHeight() != NS_INTRINSICSIZE) {
@ -298,7 +298,7 @@ nsColumnSetFrame::ChooseColumnStrategy(const nsHTMLReflowState& aReflowState,
#endif
ReflowConfig config = { numColumns, colWidth, expectedWidthLeftOver, colGap,
colHeight, isBalancing, knownFeasibleHeight,
knownInfeasibleHeight, computedHeight, consumedHeight };
knownInfeasibleHeight, computedBSize, consumedBSize };
return config;
}

View File

@ -2748,10 +2748,10 @@ nsFlexContainerFrame::GetMainSizeFromReflowState(
if (IsAxisHorizontal(aAxisTracker.GetMainAxis())) {
// Horizontal case is easy -- our main size is our computed width
// (which is already resolved).
return aReflowState.ComputedWidth();
return aReflowState.ComputedISize();
}
return GetEffectiveComputedHeight(aReflowState);
return GetEffectiveComputedBSize(aReflowState);
}
// Returns the largest outer hypothetical main-size of any line in |aLines|.
@ -2837,20 +2837,20 @@ nsFlexContainerFrame::ComputeCrossSize(const nsHTMLReflowState& aReflowState,
// Cross axis is horizontal: our cross size is our computed width
// (which is already resolved).
*aIsDefinite = true;
return aReflowState.ComputedWidth();
return aReflowState.ComputedISize();
}
nscoord effectiveComputedHeight = GetEffectiveComputedHeight(aReflowState);
if (effectiveComputedHeight != NS_INTRINSICSIZE) {
nscoord effectiveComputedBSize = GetEffectiveComputedBSize(aReflowState);
if (effectiveComputedBSize != NS_INTRINSICSIZE) {
// Cross-axis is vertical, and we have a fixed height:
*aIsDefinite = true;
if (aAvailableHeightForContent == NS_UNCONSTRAINEDSIZE ||
effectiveComputedHeight < aAvailableHeightForContent) {
effectiveComputedBSize < aAvailableHeightForContent) {
// Not in a fragmenting context, OR no need to fragment because we have
// more available height than we need. Either way, just use our fixed
// height. (Note that the reflow state has already done the appropriate
// min/max-height clamping.)
return effectiveComputedHeight;
return effectiveComputedBSize;
}
// Fragmenting *and* our fixed height is too tall for available height:
@ -2864,7 +2864,7 @@ nsFlexContainerFrame::ComputeCrossSize(const nsHTMLReflowState& aReflowState,
if (aSumLineCrossSizes <= aAvailableHeightForContent) {
return aAvailableHeightForContent;
}
return std::min(effectiveComputedHeight, aSumLineCrossSizes);
return std::min(effectiveComputedBSize, aSumLineCrossSizes);
}
// Cross axis is vertical and we have auto-height: shrink-wrap our line(s),

View File

@ -55,7 +55,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
nsMargin bp = aReflowState.ComputedPhysicalBorderPadding();
ApplySkipSides(bp);
nscoord contentHeight = GetEffectiveComputedHeight(aReflowState);
nscoord contentHeight = GetEffectiveComputedBSize(aReflowState);
if (contentHeight == NS_AUTOHEIGHT) {
contentHeight = 0;
}

View File

@ -240,6 +240,15 @@ public:
return mBSize;
}
// Set inline and block size from a LogicalSize, converting to our
// writing mode as necessary.
void SetSize(mozilla::WritingMode aWM, mozilla::LogicalSize aSize)
{
mozilla::LogicalSize convertedSize = aSize.ConvertTo(mWritingMode, aWM);
mBSize = convertedSize.BSize(mWritingMode);
mISize = convertedSize.ISize(mWritingMode);
}
// Width and Height are physical dimensions, independent of writing mode.
// Accessing these is slightly more expensive than accessing the logical
// dimensions (once vertical writing mode support is enabled); as far as

View File

@ -243,8 +243,8 @@ nsLineBox::List(FILE* out, const char* aPrefix, uint32_t aFlags) const
str += nsPrintfCString("line %p: count=%d state=%s ",
static_cast<const void*>(this), GetChildCount(),
StateToString(cbuf, sizeof(cbuf)));
if (IsBlock() && !GetCarriedOutBottomMargin().IsZero()) {
str += nsPrintfCString("bm=%d ", GetCarriedOutBottomMargin().get());
if (IsBlock() && !GetCarriedOutBEndMargin().IsZero()) {
str += nsPrintfCString("bm=%d ", GetCarriedOutBEndMargin().get());
}
nsRect bounds = GetPhysicalBounds();
str += nsPrintfCString("{%d,%d,%d,%d} ",
@ -430,17 +430,17 @@ nsLineBox::RFindLineContaining(nsIFrame* aFrame,
}
nsCollapsingMargin
nsLineBox::GetCarriedOutBottomMargin() const
nsLineBox::GetCarriedOutBEndMargin() const
{
NS_ASSERTION(IsBlock(),
"GetCarriedOutBottomMargin called on non-block line.");
"GetCarriedOutBEndMargin called on non-block line.");
return (IsBlock() && mBlockData)
? mBlockData->mCarriedOutBottomMargin
? mBlockData->mCarriedOutBEndMargin
: nsCollapsingMargin();
}
bool
nsLineBox::SetCarriedOutBottomMargin(nsCollapsingMargin aValue)
nsLineBox::SetCarriedOutBEndMargin(nsCollapsingMargin aValue)
{
bool changed = false;
if (IsBlock()) {
@ -448,12 +448,12 @@ nsLineBox::SetCarriedOutBottomMargin(nsCollapsingMargin aValue)
if (!mBlockData) {
mBlockData = new ExtraBlockData(GetPhysicalBounds());
}
changed = aValue != mBlockData->mCarriedOutBottomMargin;
mBlockData->mCarriedOutBottomMargin = aValue;
changed = aValue != mBlockData->mCarriedOutBEndMargin;
mBlockData->mCarriedOutBEndMargin = aValue;
}
else if (mBlockData) {
changed = aValue != mBlockData->mCarriedOutBottomMargin;
mBlockData->mCarriedOutBottomMargin = aValue;
changed = aValue != mBlockData->mCarriedOutBEndMargin;
mBlockData->mCarriedOutBEndMargin = aValue;
MaybeFreeData();
}
}
@ -471,7 +471,7 @@ nsLineBox::MaybeFreeData()
mInlineData = nullptr;
}
}
else if (mBlockData->mCarriedOutBottomMargin.IsZero()) {
else if (mBlockData->mCarriedOutBEndMargin.IsZero()) {
delete mBlockData;
mBlockData = nullptr;
}

View File

@ -427,10 +427,10 @@ public:
return !IsBlock() ? mFlags.mBreakType : NS_STYLE_CLEAR_NONE;
}
// mCarriedOutBottomMargin value
nsCollapsingMargin GetCarriedOutBottomMargin() const;
// mCarriedOutBEndMargin value
nsCollapsingMargin GetCarriedOutBEndMargin() const;
// Returns true if the margin changed
bool SetCarriedOutBottomMargin(nsCollapsingMargin aValue);
bool SetCarriedOutBEndMargin(nsCollapsingMargin aValue);
// mFloats
bool HasFloats() const {
@ -647,10 +647,10 @@ public:
struct ExtraBlockData : public ExtraData {
ExtraBlockData(const nsRect& aBounds)
: ExtraData(aBounds),
mCarriedOutBottomMargin()
mCarriedOutBEndMargin()
{
}
nsCollapsingMargin mCarriedOutBottomMargin;
nsCollapsingMargin mCarriedOutBEndMargin;
};
struct ExtraInlineData : public ExtraData {

View File

@ -207,7 +207,7 @@ nsSplittableFrame::RemoveFromFlow(nsIFrame* aFrame)
}
nscoord
nsSplittableFrame::GetConsumedHeight() const
nsSplittableFrame::GetConsumedBSize() const
{
nscoord height = 0;
for (nsIFrame* prev = GetPrevInFlow(); prev; prev = prev->GetPrevInFlow()) {
@ -217,22 +217,22 @@ nsSplittableFrame::GetConsumedHeight() const
}
nscoord
nsSplittableFrame::GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
nscoord aConsumedHeight) const
nsSplittableFrame::GetEffectiveComputedBSize(const nsHTMLReflowState& aReflowState,
nscoord aConsumedBSize) const
{
nscoord height = aReflowState.ComputedHeight();
if (height == NS_INTRINSICSIZE) {
nscoord bSize = aReflowState.ComputedBSize();
if (bSize == NS_INTRINSICSIZE) {
return NS_INTRINSICSIZE;
}
if (aConsumedHeight == NS_INTRINSICSIZE) {
aConsumedHeight = GetConsumedHeight();
if (aConsumedBSize == NS_INTRINSICSIZE) {
aConsumedBSize = GetConsumedBSize();
}
height -= aConsumedHeight;
bSize -= aConsumedBSize;
// We may have stretched the frame beyond its computed height. Oh well.
return std::max(0, height);
return std::max(0, bSize);
}
int
@ -258,10 +258,10 @@ nsSplittableFrame::GetLogicalSkipSides(const nsHTMLReflowState* aReflowState) co
// height, though, then we're going to need a next-in-flow, it just hasn't
// been created yet.
if (NS_UNCONSTRAINEDSIZE != aReflowState->AvailableHeight()) {
nscoord effectiveCH = this->GetEffectiveComputedHeight(*aReflowState);
if (NS_UNCONSTRAINEDSIZE != aReflowState->AvailableBSize()) {
nscoord effectiveCH = this->GetEffectiveComputedBSize(*aReflowState);
if (effectiveCH != NS_INTRINSICSIZE &&
effectiveCH > aReflowState->AvailableHeight()) {
effectiveCH > aReflowState->AvailableBSize()) {
// Our content height is going to exceed our available height, so we're
// going to need a next-in-flow.
skip |= LOGICAL_SIDE_B_END;

View File

@ -83,14 +83,14 @@ protected:
* O(N^2)! So, use this function with caution and minimize the number
* of calls to this method.
*/
nscoord GetConsumedHeight() const;
nscoord GetConsumedBSize() const;
/**
* Retrieve the effective computed height of this frame, which is the computed
* height, minus the height consumed by any previous in-flows.
* Retrieve the effective computed block size of this frame, which is the
* computed block size, minus the block size consumed by any previous in-flows.
*/
nscoord GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowState,
nscoord aConsumed = NS_INTRINSICSIZE) const;
nscoord GetEffectiveComputedBSize(const nsHTMLReflowState& aReflowState,
nscoord aConsumed = NS_INTRINSICSIZE) const;
/**
* @see nsIFrame::GetLogicalSkipSides()

View File

@ -2837,7 +2837,8 @@ nsTableFrame::PlaceRepeatedFooter(nsTableReflowState& aReflowState,
kidAvailSize.height = aFooterHeight;
nsHTMLReflowState footerReflowState(presContext,
aReflowState.reflowState,
aTfoot, kidAvailSize,
aTfoot,
kidAvailSize,
-1, -1,
nsHTMLReflowState::CALLER_WILL_INIT);
InitChildReflowState(footerReflowState);