1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
/* This file is part of MyPaint.
* Copyright (C) 2008-2011 by Martin Renold <martinxyz@gmx.ch>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include "pythontiledsurface.h"
#include "surface.hpp"
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define NO_IMPORT_ARRAY
#include <numpy/arrayobject.h>
#include <numpy/ndarraytypes.h>
#include <mypaint-tiled-surface.h>
struct MyPaintPythonTiledSurface {
MyPaintTiledSurface2 parent;
PyObject * py_obj;
};
// Forward declare
void free_tiledsurf(MyPaintSurface *surface);
static void
tile_request_start(MyPaintTiledSurface2 *tiled_surface, MyPaintTileRequest *request)
{
MyPaintPythonTiledSurface *self = (MyPaintPythonTiledSurface *)tiled_surface;
const gboolean readonly = request->readonly;
const int tx = request->tx;
const int ty = request->ty;
PyArrayObject* rgba = NULL;
{
PyGILState_STATE gstate = PyGILState_Ensure();
rgba = (PyArrayObject*)PyObject_CallMethod(self->py_obj, "_get_tile_numpy", "(iii)", tx, ty, readonly);
if (rgba == NULL) {
request->buffer = NULL;
printf("Python exception during get_tile_numpy()!\n");
if (PyErr_Occurred()) {
PyErr_Print();
}
} else {
#ifdef HEAVY_DEBUG
assert(PyArray_NDIM(rgba) == 3);
assert(PyArray_DIM(rgba, 0) == tiled_surface->tile_size);
assert(PyArray_DIM(rgba, 1) == tiled_surface->tile_size);
assert(PyArray_DIM(rgba, 2) == 4);
assert(PyArray_ISCARRAY(rgba));
assert(PyArray_TYPE(rgba) == NPY_UINT16);
#endif
// tiledsurface.py will keep a reference in its tiledict, at least until the final end_atomic()
Py_DECREF((PyObject *)rgba);
request->buffer = (uint16_t*)PyArray_DATA(rgba);
}
PyGILState_Release(gstate);
}
}
static void
tile_request_end(MyPaintTiledSurface2 *tiled_surface, MyPaintTileRequest *request)
{
// We modify tiles directly, so don't need to do anything here
}
MyPaintPythonTiledSurface *
mypaint_python_tiled_surface_new(PyObject *py_object)
{
MyPaintPythonTiledSurface *self = (MyPaintPythonTiledSurface *)malloc(sizeof(MyPaintPythonTiledSurface));
mypaint_tiled_surface2_init(&self->parent, tile_request_start, tile_request_end);
self->parent.threadsafe_tile_requests = TRUE;
// MyPaintSurface vfuncs
self->parent.parent.parent.destroy = free_tiledsurf;
self->py_obj = py_object; // no need to incref
return self;
}
void free_tiledsurf(MyPaintSurface *surface)
{
MyPaintPythonTiledSurface *self = (MyPaintPythonTiledSurface *)surface;
mypaint_tiled_surface2_destroy(&self->parent);
free(self);
}
|