Py::Object _path_module::count_bboxes_overlapping_bbox(const Py::Tuple& args) { args.verify_length(2); Py::Object bbox = args[0]; Py::SeqBase<Py::Object> bboxes = args[1]; double ax0, ay0, ax1, ay1; double bx0, by0, bx1, by1; long count = 0; if (py_convert_bbox(bbox.ptr(), ax0, ay0, ax1, ay1)) { if (ax1 < ax0) { std::swap(ax0, ax1); } if (ay1 < ay0) { std::swap(ay0, ay1); } size_t num_bboxes = bboxes.size(); for (size_t i = 0; i < num_bboxes; ++i) { Py::Object bbox_b = bboxes[i]; if (py_convert_bbox(bbox_b.ptr(), bx0, by0, bx1, by1)) { if (bx1 < bx0) { std::swap(bx0, bx1); } if (by1 < by0) { std::swap(by0, by1); } if (!((bx1 <= ax0) || (by1 <= ay0) || (bx0 >= ax1) || (by0 >= ay1))) { ++count; } } else { throw Py::ValueError("Non-bbox object in bboxes list"); } } } else { throw Py::ValueError("First argument to count_bboxes_overlapping_bbox must be a Bbox object."); } return Py::Int(count); }
Py::Object _path_module::clip_path_to_rect(const Py::Tuple &args) { args.verify_length(3); PathIterator path(args[0]); Py::Object bbox_obj = args[1]; bool inside = Py::Boolean(args[2]); double x0, y0, x1, y1; if (!py_convert_bbox(bbox_obj.ptr(), x0, y0, x1, y1)) { throw Py::TypeError("Argument 2 to clip_to_rect must be a Bbox object."); } std::vector<Polygon> results; ::clip_to_rect(path, x0, y0, x1, y1, inside, results); npy_intp dims[2]; dims[1] = 2; PyObject* py_results = PyList_New(results.size()); if (!py_results) { throw Py::RuntimeError("Error creating results list"); } try { for (std::vector<Polygon>::const_iterator p = results.begin(); p != results.end(); ++p) { size_t size = p->size(); dims[0] = p->size(); PyArrayObject* pyarray = (PyArrayObject*)PyArray_SimpleNew(2, dims, PyArray_DOUBLE); if (pyarray == NULL) { throw Py::MemoryError("Could not allocate result array"); } for (size_t i = 0; i < size; ++i) { ((double *)pyarray->data)[2*i] = (*p)[i].x; ((double *)pyarray->data)[2*i+1] = (*p)[i].y; } if (PyList_SetItem(py_results, p - results.begin(), (PyObject *)pyarray) != -1) { throw Py::RuntimeError("Error creating results list"); } } } catch (...) { Py_XDECREF(py_results); throw; } return Py::Object(py_results, true); }
Py::Object agg_to_gtk_drawable(const Py::Tuple &args) { // args are gc, renderer, bbox where bbox is a transforms BBox // (possibly None). If bbox is None, blit the entire agg buffer // to gtk. If bbox is not None, blit only the region defined by // the bbox args.verify_length(3); PyGObject *py_drawable = (PyGObject *)(args[0].ptr()); RendererAgg* aggRenderer = static_cast<RendererAgg*>(args[1].ptr()); GdkDrawable *drawable = GDK_DRAWABLE(py_drawable->obj); GdkGC* gc = gdk_gc_new(drawable); int srcstride = aggRenderer->get_width() * 4; int srcwidth = (int)aggRenderer->get_width(); int srcheight = (int)aggRenderer->get_height(); // these three will be overridden below int destx = 0; int desty = 0; int destwidth = 1; int destheight = 1; int deststride = 1; bool needfree = false; agg::int8u *destbuffer = NULL; if (args[2].ptr() == Py_None) { //bbox is None; copy the entire image destbuffer = aggRenderer->pixBuffer; destwidth = srcwidth; destheight = srcheight; deststride = srcstride; } else { //bbox is not None; copy the image in the bbox PyObject* clipbox = args[2].ptr(); double l, b, r, t; if (!py_convert_bbox(clipbox, l, b, r, t)) { throw Py::TypeError ("Argument 3 to agg_to_gtk_drawable must be a Bbox object."); } destx = (int)l; desty = srcheight - (int)t; destwidth = (int)(r - l); destheight = (int)(t - b); deststride = destwidth * 4; needfree = true; destbuffer = new agg::int8u[deststride*destheight]; if (destbuffer == NULL) { throw Py::MemoryError("_gtkagg could not allocate memory for destbuffer"); } agg::rendering_buffer destrbuf; destrbuf.attach(destbuffer, destwidth, destheight, deststride); pixfmt destpf(destrbuf); renderer_base destrb(destpf); //destrb.clear(agg::rgba(1, 1, 1, 0)); agg::rect_base<int> region(destx, desty, (int)r, srcheight - (int)b); destrb.copy_from(aggRenderer->renderingBuffer, ®ion, -destx, -desty); } /*std::cout << desty << " " << destheight << " " << srcheight << std::endl;*/ //gdk_rgb_init(); gdk_draw_rgb_32_image(drawable, gc, destx, desty, destwidth, destheight, GDK_RGB_DITHER_NORMAL, destbuffer, deststride); if (needfree) { delete [] destbuffer; } return Py::Object(); }
Py::Object _path_module::update_path_extents(const Py::Tuple& args) { args.verify_length(5); double x0, y0, x1, y1; PathIterator path(args[0]); agg::trans_affine trans = py_to_agg_transformation_matrix( args[1].ptr(), false); if (!py_convert_bbox(args[2].ptr(), x0, y0, x1, y1)) { throw Py::ValueError( "Must pass Bbox object as arg 3 of update_path_extents"); } Py::Object minpos_obj = args[3]; bool ignore = Py::Boolean(args[4]); double xm, ym; PyArrayObject* input_minpos = NULL; try { input_minpos = (PyArrayObject*)PyArray_FromObject( minpos_obj.ptr(), PyArray_DOUBLE, 1, 1); if (!input_minpos || PyArray_DIM(input_minpos, 0) != 2) { throw Py::TypeError( "Argument 4 to update_path_extents must be a length-2 numpy array."); } xm = *(double*)PyArray_GETPTR1(input_minpos, 0); ym = *(double*)PyArray_GETPTR1(input_minpos, 1); } catch (...) { Py_XDECREF(input_minpos); throw; } Py_XDECREF(input_minpos); npy_intp extent_dims[] = { 2, 2, 0 }; double* extents_data = NULL; npy_intp minpos_dims[] = { 2, 0 }; double* minpos_data = NULL; PyArrayObject* extents = NULL; PyArrayObject* minpos = NULL; bool changed = false; try { extents = (PyArrayObject*)PyArray_SimpleNew (2, extent_dims, PyArray_DOUBLE); if (extents == NULL) { throw Py::MemoryError("Could not allocate result array"); } minpos = (PyArrayObject*)PyArray_SimpleNew (1, minpos_dims, PyArray_DOUBLE); if (minpos == NULL) { throw Py::MemoryError("Could not allocate result array"); } extents_data = (double*)PyArray_DATA(extents); minpos_data = (double*)PyArray_DATA(minpos); if (ignore) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); minpos_data[0] = std::numeric_limits<double>::infinity(); minpos_data[1] = std::numeric_limits<double>::infinity(); } else { if (x0 > x1) { extents_data[0] = std::numeric_limits<double>::infinity(); extents_data[2] = -std::numeric_limits<double>::infinity(); } else { extents_data[0] = x0; extents_data[2] = x1; } if (y0 > y1) { extents_data[1] = std::numeric_limits<double>::infinity(); extents_data[3] = -std::numeric_limits<double>::infinity(); } else { extents_data[1] = y0; extents_data[3] = y1; } minpos_data[0] = xm; minpos_data[1] = ym; } ::get_path_extents(path, trans, &extents_data[0], &extents_data[1], &extents_data[2], &extents_data[3], &minpos_data[0], &minpos_data[1]); changed = (extents_data[0] != x0 || extents_data[1] != y0 || extents_data[2] != x1 || extents_data[3] != y1 || minpos_data[0] != xm || minpos_data[1] != ym); } catch (...) { Py_XDECREF(extents); Py_XDECREF(minpos); throw; } Py::Tuple result(3); result[0] = Py::Object((PyObject*) extents); result[1] = Py::Object((PyObject*) minpos); result[2] = Py::Int(changed ? 1 : 0); Py_XDECREF(extents); Py_XDECREF(minpos); return result; }
static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp* interp, int argc, char **argv) { Tk_PhotoHandle photo; Tk_PhotoImageBlock block; PyObject* aggo; // vars for blitting PyObject* bboxo; unsigned long aggl, bboxl; bool has_bbox; agg::int8u *destbuffer; double l, b, r, t; int destx, desty, destwidth, destheight, deststride; //unsigned long tmp_ptr; long mode; long nval; if (Tk_MainWindow(interp) == NULL) { // Will throw a _tkinter.TclError with "this isn't a Tk application" return TCL_ERROR; } if (argc != 5) { Tcl_AppendResult(interp, "usage: ", argv[0], " destPhoto srcImage", (char *) NULL); return TCL_ERROR; } /* get Tcl PhotoImage handle */ photo = Tk_FindPhoto(interp, argv[1]); if (photo == NULL) { Tcl_AppendResult(interp, "destination photo must exist", (char *) NULL); return TCL_ERROR; } /* get array (or object that can be converted to array) pointer */ if (sscanf(argv[2], "%lu", &aggl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *) NULL); return TCL_ERROR; } aggo = (PyObject*)aggl; //aggo = (PyObject*)atol(argv[2]); //std::stringstream agg_ptr_ss; //agg_ptr_ss.str(argv[2]); //agg_ptr_ss >> tmp_ptr; //aggo = (PyObject*)tmp_ptr; RendererAgg *aggRenderer = (RendererAgg *)aggo; int srcheight = (int)aggRenderer->get_height(); /* XXX insert aggRenderer type check */ /* get array mode (0=mono, 1=rgb, 2=rgba) */ mode = atol(argv[3]); if ((mode != 0) && (mode != 1) && (mode != 2)) { Tcl_AppendResult(interp, "illegal image mode", (char *) NULL); return TCL_ERROR; } /* check for bbox/blitting */ if (sscanf(argv[4], "%lu", &bboxl) != 1) { Tcl_AppendResult(interp, "error casting pointer", (char *) NULL); return TCL_ERROR; } bboxo = (PyObject*)bboxl; //bboxo = (PyObject*)atol(argv[4]); //std::stringstream bbox_ptr_ss; //bbox_ptr_ss.str(argv[4]); //bbox_ptr_ss >> tmp_ptr; //bboxo = (PyObject*)tmp_ptr; if (py_convert_bbox(bboxo, l, b, r, t)) { has_bbox = true; destx = (int)l; desty = srcheight - (int)t; destwidth = (int)(r - l); destheight = (int)(t - b); deststride = 4 * destwidth; destbuffer = new agg::int8u[deststride*destheight]; if (destbuffer == NULL) { throw Py::MemoryError("_tkagg could not allocate memory for destbuffer"); } agg::rendering_buffer destrbuf; destrbuf.attach(destbuffer, destwidth, destheight, deststride); pixfmt destpf(destrbuf); renderer_base destrb(destpf); agg::rect_base<int> region(destx, desty, (int)r, srcheight - (int)b); destrb.copy_from(aggRenderer->renderingBuffer, ®ion, -destx, -desty); } else { has_bbox = false; destbuffer = NULL; destx = desty = destwidth = destheight = deststride = 0; } /* setup tkblock */ block.pixelSize = 1; if (mode == 0) { block.offset[0] = block.offset[1] = block.offset[2] = 0; nval = 1; } else { block.offset[0] = 0; block.offset[1] = 1; block.offset[2] = 2; if (mode == 1) { block.offset[3] = 0; block.pixelSize = 3; nval = 3; } else { block.offset[3] = 3; block.pixelSize = 4; nval = 4; } } if (has_bbox) { block.width = destwidth; block.height = destheight; block.pitch = deststride; block.pixelPtr = destbuffer; Tk_PhotoPutBlock(photo, &block, destx, desty, destwidth, destheight); delete [] destbuffer; } else { block.width = aggRenderer->get_width(); block.height = aggRenderer->get_height(); block.pitch = block.width * nval; block.pixelPtr = aggRenderer->pixBuffer; /* Clear current contents */ Tk_PhotoBlank(photo); /* Copy opaque block to photo image, and leave the rest to TK */ Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height); } return TCL_OK; }