gdkregion-win32.c

Go to the documentation of this file.
00001 /* GDK - The GIMP Drawing Kit
00002  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
00022  * file for a list of people on the GTK+ Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
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    /* Create an empty region */
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;    /*what else ? */
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);    /* maybe we should check for at least three points */
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       /* We want to shrink it in one or both dimensions.
00199        * Is it correct just to intersect it with a smaller bounding box?
00200        * XXX
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       /* Do nothing if the regions is expanded? XXX */
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 }

Generated on Tue Jul 5 14:14:40 2011 for ROOT_528-00b_version by  doxygen 1.5.1