13
13
#include < cstdio>
14
14
#include < sstream>
15
15
16
- #include " py_converters.h "
16
+ #include < agg_basics.h > // agg:int8u
17
17
18
18
// Include our own excerpts from the Tcl / Tk headers
19
19
#include " _tkmini.h"
20
20
21
21
#if defined(_MSC_VER)
22
- # define SIZE_T_FORMAT " %Iu"
22
+ # define IMG_FORMAT " %Iu %d %d "
23
23
#else
24
- # define SIZE_T_FORMAT " %zu"
24
+ # define IMG_FORMAT " %zu %d %d "
25
25
#endif
26
+ #define BBOX_FORMAT " %f %f %f %f"
26
27
27
28
typedef struct
28
29
{
@@ -44,16 +45,15 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
44
45
{
45
46
Tk_PhotoHandle photo;
46
47
Tk_PhotoImageBlock block;
47
- PyObject *bufferobj;
48
48
49
49
// vars for blitting
50
- PyObject *bboxo;
51
50
52
- size_t aggl, bboxl;
51
+ size_t pdata;
52
+ int wdata, hdata, bbox_parse;
53
+ float x1, x2, y1 , y2;
53
54
bool has_bbox;
54
- uint8_t *destbuffer;
55
+ agg::int8u *destbuffer, *buffer ;
55
56
int destx, desty, destwidth, destheight, deststride;
56
- // unsigned long tmp_ptr;
57
57
58
58
long mode;
59
59
long nval;
@@ -73,24 +73,14 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
73
73
TCL_APPEND_RESULT (interp, " destination photo must exist" , (char *)NULL );
74
74
return TCL_ERROR;
75
75
}
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 );
79
81
return TCL_ERROR;
80
82
}
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;
94
84
95
85
/* get array mode (0=mono, 1=rgb, 2=rgba) */
96
86
mode = atol (argv[3 ]);
@@ -100,24 +90,23 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
100
90
}
101
91
102
92
/* 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 );
105
101
return TCL_ERROR;
106
102
}
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 ;
116
103
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 );
121
110
deststride = 4 * destwidth;
122
111
123
112
destbuffer = new agg::int8u[deststride * destheight];
@@ -128,11 +117,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
128
117
129
118
for (int i = 0 ; i < destheight; ++i) {
130
119
memcpy (destbuffer + (deststride * i),
131
- &buffer (i + desty, destx, 0 ) ,
120
+ &buffer[ (i + desty) * srcstride + ( destx * 4 )] ,
132
121
deststride);
133
122
}
134
123
} else {
135
- has_bbox = false ;
136
124
destbuffer = NULL ;
137
125
destx = desty = destwidth = destheight = deststride = 0 ;
138
126
}
@@ -168,10 +156,10 @@ static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
168
156
delete[] destbuffer;
169
157
170
158
} else {
171
- block.width = buffer. dim ( 1 ) ;
172
- block.height = buffer. dim ( 0 ) ;
159
+ block.width = wdata ;
160
+ block.height = hdata ;
173
161
block.pitch = (int )block.width * nval;
174
- block.pixelPtr = buffer. data () ;
162
+ block.pixelPtr = buffer;
175
163
176
164
/* Clear current contents */
177
165
TK_PHOTO_BLANK (photo);
@@ -199,7 +187,7 @@ static PyObject *_tkinit(PyObject *self, PyObject *args)
199
187
} else {
200
188
/* Do it the hard way. This will break if the TkappObject
201
189
layout changes */
202
- app = (TkappObject *)PyLong_AsVoidPtr ( arg) ;
190
+ app = (TkappObject *)arg;
203
191
interp = app->interp ;
204
192
}
205
193
@@ -338,7 +326,7 @@ int load_tkinter_funcs(void)
338
326
* tkinter uses these symbols, and the symbols are therefore visible in the
339
327
* tkinter dynamic library (module).
340
328
*/
341
- #if PY3K
329
+ #if PY_MAJOR_VERSION >= 3
342
330
#define TKINTER_PKG " tkinter"
343
331
#define TKINTER_MOD " _tkinter"
344
332
// From module __file__ attribute to char *string for dlopen.
@@ -432,13 +420,31 @@ int load_tkinter_funcs(void)
432
420
}
433
421
tkinter_lib = dlopen (tkinter_libname, RTLD_LAZY);
434
422
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;
438
440
}
439
441
ret = _func_loader (tkinter_lib);
440
442
// dlclose probably safe because tkinter has been imported.
441
443
dlclose (tkinter_lib);
444
+ goto exit ;
445
+ fail:
446
+ PyErr_SetString (PyExc_RuntimeError,
447
+ " Cannot dlopen tkinter module file" );
442
448
exit :
443
449
Py_XDECREF (pModule);
444
450
Py_XDECREF (pSubmodule);
@@ -447,7 +453,7 @@ int load_tkinter_funcs(void)
447
453
}
448
454
#endif // end not Windows
449
455
450
- #if PY3K
456
+ #if PY_MAJOR_VERSION >= 3
451
457
static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, " _tkagg" , " " , -1 , functions,
452
458
NULL , NULL , NULL , NULL };
453
459
@@ -457,15 +463,11 @@ PyMODINIT_FUNC PyInit__tkagg(void)
457
463
458
464
m = PyModule_Create (&_tkagg_module);
459
465
460
- import_array ();
461
-
462
466
return (load_tkinter_funcs () == 0 ) ? m : NULL ;
463
467
}
464
468
#else
465
469
PyMODINIT_FUNC init_tkagg (void )
466
470
{
467
- import_array ();
468
-
469
471
Py_InitModule (" _tkagg" , functions);
470
472
471
473
load_tkinter_funcs ();
0 commit comments