зеркало из https://github.com/mozilla/gecko-dev.git
Bug 159587. Force view manager to invalidate necessary areas when clipping is changed. r=kmcclusk,sr=bz
This commit is contained in:
Родитель
f80c071193
Коммит
9e4e0e3b45
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче