Beispiel #1
0
static void cdpoly(cdCtxCanvas *ctxcanvas, int mode, cdPoint* poly, int n)
{
  int i;

  if (mode != CD_BEZIER && mode != CD_PATH)
  {
    for (i = 0; i < n; i++)
    {
      if (ctxcanvas->canvas->use_matrix)
        cdMatrixTransformPoint(ctxcanvas->xmatrix, poly[i].x, poly[i].y, &(poly[i].x), &(poly[i].y));
    }
  }

  switch( mode )
  {
  case CD_FILL:
    if (ctxcanvas->canvas->new_region)
    {
      GdkRegion* rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);
      sCombineRegion(ctxcanvas, rgn);
    }
    else
      gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, TRUE, (GdkPoint*)poly, n);
    break;

  case CD_CLOSED_LINES:
    cdgdkCheckSolidStyle(ctxcanvas, 1);
    gdk_draw_polygon(ctxcanvas->wnd, ctxcanvas->gc, FALSE, (GdkPoint*)poly, n);
    cdgdkCheckSolidStyle(ctxcanvas, 0);
    break;

  case CD_OPEN_LINES:
    cdgdkCheckSolidStyle(ctxcanvas, 1);
    gdk_draw_lines(ctxcanvas->wnd, ctxcanvas->gc, (GdkPoint*)poly, n);
    cdgdkCheckSolidStyle(ctxcanvas, 0);
    break;

  case CD_CLIP:
    ctxcanvas->clip_rgn = gdk_region_polygon((GdkPoint*)poly, n, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);     
    if (ctxcanvas->canvas->clip_mode == CD_CLIPPOLYGON)
      cdclip(ctxcanvas, CD_CLIPPOLYGON);
    break;

  case CD_BEZIER:
    cdSimPolyBezier(ctxcanvas->canvas, poly, n);
    break;

  case CD_PATH:
    cdSimPolyPath(ctxcanvas->canvas, poly, n);
    break;
  }
}
Beispiel #2
0
static VALUE
rg_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE points_or_rectangle, rbfill_rule;
    GdkRegion *region;

    rb_scan_args(argc, argv, "02", &points_or_rectangle, &rbfill_rule);
    if (NIL_P(points_or_rectangle)) {
        region = gdk_region_new();
    } else if (TYPE(points_or_rectangle) == T_ARRAY) {
        GdkFillRule fill_rule = RVAL2GENUM(rbfill_rule, GDK_TYPE_FILL_RULE);
        long n;
        GdkPoint *points = RVAL2GDKPOINTS(points_or_rectangle, &n);

        region = gdk_region_polygon(points, n, fill_rule);

        g_free(points);
    } else if (RVAL2GTYPE(points_or_rectangle) == GDK_TYPE_RECTANGLE) {
        region = gdk_region_rectangle((GdkRectangle*)RVAL2BOXED(points_or_rectangle, 
                                                                GDK_TYPE_RECTANGLE));
    } else {
        rb_raise(rb_eArgError, 
                 "invalid argument %s (expect array of Gdk::Point or Gdk::Rectangle, nil)",
                 rb_class2name(CLASS_OF(points_or_rectangle)));
    }

    G_INITIALIZE(self, region);

    return Qnil;
}
wxRegion::wxRegion( size_t WXUNUSED(n), const wxPoint *WXUNUSED(points), wxPolygonFillMode WXUNUSED(fillStyle) )
{
#if 0
    XPoint *xpoints = new XPoint[n];
    for ( size_t i = 0 ; i < n ; i++ )
    {
        xpoints[i].x = points[i].x;
        xpoints[i].y = points[i].y;
    }

    m_refData = new wxRegionRefData();

    Region* reg = gdk_region_polygon
                     (
                        gdkpoints,
                        n,
                        fillStyle == wxWINDING_RULE ? GDK_WINDING_RULE
                                                    : GDK_EVEN_ODD_RULE
                     );

    M_REGIONDATA->m_region = reg;

    delete [] xpoints;
#endif
}
void scenemanager_claim_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints)
{
	// Create a GdkRegion from the given points and union it with the 'taken region'
	GdkRegion* pNewRegion = gdk_region_polygon(pPoints, nNumPoints, GDK_WINDING_RULE);
	gdk_region_union(pSceneManager->pTakenRegion, pNewRegion);
	gdk_region_destroy(pNewRegion);
}
gboolean scenemanager_can_draw_polygon(scenemanager_t* pSceneManager, GdkPoint *pPoints, gint nNumPoints, gint nFlags)
{
	//
	// 1) Enforce on-screen rules
	//
	if(nFlags & SCENEMANAGER_FLAG_FULLY_ON_SCREEN) {
		// all points must be within screen box
		gint i;
		for(i=0 ; i<nNumPoints ; i++) {
			GdkPoint* pPoint = &pPoints[i];
			if(pPoint->x < 0 || pPoint->x > pSceneManager->nWindowWidth) return FALSE;
			if(pPoint->y < 0 || pPoint->y > pSceneManager->nWindowHeight) return FALSE;
		}
		// else go on to test below
	}
	else if(nFlags & SCENEMANAGER_FLAG_PARTLY_ON_SCREEN) {
		// one point must be withing screen box   XXX: handle polygon bigger than window case?
		gint i;
		gboolean bFound = FALSE;
		for(i=0 ; i<nNumPoints ; i++) {
			GdkPoint* pPoint = &pPoints[i];
			if(pPoint->x > 0 && pPoint->x < pSceneManager->nWindowWidth) {
				bFound = TRUE;
				break;
			}
			if(pPoint->y > 0 && pPoint->y < pSceneManager->nWindowHeight) {
				bFound = TRUE;
				break;
			}
		}
		if(!bFound) return FALSE;
		// else go on to test below
	}

	//
	// 2) Enforce overlap rules
	//
	GdkRegion* pNewRegion = gdk_region_polygon(pPoints, nNumPoints, GDK_WINDING_RULE);

	gdk_region_intersect(pNewRegion, pSceneManager->pTakenRegion); // sets pNewRegion to the intersection of itself and the 'taken region'
	gboolean bOK = gdk_region_empty(pNewRegion);	// it's ok to draw here if the intersection is empty
	gdk_region_destroy(pNewRegion);

	return bOK;
}
Beispiel #6
0
wxRegion::wxRegion( size_t n, const wxPoint *points, int fillStyle )
{
    GdkPoint *gdkpoints = new GdkPoint[n];
    for ( size_t i = 0 ; i < n ; i++ )
    {
        gdkpoints[i].x = points[i].x;
        gdkpoints[i].y = points[i].y;
    }

    m_refData = new wxRegionRefData();

    GdkRegion* reg = gdk_region_polygon
                     (
                        gdkpoints,
                        n,
                        fillStyle == wxWINDING_RULE ? GDK_WINDING_RULE
                                                    : GDK_EVEN_ODD_RULE
                     );

    M_REGIONDATA->m_region = reg;

    delete [] gdkpoints;
}
Beispiel #7
0
static VALUE
gdkregion_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE points_or_rectangle, fill_rule;
    GdkRegion* region;
    GdkPoint *gpoints;
    int i;

    rb_scan_args(argc, argv, "02", &points_or_rectangle, &fill_rule);
    if (NIL_P(points_or_rectangle)){
        region = gdk_region_new();
    } else if (TYPE(points_or_rectangle) == T_ARRAY){
        gpoints = ALLOCA_N(GdkPoint, RARRAY_LEN(points_or_rectangle));

        for (i = 0; i < RARRAY_LEN(points_or_rectangle); i++) {
            Check_Type(RARRAY_PTR(points_or_rectangle)[i], T_ARRAY);
            if (RARRAY_LEN(RARRAY_PTR(points_or_rectangle)[i]) < 2) {
                rb_raise(rb_eArgError, "point %d should be array of size 2", i);
            }
            gpoints[i].x = NUM2INT(RARRAY_PTR(RARRAY_PTR(points_or_rectangle)[i])[0]);
            gpoints[i].y = NUM2INT(RARRAY_PTR(RARRAY_PTR(points_or_rectangle)[i])[1]);
        }
        region = gdk_region_polygon(gpoints, RARRAY_LEN(points_or_rectangle),
                                    RVAL2GENUM(fill_rule, GDK_TYPE_FILL_RULE));
    } else if (RVAL2GTYPE(points_or_rectangle) == GDK_TYPE_RECTANGLE){
        region = gdk_region_rectangle((GdkRectangle*)RVAL2BOXED(points_or_rectangle, 
                                                                GDK_TYPE_RECTANGLE));
    } else {
        rb_raise(rb_eArgError, 
                 "invalid argument %s (expect array of Gdk::Point or Gdk::Rectangle, nil)",
                 rb_class2name(CLASS_OF(points_or_rectangle)));
    }

    G_INITIALIZE(self, region);
    return Qnil;
}
Beispiel #8
0
static void cdputimagerectmap_matrix(cdCtxCanvas* ctxcanvas, int iw, int ih, const unsigned char *index, const long int *colors, int x, int y, int w, int h, int xmin, int xmax, int ymin, int ymax)
{
  int t_xmin, t_xmax, t_ymin, t_ymax, ew, eh,
      t_x, t_y, dst_offset, size, doff, rect[8];
  float i_x, i_y, xfactor, yfactor;
  unsigned char *dst_index;
  double inv_matrix[6];

  /* calculate the destination limits */
  cdImageRGBCalcDstLimits(ctxcanvas->canvas, x, y, w, h, &t_xmin, &t_xmax, &t_ymin, &t_ymax, rect);

  /* Setup inverse transform (use the original transform here, NOT ctxcanvas->xmatrix) */
  cdImageRGBInitInverseTransform(w, h, xmin, xmax, ymin, ymax, &xfactor, &yfactor, ctxcanvas->canvas->matrix, inv_matrix);

  /* create an image for the destination area */
  ew = (t_xmax-t_xmin+1);
  eh = (t_ymax-t_ymin+1); 
  size = ew*eh;
  dst_index = malloc(size);
  if (!dst_index)
    return;

  memset(dst_index, 0, size);

  /* for all pixels in the destiny area */
  for(t_y = t_ymin; t_y <= t_ymax; t_y++)
  {
    dst_offset = (t_y-t_ymin) * ew;

    for(t_x = t_xmin; t_x <= t_xmax; t_x++)
    {
      cdImageRGBInverseTransform(t_x, t_y, &i_x, &i_y, xfactor, yfactor, xmin, ymin, x, y, inv_matrix);

      if (i_x > xmin && i_y > ymin && i_x < xmax+1 && i_y < ymax+1)
      {
        doff = (t_x-t_xmin) + dst_offset;
        *(dst_index+doff) = cdZeroOrderInterpolation(iw, ih, index, i_x, i_y);
      }
    }
  }

  {
    int ex = t_xmin, 
        ey = t_ymin + eh-1;  /* GdkPixbuf* origin is at top-left */
    
    GdkPixbuf *pixbuf;
    GdkRegion *clip_polygon;
    GdkPoint pnt[4];

    /* Since the transformation used was the original transformation, */
    /* must invert the Y axis here. */
    ey = _cdInvertYAxis(ctxcanvas->canvas, ey);

    /* use clipping to select only the transformed rectangle */
    pnt[0].x = (short)rect[0]; pnt[0].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[1]);
    pnt[1].x = (short)rect[2]; pnt[1].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[3]);
    pnt[2].x = (short)rect[4]; pnt[2].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[5]);
    pnt[3].x = (short)rect[6]; pnt[3].y = (short)_cdInvertYAxis(ctxcanvas->canvas, rect[7]);

    clip_polygon = gdk_region_polygon(pnt, 4, ctxcanvas->canvas->fill_mode == CD_EVENODD ? GDK_EVEN_ODD_RULE : GDK_WINDING_RULE);

    /* combine with the existing clipping */
    gdk_gc_set_function(ctxcanvas->gc, GDK_AND);
    gdk_gc_set_clip_region(ctxcanvas->gc, clip_polygon);

    cdwritemode(ctxcanvas, ctxcanvas->canvas->write_mode);  /* reset gdk_gc_set_function */

    pixbuf = cdgdkCreatePixbufMap(ew, eh, colors, dst_index, 0, 0, ew);
    if (!pixbuf)
      return;

    gdk_draw_pixbuf(ctxcanvas->wnd, ctxcanvas->gc, pixbuf, 0, 0, ex, ey, -1, -1, ctxcanvas->img_dither, 0, 0);

    /* reset clipping */
    gdk_region_destroy(clip_polygon);
    cdclip(ctxcanvas, ctxcanvas->canvas->clip_mode);

    g_object_unref(pixbuf);
  }

  free(dst_index);
}
Beispiel #9
0
/*
parameters - ([mObj], <aPoints>, [nPoints], [nFillRule])
	[mObj] - object, will returned;
	<aPoints> - array of points. Every point is an array {x,y};
        [nPoints] - number of points. If no, gets the length of aPoints;
        [nFillRule] - specifies which pixels are included in the region
        		when the polygon overlaps itself.
*/
int
clip_GDK_REGIONPOLYGON(ClipMachine * ClipMachineMemory)
{
   ClipVar  *cv = _clip_spar(ClipMachineMemory, 1);

   ClipVar  *cap = _clip_spar(ClipMachineMemory, 2);

   int       npoints = _clip_parni(ClipMachineMemory, 3);

   int       fillrule = _clip_parni(ClipMachineMemory, 4);

   GdkRegion *region;

   C_object *cregion;

   unsigned short i;

   ClipVar  *cpoint;

   GdkPoint *points;

   CHECKOPT(1, MAP_type_of_ClipVarType);
   CHECKARG(2, ARRAY_type_of_ClipVarType);
   CHECKOPT(3, NUMERIC_type_of_ClipVarType);
   CHECKOPT(4, NUMERIC_type_of_ClipVarType);

   if (_clip_parinfo(ClipMachineMemory, 3) == UNDEF_type_of_ClipVarType)
      npoints = cap->ClipArrVar_a_of_ClipVar.count_of_ClipArrVar;
   npoints = MIN(npoints, cap->ClipArrVar_a_of_ClipVar.count_of_ClipArrVar);

   points = (GdkPoint *) calloc(npoints, sizeof(GdkPoint));
   for (i = 0; i < npoints; i++)
    {
       cpoint = &cap->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar[i];
       if (cpoint->ClipType_t_of_ClipVar.ClipVartype_type_of_ClipType == ARRAY_type_of_ClipVarType)
	{
	   if (cpoint->ClipArrVar_a_of_ClipVar.count_of_ClipArrVar > 0
	       && cpoint->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar[0].ClipType_t_of_ClipVar.
	       ClipVartype_type_of_ClipType == NUMERIC_type_of_ClipVarType)
	      points[i].x =
	       cpoint->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar[0].ClipNumVar_n_of_ClipVar.double_of_ClipNumVar;
	   if (cpoint->ClipArrVar_a_of_ClipVar.count_of_ClipArrVar > 1
	       && cpoint->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar[1].ClipType_t_of_ClipVar.
	       ClipVartype_type_of_ClipType == NUMERIC_type_of_ClipVarType)
	      points[i].y =
	       cpoint->ClipArrVar_a_of_ClipVar.ClipVar_items_of_ClipArrVar[1].ClipNumVar_n_of_ClipVar.double_of_ClipNumVar;
	}
    }

   region = gdk_region_polygon(points, npoints, fillrule);

   free(points);

   if (region)
    {
       cregion = _register_object(ClipMachineMemory, region, GDK_TYPE_REGION, cv, NULL);
       if (cregion)
	  _clip_mclone(ClipMachineMemory, RETPTR(ClipMachineMemory), &cregion->obj);
       else
	  gdk_region_destroy(region);
    }
   return 0;
 err:
   return 1;
}
Beispiel #10
0
static void create_border_with_arrow(GtkWidget* nw, WindowData* windata)
{
	int             width;
	int             height;
	int             y;
	int             norm_point_x;
	int             norm_point_y;
	GtkArrowType    arrow_type;
	GdkScreen*      screen;
	int             arrow_side1_width = DEFAULT_ARROW_WIDTH / 2;
	int             arrow_side2_width = DEFAULT_ARROW_WIDTH / 2;
	int             arrow_offset = DEFAULT_ARROW_OFFSET;
	GdkPoint*       shape_points = NULL;
	int             i = 0;
	int             monitor;
	GdkRectangle    monitor_geometry;

	width = windata->width;
	height = windata->height;

	screen = gdk_window_get_screen(GDK_WINDOW(gtk_widget_get_window(nw)));
	monitor = gdk_screen_get_monitor_at_point(screen, windata->point_x, windata->point_y);
	gdk_screen_get_monitor_geometry(screen, monitor, &monitor_geometry);

	windata->num_border_points = 5;

	arrow_type = get_notification_arrow_type(windata->win);

	norm_point_x = windata->point_x - monitor_geometry.x;
	norm_point_y = windata->point_y - monitor_geometry.y;

	/* Handle the offset and such */
	switch (arrow_type)
	{
		case GTK_ARROW_UP:
		case GTK_ARROW_DOWN:

			if (norm_point_x < arrow_side1_width)
			{
				arrow_side1_width = 0;
				arrow_offset = 0;
			}
			else if (norm_point_x > monitor_geometry.width - arrow_side2_width)
			{
				arrow_side2_width = 0;
				arrow_offset = width - arrow_side1_width;
			}
			else
			{
				if (norm_point_x - arrow_side2_width + width >= monitor_geometry.width)
				{
					arrow_offset = width - monitor_geometry.width + norm_point_x;
				}
				else
				{
					arrow_offset = MIN(norm_point_x - arrow_side1_width, DEFAULT_ARROW_OFFSET);
				}

				if (arrow_offset == 0 || arrow_offset == width - arrow_side1_width)
				{
					windata->num_border_points++;
				}
				else
				{
					windata->num_border_points += 2;
				}
			}

			/*
			 * Why risk this for official builds? If it's somehow off the
			 * screen, it won't horribly impact the user. Definitely less
			 * than an assertion would...
			 */
			#if 0
				g_assert(arrow_offset + arrow_side1_width >= 0);
				g_assert(arrow_offset + arrow_side1_width + arrow_side2_width <= width);
			#endif

			windata->border_points = g_new0(GdkPoint, windata->num_border_points);
			shape_points = g_new0(GdkPoint, windata->num_border_points);

			windata->drawn_arrow_begin_x = arrow_offset;
			windata->drawn_arrow_middle_x = arrow_offset + arrow_side1_width;
			windata->drawn_arrow_end_x = arrow_offset + arrow_side1_width + arrow_side2_width;

			if (arrow_type == GTK_ARROW_UP)
			{
				windata->drawn_arrow_begin_y = DEFAULT_ARROW_HEIGHT;
				windata->drawn_arrow_middle_y = 0;
				windata->drawn_arrow_end_y = DEFAULT_ARROW_HEIGHT;

				if (arrow_side1_width == 0)
				{
					ADD_POINT(0, 0, 0, 0);
				}
				else
				{
					ADD_POINT(0, DEFAULT_ARROW_HEIGHT, 0, 0);

					if (arrow_offset > 0)
					{
						ADD_POINT(arrow_offset - (arrow_side2_width > 0 ? 0 : 1), DEFAULT_ARROW_HEIGHT, 0, 0);
					}

					ADD_POINT(arrow_offset + arrow_side1_width - (arrow_side2_width > 0 ? 0 : 1), 0, 0, 0);
				}

				if (arrow_side2_width > 0)
				{
					ADD_POINT(windata->drawn_arrow_end_x, windata->drawn_arrow_end_y, 1, 0);
					ADD_POINT(width - 1, DEFAULT_ARROW_HEIGHT, 1, 0);
				}

				ADD_POINT(width - 1, height - 1, 1, 1);
				ADD_POINT(0, height - 1, 0, 1);

				y = windata->point_y;
			}
			else
			{
				windata->drawn_arrow_begin_y = height - DEFAULT_ARROW_HEIGHT;
				windata->drawn_arrow_middle_y = height;
				windata->drawn_arrow_end_y = height - DEFAULT_ARROW_HEIGHT;

				ADD_POINT(0, 0, 0, 0);
				ADD_POINT(width - 1, 0, 1, 0);

				if (arrow_side2_width == 0)
				{
					ADD_POINT(width - 1, height, (arrow_side1_width > 0 ? 0 : 1), 0);
				}
				else
				{
					ADD_POINT(width - 1, height - DEFAULT_ARROW_HEIGHT, 1, 1);

					if (arrow_offset < width - arrow_side1_width)
					{
						ADD_POINT(arrow_offset + arrow_side1_width + arrow_side2_width, height - DEFAULT_ARROW_HEIGHT, 0, 1);
					}

					ADD_POINT(arrow_offset + arrow_side1_width, height, 0, 1);
				}

				if (arrow_side1_width > 0)
				{
					ADD_POINT(windata->drawn_arrow_begin_x - (arrow_side2_width > 0 ? 0 : 1), windata->drawn_arrow_begin_y, 0, 0);
					ADD_POINT(0, height - DEFAULT_ARROW_HEIGHT, 0, 1);
				}

				y = windata->point_y - height;
			}

			#if 0
				g_assert(i == windata->num_border_points);
				g_assert(windata->point_x - arrow_offset - arrow_side1_width >= 0);
			#endif

			gtk_window_move(GTK_WINDOW(windata->win), windata->point_x - arrow_offset - arrow_side1_width, y);

			break;

		case GTK_ARROW_LEFT:
		case GTK_ARROW_RIGHT:

			if (norm_point_y < arrow_side1_width)
			{
				arrow_side1_width = 0;
				arrow_offset = norm_point_y;
			}
			else if (norm_point_y > monitor_geometry.height - arrow_side2_width)
			{
				arrow_side2_width = 0;
				arrow_offset = norm_point_y - arrow_side1_width;
			}
			break;

		default:
			g_assert_not_reached();
	}

	g_assert(shape_points != NULL);

#if GTK_CHECK_VERSION(3, 0, 0)
	/* FIXME!!! */
#else
	windata->window_region = gdk_region_polygon(shape_points, windata->num_border_points, GDK_EVEN_ODD_RULE);
#endif
	g_free(shape_points);
}
Beispiel #11
0
wxRegion::wxRegion( size_t n, const wxPoint *points,
                    wxPolygonFillMode fillStyle )
{
#ifdef __WXGTK3__
    // Make a cairo path from the points, draw it onto an image surface, use
    // gdk_cairo_region_create_from_surface() to get a cairo region

    // need at least 3 points to make a useful polygon
    if (n < 3)
        return;
    // get bounding rect
    int min_x = points[0].x;
    int max_x = min_x;
    int min_y = points[0].y;
    int max_y = min_y;
    size_t i;
    for (i = 1; i < n; i++)
    {
        const int x = points[i].x;
        if (min_x > x)
            min_x = x;
        else if (max_x < x)
            max_x = x;
        const int y = points[i].y;
        if (min_y > y)
            min_y = y;
        else if (max_y < y)
            max_y = y;
    }
    const int w = max_x - min_x + 1;
    const int h = max_y - min_y + 1;
    // make surface just big enough to contain polygon (A1 is native format
    //   for gdk_cairo_region_create_from_surface)
    cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_A1, w, h);
    memset(cairo_image_surface_get_data(surface), 0, cairo_image_surface_get_stride(surface) * h);
    cairo_surface_mark_dirty(surface);
    cairo_surface_set_device_offset(surface, -min_x, -min_y);
    cairo_t* cr = cairo_create(surface);
    cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
    if (fillStyle == wxODDEVEN_RULE)
        cairo_set_fill_rule(cr, CAIRO_FILL_RULE_EVEN_ODD);
    // make path
    cairo_move_to(cr, points[0].x, points[0].y);
    for (i = 1; i < n; i++)
        cairo_line_to(cr, points[i].x, points[i].y);
    cairo_close_path(cr);
    cairo_fill(cr);
    cairo_destroy(cr);
    cairo_surface_flush(surface);
    m_refData = new wxRegionRefData;
    M_REGIONDATA->m_region = gdk_cairo_region_create_from_surface(surface);
    cairo_surface_destroy(surface);
#else
    GdkPoint *gdkpoints = new GdkPoint[n];
    for ( size_t i = 0 ; i < n ; i++ )
    {
        gdkpoints[i].x = points[i].x;
        gdkpoints[i].y = points[i].y;
    }

    m_refData = new wxRegionRefData();

    GdkRegion* reg = gdk_region_polygon
                     (
                        gdkpoints,
                        n,
                        fillStyle == wxWINDING_RULE ? GDK_WINDING_RULE
                                                    : GDK_EVEN_ODD_RULE
                     );

    M_REGIONDATA->m_region = reg;

    delete [] gdkpoints;
#endif
}