123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772 |
- #include "numpy_cpp.h"
- #include "_path.h"
- #include "py_converters.h"
- #include "py_adaptors.h"
- PyObject *convert_polygon_vector(std::vector<Polygon> &polygons)
- {
- PyObject *pyresult = PyList_New(polygons.size());
- for (size_t i = 0; i < polygons.size(); ++i) {
- Polygon poly = polygons[i];
- npy_intp dims[2];
- dims[1] = 2;
- dims[0] = (npy_intp)poly.size();
- numpy::array_view<double, 2> subresult(dims);
- memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2);
- if (PyList_SetItem(pyresult, i, subresult.pyobj())) {
- Py_DECREF(pyresult);
- return NULL;
- }
- }
- return pyresult;
- }
- const char *Py_point_in_path__doc__ =
- "point_in_path(x, y, radius, path, trans)\n"
- "--\n\n";
- static PyObject *Py_point_in_path(PyObject *self, PyObject *args)
- {
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_in_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
- CALL_CPP("point_in_path", (result = point_in_path(x, y, r, path, trans)));
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- const char *Py_points_in_path__doc__ =
- "points_in_path(points, radius, path, trans)\n"
- "--\n\n";
- static PyObject *Py_points_in_path(PyObject *self, PyObject *args)
- {
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_in_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
- CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results)));
- return results.pyobj();
- }
- const char *Py_update_path_extents__doc__ =
- "update_path_extents(path, trans, rect, minpos, ignore)\n"
- "--\n\n";
- static PyObject *Py_update_path_extents(PyObject *self, PyObject *args)
- {
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d rect;
- numpy::array_view<double, 1> minpos;
- int ignore;
- int changed;
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&i:update_path_extents",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &rect,
- &minpos.converter,
- &minpos,
- &ignore)) {
- return NULL;
- }
- if (minpos.dim(0) != 2) {
- PyErr_Format(PyExc_ValueError,
- "minpos must be of length 2, got %" NPY_INTP_FMT,
- minpos.dim(0));
- return NULL;
- }
- extent_limits e;
- if (ignore) {
- CALL_CPP("update_path_extents", reset_limits(e));
- } else {
- if (rect.x1 > rect.x2) {
- e.x0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- } else {
- e.x0 = rect.x1;
- e.x1 = rect.x2;
- }
- if (rect.y1 > rect.y2) {
- e.y0 = std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- } else {
- e.y0 = rect.y1;
- e.y1 = rect.y2;
- }
- e.xm = minpos(0);
- e.ym = minpos(1);
- }
- CALL_CPP("update_path_extents", (update_path_extents(path, trans, e)));
- changed = (e.x0 != rect.x1 || e.y0 != rect.y1 || e.x1 != rect.x2 || e.y1 != rect.y2 ||
- e.xm != minpos(0) || e.ym != minpos(1));
- npy_intp extentsdims[] = { 2, 2 };
- numpy::array_view<double, 2> outextents(extentsdims);
- outextents(0, 0) = e.x0;
- outextents(0, 1) = e.y0;
- outextents(1, 0) = e.x1;
- outextents(1, 1) = e.y1;
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> outminpos(minposdims);
- outminpos(0) = e.xm;
- outminpos(1) = e.ym;
- return Py_BuildValue(
- "NNi", outextents.pyobj(), outminpos.pyobj(), changed);
- }
- const char *Py_get_path_collection_extents__doc__ =
- "get_path_collection_extents("
- "master_transform, paths, transforms, offsets, offset_transform)\n"
- "--\n\n";
- static PyObject *Py_get_path_collection_extents(PyObject *self, PyObject *args)
- {
- agg::trans_affine master_transform;
- py::PathGenerator paths;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- extent_limits e;
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&:get_path_collection_extents",
- &convert_trans_affine,
- &master_transform,
- &convert_pathgen,
- &paths,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans)) {
- return NULL;
- }
- CALL_CPP("get_path_collection_extents",
- (get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_trans, e)));
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> minpos(minposdims);
- minpos(0) = e.xm;
- minpos(1) = e.ym;
- return Py_BuildValue("NN", extents.pyobj(), minpos.pyobj());
- }
- const char *Py_point_in_path_collection__doc__ =
- "point_in_path_collection("
- "x, y, radius, master_transform, paths, transforms, offsets, "
- "offset_trans, filled)\n"
- "--\n\n";
- static PyObject *Py_point_in_path_collection(PyObject *self, PyObject *args)
- {
- double x, y, radius;
- agg::trans_affine master_transform;
- py::PathGenerator paths;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- bool filled;
- std::vector<int> result;
- if (!PyArg_ParseTuple(args,
- "dddO&O&O&O&O&O&:point_in_path_collection",
- &x,
- &y,
- &radius,
- &convert_trans_affine,
- &master_transform,
- &convert_pathgen,
- &paths,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_bool,
- &filled)) {
- return NULL;
- }
- CALL_CPP("point_in_path_collection",
- (point_in_path_collection(x,
- y,
- radius,
- master_transform,
- paths,
- transforms,
- offsets,
- offset_trans,
- filled,
- result)));
- npy_intp dims[] = {(npy_intp)result.size() };
- numpy::array_view<int, 1> pyresult(dims);
- if (result.size() > 0) {
- memcpy(pyresult.data(), &result[0], result.size() * sizeof(int));
- }
- return pyresult.pyobj();
- }
- const char *Py_path_in_path__doc__ =
- "path_in_path(path_a, trans_a, path_b, trans_b)\n"
- "--\n\n";
- static PyObject *Py_path_in_path(PyObject *self, PyObject *args)
- {
- py::PathIterator a;
- agg::trans_affine atrans;
- py::PathIterator b;
- agg::trans_affine btrans;
- bool result;
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&:path_in_path",
- &convert_path,
- &a,
- &convert_trans_affine,
- &atrans,
- &convert_path,
- &b,
- &convert_trans_affine,
- &btrans)) {
- return NULL;
- }
- CALL_CPP("path_in_path", (result = path_in_path(a, atrans, b, btrans)));
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- const char *Py_clip_path_to_rect__doc__ =
- "clip_path_to_rect(path, rect, inside)\n"
- "--\n\n";
- static PyObject *Py_clip_path_to_rect(PyObject *self, PyObject *args)
- {
- py::PathIterator path;
- agg::rect_d rect;
- bool inside;
- std::vector<Polygon> result;
- if (!PyArg_ParseTuple(args,
- "O&O&O&:clip_path_to_rect",
- &convert_path,
- &path,
- &convert_rect,
- &rect,
- &convert_bool,
- &inside)) {
- return NULL;
- }
- CALL_CPP("clip_path_to_rect", (clip_path_to_rect(path, rect, inside, result)));
- return convert_polygon_vector(result);
- }
- const char *Py_affine_transform__doc__ =
- "affine_transform(points, trans)\n"
- "--\n\n";
- static PyObject *Py_affine_transform(PyObject *self, PyObject *args)
- {
- PyObject *vertices_obj;
- agg::trans_affine trans;
- if (!PyArg_ParseTuple(args,
- "OO&:affine_transform",
- &vertices_obj,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
- PyArrayObject* vertices_arr = (PyArrayObject *)PyArray_ContiguousFromAny(vertices_obj, NPY_DOUBLE, 1, 2);
- if (vertices_arr == NULL) {
- return NULL;
- }
- if (PyArray_NDIM(vertices_arr) == 2) {
- numpy::array_view<double, 2> vertices(vertices_arr);
- Py_DECREF(vertices_arr);
- npy_intp dims[] = { (npy_intp)vertices.size(), 2 };
- numpy::array_view<double, 2> result(dims);
- CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
- return result.pyobj();
- } else { // PyArray_NDIM(vertices_arr) == 1
- numpy::array_view<double, 1> vertices(vertices_arr);
- Py_DECREF(vertices_arr);
- npy_intp dims[] = { (npy_intp)vertices.size() };
- numpy::array_view<double, 1> result(dims);
- CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
- return result.pyobj();
- }
- }
- const char *Py_count_bboxes_overlapping_bbox__doc__ =
- "count_bboxes_overlapping_bbox(bbox, bboxes)\n"
- "--\n\n";
- static PyObject *Py_count_bboxes_overlapping_bbox(PyObject *self, PyObject *args)
- {
- agg::rect_d bbox;
- numpy::array_view<const double, 3> bboxes;
- int result;
- if (!PyArg_ParseTuple(args,
- "O&O&:count_bboxes_overlapping_bbox",
- &convert_rect,
- &bbox,
- &convert_bboxes,
- &bboxes)) {
- return NULL;
- }
- CALL_CPP("count_bboxes_overlapping_bbox",
- (result = count_bboxes_overlapping_bbox(bbox, bboxes)));
- return PyLong_FromLong(result);
- }
- const char *Py_path_intersects_path__doc__ =
- "path_intersects_path(path1, path2, filled=False)\n"
- "--\n\n";
- static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObject *kwds)
- {
- py::PathIterator p1;
- py::PathIterator p2;
- agg::trans_affine t1;
- agg::trans_affine t2;
- int filled = 0;
- const char *names[] = { "p1", "p2", "filled", NULL };
- bool result;
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&i:path_intersects_path",
- (char **)names,
- &convert_path,
- &p1,
- &convert_path,
- &p2,
- &filled)) {
- return NULL;
- }
- CALL_CPP("path_intersects_path", (result = path_intersects_path(p1, p2)));
- if (filled) {
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p1, t1, p2, t2)));
- }
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p2, t1, p1, t2)));
- }
- }
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- const char *Py_path_intersects_rectangle__doc__ =
- "path_intersects_rectangle("
- "path, rect_x1, rect_y1, rect_x2, rect_y2, filled=False)\n"
- "--\n\n";
- static PyObject *Py_path_intersects_rectangle(PyObject *self, PyObject *args, PyObject *kwds)
- {
- py::PathIterator path;
- double rect_x1, rect_y1, rect_x2, rect_y2;
- bool filled = false;
- const char *names[] = { "path", "rect_x1", "rect_y1", "rect_x2", "rect_y2", "filled", NULL };
- bool result;
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&dddd|O&:path_intersects_rectangle",
- (char **)names,
- &convert_path,
- &path,
- &rect_x1,
- &rect_y1,
- &rect_x2,
- &rect_y2,
- &convert_bool,
- &filled)) {
- return NULL;
- }
- CALL_CPP("path_intersects_rectangle", (result = path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled)));
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- const char *Py_convert_path_to_polygons__doc__ =
- "convert_path_to_polygons(path, trans, width=0, height=0)\n"
- "--\n\n";
- static PyObject *Py_convert_path_to_polygons(PyObject *self, PyObject *args, PyObject *kwds)
- {
- py::PathIterator path;
- agg::trans_affine trans;
- double width = 0.0, height = 0.0;
- int closed_only = 1;
- std::vector<Polygon> result;
- const char *names[] = { "path", "transform", "width", "height", "closed_only", NULL };
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&|ddi:convert_path_to_polygons",
- (char **)names,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &width,
- &height,
- &closed_only)) {
- return NULL;
- }
- CALL_CPP("convert_path_to_polygons",
- (convert_path_to_polygons(path, trans, width, height, closed_only, result)));
- return convert_polygon_vector(result);
- }
- const char *Py_cleanup_path__doc__ =
- "cleanup_path("
- "path, trans, remove_nans, clip_rect, snap_mode, stroke_width, simplify, "
- "return_curves, sketch)\n"
- "--\n\n";
- static PyObject *Py_cleanup_path(PyObject *self, PyObject *args)
- {
- py::PathIterator path;
- agg::trans_affine trans;
- bool remove_nans;
- agg::rect_d clip_rect;
- e_snap_mode snap_mode;
- double stroke_width;
- PyObject *simplifyobj;
- bool simplify = false;
- bool return_curves;
- SketchParams sketch;
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&dOO&O&:cleanup_path",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_bool,
- &remove_nans,
- &convert_rect,
- &clip_rect,
- &convert_snap,
- &snap_mode,
- &stroke_width,
- &simplifyobj,
- &convert_bool,
- &return_curves,
- &convert_sketch_params,
- &sketch)) {
- return NULL;
- }
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else {
- switch (PyObject_IsTrue(simplifyobj)) {
- case 0: simplify = false; break;
- case 1: simplify = true; break;
- default: return NULL; // errored.
- }
- }
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
- std::vector<double> vertices;
- std::vector<npy_uint8> codes;
- CALL_CPP("cleanup_path",
- (cleanup_path(path,
- trans,
- remove_nans,
- do_clip,
- clip_rect,
- snap_mode,
- stroke_width,
- simplify,
- return_curves,
- sketch,
- vertices,
- codes)));
- size_t length = codes.size();
- npy_intp vertices_dims[] = {(npy_intp)length, 2 };
- numpy::array_view<double, 2> pyvertices(vertices_dims);
- npy_intp codes_dims[] = {(npy_intp)length };
- numpy::array_view<unsigned char, 1> pycodes(codes_dims);
- memcpy(pyvertices.data(), &vertices[0], sizeof(double) * 2 * length);
- memcpy(pycodes.data(), &codes[0], sizeof(unsigned char) * length);
- return Py_BuildValue("NN", pyvertices.pyobj(), pycodes.pyobj());
- }
- const char *Py_convert_to_string__doc__ =
- "convert_to_string("
- "path, trans, clip_rect, simplify, sketch, precision, codes, postfix)\n"
- "--\n\n"
- "Convert *path* to a bytestring.\n"
- "\n"
- "The first five parameters (up to *sketch*) are interpreted as in\n"
- "`.cleanup_path`. The following ones are detailed below.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "path : Path\n"
- "trans : Transform or None\n"
- "clip_rect : sequence of 4 floats, or None\n"
- "simplify : bool\n"
- "sketch : tuple of 3 floats, or None\n"
- "precision : int\n"
- " The precision used to \"%.*f\"-format the values. Trailing zeros\n"
- " and decimal points are always removed. (precision=-1 is a special\n"
- " case used to implement ttconv-back-compatible conversion.)\n"
- "codes : sequence of 5 bytestrings\n"
- " The bytes representation of each opcode (MOVETO, LINETO, CURVE3,\n"
- " CURVE4, CLOSEPOLY), in that order. If the bytes for CURVE3 is\n"
- " empty, quad segments are automatically converted to cubic ones\n"
- " (this is used by backends such as pdf and ps, which do not support\n"
- " quads).\n"
- "postfix : bool\n"
- " Whether the opcode comes after the values (True) or before (False).\n"
- ;
- static PyObject *Py_convert_to_string(PyObject *self, PyObject *args)
- {
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d cliprect;
- PyObject *simplifyobj;
- bool simplify = false;
- SketchParams sketch;
- int precision;
- char *codes[5];
- bool postfix;
- std::string buffer;
- bool status;
- if (!PyArg_ParseTuple(args,
- "O&O&O&OO&i(yyyyy)O&:convert_to_string",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &cliprect,
- &simplifyobj,
- &convert_sketch_params,
- &sketch,
- &precision,
- &codes[0],
- &codes[1],
- &codes[2],
- &codes[3],
- &codes[4],
- &convert_bool,
- &postfix)) {
- return NULL;
- }
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else {
- switch (PyObject_IsTrue(simplifyobj)) {
- case 0: simplify = false; break;
- case 1: simplify = true; break;
- default: return NULL; // errored.
- }
- }
- CALL_CPP("convert_to_string",
- (status = convert_to_string(
- path, trans, cliprect, simplify, sketch,
- precision, codes, postfix, buffer)));
- if (!status) {
- PyErr_SetString(PyExc_ValueError, "Malformed path codes");
- return NULL;
- }
- return PyBytes_FromStringAndSize(buffer.c_str(), buffer.size());
- }
- const char *Py_is_sorted_and_has_non_nan__doc__ =
- "is_sorted_and_has_non_nan(array, /)\n"
- "--\n\n"
- "Return whether the 1D *array* is monotonically increasing, ignoring NaNs,\n"
- "and has at least one non-nan value.";
- static PyObject *Py_is_sorted_and_has_non_nan(PyObject *self, PyObject *obj)
- {
- bool result;
- PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
- obj, NULL, 1, 1, 0, NULL);
- if (array == NULL) {
- return NULL;
- }
- /* Handle just the most common types here, otherwise coerce to double */
- switch (PyArray_TYPE(array)) {
- case NPY_INT:
- result = is_sorted_and_has_non_nan<npy_int>(array);
- break;
- case NPY_LONG:
- result = is_sorted_and_has_non_nan<npy_long>(array);
- break;
- case NPY_LONGLONG:
- result = is_sorted_and_has_non_nan<npy_longlong>(array);
- break;
- case NPY_FLOAT:
- result = is_sorted_and_has_non_nan<npy_float>(array);
- break;
- case NPY_DOUBLE:
- result = is_sorted_and_has_non_nan<npy_double>(array);
- break;
- default:
- Py_DECREF(array);
- array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);
- if (array == NULL) {
- return NULL;
- }
- result = is_sorted_and_has_non_nan<npy_double>(array);
- }
- Py_DECREF(array);
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
- }
- static PyMethodDef module_functions[] = {
- {"point_in_path", (PyCFunction)Py_point_in_path, METH_VARARGS, Py_point_in_path__doc__},
- {"points_in_path", (PyCFunction)Py_points_in_path, METH_VARARGS, Py_points_in_path__doc__},
- {"update_path_extents", (PyCFunction)Py_update_path_extents, METH_VARARGS, Py_update_path_extents__doc__},
- {"get_path_collection_extents", (PyCFunction)Py_get_path_collection_extents, METH_VARARGS, Py_get_path_collection_extents__doc__},
- {"point_in_path_collection", (PyCFunction)Py_point_in_path_collection, METH_VARARGS, Py_point_in_path_collection__doc__},
- {"path_in_path", (PyCFunction)Py_path_in_path, METH_VARARGS, Py_path_in_path__doc__},
- {"clip_path_to_rect", (PyCFunction)Py_clip_path_to_rect, METH_VARARGS, Py_clip_path_to_rect__doc__},
- {"affine_transform", (PyCFunction)Py_affine_transform, METH_VARARGS, Py_affine_transform__doc__},
- {"count_bboxes_overlapping_bbox", (PyCFunction)Py_count_bboxes_overlapping_bbox, METH_VARARGS, Py_count_bboxes_overlapping_bbox__doc__},
- {"path_intersects_path", (PyCFunction)Py_path_intersects_path, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_path__doc__},
- {"path_intersects_rectangle", (PyCFunction)Py_path_intersects_rectangle, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_rectangle__doc__},
- {"convert_path_to_polygons", (PyCFunction)Py_convert_path_to_polygons, METH_VARARGS|METH_KEYWORDS, Py_convert_path_to_polygons__doc__},
- {"cleanup_path", (PyCFunction)Py_cleanup_path, METH_VARARGS, Py_cleanup_path__doc__},
- {"convert_to_string", (PyCFunction)Py_convert_to_string, METH_VARARGS, Py_convert_to_string__doc__},
- {"is_sorted_and_has_non_nan", (PyCFunction)Py_is_sorted_and_has_non_nan, METH_O, Py_is_sorted_and_has_non_nan__doc__},
- {NULL}
- };
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT, "_path", NULL, 0, module_functions
- };
- PyMODINIT_FUNC PyInit__path(void)
- {
- import_array();
- return PyModule_Create(&moduledef);
- }
|