fix for excessive mallocing of regions bug #37352

This commit is contained in:
pavlov%netscape.com 2000-04-27 07:58:15 +00:00
Родитель 48f046e6b3
Коммит bb043e215f
2 изменённых файлов: 122 добавлений и 78 удалений

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

@ -30,6 +30,9 @@
static int nRegions;
#endif
GdkRegion *nsRegionGTK::copyRegion = nsnull;
nsRegionGTK::nsRegionGTK()
{
NS_INIT_REFCNT();
@ -56,40 +59,58 @@ nsRegionGTK::~nsRegionGTK()
NS_IMPL_ISUPPORTS1(nsRegionGTK, nsIRegion)
nsresult nsRegionGTK::Init(void)
{
if (mRegion) {
gdk_region_destroy(mRegion);
}
mRegion = ::gdk_region_new();
return NS_OK;
GdkRegion *
nsRegionGTK::GetCopyRegion() {
if (!copyRegion) copyRegion = gdk_region_new();
return copyRegion;
}
void nsRegionGTK::SetTo(const nsIRegion &aRegion)
{
nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion;
SetRegionEmpty();
GdkRegion *nRegion = ::gdk_regions_union(mRegion, pRegion->mRegion);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
GdkRegion *
nsRegionGTK::gdk_region_copy(GdkRegion *region)
{
return gdk_regions_union(region, GetCopyRegion());
}
void nsRegionGTK::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
GdkRegion *
nsRegionGTK::gdk_region_from_rect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
SetRegionEmpty();
GdkRectangle grect;
grect.x = aX;
grect.y = aY;
grect.width = aWidth;
grect.height = aHeight;
GdkRegion *nRegion = ::gdk_region_union_with_rect(mRegion, &grect);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
return ::gdk_region_union_with_rect(GetCopyRegion(), &grect);
}
nsresult nsRegionGTK::Init(void)
{
if (mRegion) {
gdk_region_destroy(mRegion);
mRegion = nsnull;
}
return NS_OK;
}
void nsRegionGTK::SetTo(const nsIRegion &aRegion)
{
SetRegionEmpty();
nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion;
mRegion = gdk_region_copy(pRegion->mRegion);
}
void nsRegionGTK::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
SetRegionEmpty();
mRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight);
}
void nsRegionGTK::Intersect(const nsIRegion &aRegion)
@ -103,7 +124,7 @@ void nsRegionGTK::Intersect(const nsIRegion &aRegion)
void nsRegionGTK::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
GdkRegion *tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight);
GdkRegion *nRegion = ::gdk_regions_intersect(mRegion, tRegion);
::gdk_region_destroy(tRegion);
@ -113,48 +134,67 @@ void nsRegionGTK::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHei
void nsRegionGTK::Union(const nsIRegion &aRegion)
{
nsRegionGTK * pRegion = (nsRegionGTK *)&aRegion;
GdkRegion *nRegion = ::gdk_regions_union(mRegion, pRegion->mRegion);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion;
if (mRegion) {
GdkRegion *nRegion = ::gdk_regions_union(mRegion, pRegion->mRegion);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
} else {
mRegion = gdk_region_copy(pRegion->mRegion);
}
}
void nsRegionGTK::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
GdkRectangle grect;
if (mRegion) {
GdkRectangle grect;
grect.x = aX;
grect.y = aY;
grect.width = aWidth;
grect.height = aHeight;
grect.x = aX;
grect.y = aY;
grect.width = aWidth;
grect.height = aHeight;
GdkRegion *nRegion = ::gdk_region_union_with_rect(mRegion, &grect);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
GdkRegion *nRegion = ::gdk_region_union_with_rect(mRegion, &grect);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
} else {
mRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight);
}
}
void nsRegionGTK::Subtract(const nsIRegion &aRegion)
{
nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion;
GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, pRegion->mRegion);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
if (mRegion) {
GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, pRegion->mRegion);
::gdk_region_destroy(mRegion);
mRegion = nRegion;
} else {
mRegion = ::gdk_regions_subtract(GetCopyRegion(), pRegion->mRegion);
}
}
void nsRegionGTK::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
GdkRegion *tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, tRegion);
::gdk_region_destroy(mRegion);
::gdk_region_destroy(tRegion);
mRegion = nRegion;
if (mRegion) {
GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight);
GdkRegion *nRegion = ::gdk_regions_subtract(mRegion, tRegion);
::gdk_region_destroy(mRegion);
::gdk_region_destroy(tRegion);
mRegion = nRegion;
} else {
GdkRegion *tRegion = gdk_region_from_rect(aX, aY, aWidth, aHeight);
mRegion = ::gdk_regions_subtract(GetCopyRegion(), tRegion);
::gdk_region_destroy(tRegion);
}
}
PRBool nsRegionGTK::IsEmpty(void)
{
if (!mRegion)
return PR_TRUE;
return (::gdk_region_empty(mRegion));
}
@ -162,8 +202,15 @@ PRBool nsRegionGTK::IsEqual(const nsIRegion &aRegion)
{
nsRegionGTK *pRegion = (nsRegionGTK *)&aRegion;
return(::gdk_region_equal(mRegion, pRegion->mRegion));
if (mRegion && pRegion->mRegion) {
return(::gdk_region_equal(mRegion, pRegion->mRegion));
} else if (!mRegion && !pRegion->mRegion) {
return PR_TRUE;
} else if ((mRegion && !pRegion->mRegion) || (!mRegion && pRegion->mRegion)) {
return PR_FALSE;
}
return PR_FALSE;
}
void nsRegionGTK::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
@ -204,20 +251,29 @@ PRBool nsRegionGTK::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32
NS_IMETHODIMP nsRegionGTK::GetRects(nsRegionRectSet **aRects)
{
nsRegionRectSet *rects;
GdkRegionPrivate *priv = (GdkRegionPrivate *)mRegion;
Region pRegion = priv->xregion;
int nbox;
BOX *pbox;
nsRegionRect *rect;
*aRects = nsnull;
if (!mRegion)
return NS_OK;
nsRegionRectSet *rects = nsnull;
GdkRegionPrivate *priv = nsnull;
Region pRegion;
int nbox = 0;
BOX *pbox = nsnull;
nsRegionRect *rect = nsnull;
priv = (GdkRegionPrivate *)mRegion;
pRegion = priv->xregion;
pbox = pRegion->rects;
nbox = pRegion->numRects;
NS_ASSERTION(!(nsnull == aRects), "bad ptr");
//code lifted from old xfe. MMP
pbox = pRegion->rects;
nbox = pRegion->numRects;
rects = *aRects;
if ((nsnull == rects) || (rects->mRectsLen < (PRUint32)nbox))
@ -287,31 +343,14 @@ void nsRegionGTK::SetRegionEmpty()
{
if (!IsEmpty()) {
::gdk_region_destroy(mRegion);
mRegion = ::gdk_region_new();
}
}
GdkRegion *nsRegionGTK::CreateRectRegion(PRInt32 aX,
PRInt32 aY,
PRInt32 aWidth,
PRInt32 aHeight)
{
GdkRegion *tRegion = ::gdk_region_new();
GdkRectangle rect;
rect.x = aX;
rect.y = aY;
rect.width = aWidth;
rect.height = aHeight;
GdkRegion *rRegion = ::gdk_region_union_with_rect(tRegion, &rect);
::gdk_region_destroy(tRegion);
return (rRegion);
}
NS_IMETHODIMP nsRegionGTK::GetNumRects(PRUint32 *aRects) const
{
if (!mRegion)
*aRects = 0;
GdkRegionPrivate *priv = (GdkRegionPrivate *)mRegion;
Region pRegion = priv->xregion;

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

@ -58,9 +58,14 @@ public:
GdkRegion *CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
NS_IMETHOD GetNumRects(PRUint32 *aRects) const;
private:
GdkRegion *mRegion;
protected:
GdkRegion *gdk_region_copy(GdkRegion *region);
GdkRegion *gdk_region_from_rect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
private:
inline GdkRegion *GetCopyRegion();
GdkRegion *mRegion;
static GdkRegion *copyRegion;
void SetRegionEmpty();
};