Bug 159587. Force view manager to invalidate necessary areas when clipping is changed. r=kmcclusk,sr=bz

This commit is contained in:
roc+%cs.cmu.edu 2002-08-08 01:03:57 +00:00
Родитель f80c071193
Коммит 9e4e0e3b45
3 изменённых файлов: 58 добавлений и 69 удалений

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

@ -229,11 +229,6 @@ NS_IMETHODIMP nsView::Init(nsIViewManager* aManager,
// we don't hold a reference to the view manager
mViewManager = NS_STATIC_CAST(nsViewManager*, aManager);
mChildClip.mLeft = 0;
mChildClip.mRight = 0;
mChildClip.mTop = 0;
mChildClip.mBottom = 0;
SetPosition(aBounds.x, aBounds.y);
nsRect dim(0, 0, aBounds.width, aBounds.height);
@ -550,28 +545,6 @@ NS_IMETHODIMP nsView::GetBounds(nsRect &aBounds) const
return NS_OK;
}
NS_IMETHODIMP nsView::SetChildClip(nscoord aLeft, nscoord aTop, nscoord aRight, nscoord aBottom)
{
NS_PRECONDITION(aLeft <= aRight && aTop <= aBottom, "bad clip values");
mChildClip.mLeft = aLeft;
mChildClip.mTop = aTop;
mChildClip.mRight = aRight;
mChildClip.mBottom = aBottom;
return NS_OK;
}
NS_IMETHODIMP nsView::GetChildClip(nscoord *aLeft, nscoord *aTop, nscoord *aRight, nscoord *aBottom) const
{
*aLeft = mChildClip.mLeft;
*aTop = mChildClip.mTop;
*aRight = mChildClip.mRight;
*aBottom = mChildClip.mBottom;
return NS_OK;
}
NS_IMETHODIMP nsView::SetVisibility(nsViewVisibility aVisibility)
{
@ -1047,17 +1020,11 @@ NS_IMETHODIMP nsView::GetClippedRect(nsRect& aClippedRect, PRBool& aIsClipped, P
if (parentView->GetClipChildren()) {
aIsClipped = PR_TRUE;
// Adjust for clip specified by ancestor
nscoord clipLeft;
nscoord clipTop;
nscoord clipRight;
nscoord clipBottom;
parentView->GetChildClip(&clipLeft, &clipTop, &clipRight, &clipBottom);
nsRect clipRect;
parentView->GetChildClip(clipRect);
//Offset the cliprect by the amount the child offsets from the parent
clipRect.x = clipLeft + ancestorX;
clipRect.y = clipTop + ancestorY;
clipRect.width = clipRight - clipLeft;
clipRect.height = clipBottom - clipTop;
clipRect.x += ancestorX;
clipRect.y += ancestorY;
PRBool overlap = aClippedRect.IntersectRect(clipRect, aClippedRect);
if (!overlap) {
aEmpty = PR_TRUE; // Does not intersect so the rect is empty.

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

@ -49,13 +49,6 @@
//mmptemp
struct nsViewClip {
nscoord mLeft;
nscoord mRight;
nscoord mTop;
nscoord mBottom;
};
class nsIRegion;
class nsIRenderingContext;
class nsIViewManager;
@ -192,20 +185,17 @@ public:
* The clip is relative to the origin of the view.
* All of the children of this view will be clipped using
* the specified rectangle
* @param aLeft new left position
* @param aTop new top position
* @param aRight new right position
* @param aBottom new bottom position
*/
NS_IMETHOD SetChildClip(nscoord aX, nscoord aY, nscoord aWidth, nscoord aHeight);
void SetClipChildren(PRBool aDoClip) {
mVFlags = (mVFlags & ~NS_VIEW_FLAG_CLIPCHILDREN) | (aDoClip ? NS_VIEW_FLAG_CLIPCHILDREN : 0);
}
void SetChildClip(const nsRect &aRect) { mChildClip = aRect; }
/**
* Called to get the dimensions and position of the clip for the view.
* @param aLeft left position
* @param aTop top position
* @param aRight right position
* @param aBottom bottom position
* Called to get the dimensions and position of the clip for the children of this view.
*/
NS_IMETHOD GetChildClip(nscoord *aLeft, nscoord *aTop, nscoord *aRight, nscoord *aBottom) const;
PRBool GetClipChildren() const { return (mVFlags & NS_VIEW_FLAG_CLIPCHILDREN) != 0; }
void GetChildClip(nsRect &aRect) const { aRect = mChildClip; }
/**
* Called to indicate that the visibility of a view has been
* changed.
@ -304,7 +294,6 @@ public: // NOT in nsIView, so only available in view module
nsViewVisibility GetVisibility() const { return mVis; }
void* GetClientData() const { return mClientData; }
PRBool GetFloating() const { return (mVFlags & NS_VIEW_FLAG_FLOATING) != 0; }
PRBool GetClipChildren() const { return (mVFlags & NS_VIEW_FLAG_CLIPCHILDREN) != 0; }
PRInt32 GetChildCount() const { return mNumKids; }
nsView* GetChild(PRInt32 aIndex) const;
@ -345,7 +334,7 @@ protected:
PRInt32 mNumKids;
nscoord mPosX, mPosY;
nsRect mDimBounds; // relative to parent
nsViewClip mChildClip;
nsRect mChildClip;
float mOpacity;
PRUint32 mVFlags;
nsIRegion* mDirtyRegion;

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

@ -2444,9 +2444,13 @@ NS_IMETHODIMP nsViewManager::ResizeView(nsIView *aView, const nsRect &aRect, PRB
// nsIClipViews clip everything, including their child views. So we note that explicitly.
// This means nsView::GetClippedRect will now take account of the clipping effects of
// nsIClipViews.
// This will be overridden by SetViewChildClipRegion below, if necessary
if (IsClipView(view)) {
view->SetViewFlags(view->GetViewFlags() | NS_VIEW_FLAG_CLIPCHILDREN);
view->SetChildClip(0, 0, aRect.width, aRect.height);
nsRect childClipRect = aRect;
childClipRect.x = 0;
childClipRect.y = 0;
view->SetClipChildren(PR_TRUE);
view->SetChildClip(childClipRect);
}
}
@ -2459,31 +2463,60 @@ NS_IMETHODIMP nsViewManager::SetViewChildClipRegion(nsIView *aView, nsIRegion *a
NS_ASSERTION(!(nsnull == view), "no view");
// XXX Shouldn't we repaint the view here?
PRBool oldClipFlag = view->GetClipChildren();
nsRect oldClipRect;
if (oldClipFlag) {
view->GetChildClip(oldClipRect);
} else {
// clipping may not have been enabled, but get the area to invalidate anyway
view->GetDimensions(oldClipRect);
}
PRBool newClipFlag;
nsRect newClipRect;
// If the view implements nsIClipView then we ensure a clip rect is set,
// and it is set to no more than the bounds of the view.
if (aRegion != nsnull) {
nsRect newClip;
aRegion->GetBoundingBox(&newClip.x, &newClip.y, &newClip.width, &newClip.height);
newClipFlag = PR_TRUE;
aRegion->GetBoundingBox(&newClipRect.x, &newClipRect.y, &newClipRect.width, &newClipRect.height);
if (IsClipView(view)) {
nsRect dims;
view->GetDimensions(dims);
newClip.IntersectRect(newClip, dims);
newClipRect.IntersectRect(newClipRect, dims);
}
view->SetViewFlags(view->GetViewFlags() | NS_VIEW_FLAG_CLIPCHILDREN);
view->SetChildClip(newClip.x, newClip.y, newClip.XMost(), newClip.YMost());
} else {
if (IsClipView(view)) {
nsRect dims;
view->GetDimensions(dims);
view->SetViewFlags(view->GetViewFlags() | NS_VIEW_FLAG_CLIPCHILDREN);
view->SetChildClip(0, 0, dims.width, dims.height);
newClipFlag = PR_TRUE;
view->GetDimensions(newClipRect);
newClipRect.x = 0;
newClipRect.y = 0;
} else {
view->SetViewFlags(view->GetViewFlags() & ~NS_VIEW_FLAG_CLIPCHILDREN);
newClipFlag = PR_FALSE;
// clipping is not enabled, but get the new unclipped area for invalidation purposes
view->GetDimensions(newClipRect);
}
}
if (newClipFlag == oldClipFlag
&& (!newClipFlag || newClipRect == oldClipRect)) {
return NS_OK;
}
// Update the view properties
view->SetClipChildren(newClipFlag);
view->SetChildClip(newClipRect);
// Invalidate changed areas
// Paint (new - old) in the current view
InvalidateRectDifference(view, newClipRect, oldClipRect, NS_VMREFRESH_NO_SYNC);
// Paint (old - new) in the parent view, since it'll be clipped out of the current view
nsView* parent = view->GetParent();
if (parent != nsnull) {
view->ConvertToParentCoords(&oldClipRect.x, &oldClipRect.y);
view->ConvertToParentCoords(&newClipRect.x, &newClipRect.y);
InvalidateRectDifference(parent, oldClipRect, newClipRect, NS_VMREFRESH_NO_SYNC);
}
return NS_OK;
}