From 1b122ed826657bfcab459d1562e732443f34c8f5 Mon Sep 17 00:00:00 2001 From: "roc+%cs.cmu.edu" Date: Sun, 22 Feb 2004 03:31:30 +0000 Subject: [PATCH] Bug 180931. If we move a frame temporarily during reflow, we'd better invalidate the whole overflow area because invalidates may have been issued at the temporary position. git-svn-id: svn://10.0.0.236/trunk@153080 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/gfx/public/nsRect.h | 10 +++++ mozilla/layout/base/public/nsIFrame.h | 8 ++++ mozilla/layout/generic/nsContainerFrame.cpp | 19 ++++++--- mozilla/layout/generic/nsFrame.cpp | 41 +++++-------------- mozilla/layout/generic/nsFrame.h | 6 --- mozilla/layout/generic/nsIFrame.h | 8 ++++ .../layout/html/base/src/nsContainerFrame.cpp | 19 ++++++--- mozilla/layout/html/base/src/nsFrame.cpp | 41 +++++-------------- mozilla/layout/html/base/src/nsFrame.h | 6 --- 9 files changed, 76 insertions(+), 82 deletions(-) diff --git a/mozilla/gfx/public/nsRect.h b/mozilla/gfx/public/nsRect.h index c30a805ce45..925b96ca825 100644 --- a/mozilla/gfx/public/nsRect.h +++ b/mozilla/gfx/public/nsRect.h @@ -123,14 +123,24 @@ struct NS_GFX nsRect { PRBool operator!=(const nsRect& aRect) const { return (PRBool) !operator==(aRect); } + + // This method is weird. It should probably be deprecated. nsRect operator+(const nsRect& aRect) const { return nsRect(x + aRect.x, y + aRect.y, width + aRect.width, height + aRect.height); } + nsRect operator+(const nsPoint& aPoint) const { + return nsRect(x + aPoint.x, y + aPoint.y, width, height); + } + + // This method is weird. It should probably be deprecated. nsRect operator-(const nsRect& aRect) const { return nsRect(x - aRect.x, y - aRect.y, width - aRect.width, height - aRect.height); } + nsRect operator-(const nsPoint& aPoint) const { + return nsRect(x - aPoint.x, y - aPoint.y, width, height); + } nsRect& operator+=(const nsPoint& aPoint) {x += aPoint.x; y += aPoint.y; return *this;} nsRect& operator-=(const nsPoint& aPoint) {x -= aPoint.x; y -= aPoint.y; return *this;} diff --git a/mozilla/layout/base/public/nsIFrame.h b/mozilla/layout/base/public/nsIFrame.h index 6e735e96589..f00729963fd 100644 --- a/mozilla/layout/base/public/nsIFrame.h +++ b/mozilla/layout/base/public/nsIFrame.h @@ -1010,6 +1010,14 @@ public: */ NS_IMETHOD IsPercentageBase(PRBool& aBase) const = 0; + // Invalidate part of the frame by asking the view manager to repaint. + // aDamageRect is in the frame's local coordinate space + void Invalidate(const nsRect& aDamageRect, PRBool aImmediate = PR_FALSE) const; + // XXX deprecated, remove once we've fixed all callers + void Invalidate(nsIPresContext* aPresContext, + const nsRect& aDamageRect, PRBool aImmediate = PR_FALSE) const + { Invalidate(aDamageRect, aImmediate); } + /** Selection related calls */ /** diff --git a/mozilla/layout/generic/nsContainerFrame.cpp b/mozilla/layout/generic/nsContainerFrame.cpp index 40e61a42b73..b97720375f6 100644 --- a/mozilla/layout/generic/nsContainerFrame.cpp +++ b/mozilla/layout/generic/nsContainerFrame.cpp @@ -1036,11 +1036,20 @@ nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame, &aDesiredSize.mOverflowArea, aFlags); } - else if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW) && - ((curOrigin.x != aX) || (curOrigin.y != aY))) { - // If the frame has moved, then we need to make sure any child views are - // correctly positioned - PositionChildViews(aPresContext, aKidFrame); + + if (!(aFlags & NS_FRAME_NO_MOVE_VIEW) && + (curOrigin.x != aX || curOrigin.y != aY)) { + if (!aKidFrame->HasView()) { + // If the frame has moved, then we need to make sure any child views are + // correctly positioned + PositionChildViews(aPresContext, aKidFrame); + } + + // We also need to redraw the frame because if the frame's Reflow issued any + // invalidates, then they will be at the wrong offset ... note that this includes + // invalidates issued against the frame's children, so we need to invalidate + // the overflow area too. + aKidFrame->Invalidate(aDesiredSize.mOverflowArea); } return aKidFrame->DidReflow(aPresContext, aReflowState, NS_FRAME_REFLOW_FINISHED); diff --git a/mozilla/layout/generic/nsFrame.cpp b/mozilla/layout/generic/nsFrame.cpp index dc6bc42c402..4f9cdf9f5b7 100644 --- a/mozilla/layout/generic/nsFrame.cpp +++ b/mozilla/layout/generic/nsFrame.cpp @@ -2489,44 +2489,25 @@ nsFrame::GetType() const } void -nsFrame::Invalidate(nsIPresContext* aPresContext, - const nsRect& aDamageRect, - PRBool aImmediate) const +nsIFrame::Invalidate(const nsRect& aDamageRect, + PRBool aImmediate) const { if (aDamageRect.IsEmpty()) { return; } - if (aPresContext) { - // Don't allow invalidates to do anything when - // painting is suppressed. - nsIPresShell *shell = aPresContext->GetPresShell(); - if (shell) { - PRBool suppressed = PR_FALSE; - shell->IsPaintingSuppressed(&suppressed); - if (suppressed) - return; - } + // Don't allow invalidates to do anything when + // painting is suppressed. + nsIPresShell *shell = GetPresContext()->GetPresShell(); + if (shell) { + PRBool suppressed = PR_FALSE; + shell->IsPaintingSuppressed(&suppressed); + if (suppressed) + return; } nsRect damageRect(aDamageRect); -#if 0 - // NOTE: inflating the damagerect is to account for outlines but - // ONLY WHEN outlines are actually drawn outside of the frame. This - // assumes that they are *but they are not* and it also assumes that the - // entire frame is being invalidated, which it often is not - // - therefore, this code is invalid and has been removed - - // Checks to see if the damaged rect should be infalted - // to include the outline - nscoord width; - GetStyleOutline()->GetOutlineWidth(width); - if (width > 0) { - damageRect.Inflate(width, width); - } -#endif - PRUint32 flags = aImmediate ? NS_VMREFRESH_IMMEDIATE : NS_VMREFRESH_NO_SYNC; if (HasView()) { nsIView* view = GetView(); @@ -2536,7 +2517,7 @@ nsFrame::Invalidate(nsIPresContext* aPresContext, nsPoint offset; nsIView *view; - GetOffsetFromView(aPresContext, offset, &view); + GetOffsetFromView(GetPresContext(), offset, &view); NS_ASSERTION(view, "no view"); rect += offset; view->GetViewManager()->UpdateView(view, rect, flags); diff --git a/mozilla/layout/generic/nsFrame.h b/mozilla/layout/generic/nsFrame.h index e2f17a15c1a..c5f32c04092 100644 --- a/mozilla/layout/generic/nsFrame.h +++ b/mozilla/layout/generic/nsFrame.h @@ -327,12 +327,6 @@ public: //-------------------------------------------------- // Additional methods - // Invalidate part of the frame by asking the view manager to repaint. - // aDamageRect is in the frame's local coordinate space - void Invalidate(nsIPresContext* aPresContext, - const nsRect& aDamageRect, - PRBool aImmediate = PR_FALSE) const; - /** * Helper method to invalidate portions of a standard container frame if the * reflow state indicates that the size has changed (specifically border, diff --git a/mozilla/layout/generic/nsIFrame.h b/mozilla/layout/generic/nsIFrame.h index 6e735e96589..f00729963fd 100644 --- a/mozilla/layout/generic/nsIFrame.h +++ b/mozilla/layout/generic/nsIFrame.h @@ -1010,6 +1010,14 @@ public: */ NS_IMETHOD IsPercentageBase(PRBool& aBase) const = 0; + // Invalidate part of the frame by asking the view manager to repaint. + // aDamageRect is in the frame's local coordinate space + void Invalidate(const nsRect& aDamageRect, PRBool aImmediate = PR_FALSE) const; + // XXX deprecated, remove once we've fixed all callers + void Invalidate(nsIPresContext* aPresContext, + const nsRect& aDamageRect, PRBool aImmediate = PR_FALSE) const + { Invalidate(aDamageRect, aImmediate); } + /** Selection related calls */ /** diff --git a/mozilla/layout/html/base/src/nsContainerFrame.cpp b/mozilla/layout/html/base/src/nsContainerFrame.cpp index 40e61a42b73..b97720375f6 100644 --- a/mozilla/layout/html/base/src/nsContainerFrame.cpp +++ b/mozilla/layout/html/base/src/nsContainerFrame.cpp @@ -1036,11 +1036,20 @@ nsContainerFrame::FinishReflowChild(nsIFrame* aKidFrame, &aDesiredSize.mOverflowArea, aFlags); } - else if (0 == (aFlags & NS_FRAME_NO_MOVE_VIEW) && - ((curOrigin.x != aX) || (curOrigin.y != aY))) { - // If the frame has moved, then we need to make sure any child views are - // correctly positioned - PositionChildViews(aPresContext, aKidFrame); + + if (!(aFlags & NS_FRAME_NO_MOVE_VIEW) && + (curOrigin.x != aX || curOrigin.y != aY)) { + if (!aKidFrame->HasView()) { + // If the frame has moved, then we need to make sure any child views are + // correctly positioned + PositionChildViews(aPresContext, aKidFrame); + } + + // We also need to redraw the frame because if the frame's Reflow issued any + // invalidates, then they will be at the wrong offset ... note that this includes + // invalidates issued against the frame's children, so we need to invalidate + // the overflow area too. + aKidFrame->Invalidate(aDesiredSize.mOverflowArea); } return aKidFrame->DidReflow(aPresContext, aReflowState, NS_FRAME_REFLOW_FINISHED); diff --git a/mozilla/layout/html/base/src/nsFrame.cpp b/mozilla/layout/html/base/src/nsFrame.cpp index dc6bc42c402..4f9cdf9f5b7 100644 --- a/mozilla/layout/html/base/src/nsFrame.cpp +++ b/mozilla/layout/html/base/src/nsFrame.cpp @@ -2489,44 +2489,25 @@ nsFrame::GetType() const } void -nsFrame::Invalidate(nsIPresContext* aPresContext, - const nsRect& aDamageRect, - PRBool aImmediate) const +nsIFrame::Invalidate(const nsRect& aDamageRect, + PRBool aImmediate) const { if (aDamageRect.IsEmpty()) { return; } - if (aPresContext) { - // Don't allow invalidates to do anything when - // painting is suppressed. - nsIPresShell *shell = aPresContext->GetPresShell(); - if (shell) { - PRBool suppressed = PR_FALSE; - shell->IsPaintingSuppressed(&suppressed); - if (suppressed) - return; - } + // Don't allow invalidates to do anything when + // painting is suppressed. + nsIPresShell *shell = GetPresContext()->GetPresShell(); + if (shell) { + PRBool suppressed = PR_FALSE; + shell->IsPaintingSuppressed(&suppressed); + if (suppressed) + return; } nsRect damageRect(aDamageRect); -#if 0 - // NOTE: inflating the damagerect is to account for outlines but - // ONLY WHEN outlines are actually drawn outside of the frame. This - // assumes that they are *but they are not* and it also assumes that the - // entire frame is being invalidated, which it often is not - // - therefore, this code is invalid and has been removed - - // Checks to see if the damaged rect should be infalted - // to include the outline - nscoord width; - GetStyleOutline()->GetOutlineWidth(width); - if (width > 0) { - damageRect.Inflate(width, width); - } -#endif - PRUint32 flags = aImmediate ? NS_VMREFRESH_IMMEDIATE : NS_VMREFRESH_NO_SYNC; if (HasView()) { nsIView* view = GetView(); @@ -2536,7 +2517,7 @@ nsFrame::Invalidate(nsIPresContext* aPresContext, nsPoint offset; nsIView *view; - GetOffsetFromView(aPresContext, offset, &view); + GetOffsetFromView(GetPresContext(), offset, &view); NS_ASSERTION(view, "no view"); rect += offset; view->GetViewManager()->UpdateView(view, rect, flags); diff --git a/mozilla/layout/html/base/src/nsFrame.h b/mozilla/layout/html/base/src/nsFrame.h index e2f17a15c1a..c5f32c04092 100644 --- a/mozilla/layout/html/base/src/nsFrame.h +++ b/mozilla/layout/html/base/src/nsFrame.h @@ -327,12 +327,6 @@ public: //-------------------------------------------------- // Additional methods - // Invalidate part of the frame by asking the view manager to repaint. - // aDamageRect is in the frame's local coordinate space - void Invalidate(nsIPresContext* aPresContext, - const nsRect& aDamageRect, - PRBool aImmediate = PR_FALSE) const; - /** * Helper method to invalidate portions of a standard container frame if the * reflow state indicates that the size has changed (specifically border,