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; } }
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; }
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; }
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; }
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); }
/* 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; }
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); }
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 }