Skip to content

Commit d4ea011

Browse files
authored
Merge pull request #27011 from QuLogic/agg-pybind11
Convert Agg extension to pybind11
2 parents 5a98a2a + 3fde41c commit d4ea011

8 files changed

+419
-516
lines changed

src/_backend_agg.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
2929
lastclippath(NULL),
3030
_fill_color(agg::rgba(1, 1, 1, 0))
3131
{
32+
if (dpi <= 0.0) {
33+
throw std::range_error("dpi must be positive");
34+
}
35+
36+
if (width >= 1 << 16 || height >= 1 << 16) {
37+
throw std::range_error(
38+
"Image size of " + std::to_string(width) + "x" + std::to_string(height) +
39+
" pixels is too large. It must be less than 2^16 in each direction.");
40+
}
41+
3242
unsigned stride(width * 4);
3343

3444
pixBuffer = new agg::int8u[NUMBYTES];

src/_backend_agg.h

+24-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66
#ifndef MPL_BACKEND_AGG_H
77
#define MPL_BACKEND_AGG_H
88

9+
#include <pybind11/pybind11.h>
10+
911
#include <cmath>
1012
#include <algorithm>
13+
#include <functional>
1114

1215
#include "agg_alpha_mask_u8.h"
1316
#include "agg_conv_curve.h"
@@ -40,6 +43,8 @@
4043
#include "array.h"
4144
#include "agg_workaround.h"
4245

46+
namespace py = pybind11;
47+
4348
/**********************************************************************/
4449

4550
// a helper class to pass agg::buffer objects around.
@@ -728,7 +733,7 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
728733
rendererBase.reset_clipping(true);
729734
if (angle != 0.0) {
730735
agg::rendering_buffer srcbuf(
731-
image.data(), (unsigned)image.shape(1),
736+
image.mutable_data(0, 0), (unsigned)image.shape(1),
732737
(unsigned)image.shape(0), (unsigned)image.shape(1));
733738
agg::pixfmt_gray8 pixf_img(srcbuf);
734739

@@ -828,8 +833,9 @@ inline void RendererAgg::draw_image(GCAgg &gc,
828833
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
829834

830835
agg::rendering_buffer buffer;
831-
buffer.attach(
832-
image.data(), (unsigned)image.shape(1), (unsigned)image.shape(0), -(int)image.shape(1) * 4);
836+
buffer.attach(image.mutable_data(0, 0, 0),
837+
(unsigned)image.shape(1), (unsigned)image.shape(0),
838+
-(int)image.shape(1) * 4);
833839
pixfmt pixf(buffer);
834840

835841
if (has_clippath) {
@@ -1226,14 +1232,27 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12261232
ColorArray &colors,
12271233
agg::trans_affine &trans)
12281234
{
1235+
if (points.shape(0) && !check_trailing_shape(points, "points", 3, 2)) {
1236+
throw py::error_already_set();
1237+
}
1238+
if (colors.shape(0) && !check_trailing_shape(colors, "colors", 3, 4)) {
1239+
throw py::error_already_set();
1240+
}
1241+
if (points.shape(0) != colors.shape(0)) {
1242+
throw py::value_error(
1243+
"points and colors arrays must be the same length, got " +
1244+
std::to_string(points.shape(0)) + " points and " +
1245+
std::to_string(colors.shape(0)) + "colors");
1246+
}
1247+
12291248
theRasterizer.reset_clipping();
12301249
rendererBase.reset_clipping(true);
12311250
set_clipbox(gc.cliprect, theRasterizer);
12321251
bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
12331252

12341253
for (int i = 0; i < points.shape(0); ++i) {
1235-
typename PointArray::sub_t point = points.subarray(i);
1236-
typename ColorArray::sub_t color = colors.subarray(i);
1254+
auto point = std::bind(points, i, std::placeholders::_1, std::placeholders::_2);
1255+
auto color = std::bind(colors, i, std::placeholders::_1, std::placeholders::_2);
12371256

12381257
_draw_gouraud_triangle(point, color, trans, has_clippath);
12391258
}

0 commit comments

Comments
 (0)