fixed potential memory problems.

This commit is contained in:
beard%netscape.com 1999-06-03 00:56:32 +00:00
Родитель 78aa051ad5
Коммит fa957816e2
1 изменённых файлов: 140 добавлений и 149 удалений

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

@ -92,10 +92,15 @@ void nsNativeRegionPool::ReleaseRegion(RgnHandle aRgnHandle)
else
slot = new nsRegionSlot;
// put this region on the region list.
slot->mRegion = aRgnHandle;
slot->mNext = mRegionSlots;
mRegionSlots = slot;
if (slot != nsnull) {
// put this region on the region list.
slot->mRegion = aRgnHandle;
slot->mNext = mRegionSlots;
mRegionSlots = slot;
} else {
// couldn't allocate a slot, toss the region.
::DisposeRgn(aRgnHandle);
}
}
@ -108,18 +113,19 @@ static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
nsRegionMac::nsRegionMac()
{
NS_INIT_REFCNT();
NS_INIT_REFCNT();
mRegion = nsnull;
mRegionType = eRegionComplexity_empty;
mRegionType = eRegionComplexity_empty;
}
//---------------------------------------------------------------------
nsRegionMac::~nsRegionMac()
{
if (mRegion)
sNativeRegionPool.ReleaseRegion(mRegion); //::DisposeRgn(mRegion);
mRegion = nsnull;
if (mRegion != nsnull) {
sNativeRegionPool.ReleaseRegion(mRegion);
mRegion = nsnull;
}
}
NS_IMPL_QUERY_INTERFACE(nsRegionMac, kRegionIID);
@ -130,9 +136,15 @@ NS_IMPL_RELEASE(nsRegionMac);
nsresult nsRegionMac::Init(void)
{
mRegion = sNativeRegionPool.GetNewRegion(); //::NewRgn();
mRegionType = eRegionComplexity_empty;
return NS_OK;
if (mRegion != nsnull)
::SetEmptyRgn(mRegion);
else
mRegion = sNativeRegionPool.GetNewRegion();
if (mRegion != nsnull) {
mRegionType = eRegionComplexity_empty;
return NS_OK;
}
return NS_ERROR_OUT_OF_MEMORY;
}
//---------------------------------------------------------------------
@ -141,7 +153,7 @@ void nsRegionMac::SetTo(const nsIRegion &aRegion)
{
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::CopyRgn(pRegion->mRegion, mRegion);
SetRegionType();
SetRegionType();
}
//---------------------------------------------------------------------
@ -149,27 +161,29 @@ void nsRegionMac::SetTo(const nsIRegion &aRegion)
void nsRegionMac::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
::SetRectRgn(mRegion, aX, aY, aX + aWidth, aY + aHeight);
SetRegionType();
SetRegionType();
}
//---------------------------------------------------------------------
void nsRegionMac::Intersect(const nsIRegion &aRegion)
{
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::SectRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::SectRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
}
//---------------------------------------------------------------------
void nsRegionMac::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::SectRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn); //::DisposeRgn(rectRgn);
SetRegionType();
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
if (rectRgn != nsnull) {
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::SectRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn);
SetRegionType();
}
}
//---------------------------------------------------------------------
@ -177,19 +191,21 @@ void nsRegionMac::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHei
void nsRegionMac::Union(const nsIRegion &aRegion)
{
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::UnionRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
::UnionRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
}
//---------------------------------------------------------------------
void nsRegionMac::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::UnionRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn); //::DisposeRgn(rectRgn);
SetRegionType();
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
if (rectRgn != nsnull) {
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::UnionRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn);
SetRegionType();
}
}
//---------------------------------------------------------------------
@ -197,37 +213,39 @@ void nsRegionMac::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
void nsRegionMac::Subtract(const nsIRegion &aRegion)
{
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
::DiffRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
::DiffRgn(mRegion, pRegion->mRegion, mRegion);
SetRegionType();
}
//---------------------------------------------------------------------
void nsRegionMac::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::DiffRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn); //::DisposeRgn(rectRgn);
SetRegionType();
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
if (rectRgn != nsnull) {
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
::DiffRgn(mRegion, rectRgn, mRegion);
sNativeRegionPool.ReleaseRegion(rectRgn);
SetRegionType();
}
}
//---------------------------------------------------------------------
PRBool nsRegionMac::IsEmpty(void)
{
if (mRegionType == eRegionComplexity_empty)
return PR_TRUE;
if (mRegionType == eRegionComplexity_empty)
return PR_TRUE;
else
return PR_FALSE;
return PR_FALSE;
}
//---------------------------------------------------------------------
PRBool nsRegionMac::IsEqual(const nsIRegion &aRegion)
{
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
return(::EqualRgn(mRegion, pRegion->mRegion));
nsRegionMac* pRegion = (nsRegionMac*)&aRegion;
return(::EqualRgn(mRegion, pRegion->mRegion));
}
//---------------------------------------------------------------------
@ -235,23 +253,23 @@ PRBool nsRegionMac::IsEqual(const nsIRegion &aRegion)
void nsRegionMac::GetBoundingBox(PRInt32 *aX, PRInt32 *aY, PRInt32 *aWidth, PRInt32 *aHeight)
{
#if TARGET_CARBON
Rect macRect;
::GetRegionBounds (mRegion, &macRect);
Rect macRect;
::GetRegionBounds (mRegion, &macRect);
#else
Rect macRect = (**mRegion).rgnBBox;
Rect macRect = (**mRegion).rgnBBox;
#endif
*aX = macRect.left;
*aY = macRect.top;
*aWidth = macRect.right - macRect.left;
*aHeight = macRect.bottom - macRect.top;
*aX = macRect.left;
*aY = macRect.top;
*aWidth = macRect.right - macRect.left;
*aHeight = macRect.bottom - macRect.top;
}
//---------------------------------------------------------------------
void nsRegionMac::Offset(PRInt32 aXOffset, PRInt32 aYOffset)
{
::OffsetRgn(mRegion, aXOffset, aYOffset);
::OffsetRgn(mRegion, aXOffset, aYOffset);
}
//---------------------------------------------------------------------
@ -267,27 +285,25 @@ PRBool nsRegionMac::ContainsRect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32
NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
{
nsRegionRectSet *rects;
nsRegionRectSet *rects;
NS_ASSERTION(!(nsnull == aRects), "bad ptr");
NS_ASSERTION(!(nsnull == aRects), "bad ptr");
rects = *aRects;
rects = *aRects;
if (nsnull == rects)
{
rects = (nsRegionRectSet *)PR_Malloc(sizeof(nsRegionRectSet) + (sizeof(nsRegionRect) << 3));
if (nsnull == rects) {
rects = (nsRegionRectSet *)PR_Malloc(sizeof(nsRegionRectSet) + (sizeof(nsRegionRect) << 3));
if (nsnull == rects)
{
*aRects = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
if (nsnull == rects) {
*aRects = nsnull;
return NS_ERROR_OUT_OF_MEMORY;
}
rects->mRectsLen = 9;
}
rects->mRectsLen = 9;
}
rects->mNumRects = 0;
rects->mArea = 0;
rects->mNumRects = 0;
rects->mArea = 0;
/* This is a minor adaptation of code written by Hugh Fisher
and published in the RegionToRectangles example in the InfoMac archives.
@ -297,12 +313,11 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
#define MaxY 32767
#define StackMax 1024
typedef struct
{
typedef struct {
short size;
Rect bbox;
short data[];
} ** Internal;
} ** Internal;
Internal region;
short width, xAdjust, y, index, x1, x2, x;
@ -312,17 +327,16 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
region = (Internal)mRegion;
/* Check for plain rectangle */
if ((**region).size == 10)
{
if ((**region).size == 10) {
rects->mRects[0].x = (**region).bbox.left;
rects->mRects[0].y = (**region).bbox.top;
rects->mRects[0].width = (**region).bbox.right - (**region).bbox.left;
rects->mRects[0].height = (**region).bbox.bottom - (**region).bbox.top;
rects->mNumRects = 1;
rects->mArea = rects->mRects[0].width * rects->mRects[0].height;
rects->mNumRects = 1;
rects->mArea = rects->mRects[0].width * rects->mRects[0].height;
*aRects = rects;
*aRects = rects;
return NS_OK;
}
@ -335,18 +349,16 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
if (width < StackMax)
buffer = stackStorage;
else
{
else {
buffer = (short *)PR_Malloc(width * 2);
if (buffer == NULL)
{
if (buffer == NULL) {
/* Truly humungous region or very low on memory.
Quietly doing nothing seems to be the
traditional Quickdraw response. */
*aRects = rects;
*aRects = rects;
return NS_OK;
}
}
}
/* Initialise scan line list to bottom edges */
@ -358,34 +370,29 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
/* Loop until we hit an empty scan line */
while ((**region).data[index] != EndMark)
{
while ((**region).data[index] != EndMark) {
y = (**region).data[index];
index ++;
index++;
/* Loop through horizontal runs on this line */
while ((**region).data[index] != EndMark)
{
while ((**region).data[index] != EndMark) {
x1 = (**region).data[index];
index ++;
x2 = (**region).data[index];
index ++;
x = x1;
while (x < x2)
{
if (buffer[x - xAdjust] < y)
{
nsRegionRect box;
while (x < x2) {
if (buffer[x - xAdjust] < y) {
nsRegionRect box;
/* We have a bottom edge - how long for? */
box.x = x;
box.y = buffer[x - xAdjust];
while (x < x2 && buffer[x - xAdjust] == box.y)
{
while (x < x2 && buffer[x - xAdjust] == box.y) {
buffer[x - xAdjust] = MaxY;
x ++;
}
@ -394,26 +401,21 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
box.width = x - box.x;
box.height = y - box.y;
if (rects->mNumRects == rects->mRectsLen)
{
void *buf = PR_Realloc((void *)rects, sizeof(nsRegionRectSet) + sizeof(nsRegionRect) * (rects->mRectsLen + 7));
if (rects->mNumRects == rects->mRectsLen) {
void *buf = PR_Realloc((void *)rects, sizeof(nsRegionRectSet) + sizeof(nsRegionRect) * (rects->mRectsLen + 7));
if (nsnull != buf)
{
rects = (nsRegionRectSet *)buf;
rects->mRectsLen += 8;
}
}
if (nsnull != buf) {
rects = (nsRegionRectSet *)buf;
rects->mRectsLen += 8;
}
}
if (rects->mNumRects != rects->mRectsLen)
{
rects->mArea += box.width * box.height;
rects->mRects[rects->mNumRects] = box;
rects->mNumRects++;
}
}
else
{
if (rects->mNumRects != rects->mRectsLen) {
rects->mArea += box.width * box.height;
rects->mRects[rects->mNumRects] = box;
rects->mNumRects++;
}
} else {
/* This becomes a top edge */
buffer[x - xAdjust] = y;
@ -434,19 +436,19 @@ NS_IMETHODIMP nsRegionMac::GetRects(nsRegionRectSet **aRects)
#undef MaxY
#undef StackMax
*aRects = rects;
*aRects = rects;
return NS_OK;
return NS_OK;
}
//---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac::FreeRects(nsRegionRectSet *aRects)
{
if (nsnull != aRects)
PR_Free((void *)aRects);
if (nsnull != aRects)
PR_Free((void *)aRects);
return NS_OK;
return NS_OK;
}
//---------------------------------------------------------------------
@ -454,31 +456,28 @@ NS_IMETHODIMP nsRegionMac::FreeRects(nsRegionRectSet *aRects)
NS_IMETHODIMP nsRegionMac::GetNativeRegion(void *&aRegion) const
{
aRegion = (void *)mRegion;
return NS_OK;
aRegion = (void *)mRegion;
return NS_OK;
}
nsresult nsRegionMac::SetNativeRegion(void *aRegion)
{
if (aRegion)
{
::CopyRgn((RgnHandle)aRegion, mRegion);
SetRegionType();
}
else
{
Init();
}
return NS_OK;
if (aRegion) {
::CopyRgn((RgnHandle)aRegion, mRegion);
SetRegionType();
} else {
Init();
}
return NS_OK;
}
//---------------------------------------------------------------------
NS_IMETHODIMP nsRegionMac::GetRegionComplexity(nsRegionComplexity &aComplexity) const
{
aComplexity = mRegionType;
return NS_OK;
aComplexity = mRegionType;
return NS_OK;
}
//---------------------------------------------------------------------
@ -486,17 +485,17 @@ NS_IMETHODIMP nsRegionMac::GetRegionComplexity(nsRegionComplexity &aComplexity)
void nsRegionMac::SetRegionType()
{
if (::EmptyRgn(mRegion) == PR_TRUE)
mRegionType = eRegionComplexity_empty;
else
if (::EmptyRgn(mRegion) == PR_TRUE)
mRegionType = eRegionComplexity_empty;
else
#if TARGET_CARBON
if ( ::IsRegionRectangular(mRegion) )
if ( ::IsRegionRectangular(mRegion) )
#else
if ((*mRegion)->rgnSize == 10)
if ((*mRegion)->rgnSize == 10)
#endif
mRegionType = eRegionComplexity_rect;
else
mRegionType = eRegionComplexity_complex;
mRegionType = eRegionComplexity_rect;
else
mRegionType = eRegionComplexity_complex;
}
@ -505,24 +504,16 @@ void nsRegionMac::SetRegionType()
void nsRegionMac::SetRegionEmpty()
{
::SetEmptyRgn(mRegion);
SetRegionType();
::SetEmptyRgn(mRegion);
SetRegionType();
}
//---------------------------------------------------------------------
RgnHandle nsRegionMac::CreateRectRegion(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
{
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion(); //::NewRgn();
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
return rectRgn;
RgnHandle rectRgn = sNativeRegionPool.GetNewRegion();
if (rectRgn != nsnull)
::SetRectRgn(rectRgn, aX, aY, aX + aWidth, aY + aHeight);
return rectRgn;
}