Implement GdkRegion in terms of cairo_region_t

Only changes in headers: GdkRegion and GdkRectangle are typedeffed to
cairo_region_t and cairo_rectangle_int_t respectively. The region type
was opaque anyway so it doesn't matter and the rectangle types are
identical.

https://bugzilla.gnome.org/show_bug.cgi?id=613284
This commit is contained in:
Benjamin Otte 2010-06-28 14:27:55 +02:00
parent b6cc7dbd21
commit 78018767ba
7 changed files with 133 additions and 1517 deletions

View File

@ -20,7 +20,6 @@
#include "gdkcairo.h" #include "gdkcairo.h"
#include "gdkdrawable.h" #include "gdkdrawable.h"
#include "gdkinternals.h" #include "gdkinternals.h"
#include "gdkregion-generic.h"
#include "gdkalias.h" #include "gdkalias.h"
/** /**
@ -143,21 +142,19 @@ void
gdk_cairo_region (cairo_t *cr, gdk_cairo_region (cairo_t *cr,
const GdkRegion *region) const GdkRegion *region)
{ {
GdkRegionBox *boxes; cairo_rectangle_int_t box;
gint n_boxes, i; gint n_boxes, i;
g_return_if_fail (cr != NULL); g_return_if_fail (cr != NULL);
g_return_if_fail (region != NULL); g_return_if_fail (region != NULL);
boxes = region->rects; n_boxes = cairo_region_num_rectangles (region);
n_boxes = region->numRects;
for (i = 0; i < n_boxes; i++) for (i = 0; i < n_boxes; i++)
cairo_rectangle (cr, {
boxes[i].x1, cairo_region_get_rectangle (region, i, &box);
boxes[i].y1, cairo_rectangle (cr, box.x, box.y, box.width, box.height);
boxes[i].x2 - boxes[i].x1, }
boxes[i].y2 - boxes[i].y1);
} }
/** /**

View File

@ -382,29 +382,25 @@ FreeStorage (ScanLineListBlock *pSLLBlock)
* stack by the calling procedure. * stack by the calling procedure.
* *
*/ */
static int static cairo_region_t *
PtsToRegion (int numFullPtBlocks, PtsToRegion (int numFullPtBlocks,
int iCurPtBlock, int iCurPtBlock,
POINTBLOCK *FirstPtBlock, POINTBLOCK *FirstPtBlock)
GdkRegion *reg)
{ {
GdkRegionBox *rects; GdkRectangle *rects, *allRects;
GdkPoint *pts; GdkPoint *pts;
POINTBLOCK *CurPtBlock; POINTBLOCK *CurPtBlock;
int i; int i;
GdkRegionBox *extents;
int numRects; int numRects;
cairo_region_t *region;
extents = &reg->extents;
numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
GROWREGION(reg, numRects); allRects = g_new (GdkRectangle, numRects);
CurPtBlock = FirstPtBlock; CurPtBlock = FirstPtBlock;
rects = reg->rects - 1; rects = allRects - 1;
numRects = 0; numRects = 0;
extents->x1 = G_MAXSHORT, extents->x2 = G_MINSHORT;
for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
/* the loop uses 2 points per iteration */ /* the loop uses 2 points per iteration */
@ -414,37 +410,24 @@ PtsToRegion (int numFullPtBlocks,
for (pts = CurPtBlock->pts; i--; pts += 2) { for (pts = CurPtBlock->pts; i--; pts += 2) {
if (pts->x == pts[1].x) if (pts->x == pts[1].x)
continue; continue;
if (numRects && pts->x == rects->x1 && pts->y == rects->y2 && if (numRects && pts->x == rects->x && pts->y == rects->y + rects->height &&
pts[1].x == rects->x2 && pts[1].x == rects->x + rects->width &&
(numRects == 1 || rects[-1].y1 != rects->y1) && (numRects == 1 || rects[-1].y != rects->y) &&
(i && pts[2].y > pts[1].y)) { (i && pts[2].y > pts[1].y)) {
rects->y2 = pts[1].y + 1; rects->height = pts[1].y + 1 - rects->y;
continue; continue;
} }
numRects++; numRects++;
rects++; rects++;
rects->x1 = pts->x; rects->y1 = pts->y; rects->x = pts->x; rects->y = pts->y;
rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1; rects->width = pts[1].x - rects->x; rects->height = pts[1].y + 1 - rects->y;
if (rects->x1 < extents->x1)
extents->x1 = rects->x1;
if (rects->x2 > extents->x2)
extents->x2 = rects->x2;
} }
CurPtBlock = CurPtBlock->next; CurPtBlock = CurPtBlock->next;
} }
if (numRects) { region = cairo_region_create_rectangles (allRects, numRects);
extents->y1 = reg->rects->y1; g_free (allRects);
extents->y2 = rects->y2; return region;
} else {
extents->x1 = 0;
extents->y1 = 0;
extents->x2 = 0;
extents->y2 = 0;
}
reg->numRects = numRects;
return(TRUE);
} }
/** /**
@ -481,8 +464,6 @@ gdk_region_polygon (const GdkPoint *points,
POINTBLOCK *tmpPtBlock; POINTBLOCK *tmpPtBlock;
int numFullPtBlocks = 0; int numFullPtBlocks = 0;
region = gdk_region_new ();
/* special case a rectangle */ /* special case a rectangle */
if (((n_points == 4) || if (((n_points == 4) ||
((n_points == 5) && (points[4].x == points[0].x) && (points[4].y == points[0].y))) && ((n_points == 5) && (points[4].x == points[0].x) && (points[4].y == points[0].y))) &&
@ -494,16 +475,13 @@ gdk_region_polygon (const GdkPoint *points,
(points[1].y == points[2].y) && (points[1].y == points[2].y) &&
(points[2].x == points[3].x) && (points[2].x == points[3].x) &&
(points[3].y == points[0].y)))) { (points[3].y == points[0].y)))) {
region->extents.x1 = MIN(points[0].x, points[2].x); GdkRectangle extents;
region->extents.y1 = MIN(points[0].y, points[2].y);
region->extents.x2 = MAX(points[0].x, points[2].x); extents.x = MIN(points[0].x, points[2].x);
region->extents.y2 = MAX(points[0].y, points[2].y); extents.y = MIN(points[0].y, points[2].y);
if ((region->extents.x1 != region->extents.x2) && extents.width = MAX(points[0].x, points[2].x) - extents.x;
(region->extents.y1 != region->extents.y2)) { extents.height = MAX(points[0].y, points[2].y) - extents.y;
region->numRects = 1; return gdk_region_rectangle (&extents);
*(region->rects) = region->extents;
}
return(region);
} }
pETEs = g_new (EdgeTableEntry, n_points); pETEs = g_new (EdgeTableEntry, n_points);
@ -610,7 +588,7 @@ gdk_region_polygon (const GdkPoint *points,
} }
} }
FreeStorage(SLLBlock.next); FreeStorage(SLLBlock.next);
(void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); region = PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock);
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
tmpPtBlock = curPtBlock->next; tmpPtBlock = curPtBlock->next;
g_free (curPtBlock); g_free (curPtBlock);

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@
#include <glib.h> #include <glib.h>
#include <pango/pango.h> #include <pango/pango.h>
#include <glib-object.h> #include <glib-object.h>
#include <cairo.h>
#ifdef G_OS_WIN32 #ifdef G_OS_WIN32
# ifdef GDK_COMPILATION # ifdef GDK_COMPILATION
@ -73,7 +74,7 @@ G_BEGIN_DECLS
/* Type definitions for the basic structures. /* Type definitions for the basic structures.
*/ */
typedef struct _GdkPoint GdkPoint; typedef struct _GdkPoint GdkPoint;
typedef struct _GdkRectangle GdkRectangle; typedef cairo_rectangle_int_t GdkRectangle;
typedef struct _GdkSegment GdkSegment; typedef struct _GdkSegment GdkSegment;
typedef struct _GdkSpan GdkSpan; typedef struct _GdkSpan GdkSpan;
@ -104,7 +105,7 @@ typedef struct _GdkColormap GdkColormap;
typedef struct _GdkCursor GdkCursor; typedef struct _GdkCursor GdkCursor;
typedef struct _GdkGC GdkGC; typedef struct _GdkGC GdkGC;
typedef struct _GdkImage GdkImage; typedef struct _GdkImage GdkImage;
typedef struct _GdkRegion GdkRegion; typedef cairo_region_t GdkRegion;
typedef struct _GdkVisual GdkVisual; typedef struct _GdkVisual GdkVisual;
typedef struct _GdkDrawable GdkDrawable; typedef struct _GdkDrawable GdkDrawable;

View File

@ -27,7 +27,6 @@
#include "config.h" #include "config.h"
#include "gdkx.h" #include "gdkx.h"
#include "gdkregion-generic.h"
#include <cairo-xlib.h> #include <cairo-xlib.h>
@ -351,22 +350,16 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
if (clip_region) if (clip_region)
{ {
GdkRegionBox *boxes = clip_region->rects; XRectangle *rects;
gint n_boxes = clip_region->numRects; int n_rects;
XRectangle *rects = g_new (XRectangle, n_boxes);
int i;
for (i=0; i < n_boxes; i++) _gdk_region_get_xrectangles (clip_region,
{ gc->clip_x_origin,
rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT); gc->clip_y_origin,
rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT); &rects,
rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x; &n_rects);
rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
}
XRenderSetPictureClipRectangles (xdisplay, picture, XRenderSetPictureClipRectangles (xdisplay, picture,
0, 0, rects, n_boxes); 0, 0, rects, n_rects);
g_free (rects); g_free (rects);
} }
else else

View File

@ -28,7 +28,6 @@
#include "gdkgc.h" #include "gdkgc.h"
#include "gdkprivate-x11.h" #include "gdkprivate-x11.h"
#include "gdkregion-generic.h"
#include "gdkx.h" #include "gdkx.h"
#include "gdkalias.h" #include "gdkalias.h"

View File

@ -49,7 +49,6 @@
#include "gdkinternals.h" #include "gdkinternals.h"
#include "gdkprivate-x11.h" #include "gdkprivate-x11.h"
#include "gdkintl.h" #include "gdkintl.h"
#include "gdkregion-generic.h"
#include "gdkalias.h" #include "gdkalias.h"
#include <gdk/gdkdeviceprivate.h> #include <gdk/gdkdeviceprivate.h>
@ -524,20 +523,24 @@ _gdk_region_get_xrectangles (const GdkRegion *region,
XRectangle **rects, XRectangle **rects,
gint *n_rects) gint *n_rects)
{ {
XRectangle *rectangles = g_new (XRectangle, region->numRects); XRectangle *rectangles;
GdkRegionBox *boxes = region->rects; cairo_rectangle_int_t box;
gint i; gint i, n;
for (i = 0; i < region->numRects; i++) n = cairo_region_num_rectangles (region);
rectangles = g_new (XRectangle, n);
for (i = 0; i < n; i++)
{ {
rectangles[i].x = CLAMP (boxes[i].x1 + x_offset, G_MINSHORT, G_MAXSHORT); cairo_region_get_rectangle (region, i, &box);
rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT); rectangles[i].x = CLAMP (box.x + x_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x; rectangles[i].y = CLAMP (box.y + y_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y; rectangles[i].width = CLAMP (box.width, G_MINSHORT, G_MAXSHORT);
rectangles[i].height = CLAMP (box.height, G_MINSHORT, G_MAXSHORT);
} }
*n_rects = n;
*rects = rectangles; *rects = rectangles;
*n_rects = region->numRects;
} }
/** /**