8000 Merge py_converters{,_11} now that they're all pybind11 · matplotlib/matplotlib@81c2717 · GitHub
[go: up one dir, main page]

Skip to content

Commit 81c2717

Browse files
committed
Merge py_converters{,_11} now that they're all pybind11
1 parent fdcb8dd commit 81c2717

File tree

7 files changed

+297
-333
lines changed

7 files changed

+297
-333
lines changed

src/_backend_agg_wrapper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "numpy_cpp.h"
66
#include "py_converters.h"
77
#include "_backend_agg.h"
8-
#include "py_converters_11.h"
98

109
namespace py = pybind11;
1110
using namespace pybind11::literals;

src/_image_wrapper.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#include <pybind11/numpy.h>
33

44
#include "_image_resample.h"
5-
#include "py_converters_11.h"
5+
#include "py_converters.h"
66

77
namespace py = pybind11;
88
using namespace pybind11::literals;
@@ -162,7 +162,7 @@ image_resample(py::array input_array,
162162
bool is_affine = py::cast<bool>(transform.attr("is_affine"));
163163

164164
if (is_affine) {
165-
convert_trans_affine(transform, params.affine);
165+
params.affine = transform.cast<agg::trans_affine>();
166166
params.is_affine = true;
167167
} else {
168168
transform_mesh = _get_transform_mesh(transform, output_array.shape());

src/_path_wrapper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "_backend_agg_basic_types.h"
1515
#include "py_adaptors.h"
1616
#include "py_converters.h"
17-
#include "py_converters_11.h"
1817

1918
namespace py = pybind11;
2019
using namespace pybind11::literals;

src/meson.build

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ extension_data = {
7474
'subdir': 'matplotlib/backends',
7575
'sources': files(
7676
'py_converters.cpp',
77-
'py_converters_11.cpp',
7877
'_backend_agg.cpp',
7978
'_backend_agg_wrapper.cpp',
8079
),
@@ -107,7 +106,7 @@ extension_data = {
107106
'subdir': 'matplotlib',
108107
'sources': files(
109108
'_image_wrapper.cpp',
110-
'py_converters_11.cpp',
109+
'py_converters.cpp',
111110
),
112111
'dependencies': [
113112
pybind11_dep,
@@ -119,7 +118,6 @@ extension_data = {
119118
'subdir': 'matplotlib',
120119
'sources': files(
121120
'py_converters.cpp',
122-
'py_converters_11.cpp',
123121
'_path_wrapper.cpp',
124122
),
125123
'dependencies': [numpy_dep, agg_dep, pybind11_dep],

src/py_converters.h

Lines changed: 294 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,17 @@
1313
* and friends.
1414
*/
1515

16-
#include <Python.h>
16+
#include <pybind11/pybind11.h>
17+
#include <pybind11/numpy.h>
18+
19+
namespace py = pybind11;
20+
21+
#include <unordered_map>
22+
23+
#include "agg_basics.h"
24+
#include "agg_color_rgba.h"
25+
#include "agg_trans_affine.h"
26+
#include "path_converters.h"
1727

1828
extern "C" {
1929
typedef int (*converter)(PyObject *, void *);
@@ -25,4 +35,287 @@ int convert_bboxes(PyObject *pygc, void *bboxp);
2535
int convert_colors(PyObject *pygc, void *colorsp);
2636
}
2737

38+
inline auto convert_points(py::array_t<double> obj)
39+
{
40+
check_trailing_shape(obj, "points", 2);
41+
return obj.unchecked<2>();
42+
}
43+
44+
inline auto convert_transforms(py::array_t<double> obj)
45+
{
46+
check_trailing_shape(obj, "transforms", 3, 3);
47+
return obj.unchecked<3>();
48+
}
49+
50+
inline auto convert_bboxes(py::array_t<double> obj)
51+
{
52+
check_trailing_shape(obj, "bbox array", 2, 2);
53+
return obj.unchecked<3>();
54+
}
55+
56+
inline auto convert_colors(py::array_t<double> obj)
57+
{
58+
check_trailing_shape(obj, "colors", 4);
59+
return obj.unchecked<2>();
60+
}
61+
62+
namespace PYBIND11_NAMESPACE { namespace detail {
63+
template <> struct type_caster<agg::rect_d> {
64+
public:
65+
PYBIND11_TYPE_CASTER(agg::rect_d, const_name("rect_d"));
66+
67+
bool load(handle src, bool) {
68+
if (src.is_none()) {
69+
value.x1 = 0.0;
70+
value.y1 = 0.0;
71+
value.x2 = 0.0;
72+
value.y2 = 0.0;
73+
return true;
74+
}
75+
76+
auto rect_arr = py::array_t<double>::ensure(src);
77+
78+
if (rect_arr.ndim() == 2) {
79+
if (rect_arr.shape(0) != 2 || rect_arr.shape(1) != 2) {
80+
throw py::value_error("Invalid bounding box");
81+
}
82+
83+
value.x1 = *rect_arr.data(0, 0);
84+
value.y1 = *rect_arr.data(0, 1);
85+
value.x2 = *rect_arr.data(1, 0);
86+
value.y2 = *rect_arr.data(1, 1);
87+
88+
} else if (rect_arr.ndim() == 1) {
89+
if (rect_arr.shape(0) != 4) {
90+
throw py::value_error("Invalid bounding box");
91+
}
92+
93+
value.x1 = *rect_arr.data(0);
94+
value.y1 = *rect_arr.data(1);
95+
value.x2 = *rect_arr.data(2);
96+
value.y2 = *rect_arr.data(3);
97+
98+
} else {
99+
throw py::value_error("Invalid bounding box");
100+
}
101+
102+
return true;
103+
}
104+
};
105+
106+
template <> struct type_caster<agg::rgba> {
107+
public:
108+
PYBIND11_TYPE_CASTER(agg::rgba, const_name("rgba"));
109+
110+
bool load(handle src, bool) {
111+
if (src.is_none()) {
112+
value.r = 0.0;
113+
value.g = 0.0;
114+
value.b = 0.0;
115+
value.a = 0.0;
116+
} else {
117+
auto rgbatuple = src.cast<py::tuple>();
118+
value.r = rgbatuple[0].cast<double>();
119+
value.g = rgbatuple[1].cast<double>();
120+
value.b = rgbatuple[2].cast<double>();
121+
switch (rgbatuple.size()) {
122+
case 4:
123+
value.a = rgbatuple[3].cast<double>();
124+
break;
125+
case 3:
126+
value.a = 1.0;
127+
break;
128+
default:
129+
throw py::value_error("RGBA value must be 3- or 4-tuple");
130+
}
131+
}
132+
return true;
133+
}
134+
};
135+
136+
template <> struct type_caster<agg::trans_affine> {
137+
public:
138+
PYBIND11_TYPE_CASTER(agg::trans_affine, const_name("trans_affine"));
139+
140+
bool load(handle src, bool) {
141+
// If None assume identity transform so leave affine unchanged
142+
if (src.is_none()) {
143+
return true;
144+
}
145+
146+
auto array = py::array_t<double, py::array::c_style>::ensure(src);
147+
if (!array || array.ndim() != 2 ||
148+
array.shape(0) != 3 || array.shape(1) != 3) {
149+
throw std::invalid_argument("Invalid affine transformation matrix");
150+
}
151+
152+
auto buffer = array.data();
153+
value.sx = buffer[0];
154+
value.shx = buffer[1];
155+
value.tx = buffer[2];
156+
value.shy = buffer[3];
157+
value.sy = buffer[4];
158+
value.ty = buffer[5];
159+
160+
return true;
161+
}
162+
};
163+
164+
template <> struct type_caster<e_snap_mode> {
165+
public:
166+
PYBIND11_TYPE_CASTER(e_snap_mode, const_name("e_snap_mode"));
167+
168+
bool load(handle src, bool) {
169+
if (src.is_none()) {
170+
value = SNAP_AUTO;
171+
return true;
172+
}
173+
174+
value = src.cast<bool>() ? SNAP_TRUE : SNAP_FALSE;
175+
176+
return true;
177+
}
178+
};
179+
180+
/* Remove all this macro magic after dropping NumPy usage and just include `py_adaptors.h`. */
181+
#ifdef MPL_PY_ADAPTORS_H
182+
template <> struct type_caster<agg::line_cap_e> {
183+
public:
184+
PYBIND11_TYPE_CASTER(agg::line_cap_e, const_name("line_cap_e"));
185+
186+
bool load(handle src, bool) {
187+
const std::unordered_map<std::string, agg::line_cap_e> enum_values = {
188+
{"butt", agg::butt_cap},
189+
{"round", agg::round_cap},
190+
{"projecting", agg::square_cap},
191+
};
192+
value = enum_values.at(src.cast<std::string>());
193+
return true;
194+
}
195+
};
196+
197+
template <> struct type_caster<agg::line_join_e> {
198+
public:
199+
PYBIND11_TYPE_CASTER(agg::line_join_e, const_name("line_join_e"));
200+
201+
bool load(handle src, bool) {
202+
const std::unordered_map<std::string, agg::line_join_e> enum_values = {
203+
{"miter", agg::miter_join_revert},
204+
{"round", agg::round_join},
205+
{"bevel", agg::bevel_join},
206+
};
207+
value = agg::miter_join_revert;
208+
value = enum_values.at(src.cast<std::string>());
209+
return true;
210+
}
211+
};
28212
#endif
213+
214+
/* Remove all this macro magic after dropping NumPy usage and just include `_backend_agg_basic_types.h`. */
215+
#ifdef MPL_BACKEND_AGG_BASIC_TYPES_H
216+
# ifndef MPL_PY_ADAPTORS_H
217+
# error "py_adaptors.h must be included to get Agg type casters"
218+
# endif
219+
220+
template <> struct type_caster<ClipPath> {
221+
public:
222+
PYBIND11_TYPE_CASTER(ClipPath, const_name("ClipPath"));
223+
224+
bool load(handle src, bool) {
225+
if (src.is_none()) {
226+
return true;
227+
}
228+
229+
auto clippath_tuple = src.cast<py::tuple>();
230+
231+
auto path = clippath_tuple[0];
232+
if (!path.is_none()) {
233+
value.path = path.cast<mpl::PathIterator>();
234+
}
235+
value.trans = clippath_tuple[1].cast<agg::trans_affine>();
236+
237+
return true;
238+
}
239+
};
240+
241+
template <> struct type_caster<Dashes> {
242+
public:
243+
PYBIND11_TYPE_CASTER(Dashes, const_name("Dashes"));
244+
245+
bool load(handle src, bool) {
246+
auto dash_tuple = src.cast<py::tuple>();
247+
auto dash_offset = dash_tuple[0].cast<double>();
248+
auto dashes_seq_or_none = dash_tuple[1];
249+
250+
if (dashes_seq_or_none.is_none()) {
251+
return true;
252+
}
253+
254+
auto dashes_seq = dashes_seq_or_none.cast<py::sequence>();
255+
256+
auto nentries = dashes_seq.size();
257+
// If the dashpattern has odd length, iterate through it twice (in
258+
// accordance with the pdf/ps/svg specs).
259+
auto dash_pattern_length = (nentries % 2) ? 2 * nentries : nentries;
260+
261+
for (py::size_t i = 0; i < dash_pattern_length; i += 2) {
262+
auto length = dashes_seq[i % nentries].cast<double>();
263+
auto skip = dashes_seq[(i + 1) % nentries].cast<double>();
264+
265+
value.add_dash_pair(length, skip);
266+
}
267+
268+
value.set_dash_offset(dash_offset);
269+
270+
return true;
271+
}
272+
};
273+
274+
template <> struct type_caster<SketchParams> {
275+
public:
276+
PYBIND11_TYPE_CASTER(SketchParams, const_name("SketchParams"));
277+
278+
bool load(handle src, bool) {
279+
if (src.is_none()) {
280+
value.scale = 0.0;
281+
value.length = 0.0;
282+
value.randomness = 0.0;
283+
return true;
284+
}
285+
286+
auto params = src.cast<std::tuple<double, double, double>>();
287+
std::tie(value.scale, value.length, value.randomness) = params;
288+
289+
return true;
290+
}
291+
};
292+
293+
template <> struct type_caster<GCAgg> {
294+
public:
295+
PYBIND11_TYPE_CASTER(GCAgg, const_name("GCAgg"));
296+
297+
bool load(handle src, bool) {
298+
value.linewidth = src.attr("_linewidth").cast<double>();
299+
value.alpha = src.attr("_alpha").cast<double>();
300+
value.forced_alpha = src.attr("_forced_alpha").cast<bool>();
301+
value.color = src.attr("_rgb").cast<agg::rgba>();
302+
value.isaa = src.attr("_antialiased").cast<bool>();
303+
value.cap = src.attr("_capstyle").cast<agg::line_cap_e>();
304+
value.join = src.attr("_joinstyle").cast<agg::line_join_e>();
305+
value.dashes = src.attr("get_dashes")().cast<Dashes>();
306+
value.cliprect = src.attr("_cliprect").cast<agg::rect_d>();
307+
/* value.clippath = src.attr("get_clip_path")().cast<ClipPath>(); */
308+
convert_clippath(src.attr("get_clip_path")().ptr(), &value.clippath);
309+
value.snap_mode = src.attr("get_snap")().cast<e_snap_mode>();
310+
value.hatchpath = src.attr("get_hatch_path")().cast<mpl::PathIterator>();
311+
value.hatch_color = src.attr("get_hatch_color")().cast<agg::rgba>();
312+
value.hatch_linewidth = src.attr("get_hatch_linewidth")().cast<double>();
313+
value.sketch = src.attr("get_sketch_params")().cast<SketchParams>();
314+
315+
return true;
316+
}
317+
};
318+
#endif
319+
}} // namespace PYBIND11_NAMESPACE::detail
320+
321+
#endif /* MPL_PY_CONVERTERS_H */

src/py_converters_11.cpp

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)
0