aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/src/_tkagg.cpp
diff options
context:
space:
mode:
authorshumkovnd <shumkovnd@yandex-team.com>2023-11-10 14:39:34 +0300
committershumkovnd <shumkovnd@yandex-team.com>2023-11-10 16:42:24 +0300
commit77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch)
treec51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py2/src/_tkagg.cpp
parentdd6d20cadb65582270ac23f4b3b14ae189704b9d (diff)
downloadydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py2/src/_tkagg.cpp')
-rw-r--r--contrib/python/matplotlib/py2/src/_tkagg.cpp475
1 files changed, 475 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/src/_tkagg.cpp b/contrib/python/matplotlib/py2/src/_tkagg.cpp
new file mode 100644
index 0000000000..ad5289b3d6
--- /dev/null
+++ b/contrib/python/matplotlib/py2/src/_tkagg.cpp
@@ -0,0 +1,475 @@
+/* -*- mode: c++; c-basic-offset: 4 -*- */
+
+/*
+ * This code is derived from The Python Imaging Library and is covered
+ * by the PIL license.
+ *
+ * See LICENSE/LICENSE.PIL for details.
+ *
+ */
+
+#include <Python.h>
+#include <cstdlib>
+#include <cstdio>
+#include <sstream>
+
+#include <agg_basics.h> // agg:int8u
+
+// Include our own excerpts from the Tcl / Tk headers
+#include "_tkmini.h"
+
+#if defined(_MSC_VER)
+# define IMG_FORMAT "%d %d %Iu"
+#else
+# define IMG_FORMAT "%d %d %zu"
+#endif
+#define BBOX_FORMAT "%f %f %f %f"
+
+typedef struct
+{
+ PyObject_HEAD
+ Tcl_Interp *interp;
+} TkappObject;
+
+// Global vars for Tcl / Tk functions. We load these symbols from the tkinter
+// extension module or loaded Tcl / Tk libraries at run-time.
+static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
+static Tcl_AppendResult_t TCL_APPEND_RESULT;
+static Tk_MainWindow_t TK_MAIN_WINDOW;
+static Tk_FindPhoto_t TK_FIND_PHOTO;
+static Tk_PhotoPutBlock_NoComposite_t TK_PHOTO_PUT_BLOCK_NO_COMPOSITE;
+static Tk_PhotoBlank_t TK_PHOTO_BLANK;
+
+static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
+ argc, char **argv)
+{
+ Tk_PhotoHandle photo;
+ Tk_PhotoImageBlock block;
+
+ // vars for blitting
+
+ size_t pdata;
+ int wdata, hdata, bbox_parse;
+ float x1, x2, y1, y2;
+ bool has_bbox;
+ agg::int8u *destbuffer, *buffer;
+ int destx, desty, destwidth, destheight, deststride;
+
+ long mode;
+ long nval;
+ if (TK_MAIN_WINDOW(interp) == NULL) {
+ // Will throw a _tkinter.TclError with "this isn't a Tk application"
+ return TCL_ERROR;
+ }
+
+ if (argc != 5) {
+ TCL_APPEND_RESULT(interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ /* get Tcl PhotoImage handle */
+ photo = TK_FIND_PHOTO(interp, argv[1]);
+ if (photo == NULL) {
+ TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL);
+ return TCL_ERROR;
+ }
+ /* get buffer from str which is "height width ptr" */
+ if (sscanf(argv[2], IMG_FORMAT, &hdata, &wdata, &pdata) != 3) {
+ TCL_APPEND_RESULT(interp,
+ "error reading data, expected height width ptr",
+ (char *)NULL);
+ return TCL_ERROR;
+ }
+ buffer = (agg::int8u*)pdata;
+
+ /* get array mode (0=mono, 1=rgb, 2=rgba) */
+ mode = atol(argv[3]);
+ if ((mode != 0) && (mode != 1) && (mode != 2)) {
+ TCL_APPEND_RESULT(interp, "illegal image mode", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ /* check for bbox/blitting */
+ 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;
+ }
+
+ 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];
+ if (destbuffer == NULL) {
+ TCL_APPEND_RESULT(interp, "could not allocate memory", (char *)NULL);
+ return TCL_ERROR;
+ }
+
+ for (int i = 0; i < destheight; ++i) {
+ memcpy(destbuffer + (deststride * i),
+ &buffer[(i + desty) * srcstride + (destx * 4)],
+ deststride);
+ }
+ } else {
+ destbuffer = NULL;
+ destx = desty = destwidth = destheight = deststride = 0;
+ }
+
+ /* setup tkblock */
+ block.pixelSize = 1;
+ if (mode == 0) {
+ block.offset[0] = block.offset[1] = block.offset[2] = 0;
+ nval = 1;
+ } else {
+ block.offset[0] = 0;
+ block.offset[1] = 1;
+ block.offset[2] = 2;
+ if (mode == 1) {
+ block.offset[3] = 0;
+ block.pixelSize = 3;
+ nval = 3;
+ } else {
+ block.offset[3] = 3;
+ block.pixelSize = 4;
+ nval = 4;
+ }
+ }
+
+ if (has_bbox) {
+ block.width = destwidth;
+ block.height = destheight;
+ block.pitch = deststride;
+ block.pixelPtr = destbuffer;
+
+ TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, destx, desty,
+ destwidth, destheight);
+ delete[] destbuffer;
+
+ } else {
+ block.width = wdata;
+ block.height = hdata;
+ block.pitch = (int)block.width * nval;
+ block.pixelPtr = buffer;
+
+ /* Clear current contents */
+ TK_PHOTO_BLANK(photo);
+ /* Copy opaque block to photo image, and leave the rest to TK */
+ TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, 0, 0, block.width,
+ block.height);
+ }
+
+ return TCL_OK;
+}
+
+static PyObject *_tkinit(PyObject *self, PyObject *args)
+{
+ Tcl_Interp *interp;
+ TkappObject *app;
+
+ PyObject *arg;
+ int is_interp;
+ if (!PyArg_ParseTuple(args, "Oi", &arg, &is_interp)) {
+ return NULL;
+ }
+
+ if (is_interp) {
+ interp = (Tcl_Interp *)PyLong_AsVoidPtr(arg);
+ } else {
+ /* Do it the hard way. This will break if the TkappObject
+ layout changes */
+ app = (TkappObject *)arg;
+ interp = app->interp;
+ }
+
+ /* This will bomb if interp is invalid... */
+
+ TCL_CREATE_COMMAND(interp,
+ "PyAggImagePhoto",
+ (Tcl_CmdProc *)PyAggImagePhoto,
+ (ClientData)0,
+ (Tcl_CmdDeleteProc *)NULL);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static PyMethodDef functions[] = {
+ /* Tkinter interface stuff */
+ { "tkinit", (PyCFunction)_tkinit, 1 },
+ { NULL, NULL } /* sentinel */
+};
+
+// Functions to fill global TCL / Tk function pointers by dynamic loading
+#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
+
+/*
+ * On Windows, we can't load the tkinter module to get the TCL or Tk symbols,
+ * because Windows does not load symbols into the library name-space of
+ * importing modules. So, knowing that tkinter has already been imported by
+ * Python, we scan all modules in the running process for the TCL and Tk
+ * function names.
+ */
+#include <windows.h>
+#define PSAPI_VERSION 1
+#include <psapi.h>
+// Must be linked with 'psapi' library
+
+FARPROC _dfunc(HMODULE lib_handle, const char *func_name)
+{
+ // Load function `func_name` from `lib_handle`.
+ // Set Python exception if we can't find `func_name` in `lib_handle`.
+ // Returns function pointer or NULL if not present.
+
+ char message[100];
+
+ FARPROC func = GetProcAddress(lib_handle, func_name);
+ if (func == NULL) {
+ sprintf(message, "Cannot load function %s", func_name);
+ PyErr_SetString(PyExc_RuntimeError, message);
+ }
+ return func;
+}
+
+int get_tcl(HMODULE hMod)
+{
+ // Try to fill TCL global vars with function pointers. Return 0 for no
+ // functions found, 1 for all functions found, -1 for some but not all
+ // functions found.
+ TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
+ GetProcAddress(hMod, "Tcl_CreateCommand");
+ if (TCL_CREATE_COMMAND == NULL) { // Maybe not TCL module
+ return 0;
+ }
+ TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod,
+ "Tcl_AppendResult");
+ return (TCL_APPEND_RESULT == NULL) ? -1 : 1;
+}
+
+int get_tk(HMODULE hMod)
+{
+ // Try to fill Tk global vars with function pointers. Return 0 for no
+ // functions found, 1 for all functions found, -1 for some but not all
+ // functions found.
+ TK_MAIN_WINDOW = (Tk_MainWindow_t)
+ GetProcAddress(hMod, "Tk_MainWindow");
+ if (TK_MAIN_WINDOW == NULL) { // Maybe not Tk module
+ return 0;
+ }
+ return ( // -1 if any remaining symbols are NULL
+ ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
+ _dfunc(hMod, "Tk_FindPhoto")) == NULL) ||
+ ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
+ _dfunc(hMod, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
+ ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
+ _dfunc(hMod, "Tk_PhotoBlank")) == NULL))
+ ? -1 : 1;
+}
+
+int load_tkinter_funcs(void)
+{
+ // Load TCL and Tk functions by searching all modules in current process.
+ // Return 0 for success, non-zero for failure.
+
+ HMODULE hMods[1024];
+ HANDLE hProcess;
+ DWORD cbNeeded;
+ unsigned int i;
+ int found_tcl = 0;
+ int found_tk = 0;
+
+ // Returns pseudo-handle that does not need to be closed
+ hProcess = GetCurrentProcess();
+
+ // Iterate through modules in this process looking for TCL / Tk names
+ if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
+ for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
+ if (!found_tcl) {
+ found_tcl = get_tcl(hMods[i]);
+ if (found_tcl == -1) {
+ return 1;
+ }
+ }
+ if (!found_tk) {
+ found_tk = get_tk(hMods[i]);
+ if (found_tk == -1) {
+ return 1;
+ }
+ }
+ if (found_tcl && found_tk) {
+ return 0;
+ }
+ }
+ }
+
+ if (found_tcl == 0) {
+ PyErr_SetString(PyExc_RuntimeError, "Could not find TCL routines");
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");
+ }
+ return 1;
+}
+
+#else // not Windows
+
+/*
+ * On Unix, we can get the TCL and Tk synbols from the tkinter module, because
+ * tkinter uses these symbols, and the symbols are therefore visible in the
+ * tkinter dynamic library (module).
+ */
+#if PY_MAJOR_VERSION >= 3
+#define TKINTER_PKG "tkinter"
+#define TKINTER_MOD "_tkinter"
+// From module __file__ attribute to char *string for dlopen.
+char *fname2char(PyObject *fname)
+{
+ PyObject* bytes;
+ bytes = PyUnicode_EncodeFSDefault(fname);
+ if (bytes == NULL) {
+ return NULL;
+ }
+ return PyBytes_AsString(bytes);
+}
+#else
+#define TKINTER_PKG "Tkinter"
+#define TKINTER_MOD "tkinter"
+// From module __file__ attribute to char *string for dlopen
+#define fname2char(s) (PyString_AsString(s))
+#endif
+
+#include <dlfcn.h>
+
+void *_dfunc(void *lib_handle, const char *func_name)
+{
+ // Load function `func_name` from `lib_handle`.
+ // Set Python exception if we can't find `func_name` in `lib_handle`.
+ // Returns function pointer or NULL if not present.
+
+ void* func;
+ // Reset errors.
+ dlerror();
+ func = dlsym(lib_handle, func_name);
+ if (func == NULL) {
+ const char *error = dlerror();
+ PyErr_SetString(PyExc_RuntimeError, error);
+ }
+ return func;
+}
+
+int _func_loader(void *lib)
+{
+ // Fill global function pointers from dynamic lib.
+ // Return 1 if any pointer is NULL, 0 otherwise.
+ return (
+ ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
+ _dfunc(lib, "Tcl_CreateCommand")) == NULL) ||
+ ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
+ _dfunc(lib, "Tcl_AppendResult")) == NULL) ||
+ ((TK_MAIN_WINDOW = (Tk_MainWindow_t)
+ _dfunc(lib, "Tk_MainWindow")) == NULL) ||
+ ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
+ _dfunc(lib, "Tk_FindPhoto")) == NULL) ||
+ ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
+ _dfunc(lib, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
+ ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
+ _dfunc(lib, "Tk_PhotoBlank")) == NULL));
+}
+
+int load_tkinter_funcs(void)
+{
+ // Load tkinter global funcs from tkinter compiled module.
+ // Return 0 for success, non-zero for failure.
+ int ret = -1;
+ void *main_program, *tkinter_lib;
+ char *tkinter_libname;
+ PyObject *pModule = NULL, *pSubmodule = NULL, *pString = NULL;
+
+ // Try loading from the main program namespace first
+ main_program = dlopen(NULL, RTLD_LAZY);
+ if (_func_loader(main_program) == 0) {
+ return 0;
+ }
+ // Clear exception triggered when we didn't find symbols above.
+ PyErr_Clear();
+
+ // Now try finding the tkinter compiled module
+ pModule = PyImport_ImportModule(TKINTER_PKG);
+ if (pModule == NULL) {
+ goto exit;
+ }
+ pSubmodule = PyObject_GetAttrString(pModule, TKINTER_MOD);
+ if (pSubmodule == NULL) {
+ goto exit;
+ }
+ pString = PyObject_GetAttrString(pSubmodule, "__file__");
+ if (pString == NULL) {
+ goto exit;
+ }
+ tkinter_libname = fname2char(pString);
+ if (tkinter_libname == NULL) {
+ goto exit;
+ }
+ tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
+ if (tkinter_lib == NULL) {
+ /* 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);
+ Py_XDECREF(pString);
+ return ret;
+}
+#endif // end not Windows
+
+#if PY_MAJOR_VERSION >= 3
+static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions,
+ NULL, NULL, NULL, NULL };
+
+PyMODINIT_FUNC PyInit__tkagg(void)
+{
+ PyObject *m;
+
+ m = PyModule_Create(&_tkagg_module);
+
+ return (load_tkinter_funcs() == 0) ? m : NULL;
+}
+#else
+PyMODINIT_FUNC init_tkagg(void)
+{
+ Py_InitModule("_tkagg", functions);
+
+ load_tkinter_funcs();
+}
+#endif