Added a hack to only do incremental painting for the block whish is reflowing the html BODY; improved trace msgs; added code to collapse into nothingness empty blocks

This commit is contained in:
kipp 1998-06-04 17:49:15 +00:00
Родитель 0a142c521a
Коммит b3a0265470
6 изменённых файлов: 378 добавлений и 264 удалений

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }

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

@ -148,6 +148,7 @@ nsBlockReflowState::Initialize(nsIPresContext* aPresContext,
mPrevPosBottomMargin = 0; mPrevPosBottomMargin = 0;
mPrevNegBottomMargin = 0; mPrevNegBottomMargin = 0;
mPrevMarginSynthetic = PR_FALSE;
mNextListOrdinal = -1; mNextListOrdinal = -1;
@ -672,21 +673,27 @@ nsBlockFrame::PlaceLine(nsBlockReflowState& aState,
// optimization cannot be done because this may be a nested block // optimization cannot be done because this may be a nested block
// that will be pushed to a new page by the containing block and the // that will be pushed to a new page by the containing block and the
// nested block can't know that during its reflow. // nested block can't know that during its reflow.
// XXX and actually, this only always works for the block which is a
// child of the body.
if (!aState.mPresContext->IsPaginated()) { if (!aState.mPresContext->IsPaginated()) {
nsIFrame* child = aLine->mFirstChild; nsIAtom* tag = mContent->GetTag();
for (PRInt32 i = aLine->mChildCount; --i >= 0; ) { if (nsHTMLAtoms::body == tag) {
nsFrameState state; nsIFrame* child = aLine->mFirstChild;
child->GetFrameState(state); for (PRInt32 i = aLine->mChildCount; --i >= 0; ) {
if (NS_FRAME_IN_REFLOW & state) { nsFrameState state;
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED); child->GetFrameState(state);
if (NS_FRAME_IN_REFLOW & state) {
child->DidReflow(*aState.mPresContext, NS_FRAME_REFLOW_FINISHED);
}
child->GetNextSibling(child);
} }
child->GetNextSibling(child);
}
// Paint this portion of ourselves // Paint this portion of ourselves
if (!aLine->mBounds.IsEmpty()) { if (!aLine->mBounds.IsEmpty()) {
Invalidate(aLine->mBounds); Invalidate(aLine->mBounds);
}
} }
NS_IF_RELEASE(tag);
} }
// Consume space and advance running values // Consume space and advance running values
@ -1435,7 +1442,9 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext,
PostReflowCheck(aStatus); PostReflowCheck(aStatus);
} }
#endif #endif
NS_FRAME_TRACE_REFLOW_OUT("exit nsBlockFrame::Reflow", aStatus); NS_FRAME_TRACE_MSG(
("exit nsBlockFrame::Reflow: status=%d width=%d height=%d",
aStatus, aDesiredRect.width, aDesiredRect.height));
return rv; return rv;
} }
@ -1490,42 +1499,52 @@ void nsBlockFrame::ComputeDesiredRect(nsBlockReflowState& aState,
{ {
aDesiredRect.x = 0; aDesiredRect.x = 0;
aDesiredRect.y = 0; aDesiredRect.y = 0;
aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
if (!aState.mUnconstrainedWidth) { // Special check for zero sized content: If our content is zero
// Make sure we're at least as wide as the max size we were given // sized then we collapse into nothingness.
nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left + if ((0 == aState.mKidXMost - aState.mBorderPadding.left) &&
aState.mBorderPadding.right; (0 == aState.mY - aState.mBorderPadding.top)) {
if (aDesiredRect.width < maxWidth) { aDesiredRect.width = 0;
aDesiredRect.width = maxWidth; aDesiredRect.height = 0;
}
} }
aState.mY += aState.mBorderPadding.bottom; else {
nscoord lastBottomMargin = aState.mPrevPosBottomMargin - aDesiredRect.width = aState.mKidXMost + aState.mBorderPadding.right;
aState.mPrevNegBottomMargin; if (!aState.mUnconstrainedWidth) {
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) { // Make sure we're at least as wide as the max size we were given
// It's possible that we don't have room for the last bottom nscoord maxWidth = aState.mAvailSize.width + aState.mBorderPadding.left +
// margin (the last bottom margin is the margin following a block aState.mBorderPadding.right;
// element that we contain; it isn't applied immediately because if (aDesiredRect.width < maxWidth) {
// of the margin collapsing logic). This can happen when we are aDesiredRect.width = maxWidth;
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
} }
} }
} aState.mY += aState.mBorderPadding.bottom;
aState.mY += lastBottomMargin; nscoord lastBottomMargin = aState.mPrevPosBottomMargin -
aDesiredRect.height = aState.mY; aState.mPrevNegBottomMargin;
if (!aState.mUnconstrainedHeight && (lastBottomMargin > 0)) {
// It's possible that we don't have room for the last bottom
// margin (the last bottom margin is the margin following a block
// element that we contain; it isn't applied immediately because
// of the margin collapsing logic). This can happen when we are
// reflowed in a limited amount of space because we don't know in
// advance what the last bottom margin will be.
nscoord maxY = aMaxSize.height;
if (aState.mY + lastBottomMargin > maxY) {
lastBottomMargin = maxY - aState.mY;
if (lastBottomMargin < 0) {
lastBottomMargin = 0;
}
}
}
aState.mY += lastBottomMargin;
aDesiredRect.height = aState.mY;
if (!aState.mBlockIsPseudo) { if (!aState.mBlockIsPseudo) {
// Clamp the desired rect height when style height applies // Clamp the desired rect height when style height applies
PRIntn ss = aState.mStyleSizeFlags; PRIntn ss = aState.mStyleSizeFlags;
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) { if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
aDesiredRect.height = aState.mBorderPadding.top + aDesiredRect.height = aState.mBorderPadding.top +
aState.mStyleSize.height + aState.mBorderPadding.bottom; aState.mStyleSize.height + aState.mBorderPadding.bottom;
}
} }
} }
} }