Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

COMPAT: use tkagg backend on PyPy#9356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
tacaswell merged 12 commits intomatplotlib:masterfrommattip:tkagg-cffi
Jan 12, 2018
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
12 commits
Select commitHold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
Rework TkAgg backend to support PyPy
------------------------------------

PyPy_ can plot using the TkAgg backend, supported on PyPy 5.9
and greater (both PyPy for python 2.7 and PyPy for python 3.5)

.. _PyPy: https:/www.pypy.org
1 change: 1 addition & 0 deletionsexamples/user_interfaces/embedding_in_tk_sgskip.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,6 +12,7 @@
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
from six.moves import tkinter as Tk

import numpy as np

Expand Down
24 changes: 13 additions & 11 deletionslib/matplotlib/backends/tkagg.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,23 +13,25 @@ def blit(photoimage, aggimage, bbox=None, colormode=1):

if bbox is not None:
bbox_array = bbox.__array__()
# x1, x2, y1, y2
bboxptr = (bbox_array[0, 0], bbox_array[1, 0],
bbox_array[0, 1], bbox_array[1, 1])
else:
bbox_array =None
bboxptr =0
data = np.asarray(aggimage)
dataptr = (data.ctypes.data, data.shape[0], data.shape[1])
try:
tk.call(
"PyAggImagePhoto", photoimage,
id(data), colormode,id(bbox_array))
dataptr, colormode,bboxptr)
except Tk.TclError:
try:
try:
_tkagg.tkinit(tk.interpaddr(), 1)
except AttributeError:
_tkagg.tkinit(id(tk), 0)
tk.call("PyAggImagePhoto", photoimage,
id(data), colormode, id(bbox_array))
except (ImportError, AttributeError, Tk.TclError):
raise
if hasattr(tk, 'interpaddr'):
_tkagg.tkinit(tk.interpaddr(), 1)
else:
# very old python?
_tkagg.tkinit(tk, 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

interpaddr was added in 1998(!python/cpython@9d1b7ae) so I cannot actually imagine a case where this is triggered today (but that can go to another PR of course)

tk.call("PyAggImagePhoto", photoimage,
dataptr, colormode, bboxptr)

def test(aggimage):
r = Tk.Tk()
Expand Down
2 changes: 0 additions & 2 deletionssetupext.py
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1505,13 +1505,11 @@ def runtime_check(self):

def get_extension(self):
sources = [
'src/py_converters.cpp',
'src/_tkagg.cpp'
]

ext = make_extension('matplotlib.backends._tkagg', sources)
self.add_flags(ext)
Numpy().add_flags(ext)
LibAgg().add_flags(ext, add_sources=False)
return ext

Expand Down
110 changes: 56 additions & 54 deletionssrc/_tkagg.cpp
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,16 +13,17 @@
#include <cstdio>
#include <sstream>

#include"py_converters.h"
#include<agg_basics.h> // agg:int8u

// Include our own excerpts from the Tcl / Tk headers
#include "_tkmini.h"

#if defined(_MSC_VER)
# defineSIZE_T_FORMAT "%Iu"
# defineIMG_FORMAT "%Iu %d %d"
#else
# defineSIZE_T_FORMAT "%zu"
# defineIMG_FORMAT "%zu %d %d"
#endif
#define BBOX_FORMAT "%f %f %f %f"

typedef struct
{
Expand All@@ -44,16 +45,15 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
{
Tk_PhotoHandle photo;
Tk_PhotoImageBlock block;
PyObject *bufferobj;

// vars for blitting
PyObject *bboxo;

size_t aggl, bboxl;
size_t pdata;
int wdata, hdata, bbox_parse;
float x1, x2, y1, y2;
bool has_bbox;
uint8_t *destbuffer;
agg::int8u *destbuffer, *buffer;
int destx, desty, destwidth, destheight, deststride;
//unsigned long tmp_ptr;

long mode;
long nval;
Expand All@@ -73,24 +73,14 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL);
return TCL_ERROR;
}
/* get array (or object that can be converted to array) pointer */
if (sscanf(argv[2], SIZE_T_FORMAT, &aggl) != 1) {
TCL_APPEND_RESULT(interp, "error casting pointer", (char *)NULL);
/* get buffer from str which is "ptr height width" */
if (sscanf(argv[2], IMG_FORMAT, &pdata, &hdata, &wdata) != 3) {
TCL_APPEND_RESULT(interp,
"error reading data, expected ptr height width",
(char *)NULL);
return TCL_ERROR;
}
bufferobj = (PyObject *)aggl;

numpy::array_view<uint8_t, 3> buffer;
try {
buffer = numpy::array_view<uint8_t, 3>(bufferobj);
} catch (...) {
TCL_APPEND_RESULT(interp, "buffer is of wrong type", (char *)NULL);
PyErr_Clear();
return TCL_ERROR;
}
int srcheight = buffer.dim(0);

/* XXX insert aggRenderer type check */
buffer = (agg::int8u*)pdata;

/* get array mode (0=mono, 1=rgb, 2=rgba) */
mode = atol(argv[3]);
Expand All@@ -100,24 +90,23 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
}

/* check for bbox/blitting */
if (sscanf(argv[4], SIZE_T_FORMAT, &bboxl) != 1) {
TCL_APPEND_RESULT(interp, "error casting pointer", (char *)NULL);
bbox_parse = sscanf(argv[4], BBOX_FORMAT, &x1, &x2, &y1, &y2);
if (bbox_parse == 4) {
has_bbox = true;
}
else if ((bbox_parse == 1) && (x1 == 0)){
has_bbox = false;
} else {
TCL_APPEND_RESULT(interp, "illegal bbox", (char *)NULL);
return TCL_ERROR;
}
bboxo = (PyObject *)bboxl;

if (bboxo != NULL && bboxo != Py_None) {
agg::rect_d rect;
if (!convert_rect(bboxo, &rect)) {
return TCL_ERROR;
}

has_bbox = true;

destx = (int)rect.x1;
desty = srcheight - (int)rect.y2;
destwidth = (int)(rect.x2 - rect.x1);
destheight = (int)(rect.y2 - rect.y1);
if (has_bbox) {
int srcstride = wdata * 4;
destx = (int)x1;
desty = (int)(hdata - y2);
destwidth = (int)(x2 - x1);
destheight = (int)(y2 - y1);
deststride = 4 * destwidth;

destbuffer = new agg::int8u[deststride * destheight];
Expand All@@ -128,11 +117,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int

for (int i = 0; i < destheight; ++i) {
memcpy(destbuffer + (deststride * i),
&buffer(i + desty,destx, 0),
&buffer[(i + desty) * srcstride + (destx * 4)],
deststride);
}
} else {
has_bbox = false;
destbuffer = NULL;
destx = desty = destwidth = destheight = deststride = 0;
}
Expand DownExpand Up@@ -168,10 +156,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
delete[] destbuffer;

} else {
block.width =buffer.dim(1);
block.height =buffer.dim(0);
block.width =wdata;
block.height =hdata;
block.pitch = (int)block.width * nval;
block.pixelPtr = buffer.data();
block.pixelPtr = buffer;

/* Clear current contents */
TK_PHOTO_BLANK(photo);
Expand DownExpand Up@@ -199,7 +187,7 @@ static PyObject *_tkinit(PyObject *self, PyObject *args)
} else {
/* Do it the hard way. This will break if the TkappObject
layout changes */
app = (TkappObject *)PyLong_AsVoidPtr(arg);
app = (TkappObject *)arg;
interp = app->interp;
}

Expand DownExpand Up@@ -338,7 +326,7 @@ int load_tkinter_funcs(void)
* tkinter uses these symbols, and the symbols are therefore visible in the
* tkinter dynamic library (module).
*/
#ifPY3K
#ifPY_MAJOR_VERSION >= 3
#define TKINTER_PKG "tkinter"
#define TKINTER_MOD "_tkinter"
// From module __file__ attribute to char *string for dlopen.
Expand DownExpand Up@@ -432,13 +420,31 @@ int load_tkinter_funcs(void)
}
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
if (tkinter_lib == NULL) {
PyErr_SetString(PyExc_RuntimeError,
"Cannot dlopen tkinter module file");
goto exit;
/* Perhaps it is a cffi module, like in PyPy? */
pString = PyObject_GetAttrString(pSubmodule, "tklib_cffi");
if (pString == NULL) {
goto fail;
}
pString = PyObject_GetAttrString(pString, "__file__");
if (pString == NULL) {
goto fail;
}
tkinter_libname = fname2char(pString);
if (tkinter_libname == NULL) {
goto fail;
}
tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
}
if (tkinter_lib == NULL) {
goto fail;
}
ret = _func_loader(tkinter_lib);
// dlclose probably safe because tkinter has been imported.
dlclose(tkinter_lib);
goto exit;
fail:
PyErr_SetString(PyExc_RuntimeError,
"Cannot dlopen tkinter module file");
exit:
Py_XDECREF(pModule);
Py_XDECREF(pSubmodule);
Expand All@@ -447,7 +453,7 @@ int load_tkinter_funcs(void)
}
#endif // end not Windows

#ifPY3K
#ifPY_MAJOR_VERSION >= 3
static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions,
NULL, NULL, NULL, NULL };

Expand All@@ -457,15 +463,11 @@ PyMODINIT_FUNC PyInit__tkagg(void)

m = PyModule_Create(&_tkagg_module);

import_array();

return (load_tkinter_funcs() == 0) ? m : NULL;
}
#else
PyMODINIT_FUNC init_tkagg(void)
{
import_array();

Py_InitModule("_tkagg", functions);

load_tkinter_funcs();
Expand Down
2 changes: 1 addition & 1 deletionsrc/file_compat.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,7 +48,7 @@ extern "C" {
/*
* PyFile_* compatibility
*/
#if PY3K
#ifdefined(PY3K) | defined(PYPY_VERSION)

/*
* Get a FILE* handle to the file represented by the Python object
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp