diff --git a/mozilla/content/base/src/nsStyleContext.cpp b/mozilla/content/base/src/nsStyleContext.cpp index 687fd51fa1a..2d87c4fbec0 100644 --- a/mozilla/content/base/src/nsStyleContext.cpp +++ b/mozilla/content/base/src/nsStyleContext.cpp @@ -455,6 +455,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther) DO_STRUCT_DIFFERENCE(Content); DO_STRUCT_DIFFERENCE(UserInterface); DO_STRUCT_DIFFERENCE(Visibility); + DO_STRUCT_DIFFERENCE(Outline); #ifdef MOZ_SVG DO_STRUCT_DIFFERENCE(SVG); #endif @@ -489,7 +490,6 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther) // UIReset DO_STRUCT_DIFFERENCE(Color); DO_STRUCT_DIFFERENCE(Background); - DO_STRUCT_DIFFERENCE(Outline); DO_STRUCT_DIFFERENCE(UIReset); #undef DO_STRUCT_DIFFERENCE diff --git a/mozilla/content/shared/src/nsStyleStruct.cpp b/mozilla/content/shared/src/nsStyleStruct.cpp index 424ad899f6e..72df5dcf81b 100644 --- a/mozilla/content/shared/src/nsStyleStruct.cpp +++ b/mozilla/content/shared/src/nsStyleStruct.cpp @@ -640,11 +640,18 @@ nsStyleOutline::RecalcData(void) nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const { - if ((mOutlineWidth != aOther.mOutlineWidth) || - (mOutlineStyle != aOther.mOutlineStyle) || + PRBool outlineWasVisible = + mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE; + PRBool outlineIsVisible = + aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE; + if (outlineWasVisible != outlineIsVisible || + mOutlineWidth != aOther.mOutlineWidth) { + return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame); + } + if ((mOutlineStyle != aOther.mOutlineStyle) || (mOutlineColor != aOther.mOutlineColor) || (mOutlineRadius != aOther.mOutlineRadius)) { - return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816 + return nsChangeHint_RepaintFrame; } return NS_STYLE_HINT_NONE; } diff --git a/mozilla/layout/base/nsCSSRendering.cpp b/mozilla/layout/base/nsCSSRendering.cpp index 7f2cb5aa1f5..571960edd3d 100644 --- a/mozilla/layout/base/nsCSSRendering.cpp +++ b/mozilla/layout/base/nsCSSRendering.cpp @@ -2093,39 +2093,17 @@ nscoord width; } } - - // This if control whether the outline paints on the inside - // or outside of the frame - // XXX This is temporary fix for nsbeta3+ Bug 48973 - // so we can use "mozoutline -#if 0 // outside nsRect inside(aBorderArea); nsRect outside(inside); - inside.Inflate(width, width); + outside.Inflate(width, width); nsRect clipRect(aBorderArea); clipRect.Inflate(width, width); // make clip extra big for now -#else // inside - nsMargin borderWidth; - aBorderStyle.GetBorder(borderWidth); - - nsRect outside(aBorderArea); - outside.Deflate(borderWidth); - nsRect inside(outside); - inside.Deflate(width, width); - - nsRect clipRect(outside); -#endif - - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace); - // rounded version of the border for(i=0;i<4;i++){ if(borderRadii[i] > 0){ PaintRoundedBorder(aPresContext,aRenderingContext,aForFrame,aDirtyRect,aBorderArea,nsnull,&aOutlineStyle,aStyleContext,aSkipSides,borderRadii,aGap,PR_TRUE); - aRenderingContext.PopState(); return; } } @@ -2137,7 +2115,6 @@ nscoord width; (outlineStyle == NS_STYLE_BORDER_STYLE_DASHED)) { DrawDashedSides(0, aRenderingContext, aDirtyRect, ourColor, nsnull, &aOutlineStyle, PR_TRUE, outside, inside, aSkipSides, aGap); - aRenderingContext.PopState(); return; } @@ -2192,8 +2169,6 @@ nscoord width; aRenderingContext.SetPenMode(nsPenMode_kNone); } } - // Restore clipping - aRenderingContext.PopState(); } /* draw the edges of the border described in aBorderEdges one segment at a time. diff --git a/mozilla/layout/base/nsPresShell.cpp b/mozilla/layout/base/nsPresShell.cpp index 5f0f1a902d3..2bd089c4b85 100644 --- a/mozilla/layout/base/nsPresShell.cpp +++ b/mozilla/layout/base/nsPresShell.cpp @@ -908,7 +908,8 @@ IncrementalReflow::Dispatch(nsIPresContext *aPresContext, first->SetSize(nsSize(aDesiredSize.width, aDesiredSize.height)); - nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), nsnull); + nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), + &aDesiredSize.mOverflowArea); first->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED); } diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index fbd38a72d6e..bba9a79a33f 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -49,6 +49,7 @@ #include "nsStyleStruct.h" #include "nsStyleContext.h" #include "nsIContent.h" +#include "nsHTMLReflowMetrics.h" /** * New rules of reflow: @@ -69,7 +70,6 @@ struct nsHTMLReflowState; class nsHTMLReflowCommand; -struct nsHTMLReflowMetrics; class nsIAtom; class nsIPresContext; @@ -1029,7 +1029,18 @@ public: * @param if nonnull, we record whether this rect is bigger than the frame's bounds * @return the rect relative to this frame's origin */ - nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull) const; + nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull, nsSize *aUseSize = nsnull) const; + + /** + * Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area + * as a frame property in the frame manager so that it can be retrieved + * later without reflowing the frame. + */ + void FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize); + + void FinishAndStoreOverflow(nsHTMLReflowMetrics* aMetrics) { + FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height)); + } /** Selection related calls */ @@ -1207,8 +1218,7 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel)) * @param aCreateIfNecessary create a new nsRect for the overflow area * @return pointer to the overflow area rectangle */ - virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary = PR_FALSE) = 0; + nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE); /** * Return PR_TRUE if and only if this frame obeys visibility:hidden. diff --git a/mozilla/layout/forms/nsFieldSetFrame.cpp b/mozilla/layout/forms/nsFieldSetFrame.cpp index bb53c50f52d..d9c8b9de2d0 100644 --- a/mozilla/layout/forms/nsFieldSetFrame.cpp +++ b/mozilla/layout/forms/nsFieldSetFrame.cpp @@ -601,7 +601,8 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext, ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mLegendFrame); if (mContentFrame) ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mContentFrame); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); + #ifdef NOISY_REFLOW printf("FIELDSET: w=%d, maxWidth=%d, MEW=%d\n", aDesiredSize.width, aDesiredSize.mMaximumWidth, diff --git a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp index b546575b812..5073cec502a 100644 --- a/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/generic/nsAbsoluteContainingBlock.cpp @@ -206,7 +206,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, // If the frame has visible overflow, then take it into account, too. if (kidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property - nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(); if (overflowArea) { // The overflow area is in the child's coordinate space, so translate @@ -237,7 +237,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext, // If the frame has visible overflow, then take it into account, too. if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property - nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = f->GetOverflowAreaProperty(); if (overflowArea) { // The overflow area is in the child's coordinate space, so translate @@ -489,7 +489,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat // the frame if (aKidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property (creating a rect struct if necessary) - nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE); + nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(PR_TRUE); NS_ASSERTION(overflowArea, "should have created rect"); if (overflowArea) { diff --git a/mozilla/layout/generic/nsBlockFrame.cpp b/mozilla/layout/generic/nsBlockFrame.cpp index 687b1300189..6265a3b1b7a 100644 --- a/mozilla/layout/generic/nsBlockFrame.cpp +++ b/mozilla/layout/generic/nsBlockFrame.cpp @@ -651,7 +651,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); return NS_OK; } @@ -911,7 +911,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Compute our final size ComputeFinalSize(aReflowState, state, aMetrics); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); // see if verifyReflow is enabled, and if so store off the space manager pointer #ifdef DEBUG @@ -967,7 +967,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Factor the absolutely positioned child bounds into the overflow area aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); } // Clear the space manager pointer in the block reflow state so we // don't waste time translating the coordinate system back on a dead diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index 486446ca466..bafd3fdd0c5 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -772,6 +772,7 @@ nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext) static void RefreshAllContentFrames(nsIFrame* aFrame, nsIContent* aContent) { if (aFrame->GetContent() == aContent) { + // XXX is this necessary? aFrame->Invalidate(aFrame->GetOutlineRect(), PR_FALSE); } @@ -2506,11 +2507,15 @@ nsIFrame::Invalidate(const nsRect& aDamageRect, } nsRect -nsIFrame::GetOutlineRect(PRBool* aAnyOutline) const +nsIFrame::GetOutlineRect(PRBool* aAnyOutline, nsSize *aUseSize) const { const nsStyleOutline* outline = GetStyleOutline(); PRUint8 outlineStyle = outline->GetOutlineStyle(); nsRect r(0, 0, mRect.width, mRect.height); + if (aUseSize) { + r.width = aUseSize->width; + r.height = aUseSize->height; + } PRBool anyOutline = PR_FALSE; if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE) { nscoord width; @@ -2550,11 +2555,6 @@ nsFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext, // invalidated) // Invalidate the entire old frame+outline if the frame has an outline - - // This assumes 'outline' is painted outside the element, as CSS2 requires. - // Currently we actually paint 'outline' inside the element so this code - // isn't strictly necessary. But we're trying to get ready to switch to - // CSS2 compliance. PRBool anyOutline; nsRect r = GetOutlineRect(&anyOutline); if (anyOutline) { @@ -4219,14 +4219,13 @@ DestroyRectFunc(nsIPresContext* aPresContext, } nsRect* -nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary) +nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) { if (!((GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) { return nsnull; } - nsFrameManager *frameManager = aPresContext->FrameManager(); + nsFrameManager *frameManager = GetPresContext()->FrameManager(); void *value = frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, @@ -4248,24 +4247,32 @@ nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext, } void -nsFrame::StoreOverflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aMetrics) -{ - if ((aMetrics.mOverflowArea.x < 0) || - (aMetrics.mOverflowArea.y < 0) || - (aMetrics.mOverflowArea.XMost() > aMetrics.width) || - (aMetrics.mOverflowArea.YMost() > aMetrics.height)) { +nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize) +{ + // This is now called FinishAndStoreOverflow() instead of + // StoreOverflow() because frame-generic ways of adding overflow + // can happen here, e.g. CSS2 outline. + // If we find more things other than outline that need to be added, + // we should think about starting a new method like GetAdditionalOverflow() + + PRBool hasOutline; + nsRect outlineRect(GetOutlineRect(&hasOutline, &aNewSize)); + + if (hasOutline || + (aOverflowArea->x < 0) || + (aOverflowArea->y < 0) || + (aOverflowArea->XMost() > aNewSize.width) || + (aOverflowArea->YMost() > aNewSize.height)) { mState |= NS_FRAME_OUTSIDE_CHILDREN; - nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE); + nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE); NS_ASSERTION(overflowArea, "should have created rect"); - if (overflowArea) { - *overflowArea = aMetrics.mOverflowArea; - } + aOverflowArea->UnionRect(outlineRect, *aOverflowArea); + *overflowArea = *aOverflowArea; } else { if (mState & NS_FRAME_OUTSIDE_CHILDREN) { // remove the previously stored overflow area - aPresContext->FrameManager()-> + GetPresContext()->FrameManager()-> RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty); } mState &= ~NS_FRAME_OUTSIDE_CHILDREN; @@ -4282,7 +4289,7 @@ nsFrame::ConsiderChildOverflow(nsIPresContext* aPresContext, // don't wrap their content into a scrollable frame if overflow is specified if (NS_STYLE_OVERFLOW_HIDDEN != disp->mOverflow && NS_STYLE_OVERFLOW_SCROLLBARS_NONE != disp->mOverflow) { - nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(); if (overflowArea) { nsRect childOverflow(*overflowArea); childOverflow.MoveBy(aChildFrame->GetPosition()); @@ -5336,7 +5343,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext, DR_state->PrettyUC(aMetrics.mOverflowArea.width, width); DR_state->PrettyUC(aMetrics.mOverflowArea.height, height); printf("o=(%s,%s) %s x %s", x, y, width, height); - nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext); + nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(); if (storedOverflow) { if (aMetrics.mOverflowArea != *storedOverflow) { DR_state->PrettyUC(storedOverflow->x, x); diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index 6b11981bc24..b4a0c1310c4 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -366,17 +366,6 @@ public: nsIFrame** aProviderFrame, PRBool* aIsChild); - // Return the previously stored overflow area, if the frame does not - // overflow and a creation is not requested it will return nsnull - virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary = PR_FALSE); - - // Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area - // as a frame property in the frame manager so that it can be retrieved - // later without reflowing the frame. - void StoreOverflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aMetrics); - // incorporate the child overflow area into the parent overflow area // if the child does not have a overflow use the child area void ConsiderChildOverflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index fbd38a72d6e..bba9a79a33f 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -49,6 +49,7 @@ #include "nsStyleStruct.h" #include "nsStyleContext.h" #include "nsIContent.h" +#include "nsHTMLReflowMetrics.h" /** * New rules of reflow: @@ -69,7 +70,6 @@ struct nsHTMLReflowState; class nsHTMLReflowCommand; -struct nsHTMLReflowMetrics; class nsIAtom; class nsIPresContext; @@ -1029,7 +1029,18 @@ public: * @param if nonnull, we record whether this rect is bigger than the frame's bounds * @return the rect relative to this frame's origin */ - nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull) const; + nsRect GetOutlineRect(PRBool* aAnyOutline = nsnull, nsSize *aUseSize = nsnull) const; + + /** + * Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area + * as a frame property in the frame manager so that it can be retrieved + * later without reflowing the frame. + */ + void FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize); + + void FinishAndStoreOverflow(nsHTMLReflowMetrics* aMetrics) { + FinishAndStoreOverflow(&aMetrics->mOverflowArea, nsSize(aMetrics->width, aMetrics->height)); + } /** Selection related calls */ @@ -1207,8 +1218,7 @@ NS_PTR_TO_INT32(frame->GetProperty(nsLayoutAtoms::embeddingLevel)) * @param aCreateIfNecessary create a new nsRect for the overflow area * @return pointer to the overflow area rectangle */ - virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary = PR_FALSE) = 0; + nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE); /** * Return PR_TRUE if and only if this frame obeys visibility:hidden. diff --git a/mozilla/layout/generic/nsImageFrame.cpp b/mozilla/layout/generic/nsImageFrame.cpp index b42615bd5dc..2dc50bf5dd6 100644 --- a/mozilla/layout/generic/nsImageFrame.cpp +++ b/mozilla/layout/generic/nsImageFrame.cpp @@ -1012,6 +1012,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext, if (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aMetrics.mMaximumWidth = aMetrics.width; } + FinishAndStoreOverflow(&aMetrics); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsImageFrame::Reflow: size=%d,%d", @@ -1331,7 +1332,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, } } else { - PRBool paintOutline = PR_FALSE; if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && imgCon) { // Render the image into our content area (the area inside // the borders and padding) @@ -1383,7 +1383,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawImage(imgCon, r, paintArea); } - paintOutline = PR_TRUE; } nsImageMap* map = GetImageMap(aPresContext); @@ -1396,18 +1395,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.Translate(inner.x, inner.y); map->Draw(aPresContext, aRenderingContext); aRenderingContext.PopState(); - paintOutline = PR_TRUE; - } - - // paint the outline in the overlay layer (or if there is an image map) until the - // general problem of painting it outside the border box is solved. - if (paintOutline) { - const nsStyleBorder* myBorder = GetStyleBorder(); - const nsStyleOutline* myOutline = GetStyleOutline(); - nsRect rect(0, 0, mRect.width, mRect.height); - nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, - *myOutline, mStyleContext, 0); } #ifdef DEBUG diff --git a/mozilla/layout/generic/nsInlineFrame.cpp b/mozilla/layout/generic/nsInlineFrame.cpp index 6fcfc68455a..a0f2c3beaee 100644 --- a/mozilla/layout/generic/nsInlineFrame.cpp +++ b/mozilla/layout/generic/nsInlineFrame.cpp @@ -1256,15 +1256,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); - // Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly - if ((aDesiredSize.mOverflowArea.x < 0) || - (aDesiredSize.mOverflowArea.y < 0) || - (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) || - (aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + FinishAndStoreOverflow(&aDesiredSize); return rv; } } @@ -1302,15 +1294,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, // Factor the absolutely positioned child bounds into the overflow area aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); - // Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly - if ((aDesiredSize.mOverflowArea.x < 0) || - (aDesiredSize.mOverflowArea.y < 0) || - (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) || - (aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + FinishAndStoreOverflow(&aDesiredSize); } return rv; diff --git a/mozilla/layout/generic/nsLineLayout.cpp b/mozilla/layout/generic/nsLineLayout.cpp index cd3a2e33b6f..c11bfd3f31c 100644 --- a/mozilla/layout/generic/nsLineLayout.cpp +++ b/mozilla/layout/generic/nsLineLayout.cpp @@ -3005,21 +3005,14 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) combinedAreaResult.UnionRect(combinedAreaResult, *r + origin); } - aCombinedArea = combinedAreaResult; - // If we just computed a spans combined area, we need to update its // NS_FRAME_OUTSIDE_CHILDREN bit.. if (psd->mFrame) { 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); - } + frame->FinishAndStoreOverflow(&combinedAreaResult, frame->GetSize()); } + aCombinedArea = combinedAreaResult; } void diff --git a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp index b546575b812..5073cec502a 100644 --- a/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp +++ b/mozilla/layout/html/base/src/nsAbsoluteContainingBlock.cpp @@ -206,7 +206,7 @@ nsAbsoluteContainingBlock::Reflow(nsIFrame* aDelegatingFrame, // If the frame has visible overflow, then take it into account, too. if (kidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property - nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = kidFrame->GetOverflowAreaProperty(); if (overflowArea) { // The overflow area is in the child's coordinate space, so translate @@ -237,7 +237,7 @@ nsAbsoluteContainingBlock::CalculateChildBounds(nsIPresContext* aPresContext, // If the frame has visible overflow, then take it into account, too. if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property - nsRect* overflowArea = f->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = f->GetOverflowAreaProperty(); if (overflowArea) { // The overflow area is in the child's coordinate space, so translate @@ -489,7 +489,7 @@ nsAbsoluteContainingBlock::ReflowAbsoluteFrame(nsIFrame* aDelegat // the frame if (aKidFrame->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { // Get the property (creating a rect struct if necessary) - nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(aPresContext, PR_TRUE); + nsRect* overflowArea = aKidFrame->GetOverflowAreaProperty(PR_TRUE); NS_ASSERTION(overflowArea, "should have created rect"); if (overflowArea) { diff --git a/mozilla/layout/html/base/src/nsBlockFrame.cpp b/mozilla/layout/html/base/src/nsBlockFrame.cpp index 687b1300189..6265a3b1b7a 100644 --- a/mozilla/layout/html/base/src/nsBlockFrame.cpp +++ b/mozilla/layout/html/base/src/nsBlockFrame.cpp @@ -651,7 +651,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); return NS_OK; } @@ -911,7 +911,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Compute our final size ComputeFinalSize(aReflowState, state, aMetrics); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); // see if verifyReflow is enabled, and if so store off the space manager pointer #ifdef DEBUG @@ -967,7 +967,7 @@ nsBlockFrame::Reflow(nsIPresContext* aPresContext, // Factor the absolutely positioned child bounds into the overflow area aMetrics.mOverflowArea.UnionRect(aMetrics.mOverflowArea, childBounds); - StoreOverflow(aPresContext, aMetrics); + FinishAndStoreOverflow(&aMetrics); } // Clear the space manager pointer in the block reflow state so we // don't waste time translating the coordinate system back on a dead diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index 486446ca466..bafd3fdd0c5 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -772,6 +772,7 @@ nsFrame::SetOverflowClipRect(nsIRenderingContext& aRenderingContext) static void RefreshAllContentFrames(nsIFrame* aFrame, nsIContent* aContent) { if (aFrame->GetContent() == aContent) { + // XXX is this necessary? aFrame->Invalidate(aFrame->GetOutlineRect(), PR_FALSE); } @@ -2506,11 +2507,15 @@ nsIFrame::Invalidate(const nsRect& aDamageRect, } nsRect -nsIFrame::GetOutlineRect(PRBool* aAnyOutline) const +nsIFrame::GetOutlineRect(PRBool* aAnyOutline, nsSize *aUseSize) const { const nsStyleOutline* outline = GetStyleOutline(); PRUint8 outlineStyle = outline->GetOutlineStyle(); nsRect r(0, 0, mRect.width, mRect.height); + if (aUseSize) { + r.width = aUseSize->width; + r.height = aUseSize->height; + } PRBool anyOutline = PR_FALSE; if (outlineStyle != NS_STYLE_BORDER_STYLE_NONE) { nscoord width; @@ -2550,11 +2555,6 @@ nsFrame::CheckInvalidateSizeChange(nsIPresContext* aPresContext, // invalidated) // Invalidate the entire old frame+outline if the frame has an outline - - // This assumes 'outline' is painted outside the element, as CSS2 requires. - // Currently we actually paint 'outline' inside the element so this code - // isn't strictly necessary. But we're trying to get ready to switch to - // CSS2 compliance. PRBool anyOutline; nsRect r = GetOutlineRect(&anyOutline); if (anyOutline) { @@ -4219,14 +4219,13 @@ DestroyRectFunc(nsIPresContext* aPresContext, } nsRect* -nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary) +nsIFrame::GetOverflowAreaProperty(PRBool aCreateIfNecessary) { if (!((GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) || aCreateIfNecessary)) { return nsnull; } - nsFrameManager *frameManager = aPresContext->FrameManager(); + nsFrameManager *frameManager = GetPresContext()->FrameManager(); void *value = frameManager->GetFrameProperty(this, nsLayoutAtoms::overflowAreaProperty, @@ -4248,24 +4247,32 @@ nsFrame::GetOverflowAreaProperty(nsIPresContext* aPresContext, } void -nsFrame::StoreOverflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aMetrics) -{ - if ((aMetrics.mOverflowArea.x < 0) || - (aMetrics.mOverflowArea.y < 0) || - (aMetrics.mOverflowArea.XMost() > aMetrics.width) || - (aMetrics.mOverflowArea.YMost() > aMetrics.height)) { +nsIFrame::FinishAndStoreOverflow(nsRect* aOverflowArea, nsSize aNewSize) +{ + // This is now called FinishAndStoreOverflow() instead of + // StoreOverflow() because frame-generic ways of adding overflow + // can happen here, e.g. CSS2 outline. + // If we find more things other than outline that need to be added, + // we should think about starting a new method like GetAdditionalOverflow() + + PRBool hasOutline; + nsRect outlineRect(GetOutlineRect(&hasOutline, &aNewSize)); + + if (hasOutline || + (aOverflowArea->x < 0) || + (aOverflowArea->y < 0) || + (aOverflowArea->XMost() > aNewSize.width) || + (aOverflowArea->YMost() > aNewSize.height)) { mState |= NS_FRAME_OUTSIDE_CHILDREN; - nsRect* overflowArea = GetOverflowAreaProperty(aPresContext, PR_TRUE); + nsRect* overflowArea = GetOverflowAreaProperty(PR_TRUE); NS_ASSERTION(overflowArea, "should have created rect"); - if (overflowArea) { - *overflowArea = aMetrics.mOverflowArea; - } + aOverflowArea->UnionRect(outlineRect, *aOverflowArea); + *overflowArea = *aOverflowArea; } else { if (mState & NS_FRAME_OUTSIDE_CHILDREN) { // remove the previously stored overflow area - aPresContext->FrameManager()-> + GetPresContext()->FrameManager()-> RemoveFrameProperty(this, nsLayoutAtoms::overflowAreaProperty); } mState &= ~NS_FRAME_OUTSIDE_CHILDREN; @@ -4282,7 +4289,7 @@ nsFrame::ConsiderChildOverflow(nsIPresContext* aPresContext, // don't wrap their content into a scrollable frame if overflow is specified if (NS_STYLE_OVERFLOW_HIDDEN != disp->mOverflow && NS_STYLE_OVERFLOW_SCROLLBARS_NONE != disp->mOverflow) { - nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = aChildFrame->GetOverflowAreaProperty(); if (overflowArea) { nsRect childOverflow(*overflowArea); childOverflow.MoveBy(aChildFrame->GetPosition()); @@ -5336,7 +5343,7 @@ void nsFrame::DisplayReflowExit(nsIPresContext* aPresContext, DR_state->PrettyUC(aMetrics.mOverflowArea.width, width); DR_state->PrettyUC(aMetrics.mOverflowArea.height, height); printf("o=(%s,%s) %s x %s", x, y, width, height); - nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(aPresContext); + nsRect* storedOverflow = aFrame->GetOverflowAreaProperty(); if (storedOverflow) { if (aMetrics.mOverflowArea != *storedOverflow) { DR_state->PrettyUC(storedOverflow->x, x); diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index 6b11981bc24..b4a0c1310c4 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -366,17 +366,6 @@ public: nsIFrame** aProviderFrame, PRBool* aIsChild); - // Return the previously stored overflow area, if the frame does not - // overflow and a creation is not requested it will return nsnull - virtual nsRect* GetOverflowAreaProperty(nsIPresContext* aPresContext, - PRBool aCreateIfNecessary = PR_FALSE); - - // Set/unset the NS_FRAME_OUTSIDE_CHILDREN flag and store the overflow area - // as a frame property in the frame manager so that it can be retrieved - // later without reflowing the frame. - void StoreOverflow(nsIPresContext* aPresContext, - nsHTMLReflowMetrics& aMetrics); - // incorporate the child overflow area into the parent overflow area // if the child does not have a overflow use the child area void ConsiderChildOverflow(nsIPresContext* aPresContext, diff --git a/mozilla/layout/html/base/src/nsImageFrame.cpp b/mozilla/layout/html/base/src/nsImageFrame.cpp index b42615bd5dc..2dc50bf5dd6 100644 --- a/mozilla/layout/html/base/src/nsImageFrame.cpp +++ b/mozilla/layout/html/base/src/nsImageFrame.cpp @@ -1012,6 +1012,7 @@ nsImageFrame::Reflow(nsIPresContext* aPresContext, if (aMetrics.mFlags & NS_REFLOW_CALC_MAX_WIDTH) { aMetrics.mMaximumWidth = aMetrics.width; } + FinishAndStoreOverflow(&aMetrics); NS_FRAME_TRACE(NS_FRAME_TRACE_CALLS, ("exit nsImageFrame::Reflow: size=%d,%d", @@ -1331,7 +1332,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, } } else { - PRBool paintOutline = PR_FALSE; if (NS_FRAME_PAINT_LAYER_FOREGROUND == aWhichLayer && imgCon) { // Render the image into our content area (the area inside // the borders and padding) @@ -1383,7 +1383,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawImage(imgCon, r, paintArea); } - paintOutline = PR_TRUE; } nsImageMap* map = GetImageMap(aPresContext); @@ -1396,18 +1395,6 @@ nsImageFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.Translate(inner.x, inner.y); map->Draw(aPresContext, aRenderingContext); aRenderingContext.PopState(); - paintOutline = PR_TRUE; - } - - // paint the outline in the overlay layer (or if there is an image map) until the - // general problem of painting it outside the border box is solved. - if (paintOutline) { - const nsStyleBorder* myBorder = GetStyleBorder(); - const nsStyleOutline* myOutline = GetStyleOutline(); - nsRect rect(0, 0, mRect.width, mRect.height); - nsCSSRendering::PaintOutline(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, - *myOutline, mStyleContext, 0); } #ifdef DEBUG diff --git a/mozilla/layout/html/base/src/nsInlineFrame.cpp b/mozilla/layout/html/base/src/nsInlineFrame.cpp index 6fcfc68455a..a0f2c3beaee 100644 --- a/mozilla/layout/html/base/src/nsInlineFrame.cpp +++ b/mozilla/layout/html/base/src/nsInlineFrame.cpp @@ -1256,15 +1256,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, mAbsoluteContainer.CalculateChildBounds(aPresContext, childBounds); aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); - // Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly - if ((aDesiredSize.mOverflowArea.x < 0) || - (aDesiredSize.mOverflowArea.y < 0) || - (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) || - (aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + FinishAndStoreOverflow(&aDesiredSize); return rv; } } @@ -1302,15 +1294,7 @@ nsPositionedInlineFrame::Reflow(nsIPresContext* aPresContext, // Factor the absolutely positioned child bounds into the overflow area aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, childBounds); - // Make sure the NS_FRAME_OUTSIDE_CHILDREN flag is set correctly - if ((aDesiredSize.mOverflowArea.x < 0) || - (aDesiredSize.mOverflowArea.y < 0) || - (aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width) || - (aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height)) { - mState |= NS_FRAME_OUTSIDE_CHILDREN; - } else { - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; - } + FinishAndStoreOverflow(&aDesiredSize); } return rv; diff --git a/mozilla/layout/html/base/src/nsLineLayout.cpp b/mozilla/layout/html/base/src/nsLineLayout.cpp index cd3a2e33b6f..c11bfd3f31c 100644 --- a/mozilla/layout/html/base/src/nsLineLayout.cpp +++ b/mozilla/layout/html/base/src/nsLineLayout.cpp @@ -3005,21 +3005,14 @@ nsLineLayout::RelativePositionFrames(PerSpanData* psd, nsRect& aCombinedArea) combinedAreaResult.UnionRect(combinedAreaResult, *r + origin); } - aCombinedArea = combinedAreaResult; - // If we just computed a spans combined area, we need to update its // NS_FRAME_OUTSIDE_CHILDREN bit.. if (psd->mFrame) { 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); - } + frame->FinishAndStoreOverflow(&combinedAreaResult, frame->GetSize()); } + aCombinedArea = combinedAreaResult; } void diff --git a/mozilla/layout/html/base/src/nsPresShell.cpp b/mozilla/layout/html/base/src/nsPresShell.cpp index 5f0f1a902d3..2bd089c4b85 100644 --- a/mozilla/layout/html/base/src/nsPresShell.cpp +++ b/mozilla/layout/html/base/src/nsPresShell.cpp @@ -908,7 +908,8 @@ IncrementalReflow::Dispatch(nsIPresContext *aPresContext, first->SetSize(nsSize(aDesiredSize.width, aDesiredSize.height)); - nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), nsnull); + nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, first, first->GetView(), + &aDesiredSize.mOverflowArea); first->DidReflow(aPresContext, nsnull, NS_FRAME_REFLOW_FINISHED); } diff --git a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp index bb53c50f52d..d9c8b9de2d0 100644 --- a/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp +++ b/mozilla/layout/html/forms/src/nsFieldSetFrame.cpp @@ -601,7 +601,8 @@ nsFieldSetFrame::Reflow(nsIPresContext* aPresContext, ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mLegendFrame); if (mContentFrame) ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, mContentFrame); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); + #ifdef NOISY_REFLOW printf("FIELDSET: w=%d, maxWidth=%d, MEW=%d\n", aDesiredSize.width, aDesiredSize.mMaximumWidth, diff --git a/mozilla/layout/html/style/src/nsCSSRendering.cpp b/mozilla/layout/html/style/src/nsCSSRendering.cpp index 7f2cb5aa1f5..571960edd3d 100644 --- a/mozilla/layout/html/style/src/nsCSSRendering.cpp +++ b/mozilla/layout/html/style/src/nsCSSRendering.cpp @@ -2093,39 +2093,17 @@ nscoord width; } } - - // This if control whether the outline paints on the inside - // or outside of the frame - // XXX This is temporary fix for nsbeta3+ Bug 48973 - // so we can use "mozoutline -#if 0 // outside nsRect inside(aBorderArea); nsRect outside(inside); - inside.Inflate(width, width); + outside.Inflate(width, width); nsRect clipRect(aBorderArea); clipRect.Inflate(width, width); // make clip extra big for now -#else // inside - nsMargin borderWidth; - aBorderStyle.GetBorder(borderWidth); - - nsRect outside(aBorderArea); - outside.Deflate(borderWidth); - nsRect inside(outside); - inside.Deflate(width, width); - - nsRect clipRect(outside); -#endif - - aRenderingContext.PushState(); - aRenderingContext.SetClipRect(clipRect, nsClipCombine_kReplace); - // rounded version of the border for(i=0;i<4;i++){ if(borderRadii[i] > 0){ PaintRoundedBorder(aPresContext,aRenderingContext,aForFrame,aDirtyRect,aBorderArea,nsnull,&aOutlineStyle,aStyleContext,aSkipSides,borderRadii,aGap,PR_TRUE); - aRenderingContext.PopState(); return; } } @@ -2137,7 +2115,6 @@ nscoord width; (outlineStyle == NS_STYLE_BORDER_STYLE_DASHED)) { DrawDashedSides(0, aRenderingContext, aDirtyRect, ourColor, nsnull, &aOutlineStyle, PR_TRUE, outside, inside, aSkipSides, aGap); - aRenderingContext.PopState(); return; } @@ -2192,8 +2169,6 @@ nscoord width; aRenderingContext.SetPenMode(nsPenMode_kNone); } } - // Restore clipping - aRenderingContext.PopState(); } /* draw the edges of the border described in aBorderEdges one segment at a time. diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index b1b7cc77487..9694940be8a 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -598,7 +598,7 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex desiredSize.height = mRect.height; desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height); ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid); - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize); if (kidYTop != kidRect.y) { // Make sure any child views are correctly positioned. We know the inner table // cell won't have a view diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 17e7b169126..63436782fcf 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -2098,20 +2098,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width), PR_MAX(mRect.height, aDesiredSize.height)); damage.UnionRect(damage, aDesiredSize.mOverflowArea); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); if (oldOverflowArea) { damage.UnionRect(damage, *oldOverflowArea); } Invalidate(damage); } else { // use the old overflow area - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); if (oldOverflowArea) { aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, *oldOverflowArea); } } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -3007,7 +3007,8 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, kidFrame); } - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize.mOverflowArea, + nsSize(desiredSize.width, desiredSize.height)); } return rv; } @@ -3489,13 +3490,15 @@ void ResizeCells(nsTableFrame& aTableFrame, rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame); rowFrame = rowFrame->GetNextRow(); } - rgFrame->StoreOverflow(aPresContext, groupDesiredSize); + rgFrame->FinishAndStoreOverflow(&groupDesiredSize.mOverflowArea, + nsSize(groupDesiredSize.width, groupDesiredSize.height)); // make the coordinates of |desiredSize.mOverflowArea| incorrect // since it's about to go away: groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition()); tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea); } - aTableFrame.StoreOverflow(aPresContext, tableDesiredSize); + aTableFrame.FinishAndStoreOverflow(&tableDesiredSize.mOverflowArea, + nsSize(tableDesiredSize.width, tableDesiredSize.height)); } void diff --git a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp index 7c716889599..32514a2f57d 100644 --- a/mozilla/layout/html/table/src/nsTableOuterFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableOuterFrame.cpp @@ -556,7 +556,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, if (aOldOverflowArea) { damage.UnionRect(damage, *aOldOverflowArea); } - nsRect* overflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = GetOverflowAreaProperty(); if (overflowArea) { damage.UnionRect(damage, *overflowArea); } @@ -1370,7 +1370,7 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext, if (mCaptionFrame) { ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame); } - StoreOverflow(aPresContext, aMet); + FinishAndStoreOverflow(&aMet); } nsresult @@ -1541,7 +1541,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { @@ -1599,7 +1599,7 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext, aDesiredSize.height = innerRect.YMost() + innerMargin.bottom; sizeSet = PR_TRUE; // Repaint the inner's entire bounds if it moved - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); PRBool innerMoved = (innerRect.x != innerOrigin.x) || (innerRect.y != innerOrigin.y); nsSize desSize(aDesiredSize.width, aDesiredSize.height); @@ -1763,7 +1763,7 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, if (aOuterMet.mComputeMEW) { aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth; } - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { @@ -1854,7 +1854,7 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext, rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index 98eead9f230..e9e844e1a8a 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -398,7 +398,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, // Get the next child childFrame = iter.Next(); } - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize); if (HasView()) { nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, this, GetView(), &desiredSize.mOverflowArea, 0); } @@ -985,7 +985,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, desiredSize.width = cellDesiredSize.width; desiredSize.height = cellDesiredSize.height; nsRect *overflowArea = - cellFrame->GetOverflowAreaProperty(aPresContext); + cellFrame->GetOverflowAreaProperty(); if (overflowArea) desiredSize.mOverflowArea = *overflowArea; else @@ -1084,7 +1084,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, } nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height); aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); return rv; } @@ -1318,7 +1318,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, nsIFrame* cellKidFrame = cellFrame->GetFirstChild(nsnull); if (cellKidFrame) { cellFrame->ConsiderChildOverflow(aPresContext, cellMet.mOverflowArea, cellKidFrame); - cellFrame->StoreOverflow(aPresContext, cellMet); + cellFrame->FinishAndStoreOverflow(&cellMet); if (cellFrame->HasView()) { nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, cellFrame, cellFrame->GetView(), &cellMet.mOverflowArea, 0); } @@ -1335,7 +1335,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsIFrame* cell = mFrames.FirstChild(); cell; cell = cell->GetNextSibling()) { ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cell); } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); // When returning whether we're complete we need to look at each of our cell // frames. If any of them has a continuing frame, then we're not complete. We // can't just return the status of the cell frame we just reflowed... diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 9e3d70a9655..bc4d02196d3 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -1273,7 +1273,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif @@ -1698,7 +1698,7 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) { ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, rowFrame); } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); } } diff --git a/mozilla/layout/mathml/base/src/nsMathMLTokenFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLTokenFrame.cpp index 20efc6e9b2f..83378f9c9f8 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLTokenFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLTokenFrame.cpp @@ -176,6 +176,15 @@ printf("\n"); aDesiredSize.mMaxElementWidth = childDesiredSize.mMaxElementWidth; } + FinishAndStoreOverflow(&aDesiredSize); + // Act as if there is overflow no matter what. This is a + // safety measure to cater for math fonts with metrics that sometimes + // cause glyphs in the text frames to protrude outside. Without this, + // such glyphs may be clipped at the painting stage + // This flag has already been set on the children as well in + // SetInitialChildList() + mState |= NS_FRAME_OUTSIDE_CHILDREN; + // cache the frame's mBoundingMetrics mBoundingMetrics = aDesiredSize.mBoundingMetrics; diff --git a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp index 88a9d3b6658..0944fec0b9d 100644 --- a/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp +++ b/mozilla/layout/mathml/base/src/nsMathMLmpaddedFrame.cpp @@ -471,15 +471,7 @@ nsMathMLmpaddedFrame::Reflow(nsIPresContext* aPresContext, mReference.x = 0; mReference.y = aDesiredSize.ascent; - // If we have tweaked things so that our children now stick outside, - // we need to update our NS_FRAME_OUTSIDE_CHILDREN bit - if (aDesiredSize.mOverflowArea.x < 0 || - aDesiredSize.mOverflowArea.y < 0 || - aDesiredSize.mOverflowArea.XMost() > aDesiredSize.width || - aDesiredSize.mOverflowArea.YMost() > aDesiredSize.height) - mState |= NS_FRAME_OUTSIDE_CHILDREN; - else - mState &= ~NS_FRAME_OUTSIDE_CHILDREN; + FinishAndStoreOverflow(&aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return NS_OK; diff --git a/mozilla/layout/style/nsStyleContext.cpp b/mozilla/layout/style/nsStyleContext.cpp index 687fd51fa1a..2d87c4fbec0 100644 --- a/mozilla/layout/style/nsStyleContext.cpp +++ b/mozilla/layout/style/nsStyleContext.cpp @@ -455,6 +455,7 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther) DO_STRUCT_DIFFERENCE(Content); DO_STRUCT_DIFFERENCE(UserInterface); DO_STRUCT_DIFFERENCE(Visibility); + DO_STRUCT_DIFFERENCE(Outline); #ifdef MOZ_SVG DO_STRUCT_DIFFERENCE(SVG); #endif @@ -489,7 +490,6 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aOther) // UIReset DO_STRUCT_DIFFERENCE(Color); DO_STRUCT_DIFFERENCE(Background); - DO_STRUCT_DIFFERENCE(Outline); DO_STRUCT_DIFFERENCE(UIReset); #undef DO_STRUCT_DIFFERENCE diff --git a/mozilla/layout/style/nsStyleStruct.cpp b/mozilla/layout/style/nsStyleStruct.cpp index 424ad899f6e..72df5dcf81b 100644 --- a/mozilla/layout/style/nsStyleStruct.cpp +++ b/mozilla/layout/style/nsStyleStruct.cpp @@ -640,11 +640,18 @@ nsStyleOutline::RecalcData(void) nsChangeHint nsStyleOutline::CalcDifference(const nsStyleOutline& aOther) const { - if ((mOutlineWidth != aOther.mOutlineWidth) || - (mOutlineStyle != aOther.mOutlineStyle) || + PRBool outlineWasVisible = + mCachedOutlineWidth > 0 && mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE; + PRBool outlineIsVisible = + aOther.mCachedOutlineWidth > 0 && aOther.mOutlineStyle != NS_STYLE_BORDER_STYLE_NONE; + if (outlineWasVisible != outlineIsVisible || + mOutlineWidth != aOther.mOutlineWidth) { + return NS_CombineHint(nsChangeHint_ReflowFrame, nsChangeHint_RepaintFrame); + } + if ((mOutlineStyle != aOther.mOutlineStyle) || (mOutlineColor != aOther.mOutlineColor) || (mOutlineRadius != aOther.mOutlineRadius)) { - return NS_STYLE_HINT_VISUAL; // XXX: should be VISUAL: see bugs 9809 and 9816 + return nsChangeHint_RepaintFrame; } return NS_STYLE_HINT_NONE; } diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index b1b7cc77487..9694940be8a 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -598,7 +598,7 @@ void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContex desiredSize.height = mRect.height; desiredSize.mOverflowArea = nsRect(0, 0, mRect.width, mRect.height); ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, firstKid); - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize); if (kidYTop != kidRect.y) { // Make sure any child views are correctly positioned. We know the inner table // cell won't have a view diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 17e7b169126..63436782fcf 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -2098,20 +2098,20 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext, nsRect damage(0, 0, PR_MAX(mRect.width, aDesiredSize.width), PR_MAX(mRect.height, aDesiredSize.height)); damage.UnionRect(damage, aDesiredSize.mOverflowArea); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); if (oldOverflowArea) { damage.UnionRect(damage, *oldOverflowArea); } Invalidate(damage); } else { // use the old overflow area - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); if (oldOverflowArea) { aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, *oldOverflowArea); } } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize); return rv; } @@ -3007,7 +3007,8 @@ nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsIFrame* kidFrame = mFrames.FirstChild(); kidFrame; kidFrame = kidFrame->GetNextSibling()) { ConsiderChildOverflow(aPresContext, desiredSize.mOverflowArea, kidFrame); } - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize.mOverflowArea, + nsSize(desiredSize.width, desiredSize.height)); } return rv; } @@ -3489,13 +3490,15 @@ void ResizeCells(nsTableFrame& aTableFrame, rgFrame->ConsiderChildOverflow(aPresContext, groupDesiredSize.mOverflowArea, rowFrame); rowFrame = rowFrame->GetNextRow(); } - rgFrame->StoreOverflow(aPresContext, groupDesiredSize); + rgFrame->FinishAndStoreOverflow(&groupDesiredSize.mOverflowArea, + nsSize(groupDesiredSize.width, groupDesiredSize.height)); // make the coordinates of |desiredSize.mOverflowArea| incorrect // since it's about to go away: groupDesiredSize.mOverflowArea.MoveBy(rgFrame->GetPosition()); tableDesiredSize.mOverflowArea.UnionRect(tableDesiredSize.mOverflowArea, groupDesiredSize.mOverflowArea); } - aTableFrame.StoreOverflow(aPresContext, tableDesiredSize); + aTableFrame.FinishAndStoreOverflow(&tableDesiredSize.mOverflowArea, + nsSize(tableDesiredSize.width, tableDesiredSize.height)); } void diff --git a/mozilla/layout/tables/nsTableOuterFrame.cpp b/mozilla/layout/tables/nsTableOuterFrame.cpp index 7c716889599..32514a2f57d 100644 --- a/mozilla/layout/tables/nsTableOuterFrame.cpp +++ b/mozilla/layout/tables/nsTableOuterFrame.cpp @@ -556,7 +556,7 @@ nsTableOuterFrame::InvalidateDamage(nsIPresContext* aPresContext, if (aOldOverflowArea) { damage.UnionRect(damage, *aOldOverflowArea); } - nsRect* overflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* overflowArea = GetOverflowAreaProperty(); if (overflowArea) { damage.UnionRect(damage, *overflowArea); } @@ -1370,7 +1370,7 @@ nsTableOuterFrame::UpdateReflowMetrics(nsIPresContext* aPresContext, if (mCaptionFrame) { ConsiderChildOverflow(aPresContext, aMet.mOverflowArea, mCaptionFrame); } - StoreOverflow(aPresContext, aMet); + FinishAndStoreOverflow(&aMet); } nsresult @@ -1541,7 +1541,7 @@ nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPresContex rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { @@ -1599,7 +1599,7 @@ nsTableOuterFrame::IR_ReflowDirty(nsIPresContext* aPresContext, aDesiredSize.height = innerRect.YMost() + innerMargin.bottom; sizeSet = PR_TRUE; // Repaint the inner's entire bounds if it moved - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); PRBool innerMoved = (innerRect.x != innerOrigin.x) || (innerRect.y != innerOrigin.y); nsSize desSize(aDesiredSize.width, aDesiredSize.height); @@ -1763,7 +1763,7 @@ nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresContext, if (aOuterMet.mComputeMEW) { aOuterMet.mMaxElementWidth = innerMet.mMaxElementWidth; } - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { @@ -1854,7 +1854,7 @@ nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresContext, rv = FinishReflowChild(mCaptionFrame, aPresContext, nsnull, captionMet, captionOrigin.x, captionOrigin.y, 0); - nsRect* oldOverflowArea = GetOverflowAreaProperty(aPresContext); + nsRect* oldOverflowArea = GetOverflowAreaProperty(); nsRect* overflowStorage = nsnull; nsRect overflow; if (oldOverflowArea) { diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index 98eead9f230..e9e844e1a8a 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -398,7 +398,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext, // Get the next child childFrame = iter.Next(); } - StoreOverflow(aPresContext, desiredSize); + FinishAndStoreOverflow(&desiredSize); if (HasView()) { nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, this, GetView(), &desiredSize.mOverflowArea, 0); } @@ -985,7 +985,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, desiredSize.width = cellDesiredSize.width; desiredSize.height = cellDesiredSize.height; nsRect *overflowArea = - cellFrame->GetOverflowAreaProperty(aPresContext); + cellFrame->GetOverflowAreaProperty(); if (overflowArea) desiredSize.mOverflowArea = *overflowArea; else @@ -1084,7 +1084,7 @@ nsTableRowFrame::ReflowChildren(nsIPresContext* aPresContext, } nsRect rowRect(0, 0, aDesiredSize.width, aDesiredSize.height); aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, rowRect); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); return rv; } @@ -1318,7 +1318,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, nsIFrame* cellKidFrame = cellFrame->GetFirstChild(nsnull); if (cellKidFrame) { cellFrame->ConsiderChildOverflow(aPresContext, cellMet.mOverflowArea, cellKidFrame); - cellFrame->StoreOverflow(aPresContext, cellMet); + cellFrame->FinishAndStoreOverflow(&cellMet); if (cellFrame->HasView()) { nsContainerFrame::SyncFrameViewAfterReflow(aPresContext, cellFrame, cellFrame->GetView(), &cellMet.mOverflowArea, 0); } @@ -1335,7 +1335,7 @@ nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsIFrame* cell = mFrames.FirstChild(); cell; cell = cell->GetNextSibling()) { ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, cell); } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); // When returning whether we're complete we need to look at each of our cell // frames. If any of them has a continuing frame, then we're not complete. We // can't just return the status of the cell frame we just reflowed... diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 9e3d70a9655..bc4d02196d3 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -1273,7 +1273,7 @@ nsTableRowGroupFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.mOverflowArea.UnionRect(aDesiredSize.mOverflowArea, nsRect(0, 0, aDesiredSize.width, aDesiredSize.height)); - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); #if defined DEBUG_TABLE_REFLOW_TIMING nsTableFrame::DebugReflow(this, (nsHTMLReflowState&)aReflowState, &aDesiredSize, aStatus); #endif @@ -1698,7 +1698,7 @@ nsTableRowGroupFrame::IR_TargetIsChild(nsIPresContext* aPresContext, for (nsTableRowFrame* rowFrame = GetFirstRow(); rowFrame; rowFrame = rowFrame->GetNextRow()) { ConsiderChildOverflow(aPresContext, aDesiredSize.mOverflowArea, rowFrame); } - StoreOverflow(aPresContext, aDesiredSize); + FinishAndStoreOverflow(&aDesiredSize); } } diff --git a/mozilla/layout/xul/base/src/nsBox.cpp b/mozilla/layout/xul/base/src/nsBox.cpp index 025ea04cdf1..a3181225eb5 100644 --- a/mozilla/layout/xul/base/src/nsBox.cpp +++ b/mozilla/layout/xul/base/src/nsBox.cpp @@ -564,6 +564,8 @@ nsBox::SetBounds(nsBoxLayoutState& aState, const nsRect& aRect) else frame->SetRect(aRect); + nsRect r(0, 0, aRect.width, aRect.height); + frame->FinishAndStoreOverflow(&r, nsSize(aRect.width, aRect.height)); if (!(flags & NS_FRAME_NO_MOVE_VIEW)) { @@ -1025,8 +1027,6 @@ nsBox::SyncLayout(nsBoxLayoutState& aState) | NS_FRAME_FIRST_REFLOW | NS_FRAME_IN_REFLOW); nsIPresContext* presContext = aState.PresContext(); - nsRect rect(0,0,0,0); - GetBounds(rect); PRUint32 flags = 0; GetLayoutFlags(flags); @@ -1035,21 +1035,40 @@ nsBox::SyncLayout(nsBoxLayoutState& aState) flags |= stateFlags; - nsIView* view = frame->GetView(); + nsRect rect(nsPoint(0, 0), frame->GetSize()); -/* - // only if the origin changed - if ((mX != rect.x) || (mY != rect.y)) { - if (view) { - nsContainerFrame::PositionFrameView(presContext, frame, view); - } else - nsContainerFrame::PositionChildViews(presContext, frame); + if (!DoesClipChildren()) { + // See if our child frames caused us to overflow after being laid + // out. If so, store the overflow area. This normally can't happen + // in XUL, but it can happen with the CSS 'outline' property and + // possibly with other exotic stuff (e.g. relatively positioned + // frames in HTML inside XUL). + nsIBox* box; + GetChildBox(&box); + while (box) + { + nsIFrame* f = nsnull; + box->GetFrame(&f); + + if (f) { + nsRect bounds; + if (f->GetStateBits() & NS_FRAME_OUTSIDE_CHILDREN) { + nsRect* overflowArea = f->GetOverflowAreaProperty(); + NS_ASSERTION(overflowArea, "Should have created property for overflowing frame"); + bounds = *overflowArea + f->GetPosition(); + } else { + bounds = f->GetRect(); + } + rect.UnionRect(rect, bounds); + } - mX = rect.x; - mY = rect.y; + box->GetNextBox(&box); } -*/ + } + frame->FinishAndStoreOverflow(&rect, frame->GetSize()); + + nsIView* view = frame->GetView(); if (view) { // Make sure the frame's view is properly sized and positioned and has // things like opacity correct @@ -1057,7 +1076,7 @@ nsBox::SyncLayout(nsBoxLayoutState& aState) presContext, frame, view, - nsnull, + &rect, flags); } @@ -1085,18 +1104,8 @@ nsBox::Redraw(nsBoxLayoutState& aState, nsRect damageRect(0,0,0,0); if (aDamageRect) damageRect = *aDamageRect; - else - GetContentRect(damageRect); - - // Checks to see if the damaged rect should be infalted - // to include the outline - // XXX This makes NO SENSE. if the damage rect is just a small part of - // this frame's rect then adding the outline width doesn't make any sense. - nscoord width; - frame->GetStyleOutline()->GetOutlineWidth(width); - if (width > 0) { - damageRect.Inflate(width, width); - } + else + damageRect = frame->GetOutlineRect(); frame->Invalidate(damageRect, aImmediate); diff --git a/mozilla/layout/xul/base/src/nsBox.h b/mozilla/layout/xul/base/src/nsBox.h index feed2d6fdfb..a10a481e56b 100644 --- a/mozilla/layout/xul/base/src/nsBox.h +++ b/mozilla/layout/xul/base/src/nsBox.h @@ -111,6 +111,11 @@ public: nsBox(nsIPresShell* aShell); virtual ~nsBox(); + /** + * Returns PR_TRUE if this box clips its children, e.g., if this box is an scrollbox. + */ + virtual PRBool DoesClipChildren() { return PR_FALSE; } + virtual nsresult SyncLayout(nsBoxLayoutState& aBoxLayoutState); virtual PRBool DoesNeedRecalc(const nsSize& aSize); diff --git a/mozilla/layout/xul/base/src/nsBoxFrame.cpp b/mozilla/layout/xul/base/src/nsBoxFrame.cpp index 8b5a5e13466..b4d1df3592c 100644 --- a/mozilla/layout/xul/base/src/nsBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsBoxFrame.cpp @@ -895,6 +895,13 @@ nsBoxFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.ascent = ascent; aDesiredSize.descent = r.height - ascent; + // NS_FRAME_OUTSIDE_CHILDREN is set in SetBounds() above + if (mState & NS_FRAME_OUTSIDE_CHILDREN) { + nsRect* overflowArea = GetOverflowAreaProperty(); + NS_ASSERTION(overflowArea, "Failed to set overflow area property"); + aDesiredSize.mOverflowArea = *overflowArea; + } + // max sure the max element size reflects // our min width nscoord* maxElementWidth = state.GetMaxElementWidth(); diff --git a/mozilla/layout/xul/base/src/nsLeafBoxFrame.cpp b/mozilla/layout/xul/base/src/nsLeafBoxFrame.cpp index cd5805fa509..b8005c85cfc 100644 --- a/mozilla/layout/xul/base/src/nsLeafBoxFrame.cpp +++ b/mozilla/layout/xul/base/src/nsLeafBoxFrame.cpp @@ -335,6 +335,13 @@ nsLeafBoxFrame::Reflow(nsIPresContext* aPresContext, aDesiredSize.ascent = ascent; aDesiredSize.descent = 0; + // NS_FRAME_OUTSIDE_CHILDREN is set in SetBounds() above + if (mState & NS_FRAME_OUTSIDE_CHILDREN) { + nsRect* overflowArea = GetOverflowAreaProperty(); + NS_ASSERTION(overflowArea, "Failed to set overflow area property"); + aDesiredSize.mOverflowArea = *overflowArea; + } + // max sure the max element size reflects // our min width nscoord* maxElementWidth = state.GetMaxElementWidth(); diff --git a/mozilla/layout/xul/base/src/nsScrollBoxFrame.h b/mozilla/layout/xul/base/src/nsScrollBoxFrame.h index e164edbd82a..8f0a22f3fc1 100644 --- a/mozilla/layout/xul/base/src/nsScrollBoxFrame.h +++ b/mozilla/layout/xul/base/src/nsScrollBoxFrame.h @@ -99,6 +99,11 @@ public: */ virtual nsIAtom* GetType() const; + /** + * This frame does clip its child (the scrolled frame). + */ + virtual PRBool DoesClipChildren() { return PR_TRUE; } + #ifdef NS_DEBUG NS_IMETHOD GetFrameName(nsAString& aResult) const; #endif @@ -117,7 +122,6 @@ public: virtual nsresult GetContentOf(nsIContent** aContent); - protected: nsScrollBoxFrame(nsIPresShell* aShell); diff --git a/mozilla/layout/xul/base/src/nsScrollbarFrame.h b/mozilla/layout/xul/base/src/nsScrollbarFrame.h index 7f03b611ea9..846986b64d4 100644 --- a/mozilla/layout/xul/base/src/nsScrollbarFrame.h +++ b/mozilla/layout/xul/base/src/nsScrollbarFrame.h @@ -106,6 +106,16 @@ public: NS_IMETHOD SetScrollbarMediator(nsIScrollbarMediator* aMediator) { mScrollbarMediator = aMediator; return NS_OK; }; NS_IMETHOD GetScrollbarMediator(nsIScrollbarMediator** aResult) { *aResult = mScrollbarMediator; return NS_OK; }; + // nsBox methods + + /** + * Treat scrollbars as clipping their children; overflowing children + * will not be allowed to make NS_FRAME_OUTSIDE_CHILDREN on this + * frame. This means that when the scroll code decides to hide a + * scrollframe by setting its height or width to zero, that will + * hide the children too. + */ + virtual PRBool DoesClipChildren() { return PR_TRUE; } private: nsIScrollbarMediator* mScrollbarMediator; }; // class nsScrollbarFrame