1313#include < cstdio>
1414#include < sstream>
1515
16- #include " py_converters.h "
16+ #include < agg_basics.h > // agg:int8u
1717
1818// Include our own excerpts from the Tcl / Tk headers
1919#include " _tkmini.h"
2020
2121#if defined(_MSC_VER)
22- # define SIZE_T_FORMAT " %Iu"
22+ # define IMG_FORMAT " %Iu %d %d "
2323#else
24- # define SIZE_T_FORMAT " %zu"
24+ # define IMG_FORMAT " %zu %d %d "
2525#endif
26+ #define BBOX_FORMAT " %f %f %f %f"
2627
2728typedef struct
2829{
@@ -44,16 +45,15 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
4445{
4546 Tk_PhotoHandle photo;
4647 Tk_PhotoImageBlock block;
47- PyObject *bufferobj;
4848
4949 // vars for blitting
50- PyObject *bboxo;
5150
52- size_t aggl, bboxl;
51+ size_t pdata;
52+ int wdata, hdata, bbox_parse;
53+ float x1, x2, y1, y2;
5354 bool has_bbox;
54- uint8_t *destbuffer;
55+ agg::int8u *destbuffer, *buffer ;
5556 int destx, desty, destwidth, destheight, deststride;
56- // unsigned long tmp_ptr;
5757
5858 long mode;
5959 long nval;
@@ -73,24 +73,14 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
7373 TCL_APPEND_RESULT (interp, " destination photo must exist" , (char *)NULL );
7474 return TCL_ERROR;
7575 }
76- /* get array (or object that can be converted to array) pointer */
77- if (sscanf (argv[2 ], SIZE_T_FORMAT, &aggl) != 1 ) {
78- TCL_APPEND_RESULT (interp, " error casting pointer" , (char *)NULL );
76+ /* get buffer from str which is "ptr height width" */
77+ if (sscanf (argv[2 ], IMG_FORMAT, &pdata, &hdata, &wdata) != 3 ) {
78+ TCL_APPEND_RESULT (interp,
79+ " error reading data, expected ptr height width" ,
80+ (char *)NULL );
7981 return TCL_ERROR;
8082 }
81- bufferobj = (PyObject *)aggl;
82-
83- numpy::array_view<uint8_t , 3 > buffer;
84- try {
85- buffer = numpy::array_view<uint8_t , 3 >(bufferobj);
86- } catch (...) {
87- TCL_APPEND_RESULT (interp, " buffer is of wrong type" , (char *)NULL );
88- PyErr_Clear ();
89- return TCL_ERROR;
90- }
91- int srcheight = buffer.dim (0 );
92-
93- /* XXX insert aggRenderer type check */
83+ buffer = (agg::int8u*)pdata;
9484
9585 /* get array mode (0=mono, 1=rgb, 2=rgba) */
9686 mode = atol (argv[3 ]);
@@ -100,24 +90,23 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
10090 }
10191
10292 /* check for bbox/blitting */
103- if (sscanf (argv[4 ], SIZE_T_FORMAT, &bboxl) != 1 ) {
104- TCL_APPEND_RESULT (interp, " error casting pointer" , (char *)NULL );
93+ bbox_parse = sscanf (argv[4 ], BBOX_FORMAT, &x1, &x2, &y1, &y2);
94+ if (bbox_parse == 4 ) {
95+ has_bbox = true ;
96+ }
97+ else if ((bbox_parse == 1 ) && (x1 == 0 )){
98+ has_bbox = false ;
99+ } else {
100+ TCL_APPEND_RESULT (interp, " illegal bbox" , (char *)NULL );
105101 return TCL_ERROR;
106102 }
107- bboxo = (PyObject *)bboxl;
108-
109- if (bboxo != NULL && bboxo != Py_None) {
110- agg::rect_d rect;
111- if (!convert_rect (bboxo, &rect)) {
112- return TCL_ERROR;
113- }
114-
115- has_bbox = true ;
116103
117- destx = (int )rect.x1 ;
118- desty = srcheight - (int )rect.y2 ;
119- destwidth = (int )(rect.x2 - rect.x1 );
120- destheight = (int )(rect.y2 - rect.y1 );
104+ if (has_bbox) {
105+ int srcstride = wdata * 4 ;
106+ destx = (int )x1;
107+ desty = (int )(hdata - y2);
108+ destwidth = (int )(x2 - x1);
109+ destheight = (int )(y2 - y1);
121110 deststride = 4 * destwidth;
122111
123112 destbuffer = new agg::int8u[deststride * destheight];
@@ -128,11 +117,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
128117
129118 for (int i = 0 ; i < destheight; ++i) {
130119 memcpy (destbuffer + (deststride * i),
131- &buffer (i + desty, destx, 0 ) ,
120+ &buffer[ (i + desty) * srcstride + ( destx * 4 )] ,
132121 deststride);
133122 }
134123 } else {
135- has_bbox = false ;
136124 destbuffer = NULL ;
137125 destx = desty = destwidth = destheight = deststride = 0 ;
138126 }
@@ -168,10 +156,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
168156 delete[] destbuffer;
169157
170158 } else {
171- block.width = buffer. dim ( 1 ) ;
172- block.height = buffer. dim ( 0 ) ;
159+ block.width = wdata ;
160+ block.height = hdata ;
173161 block.pitch = (int )block.width * nval;
174- block.pixelPtr = buffer. data () ;
162+ block.pixelPtr = buffer;
175163
176164 /* Clear current contents */
177165 TK_PHOTO_BLANK (photo);
@@ -199,7 +187,7 @@ static PyObject *_tkinit(PyObject *self, PyObject *args)
199187 } else {
200188 /* Do it the hard way. This will break if the TkappObject
201189 layout changes */
202- app = (TkappObject *)PyLong_AsVoidPtr ( arg) ;
190+ app = (TkappObject *)arg;
203191 interp = app->interp ;
204192 }
205193
@@ -338,7 +326,7 @@ int load_tkinter_funcs(void)
338326 * tkinter uses these symbols, and the symbols are therefore visible in the
339327 * tkinter dynamic library (module).
340328 */
341- #if PY3K
329+ #if PY_MAJOR_VERSION >= 3
342330#define TKINTER_PKG " tkinter"
343331#define TKINTER_MOD " _tkinter"
344332// From module __file__ attribute to char *string for dlopen.
@@ -432,13 +420,31 @@ int load_tkinter_funcs(void)
432420 }
433421 tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
434422 if (tkinter_lib == NULL ) {
435- PyErr_SetString (PyExc_RuntimeError,
436- " Cannot dlopen tkinter module file" );
437- goto exit;
423+ /* Perhaps it is a cffi module, like in PyPy? */
424+ pString = PyObject_GetAttrString (pSubmodule, " tklib_cffi" );
425+ if (pString == NULL ) {
426+ goto fail;
427+ }
428+ pString = PyObject_GetAttrString (pString, " __file__" );
429+ if (pString == NULL ) {
430+ goto fail;
431+ }
432+ tkinter_libname = fname2char (pString);
433+ if (tkinter_libname == NULL ) {
434+ goto fail;
435+ }
436+ tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
437+ }
438+ if (tkinter_lib == NULL ) {
439+ goto fail;
438440 }
439441 ret = _func_loader (tkinter_lib);
440442 // dlclose probably safe because tkinter has been imported.
441443 dlclose (tkinter_lib);
444+ goto exit;
445+ fail:
446+ PyErr_SetString (PyExc_RuntimeError,
447+ " Cannot dlopen tkinter module file" );
442448exit:
443449 Py_XDECREF (pModule);
444450 Py_XDECREF (pSubmodule);
@@ -447,7 +453,7 @@ int load_tkinter_funcs(void)
447453}
448454#endif // end not Windows
449455
450- #if PY3K
456+ #if PY_MAJOR_VERSION >= 3
451457static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, " _tkagg" , " " , -1 , functions,
452458 NULL , NULL , NULL , NULL };
453459
@@ -457,15 +463,11 @@ PyMODINIT_FUNC PyInit__tkagg(void)
457463
458464 m = PyModule_Create (&_tkagg_module);
459465
460- import_array ();
461-
462466 return (load_tkinter_funcs () == 0 ) ? m : NULL ;
463467}
464468#else
465469PyMODINIT_FUNC init_tkagg (void )
466470{
467- import_array ();
468-
469471 Py_InitModule (" _tkagg" , functions);
470472
471473 load_tkinter_funcs ();
0 commit comments