summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteve Chaplin <>2012-05-05 18:58:23 +0800
committerSteve Chaplin <>2012-05-05 18:58:23 +0800
commit2f9e604ac7bb5f6386179a3d0fad6f095c386f66 (patch)
treedf5be4b376d0b9cdfd4660ddc7e3dfee79862a90 /src
parentbeb3e1cb641ef4f5461b0e360d7d8d3c9fbcf4aa (diff)
Implement ImageSurface.create_for_data(), using a modified version of a patch
from Paul Colomiets, bug #44935. pycairo will not be binary compatible with earlier versions of pycairo.
Diffstat (limited to 'src')
-rw-r--r--src/py3cairo.h1
-rw-r--r--src/surface.c105
2 files changed, 25 insertions, 81 deletions
diff --git a/src/py3cairo.h b/src/py3cairo.h
index 324ac37..853c1d8 100644
--- a/src/py3cairo.h
+++ b/src/py3cairo.h
@@ -75,6 +75,7 @@ typedef struct {
PyObject_HEAD
cairo_surface_t *surface;
PyObject *base; /* base object used to create surface, or NULL */
+ Py_buffer buffer;
} PycairoSurface;
#define PycairoImageSurface PycairoSurface
diff --git a/src/surface.c b/src/surface.c
index 7d00141..0578639 100644
--- a/src/surface.c
+++ b/src/surface.c
@@ -113,6 +113,8 @@ PycairoSurface_FromSurface (cairo_surface_t *surface, PyObject *base) {
((PycairoSurface *)o)->surface = surface;
Py_XINCREF(base);
((PycairoSurface *)o)->base = base;
+
+ ((PycairoSurface *)o)->buffer.buf = NULL;
}
return o;
}
@@ -124,8 +126,6 @@ PycairoSurface_FromSurface (cairo_surface_t *surface, PyObject *base) {
static cairo_status_t
_write_func (void *closure, const unsigned char *data, unsigned int length) {
PyGILState_STATE gstate = PyGILState_Ensure();
- // PyObject *res = PyObject_CallMethod ((PyObject *)closure, "write", "(s#)",
- // data, (Py_ssize_t)length);
PyObject *res = PyObject_CallMethod ((PyObject *)closure, "write", "(y#)",
data, (Py_ssize_t)length);
if (res == NULL) {
@@ -147,8 +147,8 @@ surface_dealloc (PycairoSurface *o) {
o->surface = NULL;
}
Py_CLEAR(o->base);
+ PyBuffer_Release(&o->buffer);
- //o->ob_type->tp_free((PyObject *)o);
Py_TYPE(o)->tp_free(o);
}
@@ -416,23 +416,12 @@ image_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
static PyObject *
image_surface_create_for_data (PyTypeObject *type, PyObject *args) {
- cairo_surface_t *surface;
cairo_format_t format;
- unsigned char *buffer;
- int width, height, stride = -1, res;
- Py_ssize_t buffer_len;
- PyObject *obj;
-
- // buffer function disabled
- PyErr_SetString(PyExc_NotImplementedError, "Surface.create_for_data: Not Implemented yet.");
- return NULL;
+ int width, height, stride = -1;
+ Py_buffer buffer;
- if (!PyArg_ParseTuple(args, "Oiii|i:Surface.create_for_data",
- &obj, &format, &width, &height, &stride))
- return NULL;
-
- res = PyObject_AsWriteBuffer (obj, (void **)&buffer, &buffer_len);
- if (res == -1)
+ if (!PyArg_ParseTuple(args, "w*iii|i:Surface.create_for_data",
+ &buffer, &format, &width, &height, &stride))
return NULL;
if (width <= 0) {
@@ -452,15 +441,20 @@ image_surface_create_for_data (PyTypeObject *type, PyObject *args) {
return NULL;
}
}
- if (height * stride > buffer_len) {
+ if (height * stride > buffer.len) {
PyErr_SetString(PyExc_TypeError, "buffer is not long enough");
return NULL;
}
+ cairo_surface_t *surface;
+ PyObject *o;
Py_BEGIN_ALLOW_THREADS;
- surface = cairo_image_surface_create_for_data (buffer, format, width,
+ surface = cairo_image_surface_create_for_data (buffer.buf, format, width,
height, stride);
Py_END_ALLOW_THREADS;
- return PycairoSurface_FromSurface(surface, obj);
+
+ o = PycairoSurface_FromSurface(surface, NULL);
+ ((PycairoSurface *)o)->buffer = buffer;
+ return o;
}
@@ -570,7 +564,11 @@ image_surface_get_width (PycairoImageSurface *o) {
}
-/* Buffer interface functions, used by ImageSurface.get_data() */
+/* Buffer interface functions
+used by ImageSurface.get_data()
+PEP 3118 -- Revising the buffer protocol
+http://www.python.org/dev/peps/pep-3118/
+*/
static int
image_surface_buffer_getbufferproc (PycairoImageSurface *o, Py_buffer *view,
int flags) {
@@ -578,74 +576,19 @@ image_surface_buffer_getbufferproc (PycairoImageSurface *o, Py_buffer *view,
int height, stride;
void *data;
+ /* buffer does not give ndim, shape or stride information
+ */
+
height = cairo_image_surface_get_height (surface);
stride = cairo_image_surface_get_stride (surface);
data = cairo_image_surface_get_data (surface);
if(!PyBuffer_FillInfo(view, (PyObject *)o, data,
- height * stride, 0, PyBUF_CONTIG))
+ height * stride, 0, PyBUF_CONTIG))
return 0;
return -1;
}
-/* Buffer interface functions, used by ImageSurface.get_data() */
-/*
-static int
-image_surface_buffer_getreadbuf (PycairoImageSurface *o, int segment,
- const void **ptr) {
- cairo_surface_t *surface = o->surface;
- int height, stride;
-
- if (segment != 0) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent ImageSurface segment");
- return -1;
- }
- height = cairo_image_surface_get_height (surface);
- stride = cairo_image_surface_get_stride (surface);
- *ptr = (void *) cairo_image_surface_get_data (surface);
- return height * stride;
-}
-
-static int
-image_surface_buffer_getwritebuf (PycairoImageSurface *o, int segment,
- const void **ptr) {
- cairo_surface_t *surface = o->surface;
- int height, stride;
-
- if (segment != 0) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent ImageSurface segment");
- return -1;
- }
- height = cairo_image_surface_get_height (surface);
- stride = cairo_image_surface_get_stride (surface);
- *ptr = (void *) cairo_image_surface_get_data (surface);
- return height * stride;
-}
-
-static int
-image_surface_buffer_getsegcount (PycairoImageSurface *o, int *lenp) {
- if (lenp) {
- // report the sum of the sizes (in bytes) of all segments
- cairo_surface_t *surface = o->surface;
- int height = cairo_image_surface_get_height (surface);
- int stride = cairo_image_surface_get_stride (surface);
- *lenp = height * stride;
- }
- return 1; // surface data is all in one segment
-}
-*/
-
-/* See Python C API Manual 10.7 */
-/*
-static PyBufferProcs image_surface_as_buffer = {
- (readbufferproc) image_surface_buffer_getreadbuf,
- (writebufferproc)image_surface_buffer_getwritebuf,
- (segcountproc) image_surface_buffer_getsegcount,
- (charbufferproc) NULL,
-};
-*/
static PyBufferProcs image_surface_as_buffer = {
(getbufferproc) image_surface_buffer_getbufferproc,
(releasebufferproc) NULL,