From cc468b71ceeda331ac4c6cec939d049ffffe0525 Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Sat, 28 Feb 2004 02:55:58 +0000 Subject: [PATCH] Bug 235778. Overflow area of relatively positioned inlines must be preserved by line layout. r+sr=dbaron git-svn-id: svn://10.0.0.236/trunk@153351 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/layout/generic/nsInlineFrame.cpp | 8 --- mozilla/layout/generic/nsLineLayout.cpp | 66 +++++++------------ .../layout/html/base/src/nsInlineFrame.cpp | 8 --- mozilla/layout/html/base/src/nsLineLayout.cpp | 66 +++++++------------ 4 files changed, 46 insertions(+), 102 deletions(-) diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index 466ed61d808..572024374b9 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -1251,9 +1251,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, reflowState.path = nsnull; rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus); - // XXX Although this seems like the correct thing to do the line layout - // code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored -#if 0 // Factor the absolutely positioned child bounds into the overflow area nsRect childBounds; mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); @@ -1268,7 +1265,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, } else { mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } -#endif return rv; } } @@ -1298,9 +1294,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, containingBlockWidth, containingBlockHeight, &childBounds); - // XXX Although this seems like the correct thing to do the line layout - // code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored -#if 0 // Factor the absolutely positioned child bounds into the overflow area aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); @@ -1313,7 +1306,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, } else { mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } -#endif } return rv; diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index 7c56b9a8b77..ad75caf7d04 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -2988,33 +2988,30 @@ nsLineLayout::RelativePositionFrames(nsRect& aCombinedArea) void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) { - nsRect spanCombinedArea; - PerFrameData* pfd; - - nscoord minX, minY, maxX, maxY; + nsRect combinedAreaResult; if (nsnull != psd->mFrame) { // The minimum combined area for the frames in a span covers the - // entire span frame. - pfd = psd->mFrame; - minX = 0; - minY = 0; - maxX = pfd->mBounds.width; - maxY = pfd->mBounds.height; + // entire span frame's overflow area. The span frame might have + // overflowing additional non-inline frames (e.g. absolute children + // of a relatively positioned span) and we need to make sure their + // overflow area, if any, makes it into our final combined area. + combinedAreaResult = psd->mFrame->mCombinedArea; } else { // The minimum combined area for the frames that are direct // children of the block starts at the upper left corner of the // line and is sized to match the size of the line's bounding box // (the same size as the values returned from VerticalAlignFrames) - minX = psd->mLeftEdge; - maxX = psd->mX; - minY = mTopEdge; - maxY = mTopEdge + mFinalLineHeight; + combinedAreaResult.x = psd->mLeftEdge; + // If this turns out to be negative, the rect will be treated as empty. + // Which is just fine. + combinedAreaResult.width = psd->mX - combinedAreaResult.x; + combinedAreaResult.y = mTopEdge; + combinedAreaResult.height = mFinalLineHeight; } - for (pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { - nscoord x = pfd->mBounds.x; - nscoord y = pfd->mBounds.y; + for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { + nsPoint origin = nsPoint(pfd->mBounds.x, pfd->mBounds.y); nsIFrame* frame = pfd->mFrame; // Adjust the origin of the frame @@ -3023,8 +3020,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) // nsHTMLReflowState::ComputeRelativeOffsets nsPoint change(pfd->mOffsets.left, pfd->mOffsets.top); frame->SetPosition(frame->GetPosition() + change); - x += change.x; - y += change.y; + origin += change; } // We must position the view correctly before positioning its @@ -3040,6 +3036,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) // system. We adjust the childs combined area into our coordinate // system before computing the aggregated value by adding in // x and y which were computed above. + nsRect spanCombinedArea; nsRect* r = &pfd->mCombinedArea; if (pfd->mSpan) { // Compute a new combined area for the child span before @@ -3065,36 +3062,19 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) frame->GetView(), r, NS_FRAME_NO_MOVE_VIEW); - nscoord xl = x + r->x; - if (xl < minX) { - minX = xl; - } - nscoord xr = x + r->XMost(); - if (xr > maxX) { - maxX = xr; - } - nscoord yt = y + r->y; - if (yt < minY) { - minY = yt; - } - nscoord yb = y + r->YMost(); - if (yb > maxY) { - maxY = yb; - } + combinedAreaResult.UnionRect(combinedAreaResult, *r + origin); } - aCombinedArea.x = minX; - aCombinedArea.y = minY; - aCombinedArea.width = maxX - minX; - aCombinedArea.height = maxY - minY; + aCombinedArea = combinedAreaResult; // If we just computed a spans combined area, we need to update its // NS_FRAME_OUTSIDE_CHILDREN bit.. if (psd->mFrame) { - pfd = psd->mFrame; - nsIFrame* frame = pfd->mFrame; - if ((minX < 0) || (minY < 0) || - (maxX > pfd->mBounds.width) || (maxY > pfd->mBounds.height)) { + PerFrameData* spanPFD = psd->mFrame; + nsIFrame* frame = spanPFD->mFrame; + if ((combinedAreaResult.x < 0) || (combinedAreaResult.y < 0) || + (combinedAreaResult.XMost() > spanPFD->mBounds.width) || + (combinedAreaResult.YMost() > spanPFD->mBounds.height)) { frame->AddStateBits(NS_FRAME_OUTSIDE_CHILDREN); } else { frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN); diff --git a/mozilla/layout/html/base/src/nsInlineFrame.cpp b/mozilla/layout/html/base/src/nsInlineFrame.cpp index 466ed61d808..572024374b9 100644 --- a/mozilla/layout/html/base/src/nsInlineFrame.cpp +++ b/mozilla/layout/html/base/src/nsInlineFrame.cpp @@ -1251,9 +1251,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, reflowState.path = nsnull; rv = nsInlineFrame::Reflow(aPresContext, aDesiredSize, reflowState, aStatus); - // XXX Although this seems like the correct thing to do the line layout - // code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored -#if 0 // Factor the absolutely positioned child bounds into the overflow area nsRect childBounds; mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); @@ -1268,7 +1265,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, } else { mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } -#endif return rv; } } @@ -1298,9 +1294,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, containingBlockWidth, containingBlockHeight, &childBounds); - // XXX Although this seems like the correct thing to do the line layout - // code seems to reset the NS_FRAME_OUTSIDE_CHILDREN and so it is ignored -#if 0 // Factor the absolutely positioned child bounds into the overflow area aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); @@ -1313,7 +1306,6 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, } else { mState &= ~NS_FRAME_OUTSIDE_CHILDREN; } -#endif } return rv; diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index 7c56b9a8b77..ad75caf7d04 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -2988,33 +2988,30 @@ nsLineLayout::RelativePositionFrames(nsRect& aCombinedArea) void nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) { - nsRect spanCombinedArea; - PerFrameData* pfd; - - nscoord minX, minY, maxX, maxY; + nsRect combinedAreaResult; if (nsnull != psd->mFrame) { // The minimum combined area for the frames in a span covers the - // entire span frame. - pfd = psd->mFrame; - minX = 0; - minY = 0; - maxX = pfd->mBounds.width; - maxY = pfd->mBounds.height; + // entire span frame's overflow area. The span frame might have + // overflowing additional non-inline frames (e.g. absolute children + // of a relatively positioned span) and we need to make sure their + // overflow area, if any, makes it into our final combined area. + combinedAreaResult = psd->mFrame->mCombinedArea; } else { // The minimum combined area for the frames that are direct // children of the block starts at the upper left corner of the // line and is sized to match the size of the line's bounding box // (the same size as the values returned from VerticalAlignFrames) - minX = psd->mLeftEdge; - maxX = psd->mX; - minY = mTopEdge; - maxY = mTopEdge + mFinalLineHeight; + combinedAreaResult.x = psd->mLeftEdge; + // If this turns out to be negative, the rect will be treated as empty. + // Which is just fine. + combinedAreaResult.width = psd->mX - combinedAreaResult.x; + combinedAreaResult.y = mTopEdge; + combinedAreaResult.height = mFinalLineHeight; } - for (pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { - nscoord x = pfd->mBounds.x; - nscoord y = pfd->mBounds.y; + for (PerFrameData* pfd = psd->mFirstFrame; pfd; pfd = pfd->mNext) { + nsPoint origin = nsPoint(pfd->mBounds.x, pfd->mBounds.y); nsIFrame* frame = pfd->mFrame; // Adjust the origin of the frame @@ -3023,8 +3020,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) // nsHTMLReflowState::ComputeRelativeOffsets nsPoint change(pfd->mOffsets.left, pfd->mOffsets.top); frame->SetPosition(frame->GetPosition() + change); - x += change.x; - y += change.y; + origin += change; } // We must position the view correctly before positioning its @@ -3040,6 +3036,7 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) // system. We adjust the childs combined area into our coordinate // system before computing the aggregated value by adding in // x and y which were computed above. + nsRect spanCombinedArea; nsRect* r = &pfd->mCombinedArea; if (pfd->mSpan) { // Compute a new combined area for the child span before @@ -3065,36 +3062,19 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) frame->GetView(), r, NS_FRAME_NO_MOVE_VIEW); - nscoord xl = x + r->x; - if (xl < minX) { - minX = xl; - } - nscoord xr = x + r->XMost(); - if (xr > maxX) { - maxX = xr; - } - nscoord yt = y + r->y; - if (yt < minY) { - minY = yt; - } - nscoord yb = y + r->YMost(); - if (yb > maxY) { - maxY = yb; - } + combinedAreaResult.UnionRect(combinedAreaResult, *r + origin); } - aCombinedArea.x = minX; - aCombinedArea.y = minY; - aCombinedArea.width = maxX - minX; - aCombinedArea.height = maxY - minY; + aCombinedArea = combinedAreaResult; // If we just computed a spans combined area, we need to update its // NS_FRAME_OUTSIDE_CHILDREN bit.. if (psd->mFrame) { - pfd = psd->mFrame; - nsIFrame* frame = pfd->mFrame; - if ((minX < 0) || (minY < 0) || - (maxX > pfd->mBounds.width) || (maxY > pfd->mBounds.height)) { + PerFrameData* spanPFD = psd->mFrame; + nsIFrame* frame = spanPFD->mFrame; + if ((combinedAreaResult.x < 0) || (combinedAreaResult.y < 0) || + (combinedAreaResult.XMost() > spanPFD->mBounds.width) || + (combinedAreaResult.YMost() > spanPFD->mBounds.height)) { frame->AddStateBits(NS_FRAME_OUTSIDE_CHILDREN); } else { frame->RemoveStateBits(NS_FRAME_OUTSIDE_CHILDREN);