Skip to content

Commit ebd921b

Browse files
committed
Merge pull request matplotlib#3778 from mdboom/tkagg-simplify
MNT : Reduce coupling between _tkagg and _backend_agg modules
2 parents 86ec1b6 + 9f4bd72 commit ebd921b

File tree

5 files changed

+66
-66
lines changed

5 files changed

+66
-66
lines changed

lib/matplotlib/backends/tkagg.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import six
55
from six.moves import tkinter as Tk
66

7+
import numpy as np
8+
79
from matplotlib.backends import _tkagg
810

911
def blit(photoimage, aggimage, bbox=None, colormode=1):
@@ -13,15 +15,19 @@ def blit(photoimage, aggimage, bbox=None, colormode=1):
1315
bbox_array = bbox.__array__()
1416
else:
1517
bbox_array = None
18+
data = np.asarray(aggimage)
1619
try:
17-
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
20+
tk.call(
21+
"PyAggImagePhoto", photoimage,
22+
id(data), colormode, id(bbox_array))
1823
except Tk.TclError:
1924
try:
2025
try:
2126
_tkagg.tkinit(tk.interpaddr(), 1)
2227
except AttributeError:
2328
_tkagg.tkinit(id(tk), 0)
24-
tk.call("PyAggImagePhoto", photoimage, id(aggimage), colormode, id(bbox_array))
29+
tk.call("PyAggImagePhoto", photoimage,
30+
id(data), colormode, id(bbox_array))
2531
except (ImportError, AttributeError, Tk.TclError):
2632
raise
2733

setupext.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -852,23 +852,24 @@ def check(self):
852852
self.__class__.found_external = False
853853
return str(e) + ' Using local copy.'
854854

855-
def add_flags(self, ext):
855+
def add_flags(self, ext, add_sources=True):
856856
if self.found_external:
857857
pkg_config.setup_extension(ext, 'libagg')
858858
else:
859859
ext.include_dirs.append('extern/agg24/include')
860-
agg_sources = [
861-
'agg_bezier_arc.cpp',
862-
'agg_curves.cpp',
863-
'agg_image_filters.cpp',
864-
'agg_trans_affine.cpp',
865-
'agg_vcgen_contour.cpp',
866-
'agg_vcgen_dash.cpp',
867-
'agg_vcgen_stroke.cpp',
868-
'agg_vpgen_segmentator.cpp'
869-
]
870-
ext.sources.extend(
871-
os.path.join('extern', 'agg24', 'src', x) for x in agg_sources)
860+
if add_sources:
861+
agg_sources = [
862+
'agg_bezier_arc.cpp',
863+
'agg_curves.cpp',
864+
'agg_image_filters.cpp',
865+
'agg_trans_affine.cpp',
866+
'agg_vcgen_contour.cpp',
867+
'agg_vcgen_dash.cpp',
868+
'agg_vcgen_stroke.cpp',
869+
'agg_vpgen_segmentator.cpp'
870+
]
871+
ext.sources.extend(
872+
os.path.join('extern', 'agg24', 'src', x) for x in agg_sources)
872873

873874

874875
class FreeType(SetupPackage):
@@ -1298,7 +1299,7 @@ def get_extension(self):
12981299
ext = make_extension('matplotlib.backends._tkagg', sources)
12991300
self.add_flags(ext)
13001301
Numpy().add_flags(ext)
1301-
LibAgg().add_flags(ext)
1302+
LibAgg().add_flags(ext, add_sources=False)
13021303
return ext
13031304

13041305
def query_tcltk(self):

src/_backend_agg_wrapper.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
1-
#include "_backend_agg_wrapper.h"
1+
#include "mplutils.h"
2+
#include "py_converters.h"
3+
#include "_backend_agg.h"
4+
5+
typedef struct
6+
{
7+
PyObject_HEAD;
8+
RendererAgg *x;
9+
Py_ssize_t shape[3];
10+
Py_ssize_t strides[3];
11+
Py_ssize_t suboffsets[3];
12+
} PyRendererAgg;
13+
14+
typedef struct
15+
{
16+
PyObject_HEAD;
17+
BufferRegion *x;
18+
Py_ssize_t shape[3];
19+
Py_ssize_t strides[3];
20+
Py_ssize_t suboffsets[3];
21+
} PyBufferRegion;
22+
223

324
/**********************************************************************
425
* BufferRegion

src/_backend_agg_wrapper.h

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

src/_tkagg.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
#include <cstdio>
1717
#include <sstream>
1818

19-
#include "agg_basics.h"
20-
#include "_backend_agg_wrapper.h"
2119
#include "py_converters.h"
2220

2321
extern "C"
@@ -50,14 +48,14 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int argc,
5048
{
5149
Tk_PhotoHandle photo;
5250
Tk_PhotoImageBlock block;
53-
PyObject *aggo;
51+
PyObject *bufferobj;
5452

5553
// vars for blitting
5654
PyObject *bboxo;
5755

5856
size_t aggl, bboxl;
5957
bool has_bbox;
60-
agg::int8u *destbuffer;
58+
uint8_t *destbuffer;
6159
int destx, desty, destwidth, destheight, deststride;
6260
//unsigned long tmp_ptr;
6361

@@ -84,12 +82,17 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int argc,
8482
Tcl_AppendResult(interp, "error casting pointer", (char *)NULL);
8583
return TCL_ERROR;
8684
}
87-
aggo = (PyObject *)aggl;
88-
89-
// TODO: This is really brittle and will break when RendererAgg
90-
// comes in multiple flavors
91-
RendererAgg *aggRenderer = ((PyRendererAgg *)(aggo))->x;
92-
int srcheight = (int)aggRenderer->get_height();
85+
bufferobj = (PyObject *)aggl;
86+
87+
numpy::array_view<uint8_t, 3> buffer;
88+
try {
89+
buffer = numpy::array_view<uint8_t, 3>(bufferobj);
90+
} catch (...) {
91+
Tcl_AppendResult(interp, "buffer is of wrong type", (char *)NULL);
92+
PyErr_Clear();
93+
return TCL_ERROR;
94+
}
95+
int srcheight = buffer.dim(0);
9396

9497
/* XXX insert aggRenderer type check */
9598

@@ -127,13 +130,11 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int argc,
127130
return TCL_ERROR;
128131
}
129132

130-
agg::rendering_buffer destrbuf;
131-
destrbuf.attach(destbuffer, destwidth, destheight, deststride);
132-
pixfmt destpf(destrbuf);
133-
renderer_base destrb(destpf);
134-
135-
agg::rect_base<int> region(destx, desty, (int)rect.x2, srcheight - (int)rect.y1);
136-
destrb.copy_from(aggRenderer->renderingBuffer, &region, -destx, -desty);
133+
for (int i = 0; i < destheight; ++i) {
134+
memcpy(destbuffer + (deststride * i),
135+
&buffer(i + desty, destx, 0),
136+
deststride);
137+
}
137138
} else {
138139
has_bbox = false;
139140
destbuffer = NULL;
@@ -170,10 +171,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int argc,
170171
delete[] destbuffer;
171172

172173
} else {
173-
block.width = aggRenderer->get_width();
174-
block.height = aggRenderer->get_height();
174+
block.width = buffer.dim(1);
175+
block.height = buffer.dim(0);
175176
block.pitch = (int)block.width * nval;
176-
block.pixelPtr = aggRenderer->pixBuffer;
177+
block.pixelPtr = buffer.data();
177178

178179
/* Clear current contents */
179180
Tk_PhotoBlank(photo);

0 commit comments

Comments
 (0)