2222 */
2323class PathIterator
2424{
25- /* We hold references to the Python objects, not just the
26- underlying data arrays, so that Python reference counting can
27- work.
28- */
29- Py::Object m_vertices;
30- Py::Object m_codes;
25+ PyObject* m_vertices_arr;
26+ PyObject* m_codes_arr;
3127
3228 size_t m_iterator;
3329 size_t m_total_vertices;
@@ -41,9 +37,75 @@ class PathIterator
4137public:
4238 /* path_obj is an instance of the class Path as defined in path.py */
4339 inline PathIterator (const Py::Object& path_obj) :
44- m_vertices(), m_codes(), m_iterator(0 ), m_should_simplify(false ),
40+ m_iterator(0 ), m_should_simplify(false ),
4541 m_simplify_threshold(1.0 / 9.0 )
4642 {
43+ PyObject* _path = path_obj.ptr ();
44+
45+ PyObject* _vertices = PyObject_GetAttrString (_path, " vertices" );
46+ if (!_vertices)
47+ {
48+ throw ;
49+ }
50+ m_vertices_arr = PyArray_FromObject (_vertices, PyArray_DOUBLE, 2 , 2 );
51+ Py_DECREF (_vertices);
52+ if (!m_vertices_arr || PyArray_DIM (m_vertices_arr, 1 ) != 2 )
53+ {
54+ Py_XDECREF (m_vertices_arr);
55+ throw Py::ValueError (" Invalid vertices array." );
56+ }
57+ m_total_vertices = PyArray_DIM (m_vertices_arr, 0 );
58+
59+ PyObject *_codes = PyObject_GetAttrString (_path, " codes" );
60+ if (!_codes)
61+ {
62+ Py_DECREF (m_vertices_arr);
63+ throw ;
64+ }
65+ if (_codes != Py_None)
66+ {
67+ m_codes_arr = PyArray_FromObject (_codes, PyArray_UINT8, 1 , 1 );
68+ Py_DECREF (_codes);
69+
70+ if (!m_codes_arr)
71+ {
72+ Py_DECREF (m_vertices_arr);
73+ throw Py::ValueError (" Invalid codes array." );
74+ }
75+
76+ if (PyArray_DIM (m_codes_arr, 0 ) != m_total_vertices)
77+ {
78+ Py_DECREF (m_vertices_arr);
79+ throw Py::ValueError (" Codes array is wrong length" );
80+ }
81+ }
82+ else
83+ {
84+ m_codes_arr = NULL ;
85+ Py_DECREF (_codes);
86+ }
87+
88+ PyObject* _should_simplify = PyObject_GetAttrString (_path, " should_simplify" );
89+ if (!_should_simplify)
90+ {
91+ Py_DECREF (m_vertices_arr);
92+ Py_XDECREF (m_codes_arr);
93+ throw ;
94+ }
95+ m_should_simplify = PyObject_IsTrue (_should_simplify) != 0 ;
96+ Py_DECREF (_should_simplify);
97+
98+ PyObject* _simplify_threshold = PyObject_GetAttrString (_path, " simplify_threshold" );
99+ if (!_simplify_threshold)
100+ {
101+ Py_DECREF (m_vertices_arr);
102+ Py_XDECREF (m_codes_arr);
103+ throw ;
104+ }
105+ m_simplify_threshold = PyFloat_AsDouble (_simplify_threshold);
106+ Py_DECREF (_simplify_threshold);
107+
108+ /*
47109 Py::Object vertices_obj = path_obj.getAttr("vertices");
48110 Py::Object codes_obj = path_obj.getAttr("codes");
49111 Py::Object should_simplify_obj = path_obj.getAttr("should_simplify");
@@ -80,11 +142,13 @@ class PathIterator
80142 m_should_simplify = should_simplify_obj.isTrue();
81143 m_total_vertices = PyArray_DIM(m_vertices.ptr(), 0);
82144 m_simplify_threshold = Py::Float(simplify_threshold_obj);
145+ */
83146 }
84147
85148 ~PathIterator ()
86149 {
87-
150+ Py_DECREF (m_vertices_arr);
151+ Py_XDECREF (m_codes_arr);
88152 }
89153
90154 inline unsigned vertex (double * x, double * y)
@@ -93,13 +157,13 @@ class PathIterator
93157
94158 const size_t idx = m_iterator++;
95159
96- char * pair = (char *)PyArray_GETPTR2 (m_vertices. ptr () , idx, 0 );
160+ char * pair = (char *)PyArray_GETPTR2 (m_vertices_arr , idx, 0 );
97161 *x = *(double *)pair;
98- *y = *(double *)(pair + PyArray_STRIDE (m_vertices. ptr () , 1 ));
162+ *y = *(double *)(pair + PyArray_STRIDE (m_vertices_arr , 1 ));
99163
100- if (!m_codes. isNone () )
164+ if (m_codes_arr != NULL )
101165 {
102- return (unsigned )(*(char *)PyArray_GETPTR1 (m_codes. ptr () , idx));
166+ return (unsigned )(*(char *)PyArray_GETPTR1 (m_codes_arr , idx));
103167 }
104168 else
105169 {
@@ -129,7 +193,7 @@ class PathIterator
129193
130194 inline bool has_curves ()
131195 {
132- return !m_codes. isNone () ;
196+ return m_codes_arr != NULL ;
133197 }
134198};
135199
0 commit comments