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
parent 3f7c5e08b7
commit a156823e7f
5 changed files with 61 additions and 5 deletions

View File

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

View File

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

View File

@ -480,15 +480,28 @@ public:
}
return std::max(aWidth, mComputedMinWidth);
}
/**
* Apply the mComputed(Min/Max)Height constraints to the content
* 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) {
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 {

View File

@ -203,6 +203,19 @@ nsSplittableFrame::RemoveFromFlow(nsIFrame* aFrame)
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
void
nsSplittableFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent)

View File

@ -76,6 +76,15 @@ public:
protected:
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
virtual void DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, int32_t aIndent) MOZ_OVERRIDE;
#endif