region code for xlib gfx.
git-svn-id: svn://10.0.0.236/trunk@27562 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -16,13 +16,26 @@
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "prmem.h"
|
||||
#include "nsRegionXlib.h"
|
||||
#include "xregion.h"
|
||||
|
||||
static NS_DEFINE_IID(kRegionIID, NS_IREGION_IID);
|
||||
|
||||
nsRegionXlib::nsRegionXlib()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
|
||||
mRegion = nsnull;
|
||||
mRegionType = eRegionComplexity_empty;
|
||||
}
|
||||
|
||||
nsRegionXlib::~nsRegionXlib()
|
||||
{
|
||||
if (mRegion)
|
||||
XDestroyRegion(mRegion);
|
||||
|
||||
mRegion = NULL;
|
||||
}
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE(nsRegionXlib, kRegionIID)
|
||||
@@ -32,109 +45,266 @@ NS_IMPL_RELEASE(nsRegionXlib)
|
||||
nsresult
|
||||
nsRegionXlib::Init()
|
||||
{
|
||||
return 0;
|
||||
NS_ADDREF_THIS();
|
||||
|
||||
mRegion = XCreateRegion();
|
||||
mRegionType = eRegionComplexity_empty;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::SetTo(const nsIRegion &aRegion)
|
||||
{
|
||||
return;
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
SetRegionEmpty();
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
XUnionRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::SetTo(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return;
|
||||
SetRegionEmpty();
|
||||
|
||||
XRectangle r;
|
||||
|
||||
r.x = aX;
|
||||
r.y = aY;
|
||||
r.width = aWidth;
|
||||
r.height = aHeight;
|
||||
|
||||
Region nRegion = XCreateRegion();
|
||||
XUnionRectWithRegion(&r, mRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Intersect(const nsIRegion &aRegion)
|
||||
{
|
||||
return;
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
Region nRegion;
|
||||
XIntersectRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Intersect(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return;
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
|
||||
Region nRegion;
|
||||
|
||||
XIntersectRegion(mRegion, tRegion, nRegion);
|
||||
XDestroyRegion(tRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Union(const nsIRegion &aRegion)
|
||||
{
|
||||
return;
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
Region nRegion;
|
||||
XUnionRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Union(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return;
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
|
||||
Region nRegion;
|
||||
XUnionRegion(mRegion, tRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
XDestroyRegion(tRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Subtract(const nsIRegion &aRegion)
|
||||
{
|
||||
return;
|
||||
nsRegionXlib * pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
Region nRegion;
|
||||
XSubtractRegion(mRegion, pRegion->mRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Subtract(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return;
|
||||
Region tRegion = CreateRectRegion(aX, aY, aWidth, aHeight);
|
||||
|
||||
Region nRegion;
|
||||
XSubtractRegion(mRegion, tRegion, nRegion);
|
||||
XDestroyRegion(mRegion);
|
||||
XDestroyRegion(tRegion);
|
||||
mRegion = nRegion;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsRegionXlib::IsEmpty(void)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return XEmptyRegion(mRegion);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsRegionXlib::IsEqual(const nsIRegion &aRegion)
|
||||
{
|
||||
return PR_FALSE;
|
||||
nsRegionXlib *pRegion = (nsRegionXlib *)&aRegion;
|
||||
|
||||
return XEqualRegion(mRegion, pRegion->mRegion);
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::GetBoundingBox(PRInt32 *aX, PRInt32 *aY,
|
||||
PRInt32 *aWidth, PRInt32 *aHeight)
|
||||
{
|
||||
return;
|
||||
XRectangle r;
|
||||
|
||||
XClipBox(mRegion, &r);
|
||||
|
||||
*aX = r.x;
|
||||
*aY = r.y;
|
||||
*aWidth = r.width;
|
||||
*aHeight = r.height;
|
||||
}
|
||||
|
||||
void
|
||||
nsRegionXlib::Offset(PRInt32 aXOffset, PRInt32 aYOffset)
|
||||
{
|
||||
return;
|
||||
XOffsetRegion(mRegion, aXOffset, aYOffset);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsRegionXlib::ContainsRect(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight)
|
||||
{
|
||||
return PR_FALSE;
|
||||
return XRectInRegion(mRegion, aX, aY, aWidth, aHeight);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::GetRects(nsRegionRectSet **aRects)
|
||||
{
|
||||
nsRegionRectSet *rects;
|
||||
int nbox;
|
||||
BOX *pbox;
|
||||
nsRegionRect *rect;
|
||||
|
||||
NS_ASSERTION(!(nsnull == aRects), "bad ptr");
|
||||
|
||||
//code lifted from old xfe. MMP
|
||||
|
||||
pbox = mRegion->rects;
|
||||
nbox = mRegion->numRects;
|
||||
|
||||
rects = *aRects;
|
||||
|
||||
if ((nsnull == rects) || (rects->mRectsLen < (PRUint32)nbox))
|
||||
{
|
||||
void *buf = PR_Realloc(rects, sizeof(nsRegionRectSet) + (sizeof(nsRegionRect
|
||||
) * (nbox - 1)));
|
||||
|
||||
if (nsnull == buf)
|
||||
{
|
||||
if (nsnull != rects)
|
||||
rects->mNumRects = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rects = (nsRegionRectSet *)buf;
|
||||
rects->mRectsLen = nbox;
|
||||
}
|
||||
|
||||
rects->mNumRects = nbox;
|
||||
rects->mArea = 0;
|
||||
rect = &rects->mRects[0];
|
||||
|
||||
while (nbox--)
|
||||
{
|
||||
rect->x = pbox->x1;
|
||||
rect->width = (pbox->x2 - pbox->x1);
|
||||
rect->y = pbox->y1;
|
||||
rect->height = (pbox->y2 - pbox->y1);
|
||||
|
||||
rects->mArea += rect->width * rect->height;
|
||||
|
||||
pbox++;
|
||||
rect++;
|
||||
}
|
||||
|
||||
*aRects = rects;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::FreeRects(nsRegionRectSet *aRects)
|
||||
{
|
||||
if (nsnull != aRects)
|
||||
PR_Free((void *)aRects);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::GetNativeRegion(void *&aRegion) const
|
||||
{
|
||||
aRegion = (void *)mRegion;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsRegionXlib::GetRegionComplexity(nsRegionComplexity &aComplexity) const
|
||||
{
|
||||
// cast to avoid const-ness problems on some compilers
|
||||
if (((nsRegionXlib*)this)->IsEmpty())
|
||||
aComplexity = eRegionComplexity_empty;
|
||||
else
|
||||
aComplexity = eRegionComplexity_rect;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsRegionXlib::SetRegionEmpty()
|
||||
{
|
||||
if (!IsEmpty()) {
|
||||
XDestroyRegion(mRegion);
|
||||
mRegion = XCreateRegion();
|
||||
}
|
||||
}
|
||||
|
||||
Region
|
||||
nsRegionXlib::CreateRectRegion(PRInt32 aX,
|
||||
PRInt32 aY,
|
||||
PRInt32 aWidth,
|
||||
PRInt32 aHeight)
|
||||
{
|
||||
Region tRegion = XCreateRegion();
|
||||
XRectangle r;
|
||||
|
||||
r.x = aX;
|
||||
r.y = aY;
|
||||
r.width = aWidth;
|
||||
r.height = aHeight;
|
||||
|
||||
Region rRegion;
|
||||
XUnionRectWithRegion(&r, tRegion, rRegion);
|
||||
XDestroyRegion(tRegion);
|
||||
|
||||
return (rRegion);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,15 @@
|
||||
|
||||
#include "nsIRegion.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
class nsRegionXlib : public nsIRegion
|
||||
{
|
||||
public:
|
||||
nsRegionXlib();
|
||||
virtual ~nsRegionXlib();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
@@ -48,6 +53,14 @@ class nsRegionXlib : public nsIRegion
|
||||
NS_IMETHOD GetNativeRegion(void *&aRegion) const;
|
||||
NS_IMETHOD GetRegionComplexity(nsRegionComplexity &aComplexity) const;
|
||||
|
||||
private:
|
||||
Region mRegion;
|
||||
nsRegionComplexity mRegionType;
|
||||
|
||||
void SetRegionEmpty();
|
||||
Region CreateRectRegion(PRInt32 aX, PRInt32 aY,
|
||||
PRInt32 aWidth, PRInt32 aHeight);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
177
mozilla/gfx/src/xlib/xregion.h
Normal file
177
mozilla/gfx/src/xlib/xregion.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/* $XConsortium: region.h,v 11.13 91/09/10 08:21:49 rws Exp $ */
|
||||
/************************************************************************
|
||||
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
|
||||
and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Digital or MIT not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
|
||||
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
|
||||
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#ifndef _XREGION_H
|
||||
#define _XREGION_H
|
||||
|
||||
typedef struct {
|
||||
short x1, x2, y1, y2;
|
||||
} Box, BOX, BoxRec, *BoxPtr;
|
||||
|
||||
typedef struct {
|
||||
short x, y, width, height;
|
||||
}RECTANGLE, RectangleRec, *RectanglePtr;
|
||||
|
||||
#ifdef TRUE
|
||||
#undef TRUE
|
||||
#endif
|
||||
|
||||
#define TRUE 1
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef MAXSHORT
|
||||
#define MAXSHORT 32767
|
||||
#endif
|
||||
#ifndef MINSHORT
|
||||
#define MINSHORT -MAXSHORT
|
||||
#endif
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* clip region
|
||||
*/
|
||||
|
||||
typedef struct _XRegion {
|
||||
long size;
|
||||
long numRects;
|
||||
BOX *rects;
|
||||
BOX extents;
|
||||
} REGION;
|
||||
|
||||
/* Xutil.h contains the declaration:
|
||||
* typedef struct _XRegion *Region;
|
||||
*/
|
||||
|
||||
/* 1 if two BOXs overlap.
|
||||
* 0 if two BOXs do not overlap.
|
||||
* Remember, x2 and y2 are not in the region
|
||||
*/
|
||||
#define EXTENTCHECK(r1, r2) \
|
||||
((r1)->x2 > (r2)->x1 && \
|
||||
(r1)->x1 < (r2)->x2 && \
|
||||
(r1)->y2 > (r2)->y1 && \
|
||||
(r1)->y1 < (r2)->y2)
|
||||
|
||||
/*
|
||||
* update region extents
|
||||
*/
|
||||
#define EXTENTS(r,idRect){\
|
||||
if((r)->x1 < (idRect)->extents.x1)\
|
||||
(idRect)->extents.x1 = (r)->x1;\
|
||||
if((r)->y1 < (idRect)->extents.y1)\
|
||||
(idRect)->extents.y1 = (r)->y1;\
|
||||
if((r)->x2 > (idRect)->extents.x2)\
|
||||
(idRect)->extents.x2 = (r)->x2;\
|
||||
if((r)->y2 > (idRect)->extents.y2)\
|
||||
(idRect)->extents.y2 = (r)->y2;\
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if there is enough memory in the present region.
|
||||
*/
|
||||
#define MEMCHECK(reg, rect, firstrect){\
|
||||
if ((reg)->numRects >= ((reg)->size - 1)){\
|
||||
(firstrect) = (BOX *) Xrealloc \
|
||||
((char *)(firstrect), (unsigned) (2 * (sizeof(BOX)) * ((reg)->size)));\
|
||||
if ((firstrect) == 0)\
|
||||
return(0);\
|
||||
(reg)->size *= 2;\
|
||||
(rect) = &(firstrect)[(reg)->numRects];\
|
||||
}\
|
||||
}
|
||||
|
||||
/* this routine checks to see if the previous rectangle is the same
|
||||
* or subsumes the new rectangle to add.
|
||||
*/
|
||||
|
||||
#define CHECK_PREVIOUS(Reg, R, Rx1, Ry1, Rx2, Ry2)\
|
||||
(!(((Reg)->numRects > 0)&&\
|
||||
((R-1)->y1 == (Ry1)) &&\
|
||||
((R-1)->y2 == (Ry2)) &&\
|
||||
((R-1)->x1 <= (Rx1)) &&\
|
||||
((R-1)->x2 >= (Rx2))))
|
||||
|
||||
/* add a rectangle to the given Region */
|
||||
#define ADDRECT(reg, r, rx1, ry1, rx2, ry2){\
|
||||
if (((rx1) < (rx2)) && ((ry1) < (ry2)) &&\
|
||||
CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
|
||||
(r)->x1 = (rx1);\
|
||||
(r)->y1 = (ry1);\
|
||||
(r)->x2 = (rx2);\
|
||||
(r)->y2 = (ry2);\
|
||||
EXTENTS((r), (reg));\
|
||||
(reg)->numRects++;\
|
||||
(r)++;\
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* add a rectangle to the given Region */
|
||||
#define ADDRECTNOX(reg, r, rx1, ry1, rx2, ry2){\
|
||||
if ((rx1 < rx2) && (ry1 < ry2) &&\
|
||||
CHECK_PREVIOUS((reg), (r), (rx1), (ry1), (rx2), (ry2))){\
|
||||
(r)->x1 = (rx1);\
|
||||
(r)->y1 = (ry1);\
|
||||
(r)->x2 = (rx2);\
|
||||
(r)->y2 = (ry2);\
|
||||
(reg)->numRects++;\
|
||||
(r)++;\
|
||||
}\
|
||||
}
|
||||
|
||||
#define EMPTY_REGION(pReg) pReg->numRects = 0
|
||||
|
||||
#define REGION_NOT_EMPTY(pReg) pReg->numRects
|
||||
|
||||
#define INBOX(r, x, y) \
|
||||
( ( ((r).x2 > x)) && \
|
||||
( ((r).x1 <= x)) && \
|
||||
( ((r).y2 > y)) && \
|
||||
( ((r).y1 <= y)) )
|
||||
|
||||
/*
|
||||
* number of points to buffer before sending them off
|
||||
* to scanlines() : Must be an even number
|
||||
*/
|
||||
#define NUMPTSTOBUFFER 200
|
||||
|
||||
/*
|
||||
* used to allocate buffers for points and link
|
||||
* the buffers together
|
||||
*/
|
||||
typedef struct _POINTBLOCK {
|
||||
XPoint pts[NUMPTSTOBUFFER];
|
||||
struct _POINTBLOCK *next;
|
||||
} POINTBLOCK;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user