зеркало из https://github.com/mozilla/pjs.git
Bug 89918 - update xlib region code. Patch from timecop@network.email.ne.jp,
r=Roland.Mainz@informatik.med.uni-giessen.de, sr=brendan
This commit is contained in:
Родитель
d897b5f9bf
Коммит
3651df1e28
|
@ -1,4 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim:ts=2:et:sw=2
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
|
@ -18,41 +19,92 @@
|
|||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Stuart Parmenter <pavlov@netscape.com>
|
||||
*/
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsRegionXlib.h"
|
||||
#include "xregion.h"
|
||||
|
||||
// #define DEBUG_REGIONS 1
|
||||
|
||||
#ifdef DEBUG_REGIONS
|
||||
static int nRegions;
|
||||
#endif
|
||||
|
||||
Region nsRegionXlib::copyRegion = 0;
|
||||
|
||||
static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
|
||||
|
||||
nsRegionXlib::nsRegionXlib()
|
||||
{
|
||||
#ifdef DEBUG_REGIONS
|
||||
++nRegions;
|
||||
printf("REGIONS+ = %i\n", nRegions);
|
||||
#endif
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mRegion = nsnull;
|
||||
mRegionType = eRegionComplexity_empty;
|
||||
}
|
||||
|
||||
nsRegionXlib::~nsRegionXlib()
|
||||
{
|
||||
#ifdef DEBUG_REGIONS
|
||||
--nRegions;
|
||||
printf("REGIONS- = %i\n", nRegions);
|
||||
#endif
|
||||
|
||||
if (mRegion)
|
||||
::XDestroyRegion(mRegion);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsRegionXlib, nsIRegion)
|
||||
|
||||
nsresult
|
||||
nsRegionXlib::Init()
|
||||
{
|
||||
//NS_ASSERTION(!mRegion, "already initialized");
|
||||
if (mRegion) {
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = nsnull;
|
||||
}
|
||||
|
||||
mRegion = ::XCreateRegion();
|
||||
mRegionType = eRegionComplexity_empty;
|
||||
NS_IMPL_ISUPPORTS1(nsRegionXlib, nsIRegion)
|
||||
|
||||
Region
|
||||
nsRegionXlib::GetCopyRegion()
|
||||
{
|
||||
if (!copyRegion)
|
||||
copyRegion = ::XCreateRegion();
|
||||
return copyRegion;
|
||||
}
|
||||
|
||||
Region
|
||||
nsRegionXlib::xlib_region_copy(Region region)
|
||||
{
|
||||
Region nRegion;
|
||||
nRegion = XCreateRegion();
|
||||
|
||||
XUnionRegion(region, GetCopyRegion(), nRegion);
|
||||
|
||||
return nRegion;
|
||||
}
|
||||
|
||||
Region nsRegionXlib::xlib_region_from_rect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
XRectangle rect;
|
||||
Region nRegion;
|
||||
|
||||
rect.x = aX;
|
||||
rect.y = aY;
|
||||
rect.width = aWidth;
|
||||
rect.height = aHeight;
|
||||
|
||||
nRegion = XCreateRegion();
|
||||
|
||||
XUnionRectWithRegion(&rect, GetCopyRegion(), nRegion);
|
||||
|
||||
return nRegion;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRegionXlib::Init()
|
||||
{
|
||||
if (mRegion) {
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -60,34 +112,17 @@ nsRegionXlib::Init()
|
|||
void
|
||||
nsRegionXlib::SetTo(const nsIRegion &aRegion)
|
||||
{
|
||||
Init();
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
SetRegionEmpty();
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
::XUnionRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
mRegion = xlib_region_copy(pRegion->mRegion);
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
SetRegionEmpty();
|
||||
|
||||
XRectangle r;
|
||||
|
||||
r.x = aX;
|
||||
r.y = aY;
|
||||
r.width = aWidth;
|
||||
r.height = aHeight;
|
||||
|
||||
Region nRegion = ::XCreateRegion();
|
||||
Region tRegion = ::XCreateRegion();
|
||||
::XUnionRectWithRegion(&r, tRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
::XDestroyRegion(tRegion);
|
||||
mRegion = nRegion;
|
||||
Init();
|
||||
mRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -104,7 +139,7 @@ nsRegionXlib::Intersect(const nsIRegion &aRegion)
|
|||
void
|
||||
nsRegionXlib::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
Region tRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
|
||||
|
@ -119,45 +154,96 @@ nsRegionXlib::Union(const nsIRegion &aRegion)
|
|||
{
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
if (pRegion->mRegion && !::XEmptyRegion(pRegion->mRegion)) {
|
||||
if (mRegion) {
|
||||
if (::XEmptyRegion(mRegion)) {
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = xlib_region_copy(pRegion->mRegion);
|
||||
} else {
|
||||
Region nRegion = ::XCreateRegion();
|
||||
::XUnionRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
} else
|
||||
mRegion = xlib_region_copy(pRegion->mRegion);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
if (mRegion) {
|
||||
XRectangle rect;
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
::XUnionRegion(mRegion, tRegion, nRegion);
|
||||
rect.x = aX;
|
||||
rect.y = aY;
|
||||
rect.width = aWidth;
|
||||
rect.height = aHeight;
|
||||
|
||||
if (rect.width > 0 && rect.height > 0) {
|
||||
if (::XEmptyRegion(mRegion)) {
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
} else {
|
||||
Region nRegion = ::XCreateRegion();
|
||||
::XUnionRectWithRegion(&rect, mRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
::XDestroyRegion(tRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Subtract(const nsIRegion &aRegion)
|
||||
{
|
||||
#ifdef DEBUG_REGIONS
|
||||
printf("nsRegionXlib::Subtract ");
|
||||
#endif
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
if (pRegion->mRegion) {
|
||||
if (mRegion) {
|
||||
#ifdef DEBUG_REGIONS
|
||||
printf("-");
|
||||
#endif
|
||||
Region nRegion = ::XCreateRegion();
|
||||
::XSubtractRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
} else {
|
||||
#ifdef DEBUG_REGIONS
|
||||
printf("+");
|
||||
#endif
|
||||
mRegion = ::XCreateRegion();
|
||||
::XSubtractRegion(GetCopyRegion(), pRegion->mRegion, mRegion);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_REGIONS
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
if (mRegion) {
|
||||
Region tRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
Region nRegion = ::XCreateRegion();
|
||||
::XSubtractRegion(mRegion, tRegion, nRegion);
|
||||
::XDestroyRegion(mRegion);
|
||||
::XDestroyRegion(tRegion);
|
||||
mRegion = nRegion;
|
||||
} else {
|
||||
Region tRegion = xlib_region_from_rect(aX, aY, aWidth, aHeight);
|
||||
mRegion = XCreateRegion();
|
||||
::XSubtractRegion(GetCopyRegion(), tRegion, mRegion);
|
||||
::XDestroyRegion(tRegion);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -173,13 +259,23 @@ nsRegionXlib::IsEqual(const nsIRegion &aRegion)
|
|||
{
|
||||
nsRegionXlib *pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
if (mRegion && pRegion->mRegion) {
|
||||
return ::XEqualRegion(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
|
||||
nsRegionXlib::GetBoundingBox(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
if (mRegion) {
|
||||
XRectangle r;
|
||||
|
||||
::XClipBox(mRegion, &r);
|
||||
|
@ -188,6 +284,12 @@ nsRegionXlib::GetBoundingBox(PRInt32 *aX, PRInt32 *aY,
|
|||
*aY = r.y;
|
||||
*aWidth = r.width;
|
||||
*aHeight = r.height;
|
||||
} else {
|
||||
*aX = 0;
|
||||
*aY = 0;
|
||||
*aWidth = 0;
|
||||
*aHeight = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -202,12 +304,18 @@ PRBool
|
|||
nsRegionXlib::ContainsRect(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return ::XRectInRegion(mRegion, aX, aY, aWidth, aHeight);
|
||||
return (::XRectInRegion(mRegion, aX, aY, aWidth, aHeight) == RectangleIn) ?
|
||||
PR_TRUE : PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::GetRects(nsRegionRectSet **aRects)
|
||||
{
|
||||
*aRects = nsnull;
|
||||
|
||||
if (!mRegion)
|
||||
return NS_OK;
|
||||
|
||||
nsRegionRectSet *rects;
|
||||
int nbox;
|
||||
BOX *pbox;
|
||||
|
@ -222,13 +330,11 @@ nsRegionXlib::GetRects(nsRegionRectSet **aRects)
|
|||
|
||||
rects = *aRects;
|
||||
|
||||
if ((nsnull == rects) || (rects->mRectsLen < (PRUint32)nbox))
|
||||
{
|
||||
void *buf = PR_Realloc(rects, sizeof(nsRegionRectSet) + (sizeof(nsRegionRect
|
||||
) * (nbox - 1)));
|
||||
if ((nsnull == rects) || (rects->mRectsLen < (PRUint32)nbox)) {
|
||||
void *buf = PR_Realloc(rects, sizeof(nsRegionRectSet) +
|
||||
(sizeof(nsRegionRect) * (nbox - 1)));
|
||||
|
||||
if (nsnull == buf)
|
||||
{
|
||||
if (nsnull == buf) {
|
||||
if (nsnull != rects)
|
||||
rects->mNumRects = 0;
|
||||
|
||||
|
@ -243,8 +349,7 @@ nsRegionXlib::GetRects(nsRegionRectSet **aRects)
|
|||
rects->mArea = 0;
|
||||
rect = &rects->mRects[0];
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
while (nbox--) {
|
||||
rect->x = pbox->x1;
|
||||
rect->width = (pbox->x2 - pbox->x1);
|
||||
rect->y = pbox->y1;
|
||||
|
@ -293,25 +398,16 @@ void nsRegionXlib::SetRegionEmpty()
|
|||
{
|
||||
if (!IsEmpty()) {
|
||||
::XDestroyRegion(mRegion);
|
||||
mRegion = XCreateRegion();
|
||||
}
|
||||
}
|
||||
|
||||
Region
|
||||
nsRegionXlib::CreateRectRegion(PRInt32 aX,
|
||||
PRInt32 aY,
|
||||
PRInt32 aWidth,
|
||||
PRInt32 aHeight)
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::GetNumRects(PRUint32 *aRects) const
|
||||
{
|
||||
Region tRegion = XCreateRegion();
|
||||
XRectangle r;
|
||||
if (!mRegion)
|
||||
*aRects = 0;
|
||||
|
||||
r.x = aX;
|
||||
r.y = aY;
|
||||
r.width = aWidth;
|
||||
r.height = aHeight;
|
||||
*aRects = mRegion->numRects;
|
||||
|
||||
::XUnionRectWithRegion(&r, tRegion, tRegion);
|
||||
|
||||
return (tRegion);
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -56,16 +56,18 @@ class nsRegionXlib : public nsIRegion
|
|||
NS_IMETHOD FreeRects(nsRegionRectSet *aRects);
|
||||
NS_IMETHOD GetNativeRegion(void *&aRegion) const;
|
||||
NS_IMETHOD GetRegionComplexity(nsRegionComplexity &aComplexity) const;
|
||||
NS_IMETHOD GetNumRects(PRUint32 *aRects) const { *aRects = 0; return NS_OK; }
|
||||
NS_IMETHOD GetNumRects(PRUint32 *aRects) const;
|
||||
|
||||
protected:
|
||||
Region xlib_region_copy(Region region);
|
||||
Region xlib_region_from_rect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
private:
|
||||
Region mRegion;
|
||||
nsRegionComplexity mRegionType;
|
||||
|
||||
void SetRegionEmpty();
|
||||
Region CreateRectRegion(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
static Region copyRegion;
|
||||
|
||||
inline Region GetCopyRegion();
|
||||
inline void SetRegionEmpty();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче