Bug 743402, Part 1: Add a GetConsumedHeight() function to nsSplittableFrame in order to retrieve the portion of the computed height that was consumed by previous-in-flows. [r=roc]

This commit is contained in:
Scott Johnson 2013-07-24 12:47:01 -05:00
Родитель cd2bb4a561
Коммит 528cb9f1bf
5 изменённых файлов: 61 добавлений и 5 удалений

Просмотреть файл

@ -35,7 +35,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
nsBlockFrame* aFrame, nsBlockFrame* aFrame,
bool aTopMarginRoot, bool aTopMarginRoot,
bool aBottomMarginRoot, bool aBottomMarginRoot,
bool aBlockNeedsFloatManager) bool aBlockNeedsFloatManager,
nscoord aConsumedHeight)
: mBlock(aFrame), : mBlock(aFrame),
mPresContext(aPresContext), mPresContext(aPresContext),
mReflowState(aReflowState), mReflowState(aReflowState),
@ -44,7 +45,8 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mPrevBottomMargin(), mPrevBottomMargin(),
mLineNumber(0), mLineNumber(0),
mFlags(0), mFlags(0),
mFloatBreakType(NS_STYLE_CLEAR_NONE) mFloatBreakType(NS_STYLE_CLEAR_NONE),
mConsumedHeight(aConsumedHeight)
{ {
SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nullptr); SetFlag(BRS_ISFIRSTINFLOW, aFrame->GetPrevInFlow() == nullptr);
SetFlag(BRS_ISOVERFLOWCONTAINER, SetFlag(BRS_ISOVERFLOWCONTAINER,
@ -113,6 +115,16 @@ nsBlockReflowState::nsBlockReflowState(const nsHTMLReflowState& aReflowState,
mMinLineHeight = aReflowState.CalcLineHeight(); mMinLineHeight = aReflowState.CalcLineHeight();
} }
nscoord
nsBlockReflowState::GetConsumedHeight()
{
if (mConsumedHeight == NS_INTRINSICSIZE) {
mConsumedHeight = mBlock->GetConsumedHeight();
}
return mConsumedHeight;
}
void void
nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame, nsBlockReflowState::ComputeReplacedBlockOffsetsForFloats(nsIFrame* aFrame,
const nsRect& aFloatAvailableSpace, const nsRect& aFloatAvailableSpace,

Просмотреть файл

@ -40,7 +40,8 @@ public:
nsPresContext* aPresContext, nsPresContext* aPresContext,
nsBlockFrame* aFrame, nsBlockFrame* aFrame,
bool aTopMarginRoot, bool aBottomMarginRoot, bool aTopMarginRoot, bool aBottomMarginRoot,
bool aBlockNeedsFloatManager); bool aBlockNeedsFloatManager,
nscoord aConsumedHeight = NS_INTRINSICSIZE);
/** /**
* Get the available reflow space (the area not occupied by floats) * Get the available reflow space (the area not occupied by floats)
@ -110,6 +111,11 @@ public:
return result; return result;
} }
/**
* Retrieve the height "consumed" by any previous-in-flows.
*/
nscoord GetConsumedHeight();
// Reconstruct the previous bottom margin that goes above |aLine|. // Reconstruct the previous bottom margin that goes above |aLine|.
void ReconstructMarginAbove(nsLineList::iterator aLine); void ReconstructMarginAbove(nsLineList::iterator aLine);
@ -257,6 +263,9 @@ public:
uint8_t mFloatBreakType; uint8_t mFloatBreakType;
// The amount of computed height "consumed" by previous-in-flows.
nscoord mConsumedHeight;
void SetFlag(uint32_t aFlag, bool aValue) void SetFlag(uint32_t aFlag, bool aValue)
{ {
NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag"); NS_ASSERTION(aFlag<=BRS_LASTFLAG, "bad flag");

Просмотреть файл

@ -480,15 +480,28 @@ public:
} }
return std::max(aWidth, mComputedMinWidth); return std::max(aWidth, mComputedMinWidth);
} }
/** /**
* Apply the mComputed(Min/Max)Height constraints to the content * Apply the mComputed(Min/Max)Height constraints to the content
* size computed so far. * size computed so far.
*
* @param aHeight The height that we've computed an to which we want to apply
* min/max constraints.
* @param aConsumed The amount of the computed height that was consumed by
* our prev-in-flows.
*/ */
nscoord ApplyMinMaxHeight(nscoord aHeight) const { nscoord ApplyMinMaxHeight(nscoord aHeight, nscoord aConsumed = 0) const {
aHeight += aConsumed;
if (NS_UNCONSTRAINEDSIZE != mComputedMaxHeight) { if (NS_UNCONSTRAINEDSIZE != mComputedMaxHeight) {
aHeight = std::min(aHeight, mComputedMaxHeight); aHeight = std::min(aHeight, mComputedMaxHeight);
} }
return std::max(aHeight, mComputedMinHeight);
if (NS_UNCONSTRAINEDSIZE != mComputedMinHeight) {
aHeight = std::max(aHeight, mComputedMinHeight);
}
return aHeight - aConsumed;
} }
bool ShouldReflowAllKids() const { bool ShouldReflowAllKids() const {

Просмотреть файл

@ -203,6 +203,19 @@ nsSplittableFrame::RemoveFromFlow(nsIFrame* aFrame)
aFrame->SetNextInFlow(nullptr); aFrame->SetNextInFlow(nullptr);
} }
nscoord
nsSplittableFrame::GetConsumedHeight() const
{
nscoord height = 0;
// Reduce the height by the computed height of prev-in-flows.
for (nsIFrame* prev = GetPrevInFlow(); prev; prev = prev->GetPrevInFlow()) {
height += prev->GetRect().height;
}
return height;
}
#ifdef DEBUG #ifdef DEBUG
void void
nsSplittableFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) nsSplittableFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent)

Просмотреть файл

@ -76,6 +76,15 @@ public:
protected: protected:
nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {} nsSplittableFrame(nsStyleContext* aContext) : nsFrame(aContext) {}
/**
* Determine the height consumed by our previous-in-flows.
*
* @note (bz) This makes laying out a splittable frame with N in-flows
* O(N^2)! So, use this function with caution and minimize the number
* of calls to this method.
*/
nscoord GetConsumedHeight() const;
#ifdef DEBUG #ifdef DEBUG
virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE; virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE;
#endif #endif