зеркало из https://github.com/mozilla/gecko-dev.git
fixed potential memory problems.
This commit is contained in:
Родитель
78aa051ad5
Коммит
fa957816e2
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче