added optimization so that as we render top->bottom, if the clip region ever

becomes empty, we stop rendering.
This commit is contained in:
michaelp 1998-06-03 21:30:51 +00:00
Родитель d5808c772f
Коммит 49c4d29e3f
8 изменённых файлов: 102 добавлений и 69 удалений

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

@ -111,8 +111,9 @@ PRBool nsRenderingContextUnix :: IsVisibleRect(const nsRect& aRect)
return PR_TRUE;
}
void nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
PRBool nsRenderingContextUnix :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
{
return PR_FALSE;
}
PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
@ -120,9 +121,10 @@ PRBool nsRenderingContextUnix :: GetClipRect(nsRect &aRect)
return PR_FALSE;
}
void nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
PRBool nsRenderingContextUnix :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
{
//XXX wow, needs to do something.
return PR_FALSE;
}
void nsRenderingContextUnix :: GetClipRegion(nsIRegion **aRegion)

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

@ -68,9 +68,9 @@ public:
virtual PRBool IsVisibleRect(const nsRect& aRect);
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool GetClipRect(nsRect &aRect);
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual void GetClipRegion(nsIRegion **aRegion);
virtual void SetColor(nscolor aColor);

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

@ -119,15 +119,16 @@ public:
* @param aRect The rectangle to set the clipping rectangle to
* @param aCombine how to combine this rect with the current clip region.
* see the bottom of nsIRenderingContext.h
* @return PR_TRUE if the clip region is now empty, else PR_FALSE
*/
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0;
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine) = 0;
/**
* Gets the bounds of the clip region of the RenderingContext
* @param aRect out parameter to contain the clip region bounds
* for the RenderingContext
* @return PR_TRUE if the rendering context has a cliprect set
* (i.e. this is the exact clip rect, not a clip region bounds)
* @return PR_TRUE if the rendering context has a local cliprect set
* else aRect is undefined
*/
virtual PRBool GetClipRect(nsRect &aRect) = 0;
@ -136,8 +137,9 @@ public:
* @param aRegion The region to set the clipping area to
* @param aCombine how to combine this region with the current clip region.
* see the bottom of nsIRenderingContext.h
* @return PR_TRUE if the clip region is now empty, else PR_FALSE
*/
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0;
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine) = 0;
/**
* Gets the current clipping region for the RenderingContext

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

@ -402,9 +402,10 @@ PRBool nsRenderingContextWin :: IsVisibleRect(const nsRect& aRect)
return PR_TRUE;
}
void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
PRBool nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCombine)
{
nsRect trect = aRect;
int cliptype;
mStates->mLocalClip = aRect;
@ -419,10 +420,10 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
{
PushClipState();
::IntersectClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
cliptype = ::IntersectClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
}
else if (aCombine == nsClipCombine_kUnion)
{
@ -433,17 +434,17 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
trect.XMost(),
trect.YMost());
::ExtSelectClipRgn(mDC, tregion, RGN_OR);
cliptype = ::ExtSelectClipRgn(mDC, tregion, RGN_OR);
::DeleteObject(tregion);
}
else if (aCombine == nsClipCombine_kSubtract)
{
PushClipState();
::ExcludeClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
cliptype = ::ExcludeClipRect(mDC, trect.x,
trect.y,
trect.XMost(),
trect.YMost());
}
else if (aCombine == nsClipCombine_kReplace)
{
@ -453,11 +454,16 @@ void nsRenderingContextWin :: SetClipRect(const nsRect& aRect, nsClipCombine aCo
trect.y,
trect.XMost(),
trect.YMost());
::SelectClipRgn(mDC, tregion);
cliptype = ::SelectClipRgn(mDC, tregion);
::DeleteObject(tregion);
}
else
NS_ASSERTION(FALSE, "illegal clip combination");
if (cliptype == NULLREGION)
return PR_TRUE;
else
return PR_FALSE;
}
PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
@ -471,11 +477,11 @@ PRBool nsRenderingContextWin :: GetClipRect(nsRect &aRect)
return PR_FALSE;
}
void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
PRBool nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine)
{
nsRegionWin *pRegion = (nsRegionWin *)&aRegion;
HRGN hrgn = pRegion->GetHRGN();
int cmode;
HRGN hrgn = pRegion->GetHRGN();
int cmode, cliptype;
switch (aCombine)
{
@ -501,8 +507,15 @@ void nsRenderingContextWin :: SetClipRegion(const nsIRegion& aRegion, nsClipComb
{
mStates->mFlags &= ~FLAG_LOCAL_CLIP_VALID;
PushClipState();
::ExtSelectClipRgn(mDC, hrgn, cmode);
cliptype = ::ExtSelectClipRgn(mDC, hrgn, cmode);
}
else
return PR_FALSE;
if (cliptype == NULLREGION)
return PR_TRUE;
else
return PR_FALSE;
}
void nsRenderingContextWin :: GetClipRegion(nsIRegion **aRegion)

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

@ -65,9 +65,9 @@ public:
virtual PRBool IsVisibleRect(const nsRect& aRect);
virtual void SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool SetClipRect(const nsRect& aRect, nsClipCombine aCombine);
virtual PRBool GetClipRect(nsRect &aRect);
virtual void SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual PRBool SetClipRegion(const nsIRegion& aRegion, nsClipCombine aCombine);
virtual void GetClipRegion(nsIRegion **aRegion);
virtual void SetColor(nscolor aColor);

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

@ -126,9 +126,10 @@ public:
* @param aBackstop if we will need to do back to front
* painting, this is the view that, once rendered
* ends the back to front pass.
* @return PR_TRUE if the entire clip region has been eliminated, else PR_FALSE
*/
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0;
virtual PRBool Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull) = 0;
/**
* Called to indicate that the specified region of the view
@ -137,8 +138,9 @@ public:
* @param rc rendering context to paint into
* @param region damage area
* @param aPaintFlags see nsIView.h for flag definitions
* @return PR_TRUE if the entire clip region has been eliminated, else PR_FALSE
*/
virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags) = 0;
virtual PRBool Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags) = 0;
/**
* Called to indicate that the specified event should be handled

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

@ -373,10 +373,11 @@ nsIWidget * nsView :: GetWidget()
return mWindow;
}
void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop)
PRBool nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop)
{
nsIView *pRoot = mViewManager->GetRootView();
PRBool clipres = PR_FALSE;
rc.PushState();
@ -389,52 +390,62 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kIntersect);
clipres = rc.SetClipRect(crect, nsClipCombine_kIntersect);
}
else if (this != pRoot)
rc.SetClipRect(mBounds, nsClipCombine_kIntersect);
clipres = rc.SetClipRect(mBounds, nsClipCombine_kIntersect);
rc.Translate(mBounds.x, mBounds.y);
//XXX maybe we should set this before we set the clip? MMP
if (nsnull != mXForm)
if (clipres == PR_FALSE)
{
nsTransform2D *pXForm = rc.GetCurrentTransform();
pXForm->Concatenate(mXForm);
}
rc.Translate(mBounds.x, mBounds.y);
PRInt32 numkids = GetChildCount();
//XXX maybe we should set this before we set the clip? MMP
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
{
nsIView *kid = GetChild(cnt);
if (nsnull != kid)
if (nsnull != mXForm)
{
nsRect kidRect;
kid->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
nsTransform2D *pXForm = rc.GetCurrentTransform();
pXForm->Concatenate(mXForm);
}
if (overlap == PR_TRUE)
PRInt32 numkids = GetChildCount();
for (PRInt32 cnt = 0; cnt < numkids; cnt++)
{
nsIView *kid = GetChild(cnt);
if (nsnull != kid)
{
// Translate damage area into kid's coordinate system
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
damageArea.width, damageArea.height);
kid->Paint(rc, kidDamageArea, aPaintFlags);
nsRect kidRect;
kid->GetBounds(kidRect);
nsRect damageArea;
PRBool overlap = damageArea.IntersectRect(rect, kidRect);
if (overlap == PR_TRUE)
{
// Translate damage area into kid's coordinate system
nsRect kidDamageArea(damageArea.x - kidRect.x, damageArea.y - kidRect.y,
damageArea.width, damageArea.height);
clipres = kid->Paint(rc, kidDamageArea, aPaintFlags);
if (clipres == PR_TRUE)
break;
}
}
}
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow) && (nsnull != mFrame))
{
nsIPresContext *cx = mViewManager->GetPresContext();
rc.PushState();
mFrame->Paint(*cx, rc, rect);
rc.PopState();
NS_RELEASE(cx);
}
}
if ((mVis == nsViewVisibility_kShow) && (nsnull != mFrame))
{
nsIPresContext *cx = mViewManager->GetPresContext();
rc.PushState();
mFrame->Paint(*cx, rc, rect);
rc.PopState();
NS_RELEASE(cx);
}
//XXX would be nice if we could have a version of pop that just removes the
//state from the stack but doesn't change the state of the underlying graphics
//context. MMP
rc.PopState();
@ -442,7 +453,7 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
//paint process. only do this if this view is actually
//visible and if there is no widget (like a scrollbar) here.
if ((mVis == nsViewVisibility_kShow) && (nsnull == mWindow))
if ((clipres == PR_FALSE) && (mVis == nsViewVisibility_kShow) && (nsnull == mWindow))
{
if ((mClip.mLeft != mClip.mRight) && (mClip.mTop != mClip.mBottom))
{
@ -453,21 +464,24 @@ void nsView :: Paint(nsIRenderingContext& rc, const nsRect& rect,
crect.width = mClip.mRight - mClip.mLeft;
crect.height = mClip.mBottom - mClip.mTop;
rc.SetClipRect(crect, nsClipCombine_kSubtract);
clipres = rc.SetClipRect(crect, nsClipCombine_kSubtract);
}
else if (this != pRoot)
rc.SetClipRect(mBounds, nsClipCombine_kSubtract);
clipres = rc.SetClipRect(mBounds, nsClipCombine_kSubtract);
}
NS_RELEASE(pRoot);
return clipres;
}
void nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags)
PRBool nsView :: Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags)
{
// XXX apply region to rc
// XXX get bounding rect from region
//if (nsnull != mFrame)
// mFrame->Paint(rc, rect, aPaintFlags);
return PR_FALSE;
}
nsEventStatus nsView :: HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags)

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

@ -56,9 +56,9 @@ public:
virtual void Destroy();
virtual nsIViewManager * GetViewManager();
virtual nsIWidget * GetWidget();
virtual void Paint(nsIRenderingContext& rc, const nsRect& rect,
virtual PRBool Paint(nsIRenderingContext& rc, const nsRect& rect,
PRUint32 aPaintFlags, nsIView *aBackstop = nsnull);
virtual void Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags);
virtual PRBool Paint(nsIRenderingContext& rc, const nsIRegion& region, PRUint32 aPaintFlags);
virtual nsEventStatus HandleEvent(nsGUIEvent *event, PRUint32 aEventFlags);
virtual void SetPosition(nscoord x, nscoord y);
virtual void GetPosition(nscoord *x, nscoord *y);