Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f04475b

Browse files
committed
Add a pybind11 type caster for GCAgg and its requirements
1 parent c23f1b2 commit f04475b

File tree

3 files changed

+119
-46
lines changed

3 files changed

+119
-46
lines changed

src/_backend_agg_wrapper.cpp

Lines changed: 8 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,11 @@ PyBufferRegion_get_extents(BufferRegion *self)
4040

4141
static void
4242
PyRendererAgg_draw_path(RendererAgg *self,
43-
pybind11::object gc_obj,
43+
GCAgg &gc,
4444
mpl::PathIterator path,
4545
agg::trans_affine trans,
4646
agg::rgba face)
4747
{
48-
GCAgg gc;
49-
50-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
51-
throw pybind11::error_already_set();
52-
}
53-
5448
self->draw_path(gc, path, trans, face);
5549
}
5650

@@ -60,52 +54,38 @@ PyRendererAgg_draw_text_image(RendererAgg *self,
6054
double x,
6155
double y,
6256
double angle,
63-
pybind11::object gc_obj)
57+
GCAgg &gc)
6458
{
6559
numpy::array_view<agg::int8u, 2> image;
66-
GCAgg gc;
6760

6861
if (!image.converter_contiguous(image_obj.ptr(), &image)) {
6962
throw pybind11::error_already_set();
7063
}
71-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
72-
throw pybind11::error_already_set();
73-
}
7464

7565
self->draw_text_image(gc, image, x, y, angle);
7666
}
7767

7868
static void
7969
PyRendererAgg_draw_markers(RendererAgg *self,
80-
pybind11::object gc_obj,
70+
GCAgg &gc,
8171
mpl::PathIterator marker_path,
8272
agg::trans_affine marker_path_trans,
8373
mpl::PathIterator path,
8474
agg::trans_affine trans,
8575
agg::rgba face)
8676
{
87-
GCAgg gc;
88-
89-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
90-
throw pybind11::error_already_set();
91-
}
92-
9377
self->draw_markers(gc, marker_path, marker_path_trans, path, trans, face);
9478
}
9579

9680
static void
9781
PyRendererAgg_draw_image(RendererAgg *self,
98-
pybind11::object gc_obj,
82+
GCAgg &gc,
9983
double x,
10084
double y,
10185
pybind11::array_t<agg::int8u, pybind11::array::c_style> image_obj)
10286
{
103-
GCAgg gc;
10487
numpy::array_view<agg::int8u, 3> image;
10588

106-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
107-
throw pybind11::error_already_set();
108-
}
10989
if (!image.set(image_obj.ptr())) {
11090
throw pybind11::error_already_set();
11191
}
@@ -119,7 +99,7 @@ PyRendererAgg_draw_image(RendererAgg *self,
11999

120100
static void
121101
PyRendererAgg_draw_path_collection(RendererAgg *self,
122-
pybind11::object gc_obj,
102+
GCAgg &gc,
123103
agg::trans_affine master_transform,
124104
pybind11::object paths_obj,
125105
pybind11::object transforms_obj,
@@ -128,25 +108,20 @@ PyRendererAgg_draw_path_collection(RendererAgg *self,
128108
pybind11::object facecolors_obj,
129109
pybind11::object edgecolors_obj,
130110
pybind11::object linewidths_obj,
131-
pybind11::object dashes_obj,
111+
DashesVector dashes,
132112
pybind11::object antialiaseds_obj,
133113
pybind11::object Py_UNUSED(ignored_obj),
134114
// offset position is no longer used
135115
pybind11::object Py_UNUSED(offset_position_obj))
136116
{
137-
GCAgg gc;
138117
mpl::PathGenerator paths;
139118
numpy::array_view<const double, 3> transforms;
140119
numpy::array_view<const double, 2> offsets;
141120
numpy::array_view<const double, 2> facecolors;
142121
numpy::array_view<const double, 2> edgecolors;
143122
numpy::array_view<const double, 1> linewidths;
144-
DashesVector dashes;
145123
numpy::array_view<const uint8_t, 1> antialiaseds;
146124

147-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
148-
throw pybind11::error_already_set();
149-
}
150125
if (!convert_pathgen(paths_obj.ptr(), &paths)) {
151126
throw pybind11::error_already_set();
152127
}
@@ -165,9 +140,6 @@ PyRendererAgg_draw_path_collection(RendererAgg *self,
165140
if (!linewidths.converter(linewidths_obj.ptr(), &linewidths)) {
166141
throw pybind11::error_already_set();
167142
}
168-
if (!convert_dashes_vector(dashes_obj.ptr(), &dashes)) {
169-
throw pybind11::error_already_set();
170-
}
171143
if (!antialiaseds.converter(antialiaseds_obj.ptr(), &antialiaseds)) {
172144
throw pybind11::error_already_set();
173145
}
@@ -187,7 +159,7 @@ PyRendererAgg_draw_path_collection(RendererAgg *self,
187159

188160
static void
189161
PyRendererAgg_draw_quad_mesh(RendererAgg *self,
190-
pybind11::object gc_obj,
162+
GCAgg &gc,
191163
agg::trans_affine master_transform,
192164
unsigned int mesh_width,
193165
unsigned int mesh_height,
@@ -198,15 +170,11 @@ PyRendererAgg_draw_quad_mesh(RendererAgg *self,
198170
bool antialiased,
199171
pybind11::object edgecolors_obj)
200172
{
201-
GCAgg gc;
202173
numpy::array_view<const double, 3> coordinates;
203174
numpy::array_view<const double, 2> offsets;
204175
numpy::array_view<const double, 2> facecolors;
205176
numpy::array_view<const double, 2> edgecolors;
206177

207-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
208-
throw pybind11::error_already_set();
209-
}
210178
if (!coordinates.converter(coordinates_obj.ptr(), &coordinates)) {
211179
throw pybind11::error_already_set();
212180
}
@@ -234,18 +202,14 @@ PyRendererAgg_draw_quad_mesh(RendererAgg *self,
234202

235203
static void
236204
PyRendererAgg_draw_gouraud_triangles(RendererAgg *self,
237-
pybind11::object gc_obj,
205+
GCAgg &gc,
238206
pybind11::object points_obj,
239207
pybind11::object colors_obj,
240208
agg::trans_affine trans)
241209
{
242-
GCAgg gc;
243210
numpy::array_view<const double, 3> points;
244211
numpy::array_view<const double, 3> colors;
245212

246-
if (!convert_gcagg(gc_obj.ptr(), &gc)) {
247-
throw pybind11::error_already_set();
248-
}
249213
if (!points.converter(points_obj.ptr(), &points)) {
250214
throw pybind11::error_already_set();
251215
}

src/py_converters.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,6 @@ int convert_pathgen(PyObject *obj, void *pathgenp)
415415
int convert_clippath(PyObject *clippath_tuple, void *clippathp)
416416
{
417417
ClipPath *clippath = (ClipPath *)clippathp;
418-
mpl::PathIterator path;
419-
agg::trans_affine trans;
420418

421419
if (clippath_tuple != NULL && clippath_tuple != Py_None) {
422420
if (!PyArg_ParseTuple(clippath_tuple,

src/py_converters_11.h

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
// pybind11 equivalent of py_converters.h
55

6+
#include <map>
7+
68
#include <pybind11/pybind11.h>
79
#include <pybind11/numpy.h>
810

@@ -135,6 +137,37 @@ namespace PYBIND11_NAMESPACE { namespace detail {
135137

136138
/* Remove all this macro magic after dropping NumPy usage and just include `py_adaptors.h`. */
137139
#ifdef MPL_PY_ADAPTORS_H
140+
template <> struct type_caster<agg::line_cap_e> {
141+
public:
142+
PYBIND11_TYPE_CASTER(agg::line_cap_e, const_name("line_cap_e"));
143+
144+
bool load(handle src, bool) {
145+
const std::map<std::string, agg::line_cap_e> enum_values = {
146+
{"butt", agg::butt_cap},
147+
{"round", agg::round_cap},
148+
{"projecting", agg::square_cap},
149+
};
150+
value = enum_values.at(src.cast<std::string>());
151+
return true;
152+
}
153+
};
154+
155+
template <> struct type_caster<agg::line_join_e> {
156+
public:
157+
PYBIND11_TYPE_CASTER(agg::line_join_e, const_name("line_join_e"));
158+
159+
bool load(handle src, bool) {
160+
const std::map<std::string, agg::line_join_e> enum_values = {
161+
{"miter", agg::miter_join_revert},
162+
{"round", agg::round_join},
163+
{"bevel", agg::bevel_join},
164+
};
165+
value = agg::miter_join_revert;
166+
value = enum_values.at(src.cast<std::string>());
167+
return true;
168+
}
169+
};
170+
138171
template <> struct type_caster<mpl::PathIterator> {
139172
public:
140173
PYBIND11_TYPE_CASTER(mpl::PathIterator, const_name("PathIterator"));
@@ -161,6 +194,59 @@ namespace PYBIND11_NAMESPACE { namespace detail {
161194

162195
/* Remove all this macro magic after dropping NumPy usage and just include `_backend_agg_basic_types.h`. */
163196
#ifdef MPL_BACKEND_AGG_BASIC_TYPES_H
197+
template <> struct type_caster<ClipPath> {
198+
public:
199+
PYBIND11_TYPE_CASTER(ClipPath, const_name("ClipPath"));
200+
201+
bool load(handle src, bool) {
202+
if (src.is_none()) {
203+
return true;
204+
}
205+
206+
auto clippath_tuple = src.cast<std::tuple<pybind11::object, agg::trans_affine>>();
207+
208+
if (!convert_path(std::get<0>(clippath_tuple).ptr(), &value.path)) {
209+
throw pybind11::error_already_set();
210+
}
211+
value.trans = std::get<1>(clippath_tuple);
212+
213+
return true;
214+
}
215+
};
216+
217+
template <> struct type_caster<Dashes> {
218+
public:
219+
PYBIND11_TYPE_CASTER(Dashes, const_name("Dashes"));
220+
221+
bool load(handle src, bool) {
222+
auto dash_tuple = src.cast<std::tuple<double, pybind11::object>>();
223+
auto dash_offset = std::get<0>(dash_tuple);
224+
auto dashes_seq_or_none = std::get<1>(dash_tuple);
225+
226+
if (dashes_seq_or_none.is_none()) {
227+
return true;
228+
}
229+
230+
auto dashes_seq = dashes_seq_or_none.cast<pybind11::sequence>();
231+
232+
auto nentries = dashes_seq.size();
233+
// If the dashpattern has odd length, iterate through it twice (in
234+
// accordance with the pdf/ps/svg specs).
235+
auto dash_pattern_length = (nentries % 2) ? 2 * nentries : nentries;
236+
237+
for (pybind11::size_t i = 0; i < dash_pattern_length; i += 2) {
238+
auto length = dashes_seq[i % nentries].cast<double>();
239+
auto skip = dashes_seq[(i + 1) % nentries].cast<double>();
240+
241+
value.add_dash_pair(length, skip);
242+
}
243+
244+
value.set_dash_offset(dash_offset);
245+
246+
return true;
247+
}
248+
};
249+
164250
template <> struct type_caster<SketchParams> {
165251
public:
166252
PYBIND11_TYPE_CASTER(SketchParams, const_name("SketchParams"));
@@ -177,6 +263,31 @@ namespace PYBIND11_NAMESPACE { namespace detail {
177263
return true;
178264
}
179265
};
266+
267+
template <> struct type_caster<GCAgg> {
268+
public:
269+
PYBIND11_TYPE_CASTER(GCAgg, const_name("GCAgg"));
270+
271+
bool load(handle src, bool) {
272+
value.linewidth = src.attr("_linewidth").cast<double>();
273+
value.alpha = src.attr("_alpha").cast<double>();
274+
value.forced_alpha = src.attr("_forced_alpha").cast<bool>();
275+
value.color = src.attr("_rgb").cast<agg::rgba>();
276+
value.isaa = src.attr("_antialiased").cast<bool>();
277+
value.cap = src.attr("_capstyle").cast<agg::line_cap_e>();
278+
value.join = src.attr("_joinstyle").cast<agg::line_join_e>();
279+
value.dashes = src.attr("get_dashes")().cast<Dashes>();
280+
value.cliprect = src.attr("_cliprect").cast<agg::rect_d>();
281+
value.clippath = src.attr("get_clip_path")().cast<ClipPath>();
282+
value.snap_mode = src.attr("get_snap")().cast<e_snap_mode>();
283+
value.hatchpath = src.attr("get_hatch_path")().cast<mpl::PathIterator>();
284+
value.hatch_color = src.attr("get_hatch_color")().cast<agg::rgba>();
285+
value.hatch_linewidth = src.attr("get_hatch_linewidth")().cast<double>();
286+
value.sketch = src.attr("get_sketch_params")().cast<SketchParams>();
287+
288+
return true;
289+
}
290+
};
180291
#endif
181292
}} // namespace PYBIND11_NAMESPACE::detail
182293

0 commit comments

Comments
 (0)