1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdkprivate.h"
36 GdkRegionPrivate *private;
41 /* Create an empty region */
42 SetRectEmpty (&emptyRect);
43 xregion = CreateRectRgnIndirect (&emptyRect);
44 private = g_new (GdkRegionPrivate, 1);
45 private->xregion = xregion;
46 region = (GdkRegion*) private;
47 region->user_data = NULL;
53 gdk_region_destroy (GdkRegion *region)
55 GdkRegionPrivate *private;
57 g_return_if_fail (region != NULL);
59 private = (GdkRegionPrivate *) region;
60 DeleteObject (private->xregion);
65 gdk_region_empty (GdkRegion *region)
67 GdkRegionPrivate *private;
70 g_return_val_if_fail (region != NULL, 0);
72 private = (GdkRegionPrivate *) region;
74 return (GetRgnBox (private->xregion, &rect) == NULLREGION);
78 gdk_region_equal (GdkRegion *region1,
81 GdkRegionPrivate *private1;
82 GdkRegionPrivate *private2;
84 g_return_val_if_fail (region1 != NULL, 0);
85 g_return_val_if_fail (region2 != NULL, 0);
87 private1 = (GdkRegionPrivate *) region1;
88 private2 = (GdkRegionPrivate *) region2;
90 return EqualRgn (private1->xregion, private2->xregion);
94 gdk_region_get_clipbox(GdkRegion *region,
95 GdkRectangle *rectangle)
100 g_return_if_fail(region != NULL);
101 g_return_if_fail(rectangle != NULL);
103 rp = (GdkRegionPrivate *)region;
105 GetRgnBox (rp->xregion, &r);
106 rectangle->x = r.left;
107 rectangle->y = r.top;
108 rectangle->width = r.right - r.left;
109 rectangle->height = r.bottom - r.top;
113 gdk_region_point_in (GdkRegion *region,
117 GdkRegionPrivate *private;
119 g_return_val_if_fail (region != NULL, 0);
121 private = (GdkRegionPrivate *) region;
123 return PtInRegion (private->xregion, x, y);
127 gdk_region_rect_in (GdkRegion *region,
130 GdkRegionPrivate *private;
134 g_return_val_if_fail (region != NULL, 0);
136 private = (GdkRegionPrivate *) region;
140 r.right = rect->x + rect->width;
141 r.bottom = rect->y + rect->height;
143 if (RectInRegion (private->xregion, &r))
144 return GDK_OVERLAP_RECTANGLE_PART;
146 return GDK_OVERLAP_RECTANGLE_OUT; /*what else ? */
150 gdk_region_polygon (GdkPoint *points,
152 GdkFillRule fill_rule)
154 GdkRegionPrivate *private;
158 gint xfill_rule = ALTERNATE;
161 g_return_val_if_fail (points != NULL, NULL);
162 g_return_val_if_fail (npoints != 0, NULL); /* maybe we should check for at least three points */
166 case GDK_EVEN_ODD_RULE:
167 xfill_rule = ALTERNATE;
170 case GDK_WINDING_RULE:
171 xfill_rule = WINDING;
175 pts = g_malloc (npoints * sizeof (*pts));
176 for (i = 0; i < npoints; i++)
178 pts[i].x = points[i].x;
179 pts[i].y = points[i].y;
181 xregion = CreatePolygonRgn (pts, npoints, xfill_rule);
184 private = g_new (GdkRegionPrivate, 1);
185 private->xregion = xregion;
186 region = (GdkRegion *) private;
187 region->user_data = NULL;
193 gdk_region_offset (GdkRegion *region,
197 GdkRegionPrivate *private;
199 g_return_if_fail (region != NULL);
201 private = (GdkRegionPrivate *) region;
203 OffsetRgn (private->xregion, dx, dy);
207 gdk_region_shrink (GdkRegion *region,
211 GdkRegionPrivate *private;
215 g_return_if_fail (region != NULL);
217 private = (GdkRegionPrivate *) region;
219 if (dx > 0 || dy > 0)
221 /* We want to shrink it in one or both dimensions.
222 * Is it correct just to intersect it with a smaller bounding box?
225 GetRgnBox (private->xregion, &r);
237 shrunken_bbox = CreateRectRgnIndirect (&r);
238 CombineRgn (private->xregion, private->xregion,
239 shrunken_bbox, RGN_AND);
240 DeleteObject (shrunken_bbox);
244 /* Do nothing if the regions is expanded? XXX */
249 gdk_region_union_with_rect (GdkRegion *region,
252 GdkRegionPrivate *private;
254 GdkRegionPrivate *res_private;
258 g_return_val_if_fail (region != NULL, NULL);
260 private = (GdkRegionPrivate *) region;
262 xrect.left = rect->x;
264 xrect.right = rect->x + rect->width;
265 xrect.bottom = rect->y + rect->height;
267 res = gdk_region_new ();
268 res_private = (GdkRegionPrivate *) res;
270 rectangle = CreateRectRgnIndirect (&xrect);
271 CombineRgn (res_private->xregion, private->xregion,
273 DeleteObject (rectangle);
278 gdk_regions_intersect (GdkRegion *source1,
281 GdkRegionPrivate *private1;
282 GdkRegionPrivate *private2;
284 GdkRegionPrivate *res_private;
286 g_return_val_if_fail (source1 != NULL, NULL);
287 g_return_val_if_fail (source2 != NULL, NULL);
289 private1 = (GdkRegionPrivate *) source1;
290 private2 = (GdkRegionPrivate *) source2;
292 res = gdk_region_new ();
293 res_private = (GdkRegionPrivate *) res;
295 CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
301 gdk_regions_union (GdkRegion *source1,
304 GdkRegionPrivate *private1;
305 GdkRegionPrivate *private2;
307 GdkRegionPrivate *res_private;
309 g_return_val_if_fail (source1 != NULL, NULL);
310 g_return_val_if_fail (source2 != NULL, NULL);
312 private1 = (GdkRegionPrivate *) source1;
313 private2 = (GdkRegionPrivate *) source2;
315 res = gdk_region_new ();
316 res_private = (GdkRegionPrivate *) res;
318 CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
324 gdk_regions_subtract (GdkRegion *source1,
327 GdkRegionPrivate *private1;
328 GdkRegionPrivate *private2;
330 GdkRegionPrivate *res_private;
332 g_return_val_if_fail (source1 != NULL, NULL);
333 g_return_val_if_fail (source2 != NULL, NULL);
335 private1 = (GdkRegionPrivate *) source1;
336 private2 = (GdkRegionPrivate *) source2;
338 res = gdk_region_new ();
339 res_private = (GdkRegionPrivate *) res;
341 CombineRgn (res_private->xregion, private1->xregion, private2->xregion,
347 gdk_regions_xor (GdkRegion *source1,
350 GdkRegionPrivate *private1;
351 GdkRegionPrivate *private2;
353 GdkRegionPrivate *res_private;
355 g_return_val_if_fail (source1 != NULL, NULL);
356 g_return_val_if_fail (source2 != NULL, NULL);
358 private1 = (GdkRegionPrivate *) source1;
359 private2 = (GdkRegionPrivate *) source2;
361 res = gdk_region_new ();
362 res_private = (GdkRegionPrivate *) res;
364 CombineRgn (res_private->xregion, private1->xregion, private2->xregion,