00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028
00029 #include "gdk.h"
00030 #include "gdkprivate-win32.h"
00031
00032
00033 GdkRegion *gdk_region_new(void)
00034 {
00035 GdkRegionPrivate *private;
00036 GdkRegion *region;
00037 HRGN xregion;
00038 RECT emptyRect;
00039
00040
00041 SetRectEmpty(&emptyRect);
00042 xregion = CreateRectRgnIndirect(&emptyRect);
00043 private = g_new(GdkRegionPrivate, 1);
00044 private->xregion = xregion;
00045 region = (GdkRegion *) private;
00046 region->user_data = NULL;
00047
00048 return region;
00049 }
00050
00051 void gdk_region_destroy(GdkRegion * region)
00052 {
00053 GdkRegionPrivate *private;
00054
00055 g_return_if_fail(region != NULL);
00056
00057 private = (GdkRegionPrivate *) region;
00058 DeleteObject(private->xregion);
00059 g_free(private);
00060 }
00061
00062 gboolean gdk_region_empty(GdkRegion * region)
00063 {
00064 GdkRegionPrivate *private;
00065 RECT rect;
00066
00067 g_return_val_if_fail(region != NULL, 0);
00068
00069 private = (GdkRegionPrivate *) region;
00070
00071 return (GetRgnBox(private->xregion, &rect) == NULLREGION);
00072 }
00073
00074 gboolean gdk_region_equal(GdkRegion * region1, GdkRegion * region2)
00075 {
00076 GdkRegionPrivate *private1;
00077 GdkRegionPrivate *private2;
00078
00079 g_return_val_if_fail(region1 != NULL, 0);
00080 g_return_val_if_fail(region2 != NULL, 0);
00081
00082 private1 = (GdkRegionPrivate *) region1;
00083 private2 = (GdkRegionPrivate *) region2;
00084
00085 return EqualRgn(private1->xregion, private2->xregion);
00086 }
00087
00088 void gdk_region_get_clipbox(GdkRegion * region, GdkRectangle * rectangle)
00089 {
00090 GdkRegionPrivate *rp;
00091 RECT r;
00092
00093 g_return_if_fail(region != NULL);
00094 g_return_if_fail(rectangle != NULL);
00095
00096 rp = (GdkRegionPrivate *) region;
00097
00098 GetRgnBox(rp->xregion, &r);
00099 rectangle->x = r.left;
00100 rectangle->y = r.top;
00101 rectangle->width = r.right - r.left;
00102 rectangle->height = r.bottom - r.top;
00103 }
00104
00105 gboolean gdk_region_point_in(GdkRegion * region, gint x, gint y)
00106 {
00107 GdkRegionPrivate *private;
00108
00109 g_return_val_if_fail(region != NULL, 0);
00110
00111 private = (GdkRegionPrivate *) region;
00112
00113 return PtInRegion(private->xregion, x, y);
00114 }
00115
00116 GdkOverlapType gdk_region_rect_in(GdkRegion * region, GdkRectangle * rect)
00117 {
00118 GdkRegionPrivate *private;
00119 RECT r;
00120 int res;
00121
00122 g_return_val_if_fail(region != NULL, 0);
00123
00124 private = (GdkRegionPrivate *) region;
00125
00126 r.left = rect->x;
00127 r.top = rect->y;
00128 r.right = rect->x + rect->width;
00129 r.bottom = rect->y + rect->height;
00130
00131 if (RectInRegion(private->xregion, &r))
00132 return GDK_OVERLAP_RECTANGLE_PART;
00133
00134 return GDK_OVERLAP_RECTANGLE_OUT;
00135 }
00136
00137 GdkRegion *gdk_region_polygon(GdkPoint * points,
00138 gint npoints, GdkFillRule fill_rule)
00139 {
00140 GdkRegionPrivate *private;
00141 GdkRegion *region;
00142 HRGN xregion;
00143 POINT *pts;
00144 gint xfill_rule = ALTERNATE;
00145 gint i;
00146
00147 g_return_val_if_fail(points != NULL, NULL);
00148 g_return_val_if_fail(npoints != 0, NULL);
00149
00150 switch (fill_rule) {
00151 case GDK_EVEN_ODD_RULE:
00152 xfill_rule = ALTERNATE;
00153 break;
00154
00155 case GDK_WINDING_RULE:
00156 xfill_rule = WINDING;
00157 break;
00158 }
00159
00160 pts = g_malloc(npoints * sizeof(*pts));
00161 for (i = 0; i < npoints; i++) {
00162 pts[i].x = points[i].x;
00163 pts[i].y = points[i].y;
00164 }
00165 xregion = CreatePolygonRgn(pts, npoints, xfill_rule);
00166 g_free(pts);
00167
00168 private = g_new(GdkRegionPrivate, 1);
00169 private->xregion = xregion;
00170 region = (GdkRegion *) private;
00171 region->user_data = NULL;
00172
00173 return region;
00174 }
00175
00176 void gdk_region_offset(GdkRegion * region, gint dx, gint dy)
00177 {
00178 GdkRegionPrivate *private;
00179
00180 g_return_if_fail(region != NULL);
00181
00182 private = (GdkRegionPrivate *) region;
00183
00184 OffsetRgn(private->xregion, dx, dy);
00185 }
00186
00187 void gdk_region_shrink(GdkRegion * region, gint dx, gint dy)
00188 {
00189 GdkRegionPrivate *private;
00190 HRGN shrunken_bbox;
00191 RECT r;
00192
00193 g_return_if_fail(region != NULL);
00194
00195 private = (GdkRegionPrivate *) region;
00196
00197 if (dx > 0 || dy > 0) {
00198
00199
00200
00201
00202 GetRgnBox(private->xregion, &r);
00203 if (dx > 0) {
00204 r.left += dx - dx / 2;
00205 r.right -= dx / 2;
00206 }
00207 if (dy > 0) {
00208 r.top += dy - dy / 2;
00209 r.bottom -= dy / 2;
00210 }
00211
00212 shrunken_bbox = CreateRectRgnIndirect(&r);
00213 CombineRgn(private->xregion, private->xregion,
00214 shrunken_bbox, RGN_AND);
00215 DeleteObject(shrunken_bbox);
00216 } else {
00217
00218 }
00219 }
00220
00221 GdkRegion *gdk_region_union_with_rect(GdkRegion * region,
00222 GdkRectangle * rect)
00223 {
00224 GdkRegionPrivate *private;
00225 GdkRegion *res;
00226 GdkRegionPrivate *res_private;
00227 RECT xrect;
00228 HRGN rectangle;
00229
00230 g_return_val_if_fail(region != NULL, NULL);
00231
00232 private = (GdkRegionPrivate *) region;
00233
00234 xrect.left = rect->x;
00235 xrect.top = rect->y;
00236 xrect.right = rect->x + rect->width;
00237 xrect.bottom = rect->y + rect->height;
00238
00239 res = gdk_region_new();
00240 res_private = (GdkRegionPrivate *) res;
00241
00242 rectangle = CreateRectRgnIndirect(&xrect);
00243 CombineRgn(res_private->xregion, private->xregion, rectangle, RGN_OR);
00244 DeleteObject(rectangle);
00245 return res;
00246 }
00247
00248 static GdkRegion *gdk_regions_op(GdkRegion * source1,
00249 GdkRegion * source2, guint op)
00250 {
00251 GdkRegionPrivate *private1;
00252 GdkRegionPrivate *private2;
00253 GdkRegion *res;
00254 GdkRegionPrivate *res_private;
00255
00256 g_return_val_if_fail(source1 != NULL, NULL);
00257 g_return_val_if_fail(source2 != NULL, NULL);
00258
00259 private1 = (GdkRegionPrivate *) source1;
00260 private2 = (GdkRegionPrivate *) source2;
00261
00262 res = gdk_region_new();
00263 res_private = (GdkRegionPrivate *) res;
00264
00265 CombineRgn(res_private->xregion, private1->xregion, private2->xregion,
00266 op);
00267 return res;
00268 }
00269
00270 GdkRegion *gdk_regions_intersect(GdkRegion * source1, GdkRegion * source2)
00271 {
00272 return gdk_regions_op(source1, source2, RGN_AND);
00273 }
00274
00275 GdkRegion *gdk_regions_union(GdkRegion * source1, GdkRegion * source2)
00276 {
00277 return gdk_regions_op(source1, source2, RGN_OR);
00278 }
00279
00280 GdkRegion *gdk_regions_subtract(GdkRegion * source1, GdkRegion * source2)
00281 {
00282 return gdk_regions_op(source1, source2, RGN_DIFF);
00283 }
00284
00285 GdkRegion *gdk_regions_xor(GdkRegion * source1, GdkRegion * source2)
00286 {
00287 return gdk_regions_op(source1, source2, RGN_XOR);
00288 }