зеркало из https://github.com/mozilla/pjs.git
Integrate patches from Frank Visser <fvisser@hgmp.mrc.ac.uk> to use gtk
regions.
This commit is contained in:
Родитель
888f7a22d5
Коммит
133406a46a
|
@ -22,38 +22,56 @@
|
|||
#include "xpassert.h"
|
||||
|
||||
#include "gnome.h"
|
||||
#include "gdk/gdkprivate.h"
|
||||
#include <gdk/gdkprivate.h>
|
||||
#include <gdk/gdktypes.h>
|
||||
#include <X11/X.h>
|
||||
#include "gnomefe.h"
|
||||
|
||||
typedef struct {
|
||||
short x1, x2, y1, y2;
|
||||
} Box, BOX, BoxRec, *BoxPtr;
|
||||
/* oh, how we love hacking around in x internals */
|
||||
|
||||
typedef struct _XRegion {
|
||||
long size;
|
||||
long numRects;
|
||||
BOX *rects;
|
||||
BOX extents;
|
||||
} REGION;
|
||||
#include "x_region.h"
|
||||
|
||||
/* typedef to make working with GdkRegion** a bit easier */
|
||||
typedef GdkRegion **GdkRegionHandle;
|
||||
|
||||
/* Creates an empty region. Returns NULL if region can't be created */
|
||||
FE_Region
|
||||
FE_CreateRegion()
|
||||
{
|
||||
return (FE_Region)XCreateRegion();
|
||||
GdkRegionHandle hdl;
|
||||
GdkRegion *new_region = gdk_region_new();
|
||||
|
||||
if (new_region == NULL)
|
||||
return NULL;
|
||||
|
||||
hdl = (GdkRegionHandle)(malloc(sizeof(GdkRegionHandle)));
|
||||
(GdkRegion*)(*hdl) = new_region;
|
||||
/* printf("empty Region created at %p\n", hdl); */
|
||||
return (FE_Region)hdl;
|
||||
}
|
||||
|
||||
/* Creates a region from a rectangle. Returns NULL if region can't be created */
|
||||
FE_Region
|
||||
FE_CreateRectRegion(XP_Rect *rect)
|
||||
{
|
||||
XPoint points[4];
|
||||
GdkPoint points[4];
|
||||
GdkRegion *new_region;
|
||||
GdkRegionHandle hdl;
|
||||
|
||||
points[0].x = points[3].x = (short)rect->left; /* points[] corresponds to */
|
||||
points[0].y = points[1].y = (short)rect->top; /* top-left, top-right, */
|
||||
points[1].x = points[2].x = (short)rect->right; /* bot-left and bot-right */
|
||||
points[3].y = points[2].y = (short)rect->bottom;/* respectively. */
|
||||
|
||||
return (FE_Region)XPolygonRegion(points, 4, EvenOddRule);
|
||||
|
||||
new_region = gdk_region_polygon(points, 4, GDK_EVEN_ODD_RULE);
|
||||
if (new_region == NULL)
|
||||
return NULL;
|
||||
hdl = (GdkRegionHandle)(malloc(sizeof(GdkRegionHandle)));
|
||||
*hdl=new_region;
|
||||
/* printf("Region created from rectangle at %p\n", hdl); */
|
||||
/* printf("dimension are %d %d %d %d\n", rect->left, rect->top,
|
||||
rect->right, rect->bottom); */
|
||||
return (FE_Region)hdl;
|
||||
/* Fill rule is irrelevant since there */
|
||||
/* should be no self overlap. */
|
||||
}
|
||||
|
@ -65,55 +83,77 @@ FE_CreateRectRegion(XP_Rect *rect)
|
|||
FE_Region
|
||||
FE_SetRectRegion(FE_Region region, XP_Rect *rect)
|
||||
{
|
||||
XRectangle rectangle;
|
||||
|
||||
XP_ASSERT(region);
|
||||
|
||||
if (!XEmptyRegion((Region)region)) /* If region is not empty. */
|
||||
XSubtractRegion((Region)region, (Region)region, (Region)region);
|
||||
/* Subtract region from itself. */
|
||||
XP_ASSERT(XEmptyRegion((Region)region));
|
||||
|
||||
GdkRectangle rectangle;
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
GdkRegionHandle hdl;
|
||||
|
||||
XP_ASSERT(reg);
|
||||
|
||||
if ( !gdk_region_empty(reg) )
|
||||
reg = gdk_regions_subtract(reg, reg);
|
||||
|
||||
XP_ASSERT(gdk_empty_region(reg));
|
||||
|
||||
rectangle.x = (short)rect->left;
|
||||
rectangle.y = (short)rect->top;
|
||||
rectangle.width = (unsigned short)(rect->right - rect->left);
|
||||
rectangle.height = (unsigned short)(rect->bottom - rect->top);
|
||||
|
||||
return (FE_Region)XUnionRectWithRegion(&rectangle, (Region)region,
|
||||
(Region)region);
|
||||
reg = gdk_region_union_with_rect(reg, &rectangle);
|
||||
hdl = (GdkRegionHandle)(malloc(sizeof(GdkRegionHandle)));
|
||||
XP_ASSERT(hdl);
|
||||
*hdl = reg;
|
||||
/* printf("setrectregion done for %p\n", hdl); */
|
||||
|
||||
return (FE_Region)hdl;
|
||||
}
|
||||
|
||||
/* Destroys region */
|
||||
void
|
||||
FE_DestroyRegion(FE_Region region)
|
||||
{
|
||||
XP_ASSERT(region);
|
||||
XDestroyRegion((Region)region);
|
||||
{
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
XP_ASSERT(reg);
|
||||
|
||||
gdk_region_destroy(reg);
|
||||
free(region);
|
||||
/* printf("region freed at %p\n", region); */
|
||||
}
|
||||
|
||||
/* Make a copy of a region */
|
||||
FE_Region
|
||||
FE_CopyRegion(FE_Region src, FE_Region dst)
|
||||
{
|
||||
Region copyRegion;
|
||||
|
||||
GdkRegion *srcRegion = (GdkRegion*)(*(GdkRegionHandle)src);
|
||||
GdkRegion *dstRegion = (GdkRegion*)(*(GdkRegionHandle)dst);
|
||||
GdkRegionHandle hdl;
|
||||
GdkRegionHandle cpy;
|
||||
|
||||
XP_ASSERT(src);
|
||||
|
||||
if (dst != NULL) {
|
||||
copyRegion = (Region)dst;
|
||||
}
|
||||
else {
|
||||
/* Create an empty region */
|
||||
copyRegion = XCreateRegion();
|
||||
|
||||
if (copyRegion == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XP_ASSERT(srcRegion);
|
||||
|
||||
if (dst != NULL)
|
||||
{
|
||||
cpy = dst;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Create an empty region and assign it to the cpy handle*/
|
||||
GdkRegion *copyRegion = gdk_region_new();
|
||||
cpy = (GdkRegionHandle)malloc( sizeof(GdkRegionHandle ));
|
||||
if (copyRegion == NULL || cpy == NULL)
|
||||
return NULL;
|
||||
*cpy = copyRegion;
|
||||
}
|
||||
|
||||
/* Copy the region */
|
||||
XUnionRegion((Region)src, (Region)src, (Region)copyRegion);
|
||||
|
||||
return (FE_Region)copyRegion;
|
||||
(GdkRegion*)(*cpy) = gdk_regions_union(srcRegion, srcRegion);
|
||||
/* wierd: union between two same regions? */
|
||||
/* XUnionRegion((Region)src, (Region)src, (Region)copyRegion); */
|
||||
|
||||
/* printf("FE_CopyRegion called and done\n"); */
|
||||
return cpy;
|
||||
}
|
||||
|
||||
/* dst = src1 intersect sr2 */
|
||||
|
@ -121,11 +161,37 @@ FE_CopyRegion(FE_Region src, FE_Region dst)
|
|||
void
|
||||
FE_IntersectRegion(FE_Region src1, FE_Region src2, FE_Region dst)
|
||||
{
|
||||
XP_ASSERT(src1);
|
||||
XP_ASSERT(src2);
|
||||
XP_ASSERT(dst);
|
||||
|
||||
XIntersectRegion((Region)src1, (Region)src2, (Region)dst);
|
||||
GdkRegion *src1Region = (GdkRegion*)(*(GdkRegionHandle)src1);
|
||||
GdkRegion *src2Region = (GdkRegion*)(*(GdkRegionHandle)src2);
|
||||
GdkRegion *dstRegion = (GdkRegion*)(*(GdkRegionHandle)dst);
|
||||
GdkRegion *newRegion;
|
||||
|
||||
XP_ASSERT(src1Region);
|
||||
XP_ASSERT(src2Region);
|
||||
XP_ASSERT(dstRegion);
|
||||
|
||||
newRegion = gdk_regions_intersect(src1Region, src2Region);
|
||||
if (dstRegion == src1Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src1 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else if (dstRegion == src2Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src2 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)dst = newRegion;
|
||||
}
|
||||
/* printf("done region intersect\n"); */
|
||||
/* XIntersectRegion((Region)src1, (Region)src2, (Region)dst); */
|
||||
}
|
||||
|
||||
/* dst = src1 union src2 */
|
||||
|
@ -133,11 +199,37 @@ FE_IntersectRegion(FE_Region src1, FE_Region src2, FE_Region dst)
|
|||
void
|
||||
FE_UnionRegion(FE_Region src1, FE_Region src2, FE_Region dst)
|
||||
{
|
||||
XP_ASSERT(src1);
|
||||
XP_ASSERT(src2);
|
||||
XP_ASSERT(dst);
|
||||
GdkRegion *src1Region = (GdkRegion*)(*(GdkRegionHandle)src1);
|
||||
GdkRegion *src2Region = (GdkRegion*)(*(GdkRegionHandle)src2);
|
||||
GdkRegion *dstRegion = (GdkRegion*)(*(GdkRegionHandle)dst);
|
||||
GdkRegion *newRegion;
|
||||
|
||||
XUnionRegion((Region)src1, (Region)src2, (Region)dst);
|
||||
XP_ASSERT(src1Region);
|
||||
XP_ASSERT(src2Region);
|
||||
XP_ASSERT(dstRegion);
|
||||
|
||||
newRegion = gdk_regions_union(src1Region, src2Region);
|
||||
/* XUnionRegion((Region)src1, (Region)src2, (Region)dst); */
|
||||
if (dstRegion == src1Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src1 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else if (dstRegion == src2Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src2 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)dst = newRegion;
|
||||
}
|
||||
/* printf("done union regions\n"); */
|
||||
}
|
||||
|
||||
/* dst = src1 - src2 */
|
||||
|
@ -145,74 +237,110 @@ FE_UnionRegion(FE_Region src1, FE_Region src2, FE_Region dst)
|
|||
void
|
||||
FE_SubtractRegion(FE_Region src1, FE_Region src2, FE_Region dst)
|
||||
{
|
||||
XP_ASSERT(src1);
|
||||
XP_ASSERT(src2);
|
||||
XP_ASSERT(dst);
|
||||
GdkRegion *src1Region = (GdkRegion*)(*(GdkRegionHandle)src1);
|
||||
GdkRegion *src2Region = (GdkRegion*)(*(GdkRegionHandle)src2);
|
||||
GdkRegion *dstRegion = (GdkRegion*)(*(GdkRegionHandle)dst);
|
||||
GdkRegion *newRegion;
|
||||
|
||||
XSubtractRegion((Region)src1, (Region)src2, (Region)dst);
|
||||
XP_ASSERT(src1Region);
|
||||
XP_ASSERT(src2Region);
|
||||
XP_ASSERT(dstRegion);
|
||||
|
||||
newRegion = gdk_regions_subtract(src1Region, src2Region);
|
||||
/* XSubtractRegion((Region)src1, (Region)src2, (Region)dst); */
|
||||
if (dstRegion == src1Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src1 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else if (dstRegion == src2Region)
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)src2 =
|
||||
(GdkRegion*)*(GdkRegionHandle)dst =
|
||||
newRegion;
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_region_destroy(dstRegion);
|
||||
(GdkRegion*)*(GdkRegionHandle)dst = newRegion;
|
||||
}
|
||||
/* printf("done subtract region\n"); */
|
||||
}
|
||||
|
||||
/* Returns TRUE if the region contains no pixels */
|
||||
XP_Bool
|
||||
FE_IsEmptyRegion(FE_Region region)
|
||||
{
|
||||
XP_ASSERT(region);
|
||||
|
||||
return (XP_Bool)XEmptyRegion((Region)region);
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
XP_ASSERT(reg);
|
||||
|
||||
return (XP_Bool)gdk_region_empty(reg);
|
||||
}
|
||||
|
||||
/* Returns the bounding rectangle of the region */
|
||||
void
|
||||
FE_GetRegionBoundingBox(FE_Region region, XP_Rect *bbox)
|
||||
{
|
||||
XRectangle rect;
|
||||
|
||||
XP_ASSERT(region);
|
||||
GdkRectangle rect;
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
|
||||
XP_ASSERT(reg);
|
||||
XP_ASSERT(bbox);
|
||||
|
||||
XClipBox((Region)region, &rect);
|
||||
|
||||
|
||||
gdk_region_get_clipbox(reg, &rect);
|
||||
|
||||
bbox->left = (int32)rect.x;
|
||||
bbox->top = (int32)rect.y;
|
||||
bbox->right = (int32)(rect.x + rect.width);
|
||||
bbox->bottom = (int32)(rect.y + rect.height);
|
||||
|
||||
/* printf("done boundingbox at %p\n", region); */
|
||||
}
|
||||
|
||||
/* TRUE if rgn1 == rgn2 */
|
||||
XP_Bool
|
||||
FE_IsEqualRegion(FE_Region rgn1, FE_Region rgn2)
|
||||
{
|
||||
XP_ASSERT(rgn1);
|
||||
XP_ASSERT(rgn2);
|
||||
GdkRegion *reg1 = (GdkRegion*)(*(GdkRegionHandle)rgn1);
|
||||
GdkRegion *reg2 = (GdkRegion*)(*(GdkRegionHandle)rgn2);
|
||||
XP_ASSERT(reg1);
|
||||
XP_ASSERT(reg2);
|
||||
|
||||
return (XP_Bool)XEqualRegion((Region)rgn1, (Region)rgn2);
|
||||
/* printf ("done isequal\n"); */
|
||||
return (XP_Bool)gdk_region_equal(reg1,reg2);
|
||||
}
|
||||
|
||||
/* Moves a region by the specified offsets */
|
||||
void
|
||||
FE_OffsetRegion(FE_Region region, int32 x_offset, int32 y_offset)
|
||||
{
|
||||
XOffsetRegion((Region)region, x_offset, y_offset);
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
gdk_region_offset(reg, x_offset, y_offset);
|
||||
}
|
||||
|
||||
/* Returns TRUE if any part of the rectangle is in the specified region */
|
||||
XP_Bool
|
||||
FE_RectInRegion(FE_Region region, XP_Rect *rect)
|
||||
{
|
||||
int result;
|
||||
XRectangle box;
|
||||
|
||||
XP_ASSERT(region);
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
GdkOverlapType result;
|
||||
GdkRectangle box;
|
||||
|
||||
XP_ASSERT(reg);
|
||||
XP_ASSERT(rect);
|
||||
|
||||
|
||||
box.x = (short)rect->left;
|
||||
box.y = (short)rect->top;
|
||||
box.width = (unsigned short)(rect->right - rect->left);
|
||||
box.height = (unsigned short)(rect->bottom - rect->top);
|
||||
|
||||
result = XRectInRegion((Region)region, box.x, box.y, box.width, box.height);
|
||||
|
||||
if (result == RectangleOut)
|
||||
|
||||
result = gdk_region_rect_in(reg, &box);
|
||||
|
||||
/* printf ("done rectinregion\n"); */
|
||||
if (result == GDK_OVERLAP_RECTANGLE_OUT)
|
||||
return FALSE;
|
||||
else /* result == RectangleIn || result == RectanglePart */
|
||||
return TRUE;
|
||||
|
@ -224,27 +352,29 @@ void
|
|||
FE_ForEachRectInRegion(FE_Region region, FE_RectInRegionFunc func,
|
||||
void *closure)
|
||||
{
|
||||
Region pRegion;
|
||||
register int nbox;
|
||||
register BOX *pbox;
|
||||
XP_Rect rect;
|
||||
GdkRegion *reg = (GdkRegion*)(*(GdkRegionHandle)region);
|
||||
Region pRegion;
|
||||
register int nbox;
|
||||
register BOX *pbox;
|
||||
XP_Rect rect;
|
||||
|
||||
XP_ASSERT(region);
|
||||
XP_ASSERT(func);
|
||||
|
||||
pRegion = (Region)region;
|
||||
pbox = pRegion->rects;
|
||||
nbox = pRegion->numRects;
|
||||
|
||||
while(nbox--)
|
||||
{
|
||||
rect.left = pbox->x1;
|
||||
rect.right = pbox->x2;
|
||||
rect.top = pbox->y1;
|
||||
rect.bottom = pbox->y2;
|
||||
(*func)(closure, &rect);
|
||||
pbox++;
|
||||
}
|
||||
XP_ASSERT(reg);
|
||||
XP_ASSERT(func);
|
||||
|
||||
pRegion = (Region)((GdkRegionPrivate *)reg)->xregion;
|
||||
pbox = pRegion->rects;
|
||||
nbox = pRegion->numRects;
|
||||
|
||||
while(nbox--)
|
||||
{
|
||||
rect.left = pbox->x1;
|
||||
rect.right = pbox->x2;
|
||||
rect.top = pbox->y1;
|
||||
rect.bottom = pbox->y2;
|
||||
(*func)(closure, &rect);
|
||||
pbox++;
|
||||
}
|
||||
/* printf("done foreachrectinregion\n"); */
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -263,3 +393,8 @@ FE_HighlightRegion(void *c, FE_Region region, int how_much)
|
|||
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче