Exemple #1
0
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);
}
Exemple #2
0
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, &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();

    }
Exemple #4
0
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, &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;
}