Commit 78018767 authored by Benjamin Otte's avatar Benjamin Otte
Browse files

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
parent b6cc7dbd
......@@ -20,7 +20,6 @@
#include "gdkcairo.h"
#include "gdkdrawable.h"
#include "gdkinternals.h"
#include "gdkregion-generic.h"
#include "gdkalias.h"
/**
......@@ -143,21 +142,19 @@ void
gdk_cairo_region (cairo_t *cr,
const GdkRegion *region)
{
GdkRegionBox *boxes;
cairo_rectangle_int_t box;
gint n_boxes, i;
g_return_if_fail (cr != NULL);
g_return_if_fail (region != NULL);
boxes = region->rects;
n_boxes = region->numRects;
n_boxes = cairo_region_num_rectangles (region);
for (i = 0; i < n_boxes; i++)
cairo_rectangle (cr,
boxes[i].x1,
boxes[i].y1,
boxes[i].x2 - boxes[i].x1,
boxes[i].y2 - boxes[i].y1);
{
cairo_region_get_rectangle (region, i, &box);
cairo_rectangle (cr, box.x, box.y, box.width, box.height);
}
}
/**
......
......@@ -382,29 +382,25 @@ FreeStorage (ScanLineListBlock *pSLLBlock)
* stack by the calling procedure.
*
*/
static int
static cairo_region_t *
PtsToRegion (int numFullPtBlocks,
int iCurPtBlock,
POINTBLOCK *FirstPtBlock,
GdkRegion *reg)
POINTBLOCK *FirstPtBlock)
{
GdkRegionBox *rects;
GdkRectangle *rects, *allRects;
GdkPoint *pts;
POINTBLOCK *CurPtBlock;
int i;
GdkRegionBox *extents;
int numRects;
cairo_region_t *region;
extents = &reg->extents;
numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1;
GROWREGION(reg, numRects);
allRects = g_new (GdkRectangle, numRects);
CurPtBlock = FirstPtBlock;
rects = reg->rects - 1;
rects = allRects - 1;
numRects = 0;
extents->x1 = G_MAXSHORT, extents->x2 = G_MINSHORT;
for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) {
/* the loop uses 2 points per iteration */
......@@ -414,37 +410,24 @@ PtsToRegion (int numFullPtBlocks,
for (pts = CurPtBlock->pts; i--; pts += 2) {
if (pts->x == pts[1].x)
continue;
if (numRects && pts->x == rects->x1 && pts->y == rects->y2 &&
pts[1].x == rects->x2 &&
(numRects == 1 || rects[-1].y1 != rects->y1) &&
if (numRects && pts->x == rects->x && pts->y == rects->y + rects->height &&
pts[1].x == rects->x + rects->width &&
(numRects == 1 || rects[-1].y != rects->y) &&
(i && pts[2].y > pts[1].y)) {
rects->y2 = pts[1].y + 1;
rects->height = pts[1].y + 1 - rects->y;
continue;
}
numRects++;
rects++;
rects->x1 = pts->x; rects->y1 = pts->y;
rects->x2 = pts[1].x; rects->y2 = pts[1].y + 1;
if (rects->x1 < extents->x1)
extents->x1 = rects->x1;
if (rects->x2 > extents->x2)
extents->x2 = rects->x2;
rects->x = pts->x; rects->y = pts->y;
rects->width = pts[1].x - rects->x; rects->height = pts[1].y + 1 - rects->y;
}
CurPtBlock = CurPtBlock->next;
}
if (numRects) {
extents->y1 = reg->rects->y1;
extents->y2 = rects->y2;
} else {
extents->x1 = 0;
extents->y1 = 0;
extents->x2 = 0;
extents->y2 = 0;
}
reg->numRects = numRects;
return(TRUE);
region = cairo_region_create_rectangles (allRects, numRects);
g_free (allRects);
return region;
}
/**
......@@ -481,8 +464,6 @@ gdk_region_polygon (const GdkPoint *points,
POINTBLOCK *tmpPtBlock;
int numFullPtBlocks = 0;
region = gdk_region_new ();
/* special case a rectangle */
if (((n_points == 4) ||
((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[2].x == points[3].x) &&
(points[3].y == points[0].y)))) {
region->extents.x1 = MIN(points[0].x, points[2].x);
region->extents.y1 = MIN(points[0].y, points[2].y);
region->extents.x2 = MAX(points[0].x, points[2].x);
region->extents.y2 = MAX(points[0].y, points[2].y);
if ((region->extents.x1 != region->extents.x2) &&
(region->extents.y1 != region->extents.y2)) {
region->numRects = 1;
*(region->rects) = region->extents;
}
return(region);
GdkRectangle extents;
extents.x = MIN(points[0].x, points[2].x);
extents.y = MIN(points[0].y, points[2].y);
extents.width = MAX(points[0].x, points[2].x) - extents.x;
extents.height = MAX(points[0].y, points[2].y) - extents.y;
return gdk_region_rectangle (&extents);
}
pETEs = g_new (EdgeTableEntry, n_points);
......@@ -610,7 +588,7 @@ gdk_region_polygon (const GdkPoint *points,
}
}
FreeStorage(SLLBlock.next);
(void) PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region);
region = PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock);
for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) {
tmpPtBlock = curPtBlock->next;
g_free (curPtBlock);
......
This diff is collapsed.
......@@ -36,6 +36,7 @@
#include <glib.h>
#include <pango/pango.h>
#include <glib-object.h>
#include <cairo.h>
#ifdef G_OS_WIN32
# ifdef GDK_COMPILATION
......@@ -73,7 +74,7 @@ G_BEGIN_DECLS
/* Type definitions for the basic structures.
*/
typedef struct _GdkPoint GdkPoint;
typedef struct _GdkRectangle GdkRectangle;
typedef cairo_rectangle_int_t GdkRectangle;
typedef struct _GdkSegment GdkSegment;
typedef struct _GdkSpan GdkSpan;
......@@ -104,7 +105,7 @@ typedef struct _GdkColormap GdkColormap;
typedef struct _GdkCursor GdkCursor;
typedef struct _GdkGC GdkGC;
typedef struct _GdkImage GdkImage;
typedef struct _GdkRegion GdkRegion;
typedef cairo_region_t GdkRegion;
typedef struct _GdkVisual GdkVisual;
typedef struct _GdkDrawable GdkDrawable;
......
......@@ -27,7 +27,6 @@
#include "config.h"
#include "gdkx.h"
#include "gdkregion-generic.h"
#include <cairo-xlib.h>
......@@ -351,22 +350,16 @@ gdk_x11_drawable_update_picture_clip (GdkDrawable *drawable,
if (clip_region)
{
GdkRegionBox *boxes = clip_region->rects;
gint n_boxes = clip_region->numRects;
XRectangle *rects = g_new (XRectangle, n_boxes);
int i;
for (i=0; i < n_boxes; i++)
{
rects[i].x = CLAMP (boxes[i].x1 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT);
rects[i].y = CLAMP (boxes[i].y1 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT);
rects[i].width = CLAMP (boxes[i].x2 + gc->clip_x_origin, G_MINSHORT, G_MAXSHORT) - rects[i].x;
rects[i].height = CLAMP (boxes[i].y2 + gc->clip_y_origin, G_MINSHORT, G_MAXSHORT) - rects[i].y;
}
XRectangle *rects;
int n_rects;
_gdk_region_get_xrectangles (clip_region,
gc->clip_x_origin,
gc->clip_y_origin,
&rects,
&n_rects);
XRenderSetPictureClipRectangles (xdisplay, picture,
0, 0, rects, n_boxes);
0, 0, rects, n_rects);
g_free (rects);
}
else
......
......@@ -28,7 +28,6 @@
#include "gdkgc.h"
#include "gdkprivate-x11.h"
#include "gdkregion-generic.h"
#include "gdkx.h"
#include "gdkalias.h"
......
......@@ -49,7 +49,6 @@
#include "gdkinternals.h"
#include "gdkprivate-x11.h"
#include "gdkintl.h"
#include "gdkregion-generic.h"
#include "gdkalias.h"
#include <gdk/gdkdeviceprivate.h>
......@@ -524,20 +523,24 @@ _gdk_region_get_xrectangles (const GdkRegion *region,
XRectangle **rects,
gint *n_rects)
{
XRectangle *rectangles = g_new (XRectangle, region->numRects);
GdkRegionBox *boxes = region->rects;
gint i;
XRectangle *rectangles;
cairo_rectangle_int_t box;
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);
rectangles[i].y = CLAMP (boxes[i].y1 + y_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].width = CLAMP (boxes[i].x2 + x_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].x;
rectangles[i].height = CLAMP (boxes[i].y2 + y_offset, G_MINSHORT, G_MAXSHORT) - rectangles[i].y;
cairo_region_get_rectangle (region, i, &box);
rectangles[i].x = CLAMP (box.x + x_offset, G_MINSHORT, G_MAXSHORT);
rectangles[i].y = CLAMP (box.y + y_offset, G_MINSHORT, G_MAXSHORT);
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;
*n_rects = region->numRects;
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment