public static Polygon Clip(CombineMode clipMode, Polygon subject_polygon, Polygon clip_polygon) { Validate(clipMode); NativeConstants.gpc_op gpcOp = Convert(clipMode); NativeStructs.gpc_polygon gpc_polygon = new NativeStructs.gpc_polygon(); NativeStructs.gpc_polygon gpc_subject_polygon = PolygonTo_gpc_polygon(subject_polygon); NativeStructs.gpc_polygon gpc_clip_polygon = PolygonTo_gpc_polygon(clip_polygon); NativeMethods.gpc_polygon_clip(gpcOp, ref gpc_subject_polygon, ref gpc_clip_polygon, ref gpc_polygon); Polygon polygon = gpc_polygon_ToPolygon(gpc_polygon); Free_gpc_polygon(gpc_subject_polygon); Free_gpc_polygon(gpc_clip_polygon); NativeMethods.gpc_free_polygon(ref gpc_polygon); return polygon; }
private static NativeStructs.gpc_polygon PolygonTo_gpc_polygon(Polygon polygon) { NativeStructs.gpc_polygon gpc_pol = new NativeStructs.gpc_polygon(); gpc_pol.num_contours = polygon.NofContours; int[] hole = new int[polygon.NofContours]; for (int i = 0; i < polygon.NofContours; i++) { hole[i] = (polygon.ContourIsHole[i] ? 1 : 0); } gpc_pol.hole = Marshal.AllocCoTaskMem(polygon.NofContours * Marshal.SizeOf(typeof(int) /*hole[0]*/)); if (polygon.NofContours > 0) { Marshal.Copy(hole, 0, gpc_pol.hole, polygon.NofContours); } gpc_pol.contour = Marshal.AllocCoTaskMem(polygon.NofContours * Marshal.SizeOf(typeof(NativeStructs.gpc_vertex_list))); IntPtr ptr = gpc_pol.contour; for (int i = 0; i < polygon.NofContours; i++) { NativeStructs.gpc_vertex_list gpc_vtx_list = new NativeStructs.gpc_vertex_list(); gpc_vtx_list.num_vertices = polygon.Contour[i].NofVertices; gpc_vtx_list.vertex = Marshal.AllocCoTaskMem(polygon.Contour[i].NofVertices * Marshal.SizeOf(typeof(NativeStructs.gpc_vertex))); IntPtr ptr2 = gpc_vtx_list.vertex; for (int j = 0; j < polygon.Contour[i].NofVertices; j++) { NativeStructs.gpc_vertex gpc_vtx = new NativeStructs.gpc_vertex(); gpc_vtx.x = polygon.Contour[i].Vertex[j].X; gpc_vtx.y = polygon.Contour[i].Vertex[j].Y; Marshal.StructureToPtr(gpc_vtx, ptr2, false); ptr2 = (IntPtr)(((int)ptr2) + Marshal.SizeOf(gpc_vtx)); } Marshal.StructureToPtr(gpc_vtx_list, ptr, false); ptr = (IntPtr)(((int)ptr) + Marshal.SizeOf(gpc_vtx_list)); } return gpc_pol; }