diff --git a/gfx/src/nsIRegion.h b/gfx/src/nsIRegion.h index 37ade6caec17..9e20ece4dd1a 100644 --- a/gfx/src/nsIRegion.h +++ b/gfx/src/nsIRegion.h @@ -54,12 +54,15 @@ public: /** * copy operator equivalent that takes a rect * - * @param rect to copy + * @param aX xoffset of rect to set region to + * @param aY yoffset of rect to set region to + * @param aWidth width of rect to set region to + * @param aHeight height of rect to set region to * @return void * **/ - virtual void SetTo(const nsRect &aRect) = 0; + virtual void SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) = 0; /** * destructively intersect another region with this one @@ -74,12 +77,15 @@ public: /** * destructively intersect a rect with this region * - * @param rect to intersect + * @param aX xoffset of rect to intersect with region + * @param aY yoffset of rect to intersect with region + * @param aWidth width of rect to intersect with region + * @param aHeight height of rect to intersect with region * @return void * **/ - virtual void Intersect(const nsRect &aRect) = 0; + virtual void Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) = 0; /** * destructively union another region with this one @@ -94,12 +100,15 @@ public: /** * destructively union a rect with this region * - * @param rect to union + * @param aX xoffset of rect to union with region + * @param aY yoffset of rect to union with region + * @param aWidth width of rect to union with region + * @param aHeight height of rect to union with region * @return void * **/ - virtual void Union(const nsRect &aRect) = 0; + virtual void Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) = 0; /** * destructively subtract another region with this one @@ -136,11 +145,14 @@ public: * returns the bounding box of the region i.e. the smallest * rectangle that completely contains the region. * - * @param rect to set to the bounding box + * @param aX out parameter for xoffset of bounding rect for region + * @param aY out parameter for yoffset of bounding rect for region + * @param aWidth out parameter for width of bounding rect for region + * @param aHeight out parameter for height of bounding rect for region * @return void * **/ - virtual void GetBoundingBox(nsRect &aRect) = 0; + virtual void GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) = 0; /** * offsets the region in x and y @@ -150,7 +162,7 @@ public: * @return void * **/ - virtual void Offset(nscoord aXOffset, nscoord aYOffset) = 0; + virtual void Offset(PRInt32 aXOffset, PRInt32 aYOffset) = 0; /** * does the region completely contain the rectangle? @@ -160,7 +172,7 @@ public: * **/ - virtual PRBool ContainsRect(const nsRect &aRect) = 0; + virtual PRBool ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) = 0; /** * invoke a function for each rectangle in the region diff --git a/gfx/src/windows/nsRegionWin.cpp b/gfx/src/windows/nsRegionWin.cpp index 8a81b1e6e62b..74f9b2cddcef 100644 --- a/gfx/src/windows/nsRegionWin.cpp +++ b/gfx/src/windows/nsRegionWin.cpp @@ -25,6 +25,7 @@ nsRegionWin :: nsRegionWin() NS_INIT_REFCNT(); mRegion = NULL; + mRegionType = NULLREGION; } nsRegionWin :: ~nsRegionWin() @@ -38,58 +39,117 @@ NS_IMPL_RELEASE(nsRegionWin) nsresult nsRegionWin :: Init(void) { + mRegion = ::CreateRectRgn(0, 0, 0, 0); + mRegionType = NULLREGION; + return NS_OK; } void nsRegionWin :: SetTo(const nsIRegion &aRegion) { + nsRegionWin *pRegion = (nsRegionWin *)&aRegion; + + mRegionType = ::CombineRgn(mRegion, pRegion->mRegion, NULL, RGN_COPY); } -void nsRegionWin :: SetTo(const nsRect &aRect) +void nsRegionWin :: SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { + if (NULL != mRegion) + ::DeleteObject(mRegion); + + mRegion = ::CreateRectRgn(aX, aY, aX + aWidth, aY + aHeight); + + if ((aWidth == 0) || (aHeight == 0)) + mRegionType = NULLREGION; + else + mRegionType = SIMPLEREGION; } void nsRegionWin :: Intersect(const nsIRegion &aRegion) { + nsRegionWin *pRegion = (nsRegionWin *)&aRegion; + + mRegionType = ::CombineRgn(mRegion, pRegion->mRegion, mRegion, RGN_AND); } -void nsRegionWin :: Intersect(const nsRect &aRect) +void nsRegionWin :: Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { + HRGN tRegion; + + tRegion = ::CreateRectRgn(aX, aY, aX + aWidth, aY + aHeight); + mRegionType = ::CombineRgn(mRegion, tRegion, mRegion, RGN_AND); + + ::DeleteObject(tRegion); } void nsRegionWin :: Union(const nsIRegion &aRegion) { + nsRegionWin *pRegion = (nsRegionWin *)&aRegion; + + mRegionType = ::CombineRgn(mRegion, pRegion->mRegion, mRegion, RGN_OR); } -void nsRegionWin :: Union(const nsRect &aRect) +void nsRegionWin :: Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { + HRGN tRegion; + + tRegion = ::CreateRectRgn(aX, aY, aX + aWidth, aY + aHeight); + mRegionType = ::CombineRgn(mRegion, tRegion, mRegion, RGN_OR); + + ::DeleteObject(tRegion); } void nsRegionWin :: Subtract(const nsIRegion &aRegion) { + nsRegionWin *pRegion = (nsRegionWin *)&aRegion; + + mRegionType = ::CombineRgn(mRegion, mRegion, pRegion->mRegion, RGN_DIFF); } PRBool nsRegionWin :: IsEmpty(void) { - return PR_TRUE; + return (mRegionType == NULLREGION) ? PR_TRUE : PR_FALSE; } PRBool nsRegionWin :: IsEqual(const nsIRegion &aRegion) { - return PR_FALSE; + nsRegionWin *pRegion = (nsRegionWin *)&aRegion; + + return ::EqualRgn(mRegion, pRegion->mRegion) ? PR_TRUE : PR_FALSE; } -void nsRegionWin :: GetBoundingBox(nsRect &aRect) +void nsRegionWin :: GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight) { + RECT bounds; + + if (mRegionType != NULLREGION) + { + ::GetRgnBox(mRegion, &bounds); + + *aX = bounds.left; + *aY = bounds.top; + *aWidth = bounds.right - bounds.left; + *aHeight = bounds.bottom - bounds.top; + } + else + *aX = *aY = *aWidth = *aHeight = 0; } -void nsRegionWin :: Offset(nscoord aXOffset, nscoord aYOffset) +void nsRegionWin :: Offset(PRInt32 aXOffset, PRInt32 aYOffset) { + ::OffsetRgn(mRegion, aXOffset, aYOffset); } -PRBool nsRegionWin :: ContainsRect(const nsRect &aRect) +PRBool nsRegionWin :: ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight) { - return PR_FALSE; + RECT trect; + + trect.left = aX; + trect.top = aY; + trect.right = aX + aWidth; + trect.bottom = aY + aHeight; + + return ::RectInRegion(mRegion, &trect) ? PR_TRUE : PR_FALSE; } PRBool nsRegionWin :: ForEachRect(nsRectInRegionFunc *func, void *closure) diff --git a/gfx/src/windows/nsRegionWin.h b/gfx/src/windows/nsRegionWin.h index bc5d65f2d012..ed5d193e9173 100644 --- a/gfx/src/windows/nsRegionWin.h +++ b/gfx/src/windows/nsRegionWin.h @@ -32,17 +32,17 @@ public: virtual nsresult Init(); virtual void SetTo(const nsIRegion &aRegion); - virtual void SetTo(const nsRect &aRect); + virtual void SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); virtual void Intersect(const nsIRegion &aRegion); - virtual void Intersect(const nsRect &aRect); + virtual void Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); virtual void Union(const nsIRegion &aRegion); - virtual void Union(const nsRect &aRect); + virtual void Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); virtual void Subtract(const nsIRegion &aRegion); virtual PRBool IsEmpty(void); virtual PRBool IsEqual(const nsIRegion &aRegion); - virtual void GetBoundingBox(nsRect &aRect); - virtual void Offset(nscoord aXOffset, nscoord aYOffset); - virtual PRBool ContainsRect(const nsRect &aRect); + virtual void GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight); + virtual void Offset(PRInt32 aXOffset, PRInt32 aYOffset); + virtual PRBool ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight); virtual PRBool ForEachRect(nsRectInRegionFunc *func, void *closure); //windows specific @@ -53,6 +53,7 @@ private: ~nsRegionWin(); HRGN mRegion; + int mRegionType; }; #endif // nsRegionWin_h___