Ejemplo n.º 1
0
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;
    Bbox* bbox;
    agg::int8u *destbuffer;
    double l,b,r,t;
    int destx, desty, destwidth, destheight, deststride;

    long mode;
    long nval;
    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 */
    aggo = (PyObject*)atol(argv[2]);
    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 */
    bboxo = (PyObject*)atol(argv[4]);
    if (bboxo != Py_None) {
      bbox = (Bbox*)bboxo;
      l = bbox->ll_api()->x_api()->val();
      b = bbox->ll_api()->y_api()->val();
      r = bbox->ur_api()->x_api()->val();
      t = bbox->ur_api()->y_api()->val();

      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, &region,
		       -destx, -desty);
    } else {
      bbox = NULL;
      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 (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;
}
Ejemplo n.º 2
0
static PyObject *Py_agg_to_gtk_drawable(PyObject *self, PyObject *args, PyObject *kwds)
{
    typedef agg::pixfmt_rgba32_plain pixfmt;
    typedef agg::renderer_base<pixfmt> renderer_base;

    PyGObject *py_drawable;
    numpy::array_view<agg::int8u, 3> buffer;
    agg::rect_d rect;

    // 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

    if (!PyArg_ParseTuple(args,
                          "OO&O&:agg_to_gtk_drawable",
                          &py_drawable,
                          &buffer.converter,
                          &buffer,
                          &convert_rect,
                          &rect)) {
        return NULL;
    }

    if (buffer.dim(2) != 4) {
        PyErr_SetString(PyExc_ValueError, "Invalid image buffer.  Must be NxMx4.");
        return NULL;
    }

    GdkDrawable *drawable = GDK_DRAWABLE(py_drawable->obj);
    GdkGC *gc = gdk_gc_new(drawable);

    int srcstride = buffer.dim(1) * 4;
    int srcwidth = buffer.dim(1);
    int srcheight = buffer.dim(0);

    // these three will be overridden below
    int destx = 0;
    int desty = 0;
    int destwidth = 1;
    int destheight = 1;
    int deststride = 1;

    std::vector<agg::int8u> destbuffer;
    agg::int8u *destbufferptr;

    if (rect.x1 == 0.0 && rect.x2 == 0.0 && rect.y1 == 0.0 && rect.y2 == 0.0) {
        // bbox is None; copy the entire image
        destbufferptr = (agg::int8u *)buffer.data();
        destwidth = srcwidth;
        destheight = srcheight;
        deststride = srcstride;
    } else {
        destx = (int)rect.x1;
        desty = srcheight - (int)rect.y2;
        destwidth = (int)(rect.x2 - rect.x1);
        destheight = (int)(rect.y2 - rect.y1);
        deststride = destwidth * 4;
        destbuffer.reserve(destheight * deststride);
        destbufferptr = &destbuffer[0];

        agg::rendering_buffer destrbuf;
        destrbuf.attach(destbufferptr, destwidth, destheight, deststride);
        pixfmt destpf(destrbuf);
        renderer_base destrb(destpf);

        agg::rendering_buffer srcrbuf;
        srcrbuf.attach((agg::int8u *)buffer.data(), buffer.dim(1), buffer.dim(0), buffer.dim(1) * 4);

        agg::rect_base<int> region(destx, desty, (int)rect.x2, srcheight - (int)rect.y1);
        destrb.copy_from(srcrbuf, &region, -destx, -desty);
    }

    gdk_draw_rgb_32_image(drawable,
                          gc,
                          destx,
                          desty,
                          destwidth,
                          destheight,
                          GDK_RGB_DITHER_NORMAL,
                          destbufferptr,
                          deststride);

    gdk_gc_destroy(gc);

    Py_RETURN_NONE;
}
Ejemplo n.º 3
0
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;

    size_t aggl, bboxl;
    bool has_bbox;
    agg::int8u *destbuffer;
    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], SIZE_T_FORMAT, &aggl) != 1) {
        Tcl_AppendResult(interp, "error casting pointer", (char *)NULL);
        return TCL_ERROR;
    }
    aggo = (PyObject *)aggl;

    // TODO: This is really brittle and will break when RendererAgg
    // comes in multiple flavors
    RendererAgg *aggRenderer = ((PyRendererAgg *)(aggo))->x;
    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], SIZE_T_FORMAT, &bboxl) != 1) {
        Tcl_AppendResult(interp, "error casting pointer", (char *)NULL);
        return TCL_ERROR;
    }
    bboxo = (PyObject *)bboxl;

    if (bboxo != NULL && bboxo != Py_None) {
        agg::rect_d rect;
        if (!convert_rect(bboxo, &rect)) {
            return TCL_ERROR;
        }

        has_bbox = true;

        destx = (int)rect.x1;
        desty = srcheight - (int)rect.y2;
        destwidth = (int)(rect.x2 - rect.x1);
        destheight = (int)(rect.y2 - rect.y1);
        deststride = 4 * destwidth;

        destbuffer = new agg::int8u[deststride * destheight];
        if (destbuffer == NULL) {
            Tcl_AppendResult(interp, "could not allocate memory", (char *)NULL);
            return TCL_ERROR;
        }

        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)rect.x2, srcheight - (int)rect.y1);
        destrb.copy_from(aggRenderer->renderingBuffer, &region, -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 = (int)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;
}
    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, &region,
                             -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();

    }
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, &region,
                         -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;
}