/* -*- mode: c++; c-basic-offset: 4 -*- */ #include #include #include #include #include #include #include #include #include #include "agg_basics.h" #include "numpy/arrayobject.h" #include "_backend_agg.h" #include "agg_py_transforms.h" // the extension module class _gtkagg_module : public Py::ExtensionModule<_gtkagg_module> { public: _gtkagg_module() : Py::ExtensionModule<_gtkagg_module>("_gtkagg") { add_varargs_method("agg_to_gtk_drawable", &_gtkagg_module::agg_to_gtk_drawable, "Draw to a gtk drawable from a agg buffer."); initialize("The _gtkagg module"); } virtual ~_gtkagg_module() {} private: 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(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 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(); } }; extern "C" DL_EXPORT(void) init_gtkagg(void) { init_pygobject(); init_pygtk(); import_array(); //suppress unused warning by creating in two lines static _gtkagg_module* _gtkagg = NULL; _gtkagg = new _gtkagg_module; }