Bug 743402, Part 3: Refactor nsBlockFrame to utilize new calculations for paginated content. [r=roc]

This commit is contained in:
Scott Johnson 2013-07-25 10:34:22 -05:00
Родитель b806b3e3c9
Коммит 97549e0acc
3 изменённых файлов: 88 добавлений и 44 удалений

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

@ -1338,48 +1338,13 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
bottomEdgeOfChildren = std::max(bottomEdgeOfChildren, floatHeight);
}
// Compute final height
if (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()) {
// Figure out how much of the computed height should be
// applied to this frame.
nscoord computedHeightLeftOver = GetEffectiveComputedHeight(aReflowState);
NS_ASSERTION(!( IS_TRUE_OVERFLOW_CONTAINER(this)
&& computedHeightLeftOver ),
"overflow container must not have computedHeightLeftOver");
aMetrics.height =
NSCoordSaturatingAdd(NSCoordSaturatingAdd(borderPadding.top,
computedHeightLeftOver),
borderPadding.bottom);
if (NS_FRAME_IS_NOT_COMPLETE(aState.mReflowStatus)
&& aMetrics.height < aReflowState.availableHeight) {
// We ran out of height on this page but we're incomplete
// Set status to complete except for overflow
NS_FRAME_SET_OVERFLOW_INCOMPLETE(aState.mReflowStatus);
}
if (NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
if (computedHeightLeftOver > 0 &&
NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight &&
aMetrics.height > aReflowState.availableHeight) {
if (ShouldAvoidBreakInside(aReflowState)) {
aState.mReflowStatus = NS_INLINE_LINE_BREAK_BEFORE();
return;
}
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aMetrics.height = std::max(aReflowState.availableHeight,
aState.mY + nonCarriedOutVerticalMargin);
NS_FRAME_SET_INCOMPLETE(aState.mReflowStatus);
if (!GetNextInFlow())
aState.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
}
else {
if (NS_UNCONSTRAINEDSIZE != aReflowState.ComputedHeight()
&& (mParent->GetType() != nsGkAtoms::columnSetFrame ||
aReflowState.parentReflowState->availableHeight == NS_UNCONSTRAINEDSIZE)) {
ComputeFinalHeight(aReflowState, &aState.mReflowStatus,
aState.mY + nonCarriedOutVerticalMargin,
borderPadding, aMetrics, aState.mConsumedHeight);
if (!NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
// Use the current height; continuations will take up the rest.
// Do extend the height to at least consume the available
// height, otherwise our left/right borders (for example) won't
@ -1387,8 +1352,10 @@ nsBlockFrame::ComputeFinalSize(const nsHTMLReflowState& aReflowState,
aMetrics.height = std::max(aReflowState.availableHeight,
aState.mY + nonCarriedOutVerticalMargin);
// ... but don't take up more height than is available
nscoord effectiveComputedHeight =
GetEffectiveComputedHeight(aReflowState, aState.GetConsumedHeight());
aMetrics.height = std::min(aMetrics.height,
borderPadding.top + computedHeightLeftOver);
borderPadding.top + effectiveComputedHeight);
// XXX It's pretty wrong that our bottom border still gets drawn on
// on its own on the last-in-flow, even if we ran out of height
// here. We need GetSkipSides to check whether we ran out of content
@ -7085,6 +7052,57 @@ nsBlockFrame::GetNearestAncestorBlock(nsIFrame* aCandidate)
return nullptr;
}
void
nsBlockFrame::ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentHeight,
const nsMargin& aBorderPadding,
nsHTMLReflowMetrics& aMetrics,
nscoord aConsumed)
{
// Figure out how much of the computed height should be
// applied to this frame.
nscoord computedHeightLeftOver = GetEffectiveComputedHeight(aReflowState,
aConsumed);
NS_ASSERTION(!( IS_TRUE_OVERFLOW_CONTAINER(this)
&& computedHeightLeftOver ),
"overflow container must not have computedHeightLeftOver");
aMetrics.height =
NSCoordSaturatingAdd(NSCoordSaturatingAdd(aBorderPadding.top,
computedHeightLeftOver),
aBorderPadding.bottom);
if (NS_FRAME_IS_NOT_COMPLETE(*aStatus)
&& aMetrics.height < aReflowState.availableHeight) {
// We ran out of height on this page but we're incomplete
// Set status to complete except for overflow
NS_FRAME_SET_OVERFLOW_INCOMPLETE(*aStatus);
}
if (NS_FRAME_IS_COMPLETE(*aStatus)) {
if (computedHeightLeftOver > 0 &&
NS_UNCONSTRAINEDSIZE != aReflowState.availableHeight &&
aMetrics.height > aReflowState.availableHeight) {
if (ShouldAvoidBreakInside(aReflowState)) {
*aStatus = NS_INLINE_LINE_BREAK_BEFORE();
return;
}
// We don't fit and we consumed some of the computed height,
// so we should consume all the available height and then
// break. If our bottom border/padding straddles the break
// point, then this will increase our height and push the
// border/padding to the next page/column.
aMetrics.height = std::max(aReflowState.availableHeight,
aContentHeight);
NS_FRAME_SET_INCOMPLETE(*aStatus);
if (!GetNextInFlow())
*aStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
}
}
}
#ifdef IBMBIDI
nsresult
nsBlockFrame::ResolveBidi()

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

@ -263,6 +263,32 @@ public:
virtual nsRect ComputeTightBounds(gfxContext* aContext) const;
/**
* Compute the final height 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 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.
*/
void ComputeFinalHeight(const nsHTMLReflowState& aReflowState,
nsReflowStatus* aStatus,
nscoord aContentHeight,
const nsMargin& aBorderPadding,
nsHTMLReflowMetrics& aMetrics,
nscoord aConsumed);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,

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

@ -232,7 +232,7 @@ nsSplittableFrame::GetEffectiveComputedHeight(const nsHTMLReflowState& aReflowSt
height -= aConsumedHeight;
if (aConsumedHeight != NS_INTRINSICSIZE) {
if (aConsumedHeight != 0 && aConsumedHeight != NS_INTRINSICSIZE) {
// We just subtracted our top-border padding, since it was included in the
// first frame's height. Add it back to get the content height.
height += aReflowState.mComputedBorderPadding.top;