py2cairo/cairo/surface.c

2493 lines
84 KiB
C

/* -*- mode: C; c-basic-offset: 2 -*-
*
* Pycairo - Python bindings for cairo
*
* Copyright © 2003 James Henstridge
* Copyright © 2004-2011 Steven Chaplin
*
* This library is free software; you can redistribute it and/or
* modify it either under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation
* (the "LGPL") or, at your option, under the terms of the Mozilla
* Public License Version 1.1 (the "MPL"). If you do not alter this
* notice, a recipient may use your version of this file under either
* the MPL or the LGPL.
*
* You should have received a copy of the LGPL along with this library
* in the file COPYING-LGPL-2.1; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* You should have received a copy of the MPL along with this library
* in the file COPYING-MPL-1.1
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
* OF ANY KIND, either express or implied. See the LGPL or the MPL for
* the specific language governing rights and limitations.
*/
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include "private.h"
/* Class Surface ---------------------------------------------------------- */
PyObject *
PycairoSurface_FromSurface (cairo_surface_t *surface, PyObject *base) {
PyTypeObject *type = NULL;
PyObject *o;
assert (surface != NULL);
if (Pycairo_Check_Status (cairo_surface_status (surface))) {
cairo_surface_destroy (surface);
return NULL;
}
switch (cairo_surface_get_type (surface)) {
#ifdef CAIRO_HAS_IMAGE_SURFACE
case CAIRO_SURFACE_TYPE_IMAGE:
type = &PycairoImageSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
case CAIRO_SURFACE_TYPE_PDF:
type = &PycairoPDFSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_PS_SURFACE
case CAIRO_SURFACE_TYPE_PS:
type = &PycairoPSSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_RECORDING_SURFACE
case CAIRO_SURFACE_TYPE_RECORDING:
type = &PycairoRecordingSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
case CAIRO_SURFACE_TYPE_SVG:
type = &PycairoSVGSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
case CAIRO_SURFACE_TYPE_WIN32:
type = &PycairoWin32Surface_Type;
break;
case CAIRO_SURFACE_TYPE_WIN32_PRINTING:
type = &PycairoWin32PrintingSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_XCB_SURFACE
case CAIRO_SURFACE_TYPE_XCB:
type = &PycairoXCBSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_XLIB_SURFACE
case CAIRO_SURFACE_TYPE_XLIB:
type = &PycairoXlibSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_SCRIPT_SURFACE
case CAIRO_SURFACE_TYPE_SCRIPT:
type = &PycairoScriptSurface_Type;
break;
#endif
#ifdef CAIRO_HAS_TEE_SURFACE
case CAIRO_SURFACE_TYPE_TEE:
type = &PycairoTeeSurface_Type;
break;
#endif
default:
type = &PycairoSurface_Type;
break;
}
o = type->tp_alloc (type, 0);
if (o == NULL) {
cairo_surface_destroy (surface);
} else {
((PycairoSurface *)o)->surface = surface;
Py_XINCREF(base);
((PycairoSurface *)o)->base = base;
}
return o;
}
/* for use with
* cairo_surface_write_to_png_stream()
* cairo_pdf/ps/svg_surface_create_for_stream()
*/
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", "(" PYCAIRO_DATA_FORMAT "#)",
data, (Py_ssize_t)length);
if (res == NULL) {
PyErr_Clear();
/* an exception has occurred, it will be picked up later by
* Pycairo_Check_Status()
*/
PyGILState_Release(gstate);
return CAIRO_STATUS_WRITE_ERROR;
}
Py_DECREF(res);
PyGILState_Release(gstate);
return CAIRO_STATUS_SUCCESS;
}
static const cairo_user_data_key_t surface_base_object_key;
static const cairo_user_data_key_t surface_is_mapped_image;
static void
surface_dealloc (PycairoSurface *o) {
if (o->surface) {
if (cairo_surface_get_user_data (
o->surface, &surface_is_mapped_image) == NULL) {
cairo_surface_destroy(o->surface);
}
o->surface = NULL;
}
Py_CLEAR(o->base);
Py_TYPE(o)->tp_free(o);
}
static void
_decref_destroy_func(void *user_data) {
PyGILState_STATE gstate = PyGILState_Ensure();
Py_DECREF(user_data);
PyGILState_Release(gstate);
}
/* Like PycairoSurface_FromSurface, but keeps the base object alive as long
* as cairo_surface_t exists and not as long as the wrapper exists.
*/
static PyObject *
_surface_create_with_object(cairo_surface_t *surface, PyObject *base) {
PyObject *pysurface;
cairo_status_t status;
pysurface = PycairoSurface_FromSurface(surface, NULL);
if (pysurface == NULL)
return NULL;
if (base != NULL) {
status = cairo_surface_set_user_data(
surface, &surface_base_object_key, base, _decref_destroy_func);
if (status != CAIRO_STATUS_SUCCESS)
Py_DECREF(pysurface);
RETURN_NULL_IF_CAIRO_ERROR(status);
Py_INCREF(base);
}
return pysurface;
}
static PyObject *
surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
PyErr_SetString(PyExc_TypeError,
"The Surface type cannot be instantiated");
return NULL;
}
static PyObject *
surface_copy_page (PycairoSurface *o) {
Py_BEGIN_ALLOW_THREADS;
cairo_surface_copy_page (o->surface);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_create_similar (PycairoSurface *o, PyObject *args) {
cairo_content_t content;
int width, height, content_arg;
if (!PyArg_ParseTuple (args, "iii:Surface.create_similar",
&content_arg, &width, &height))
return NULL;
content = (cairo_content_t)content_arg;
return PycairoSurface_FromSurface (
cairo_surface_create_similar (o->surface, content, width, height),
NULL);
}
static PyObject *
surface_finish (PycairoSurface *o) {
cairo_surface_finish (o->surface);
Py_CLEAR(o->base);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_flush (PycairoSurface *o) {
Py_BEGIN_ALLOW_THREADS;
cairo_surface_flush (o->surface);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_get_content (PycairoSurface *o) {
RETURN_INT_ENUM (Content, cairo_surface_get_content (o->surface));
}
static PyObject *
surface_get_device_offset (PycairoSurface *o) {
double x_offset, y_offset;
cairo_surface_get_device_offset (o->surface, &x_offset, &y_offset);
return Py_BuildValue("(dd)", x_offset, y_offset);
}
static PyObject *
surface_get_device_scale (PycairoSurface *o) {
double x_scale, y_scale;
cairo_surface_get_device_scale (o->surface, &x_scale, &y_scale);
return Py_BuildValue("(dd)", x_scale, y_scale);
}
static PyObject *
surface_get_fallback_resolution (PycairoSurface *o) {
double x_ppi, y_ppi;
cairo_surface_get_fallback_resolution (o->surface, &x_ppi, &y_ppi);
return Py_BuildValue("(dd)", x_ppi, y_ppi);
}
static PyObject *
surface_get_font_options (PycairoSurface *o) {
cairo_font_options_t *options = cairo_font_options_create();
cairo_surface_get_font_options (o->surface, options);
/* there is no reference fn */
return PycairoFontOptions_FromFontOptions (options);
}
static PyObject *
surface_get_device (PycairoSurface *o) {
cairo_device_t *device = cairo_surface_get_device (o->surface);
if (device == NULL)
Py_RETURN_NONE;
return PycairoDevice_FromDevice (cairo_device_reference (device));
}
static PyObject *
surface_mark_dirty (PycairoSurface *o) {
cairo_surface_mark_dirty (o->surface);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_mark_dirty_rectangle (PycairoSurface *o, PyObject *args) {
int x, y, width, height;
if (!PyArg_ParseTuple(args, "iiii:Surface.mark_dirty_rectangle",
&x, &y, &width, &height))
return NULL;
cairo_surface_mark_dirty_rectangle (o->surface, x, y, width, height);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_set_device_offset (PycairoSurface *o, PyObject *args) {
double x_offset, y_offset;
if (!PyArg_ParseTuple (args, "dd:Surface.set_device_offset",
&x_offset, &y_offset))
return NULL;
cairo_surface_set_device_offset (o->surface, x_offset, y_offset);
Py_RETURN_NONE;
}
static PyObject *
surface_set_device_scale (PycairoSurface *o, PyObject *args) {
double x_scale, y_scale;
cairo_matrix_t transform;
if (!PyArg_ParseTuple (args, "dd:Surface.set_device_scale",
&x_scale, &y_scale))
return NULL;
/* cairo asserts the following without reporting an error back.
* Since we don't want things to crash in Python replicate the logic here.
*/
cairo_matrix_init_scale (&transform, x_scale, y_scale);
RETURN_NULL_IF_CAIRO_ERROR (cairo_matrix_invert (&transform));
cairo_surface_set_device_scale (o->surface, x_scale, y_scale);
Py_RETURN_NONE;
}
static PyObject *
surface_set_fallback_resolution (PycairoSurface *o, PyObject *args) {
double x_ppi, y_ppi;
if (!PyArg_ParseTuple(args, "dd:Surface.set_fallback_resolution",
&x_ppi, &y_ppi))
return NULL;
cairo_surface_set_fallback_resolution (o->surface, x_ppi, y_ppi);
Py_RETURN_NONE;
}
static PyObject *
surface_create_for_rectangle (PycairoSurface *o, PyObject *args) {
double x, y, width, height;
cairo_surface_t *new;
if (!PyArg_ParseTuple(args, "dddd:Surface.create_for_rectangle",
&x, &y, &width, &height))
return NULL;
Py_BEGIN_ALLOW_THREADS;
new = cairo_surface_create_for_rectangle(o->surface, x, y, width, height);
Py_END_ALLOW_THREADS;
return PycairoSurface_FromSurface(new, NULL);
}
static PyObject *
surface_show_page (PycairoSurface *o) {
Py_BEGIN_ALLOW_THREADS;
cairo_surface_show_page (o->surface);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
surface_create_similar_image (PycairoSurface *o, PyObject *args) {
cairo_format_t format;
int width, height, format_arg;
cairo_surface_t *new;
if (!PyArg_ParseTuple (args, "iii:Surface.create_similar_image",
&format_arg, &width, &height))
return NULL;
format = (cairo_format_t)format_arg;
Py_BEGIN_ALLOW_THREADS;
new = cairo_surface_create_similar_image (o->surface, format, width, height);
Py_END_ALLOW_THREADS;
return PycairoSurface_FromSurface (new, NULL);
}
#ifdef CAIRO_HAS_PNG_FUNCTIONS
static PyObject *
surface_write_to_png (PycairoSurface *o, PyObject *args) {
cairo_status_t status;
char *name = NULL;
PyObject *file;
if (!PyArg_ParseTuple (args, "O:Surface.write_to_png", &file))
return NULL;
if (Pycairo_is_fspath (file)) {
if (!PyArg_ParseTuple (args, "O&:Surface.write_to_png",
Pycairo_fspath_converter, &name))
return NULL;
Py_BEGIN_ALLOW_THREADS;
status = cairo_surface_write_to_png (o->surface, name);
Py_END_ALLOW_THREADS;
PyMem_Free (name);
} else {
if (PyArg_ParseTuple (args, "O&:Surface.write_to_png",
Pycairo_writer_converter, &file)) {
Py_BEGIN_ALLOW_THREADS;
status = cairo_surface_write_to_png_stream (o->surface, _write_func,
file);
Py_END_ALLOW_THREADS;
} else {
PyErr_Clear ();
PyErr_SetString (PyExc_TypeError,
"Surface.write_to_png takes one argument which must be "
"a filename, file object, or a file-like object "
"which has a \"write\" method (like StringIO)");
return NULL;
}
}
RETURN_NULL_IF_CAIRO_ERROR (status);
Py_RETURN_NONE;
}
#endif /* CAIRO_HAS_PNG_FUNCTIONS */
static void
_destroy_mime_user_data_func (PyObject *user_data) {
PyGILState_STATE gstate = PyGILState_Ensure();
Py_DECREF(user_data);
PyGILState_Release(gstate);
}
static void
_destroy_mime_data_func (PyObject *user_data) {
cairo_surface_t *surface;
PyObject *mime_intern;
PyGILState_STATE gstate = PyGILState_Ensure();
/* Remove the user data holding the source object */
surface = PyCapsule_GetPointer(PyTuple_GET_ITEM(user_data, 0), NULL);
mime_intern = PyTuple_GET_ITEM(user_data, 2);
cairo_surface_set_user_data(
surface, (cairo_user_data_key_t *)mime_intern, NULL, NULL);
/* Destroy the user data */
_destroy_mime_user_data_func(user_data);
PyGILState_Release(gstate);
}
static PyObject *
surface_set_mime_data (PycairoSurface *o, PyObject *args) {
PyObject *obj, *user_data, *mime_intern, *capsule;
const unsigned char *buffer;
const char *mime_type;
Py_ssize_t buffer_len;
int res;
cairo_status_t status;
if (!PyArg_ParseTuple(args, "sO:Surface.set_mime_data", &mime_type, &obj))
return NULL;
if (obj == Py_None) {
status = cairo_surface_set_mime_data (
o->surface, mime_type, NULL, 0, NULL, NULL);
RETURN_NULL_IF_CAIRO_ERROR(status);
Py_RETURN_NONE;
}
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
res = PyObject_AsReadBuffer (obj, (const void **)&buffer, &buffer_len);
#pragma GCC diagnostic pop
if (res == -1)
return NULL;
/* We use the interned mime type string as user data key and store the
* passed in object with it. This allows us to return the same object in
* surface_get_mime_data().
*/
mime_intern = PYCAIRO_PyUnicode_InternFromString(mime_type);
capsule = PyCapsule_New(o->surface, NULL, NULL);
user_data = Py_BuildValue("(NOO)", capsule, obj, mime_intern);
if (user_data == NULL)
return NULL;
status = cairo_surface_set_user_data(
o->surface, (cairo_user_data_key_t *)mime_intern, user_data,
(cairo_destroy_func_t)_destroy_mime_user_data_func);
if (status != CAIRO_STATUS_SUCCESS)
Py_DECREF(user_data);
RETURN_NULL_IF_CAIRO_ERROR(status);
status = cairo_surface_set_mime_data (
o->surface, mime_type, buffer, (unsigned long)buffer_len,
(cairo_destroy_func_t)_destroy_mime_data_func, user_data);
if (status != CAIRO_STATUS_SUCCESS) {
cairo_surface_set_user_data(
o->surface, (cairo_user_data_key_t *)mime_intern, NULL, NULL);
}
RETURN_NULL_IF_CAIRO_ERROR(status);
Py_INCREF(user_data);
Py_RETURN_NONE;
}
static PyObject *
surface_get_mime_data (PycairoSurface *o, PyObject *args) {
PyObject *user_data, *obj, *mime_intern;
const char *mime_type;
const unsigned char *buffer;
unsigned long buffer_len;
if (!PyArg_ParseTuple(args, "s:Surface.get_mime_data", &mime_type))
return NULL;
cairo_surface_get_mime_data (o->surface, mime_type, &buffer, &buffer_len);
if (buffer == NULL) {
Py_RETURN_NONE;
}
mime_intern = PYCAIRO_PyUnicode_InternFromString(mime_type);
user_data = cairo_surface_get_user_data(
o->surface, (cairo_user_data_key_t *)mime_intern);
if (user_data == NULL) {
/* In case the mime data wasn't set through the Python API just copy it */
return Py_BuildValue(PYCAIRO_DATA_FORMAT "#", buffer, buffer_len);
} else {
obj = PyTuple_GET_ITEM(user_data, 1);
Py_INCREF(obj);
return obj;
}
}
static PyObject *
surface_supports_mime_type (PycairoSurface *self, PyObject *args) {
const char *mime_type;
if (!PyArg_ParseTuple(args, "s:Surface.supports_mime_type", &mime_type))
return NULL;
return PyBool_FromLong(
cairo_surface_supports_mime_type(self->surface, mime_type));
}
static PyObject *
surface_has_show_text_glyphs (PycairoSurface *o) {
cairo_bool_t result;
Py_BEGIN_ALLOW_THREADS;
result = cairo_surface_has_show_text_glyphs (o->surface);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR (o->surface);
return PyBool_FromLong (result);
}
#ifdef CAIRO_HAS_IMAGE_SURFACE
static PyObject *
surface_map_to_image (PycairoSurface *self, PyObject *args) {
PyObject *pyextents, *pymapped;
cairo_rectangle_int_t *extents;
cairo_surface_t *mapped_surface;
if (!PyArg_ParseTuple(args, "O:Surface.map_to_image", &pyextents))
return NULL;
if (PyObject_TypeCheck (pyextents, &PycairoRectangleInt_Type)) {
extents = &(((PycairoRectangleInt *)pyextents)->rectangle_int);
} else {
if (pyextents == Py_None) {
extents = NULL;
} else {
PyErr_SetString (PyExc_TypeError,
"argument must be a RectangleInt or None.");
return NULL;
}
}
Py_BEGIN_ALLOW_THREADS;
mapped_surface = cairo_surface_map_to_image (self->surface, extents);
Py_END_ALLOW_THREADS;
if (Pycairo_Check_Status (cairo_surface_status (mapped_surface))) {
cairo_surface_destroy (mapped_surface);
return NULL;
}
/* So we can skip the destroy() call in the base tp_dealloc */
cairo_surface_set_user_data (
mapped_surface, &surface_is_mapped_image, (void*)1, NULL);
pymapped = PycairoMappedImageSurface_Type.tp_alloc (
&PycairoMappedImageSurface_Type, 0);
if (pymapped == NULL) {
Py_BEGIN_ALLOW_THREADS;
cairo_surface_unmap_image (self->surface, mapped_surface);
Py_END_ALLOW_THREADS;
return NULL;
}
((PycairoSurface *)pymapped)->surface = mapped_surface;
Py_XINCREF (self);
((PycairoSurface *)pymapped)->base = (PyObject *)self;
return pymapped;
}
static PyObject *
surface_unmap_image (PycairoSurface *self, PyObject *args) {
PycairoSurface *pymapped;
cairo_surface_t *base_surface, *fake_surface;
if (!PyArg_ParseTuple(args, "O!:Surface.unmap_image",
&PycairoMappedImageSurface_Type, &pymapped))
return NULL;
if (cairo_surface_get_user_data (pymapped->surface,
&surface_is_mapped_image) == NULL) {
PyErr_SetString (PyExc_RuntimeError,
"MappedImageSurface was already unmapped");
return NULL;
}
base_surface = ((PycairoSurface *)(pymapped->base))->surface;
if (base_surface != self->surface) {
PyErr_SetString (PyExc_ValueError,
"ImageSurface isn't mapped from this surface");
return NULL;
}
Py_BEGIN_ALLOW_THREADS;
cairo_surface_unmap_image (self->surface, pymapped->surface);
Py_END_ALLOW_THREADS;
/* Replace the mapped image surface with a fake one and finish it so
* that any operation on it fails.
*/
fake_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
cairo_surface_finish (fake_surface);
pymapped->surface = fake_surface;
/* We no longer need the base surface */
Py_CLEAR(pymapped->base);
Py_RETURN_NONE;
}
#endif /* CAIRO_HAS_IMAGE_SURFACE */
static PyObject *
surface_ctx_enter (PyObject *obj) {
Py_INCREF (obj);
return obj;
}
static PyObject *
surface_ctx_exit (PycairoSurface *obj, PyObject *args) {
Py_BEGIN_ALLOW_THREADS;
cairo_surface_finish (obj->surface);
Py_END_ALLOW_THREADS;
Py_RETURN_NONE;
}
static PyMethodDef surface_methods[] = {
/* methods never exposed in a language binding:
* cairo_surface_destroy()
* cairo_surface_get_type()
* cairo_surface_get_user_data()
* cairo_surface_reference()
* cairo_surface_set_user_data()
*/
{"__enter__", (PyCFunction)surface_ctx_enter, METH_NOARGS},
{"__exit__", (PyCFunction)surface_ctx_exit, METH_VARARGS},
{"copy_page", (PyCFunction)surface_copy_page, METH_NOARGS},
{"create_similar", (PyCFunction)surface_create_similar, METH_VARARGS},
{"create_similar_image", (PyCFunction)surface_create_similar_image,
METH_VARARGS},
{"finish", (PyCFunction)surface_finish, METH_NOARGS},
{"flush", (PyCFunction)surface_flush, METH_NOARGS},
{"get_content", (PyCFunction)surface_get_content, METH_NOARGS},
{"get_device_offset",(PyCFunction)surface_get_device_offset,METH_NOARGS},
{"get_device_scale", (PyCFunction)surface_get_device_scale, METH_NOARGS},
{"get_fallback_resolution",(PyCFunction)surface_get_fallback_resolution,
METH_NOARGS},
{"get_font_options",(PyCFunction)surface_get_font_options, METH_NOARGS},
{"get_device", (PyCFunction)surface_get_device, METH_NOARGS},
{"mark_dirty", (PyCFunction)surface_mark_dirty, METH_NOARGS},
{"mark_dirty_rectangle", (PyCFunction)surface_mark_dirty_rectangle,
METH_VARARGS},
{"set_device_offset",(PyCFunction)surface_set_device_offset,METH_VARARGS},
{"set_device_scale", (PyCFunction)surface_set_device_scale, METH_VARARGS},
{"set_fallback_resolution",(PyCFunction)surface_set_fallback_resolution,
METH_VARARGS},
{"show_page", (PyCFunction)surface_show_page, METH_NOARGS},
#ifdef CAIRO_HAS_PNG_FUNCTIONS
{"write_to_png", (PyCFunction)surface_write_to_png, METH_VARARGS},
#endif
{"set_mime_data", (PyCFunction)surface_set_mime_data, METH_VARARGS},
{"get_mime_data", (PyCFunction)surface_get_mime_data, METH_VARARGS},
{"supports_mime_type", (PyCFunction)surface_supports_mime_type,
METH_VARARGS},
{"create_for_rectangle",(PyCFunction)surface_create_for_rectangle,
METH_VARARGS},
{"has_show_text_glyphs", (PyCFunction)surface_has_show_text_glyphs,
METH_NOARGS},
#ifdef CAIRO_HAS_IMAGE_SURFACE
{"map_to_image", (PyCFunction)surface_map_to_image, METH_VARARGS},
{"unmap_image", (PyCFunction)surface_unmap_image, METH_VARARGS},
#endif
{NULL, NULL, 0, NULL},
};
static PyObject*
surface_richcompare (PyObject *self, PyObject *other, int op)
{
if (Py_TYPE(self) == Py_TYPE(other))
return Pycairo_richcompare (
((PycairoSurface *)self)->surface,
((PycairoSurface *)other)->surface,
op);
else {
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
}
static PYCAIRO_Py_hash_t
surface_hash (PyObject *self)
{
return PYCAIRO_Py_hash_t_FromVoidPtr (((PycairoSurface *)self)->surface);
}
PyTypeObject PycairoSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.Surface", /* tp_name */
sizeof(PycairoSurface), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)surface_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
surface_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
surface_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
/* Class ImageSurface(Surface) -------------------------------------------- */
#ifdef CAIRO_HAS_IMAGE_SURFACE
static PyObject *
image_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
cairo_format_t format;
int width, height, format_arg;
if (!PyArg_ParseTuple (args, "iii:ImageSurface.__new__",
&format_arg, &width, &height))
return NULL;
format = (cairo_format_t)format_arg;
return PycairoSurface_FromSurface (
cairo_image_surface_create (format, width, height),
NULL);
}
/* METH_CLASS */
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, format_arg;
Py_ssize_t buffer_len;
PyObject *obj;
if (!PyArg_ParseTuple (args, "Oiii|i:ImageSurface.create_for_data",
&obj, &format_arg, &width, &height, &stride))
return NULL;
format = (cairo_format_t)format_arg;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
res = PyObject_AsWriteBuffer (obj, (void **)&buffer, &buffer_len);
#pragma GCC diagnostic pop
if (res == -1)
return NULL;
if (width <= 0) {
PyErr_SetString(PyExc_ValueError, "width must be positive");
return NULL;
}
if (height <= 0) {
PyErr_SetString(PyExc_ValueError, "height must be positive");
return NULL;
}
/* if stride is missing, calculate it from width */
if (stride < 0) {
stride = cairo_format_stride_for_width (format, width);
if (stride == -1){
PyErr_SetString(PyExc_ValueError,
"format is invalid or the width too large");
return NULL;
}
}
if (height * stride > buffer_len) {
PyErr_SetString(PyExc_TypeError, "buffer is not long enough");
return NULL;
}
Py_BEGIN_ALLOW_THREADS;
surface = cairo_image_surface_create_for_data (buffer, format, width,
height, stride);
Py_END_ALLOW_THREADS;
return _surface_create_with_object(surface, obj);
}
#ifdef CAIRO_HAS_PNG_FUNCTIONS
static cairo_status_t
_read_func (void *closure, unsigned char *data, unsigned int length) {
char *buffer;
int ret;
Py_ssize_t str_length;
cairo_status_t status = CAIRO_STATUS_READ_ERROR;
PyGILState_STATE gstate = PyGILState_Ensure();
PyObject *pystr = PyObject_CallMethod ((PyObject *)closure, "read", "(i)",
length);
if (pystr == NULL) {
PyErr_Clear();
/* an exception has occurred, it will be picked up later by
* Pycairo_Check_Status()
*/
goto end;
}
ret = PYCAIRO_PyBytes_AsStringAndSize(pystr, &buffer, &str_length);
if (ret == -1 || str_length < (Py_ssize_t)length) {
PyErr_Clear();
goto end;
}
/* don't use strncpy() since png data may contain NUL bytes */
memcpy (data, buffer, (size_t)str_length);
status = CAIRO_STATUS_SUCCESS;
end:
Py_XDECREF(pystr);
PyGILState_Release(gstate);
return status;
}
/* METH_CLASS */
static PyObject *
image_surface_create_from_png (PyTypeObject *type, PyObject *args) {
cairo_surface_t *image_surface;
PyObject *file;
char *name;
if (!PyArg_ParseTuple (args, "O:ImageSurface.create_from_png", &file))
return NULL;
if (Pycairo_is_fspath (file)) {
if (!PyArg_ParseTuple(args, "O&:ImageSurface.create_from_png",
Pycairo_fspath_converter, &name))
return NULL;
Py_BEGIN_ALLOW_THREADS;
image_surface = cairo_image_surface_create_from_png (name);
Py_END_ALLOW_THREADS;
PyMem_Free(name);
return PycairoSurface_FromSurface (image_surface, NULL);
} else {
if (PyArg_ParseTuple (args, "O&:ImageSurface.create_from_png",
Pycairo_reader_converter, &file)) {
Py_BEGIN_ALLOW_THREADS;
image_surface = cairo_image_surface_create_from_png_stream (
_read_func, file);
Py_END_ALLOW_THREADS;
return PycairoSurface_FromSurface (image_surface, NULL);
} else {
PyErr_SetString(PyExc_TypeError,
"ImageSurface.create_from_png argument must be a "
"filename (str), file object, or an object that has a "
"\"read\" method (like StringIO)");
return NULL;
}
}
}
#endif /* CAIRO_HAS_PNG_FUNCTIONS */
/* METH_STATIC */
static PyObject *
image_surface_format_stride_for_width (PyObject *self, PyObject *args) {
cairo_format_t format;
int width, format_arg;
if (!PyArg_ParseTuple (args, "ii:format_stride_for_width",
&format_arg, &width))
return NULL;
format = (cairo_format_t)format_arg;
return PYCAIRO_PyLong_FromLong (cairo_format_stride_for_width (format, width));
}
static PyObject *
image_surface_get_data (PycairoImageSurface *o) {
#if PY_MAJOR_VERSION >= 3
cairo_surface_t *surface;
int height, stride;
unsigned char * buffer;
surface = o->surface;
buffer = cairo_image_surface_get_data (surface);
if (buffer == NULL) {
Py_RETURN_NONE;
}
height = cairo_image_surface_get_height (surface);
stride = cairo_image_surface_get_stride (surface);
return buffer_proxy_create_view((PyObject *)o, buffer, height * stride, 0);
#else
return PyBuffer_FromReadWriteObject((PyObject *)o, 0, Py_END_OF_BUFFER);
#endif
}
static PyObject *
image_surface_get_format (PycairoImageSurface *o) {
RETURN_INT_ENUM (Format, cairo_image_surface_get_format (o->surface));
}
static PyObject *
image_surface_get_height (PycairoImageSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_image_surface_get_height (o->surface));
}
static PyObject *
image_surface_get_stride (PycairoImageSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_image_surface_get_stride (o->surface));
}
static PyObject *
image_surface_get_width (PycairoImageSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_image_surface_get_width (o->surface));
}
#if PY_MAJOR_VERSION < 3
/* Buffer interface functions, used by ImageSurface.get_data() */
static Py_ssize_t
image_surface_buffer_getreadbuf (PycairoImageSurface *o, Py_ssize_t 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 Py_ssize_t
image_surface_buffer_getwritebuf (PycairoImageSurface *o, Py_ssize_t 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 Py_ssize_t
image_surface_buffer_getsegcount (PycairoImageSurface *o, Py_ssize_t *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 */
}
static Py_ssize_t
image_surface_buffer_getcharbuffer (PycairoImageSurface *o,
Py_ssize_t segment,
char **ptrptr) {
Py_ssize_t segment_size;
if (segment != 0) {
PyErr_SetString(PyExc_SystemError,
"accessing non-existent ImageSurface segment");
return -1;
}
image_surface_buffer_getsegcount (o, &segment_size);
return segment_size;
}
/* 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) image_surface_buffer_getcharbuffer,
};
#endif
static PyMethodDef image_surface_methods[] = {
{"create_for_data",(PyCFunction)image_surface_create_for_data,
METH_VARARGS | METH_CLASS},
#ifdef CAIRO_HAS_PNG_FUNCTIONS
{"create_from_png", (PyCFunction)image_surface_create_from_png,
METH_VARARGS | METH_CLASS},
#endif
{"format_stride_for_width",
(PyCFunction)image_surface_format_stride_for_width,
METH_VARARGS | METH_STATIC},
{"get_data", (PyCFunction)image_surface_get_data, METH_NOARGS},
{"get_format", (PyCFunction)image_surface_get_format, METH_NOARGS},
{"get_height", (PyCFunction)image_surface_get_height, METH_NOARGS},
{"get_stride", (PyCFunction)image_surface_get_stride, METH_NOARGS},
{"get_width", (PyCFunction)image_surface_get_width, METH_NOARGS},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoImageSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.ImageSurface", /* tp_name */
sizeof(PycairoImageSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
#if PY_MAJOR_VERSION < 3
&image_surface_as_buffer, /* tp_as_buffer */
#else
0, /* tp_as_buffer */
#endif
#if PY_MAJOR_VERSION < 3
Py_TPFLAGS_DEFAULT |
Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
#else
Py_TPFLAGS_DEFAULT, /* tp_flags */
#endif
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
image_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)image_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
/* Mapped Image Type*/
static PyObject *
mapped_image_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
PyErr_SetString(PyExc_TypeError,
"The MappedImage type cannot be instantiated");
return NULL;
}
static void
mapped_image_surface_dealloc (PycairoImageSurface *self) {
PycairoSurface *pybasesurface = (PycairoSurface *)(self->base);
if (cairo_surface_get_user_data (
self->surface, &surface_is_mapped_image) != NULL) {
cairo_surface_unmap_image (pybasesurface->surface, self->surface);
self->surface = NULL;
} else {
cairo_surface_destroy(self->surface);
self->surface = NULL;
}
Py_CLEAR (self->base);
Py_TYPE (self)->tp_free (self);
}
static PyObject *
mapped_image_surface_finish (PycairoSurface *self) {
PyErr_SetString(PyExc_RuntimeError,
"The MappedImage type cannot be finished, "
"use Surface.unmap_image instead");
return NULL;
}
static PyObject *
mapped_image_surface_ctx_exit (PycairoImageSurface *self, PyObject *args) {
PycairoSurface *pybasesurface = (PycairoSurface *)(self->base);
PyObject *subargs, *result;
subargs = Py_BuildValue("(O)", self);
if (subargs == NULL)
return NULL;
result = surface_unmap_image (pybasesurface, subargs);
Py_DECREF (subargs);
return result;
}
static PyMethodDef mapped_image_surface_methods[] = {
{"__exit__", (PyCFunction)mapped_image_surface_ctx_exit, METH_VARARGS},
{"finish", (PyCFunction)mapped_image_surface_finish, METH_NOARGS},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoMappedImageSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"__cairo__.MappedImageSurface", /* tp_name */
sizeof(PycairoImageSurface), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)
mapped_image_surface_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
mapped_image_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoImageSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)mapped_image_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_IMAGE_SURFACE */
/* Class PDFSurface(Surface) ---------------------------------------------- */
#ifdef CAIRO_HAS_PDF_SURFACE
#include <cairo-pdf.h>
static PyObject *
pdf_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
double width_in_points, height_in_points;
PyObject *file;
cairo_surface_t *sfc;
char *name;
if (!PyArg_ParseTuple (args, "Odd:PDFSurface.__new__",
&file, &width_in_points, &height_in_points))
return NULL;
if (Pycairo_is_fspath (file) || file == Py_None) {
if (!PyArg_ParseTuple (args, "O&dd:PDFSurface.__new__",
Pycairo_fspath_none_converter, &name,
&width_in_points, &height_in_points))
return NULL;
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_pdf_surface_create (name, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
PyMem_Free(name);
return PycairoSurface_FromSurface (sfc, NULL);
} else {
if (PyArg_ParseTuple (args, "O&dd:PDFSurface.__new__",
Pycairo_writer_converter, &file,
&width_in_points, &height_in_points)) {
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_pdf_surface_create_for_stream (
_write_func, file, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
return _surface_create_with_object (sfc, file);
} else {
PyErr_Clear ();
PyErr_SetString(PyExc_TypeError,
"PDFSurface argument 1 must be "
"None, or a filename (str), or "
"a file object, or an object that has a "
"\"write\" method (like StringIO).");
return NULL;
}
}
}
static PyObject *
pdf_surface_set_size (PycairoPDFSurface *o, PyObject *args) {
double width_in_points, height_in_points;
if (!PyArg_ParseTuple(args, "dd:PDFSurface.set_size", &width_in_points,
&height_in_points))
return NULL;
cairo_pdf_surface_set_size (o->surface, width_in_points,
height_in_points);
Py_RETURN_NONE;
}
static PyObject *
pdf_get_versions (PyObject *self) {
PyObject *list, *num;
const cairo_pdf_version_t *versions;
int i, num_versions;
Py_BEGIN_ALLOW_THREADS;
cairo_pdf_get_versions (&versions, &num_versions);
Py_END_ALLOW_THREADS;
list = PyList_New (num_versions);
if (list == NULL)
return NULL;
for (i=0; i < num_versions; i++) {
num = CREATE_INT_ENUM (PDFVersion, versions[i]);
if (num == NULL) {
Py_DECREF (list);
return NULL;
}
PyList_SET_ITEM (list, i, num);
}
return list;
}
static PyObject *
pdf_version_to_string (PyObject *self, PyObject *args) {
cairo_pdf_version_t version;
int version_arg;
const char *version_string;
if (!PyArg_ParseTuple (args, "i:PDFSurface.version_to_string", &version_arg))
return NULL;
version = (cairo_pdf_version_t)version_arg;
Py_BEGIN_ALLOW_THREADS;
version_string = cairo_pdf_version_to_string (version);
Py_END_ALLOW_THREADS;
if (version_string == NULL) {
PyErr_SetString (PyExc_ValueError, "invalid version");
return NULL;
}
return PYCAIRO_PyUnicode_FromString (version_string);
}
static PyObject *
pdf_surface_restrict_to_version (PycairoPDFSurface *o, PyObject *args) {
cairo_pdf_version_t version;
int version_arg;
if (!PyArg_ParseTuple (args, "i:PDFSurface.restrict_to_version",
&version_arg))
return NULL;
version = (cairo_pdf_version_t)version_arg;
Py_BEGIN_ALLOW_THREADS;
cairo_pdf_surface_restrict_to_version (o->surface, version);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR (o->surface);
Py_RETURN_NONE;
}
static PyMethodDef pdf_surface_methods[] = {
{"set_size", (PyCFunction)pdf_surface_set_size, METH_VARARGS},
{"get_versions", (PyCFunction)pdf_get_versions, METH_NOARGS | METH_STATIC},
{"version_to_string", (PyCFunction)pdf_version_to_string,
METH_VARARGS | METH_STATIC},
{"restrict_to_version", (PyCFunction)pdf_surface_restrict_to_version,
METH_VARARGS},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoPDFSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.PDFSurface", /* tp_name */
sizeof(PycairoPDFSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
pdf_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)pdf_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_PDF_SURFACE */
#ifdef CAIRO_HAS_SCRIPT_SURFACE
#include <cairo-script.h>
typedef PycairoSurface PycairoScriptSurface;
static PyObject *
script_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
cairo_content_t content;
int content_arg;
double width, height;
PyObject *pydevice;
if (!PyArg_ParseTuple (args, "O!idd:ScriptSurface.__new__",
&PycairoScriptDevice_Type, &pydevice, &content_arg, &width, &height))
return NULL;
content = (cairo_content_t)content_arg;
return PycairoSurface_FromSurface (
cairo_script_surface_create (
((PycairoDevice*)pydevice)->device, content, width, height),
NULL);
}
static PyObject *
script_surface_create_for_target (PyTypeObject *type, PyObject *args) {
PyObject *pydevice, *target;
if (!PyArg_ParseTuple (args, "O!O!:ScriptSurface.create_for_target",
&PycairoScriptDevice_Type, &pydevice, &PycairoSurface_Type, &target))
return NULL;
return PycairoSurface_FromSurface (
cairo_script_surface_create_for_target (
((PycairoDevice*)pydevice)->device, ((PycairoSurface*)target)->surface),
NULL);
}
static PyMethodDef script_surface_methods[] = {
{"create_for_target",
(PyCFunction)script_surface_create_for_target, METH_VARARGS | METH_CLASS},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoScriptSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.ScriptSurface", /* tp_name */
sizeof(PycairoScriptSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
script_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)script_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_SCRIPT_SURFACE */
/* Class PSSurface(Surface) ----------------------------------------------- */
#ifdef CAIRO_HAS_PS_SURFACE
#include <cairo-ps.h>
static PyObject *
ps_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
double width_in_points, height_in_points;
PyObject *file;
cairo_surface_t *sfc;
char *name;
if (!PyArg_ParseTuple (args, "Odd:PSSurface.__new__",
&file, &width_in_points, &height_in_points))
return NULL;
if (Pycairo_is_fspath (file) || file == Py_None) {
if (!PyArg_ParseTuple (args, "O&dd:PSSurface.__new__",
Pycairo_fspath_none_converter, &name,
&width_in_points, &height_in_points))
return NULL;
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_ps_surface_create (name, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
PyMem_Free(name);
return PycairoSurface_FromSurface (sfc, NULL);
} else {
if (PyArg_ParseTuple (args, "O&dd:PSSurface.__new__",
Pycairo_writer_converter, &file,
&width_in_points, &height_in_points)) {
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_ps_surface_create_for_stream (
_write_func, file, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
return _surface_create_with_object (sfc, file);
} else {
PyErr_Clear ();
PyErr_SetString(PyExc_TypeError,
"PSSurface argument 1 must be "
"None, or a filename (str), or "
"a file object, or an object that has a "
"\"write\" method (like StringIO).");
return NULL;
}
}
}
static PyObject *
ps_surface_dsc_begin_page_setup (PycairoPSSurface *o) {
cairo_ps_surface_dsc_begin_page_setup (o->surface);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
ps_surface_dsc_begin_setup (PycairoPSSurface *o) {
cairo_ps_surface_dsc_begin_setup (o->surface);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
ps_surface_dsc_comment (PycairoPSSurface *o, PyObject *args) {
const char *comment;
if (!PyArg_ParseTuple(args, "s:PSSurface.dsc_comment", &comment))
return NULL;
cairo_ps_surface_dsc_comment (o->surface, comment);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
ps_surface_get_eps (PycairoPSSurface *o) {
PyObject *eps = cairo_ps_surface_get_eps (o->surface) ? Py_True : Py_False;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_INCREF(eps);
return eps;
}
/* METH_STATIC */
static PyObject *
ps_level_to_string (PyObject *self, PyObject *args) {
cairo_ps_level_t level;
int level_arg;
const char *s;
if (!PyArg_ParseTuple (args, "i:PSSurface.level_to_string", &level_arg))
return NULL;
level = (cairo_ps_level_t)level_arg;
s = cairo_ps_level_to_string (level);
if (s == NULL){
PyErr_SetString(PyExc_ValueError, "level_to_string: "
"invalid level argument");
return NULL;
}
return PYCAIRO_PyUnicode_FromString(s);
}
static PyObject *
ps_surface_restrict_to_level (PycairoPSSurface *o, PyObject *args) {
cairo_ps_level_t level;
int level_arg;
if (!PyArg_ParseTuple (args, "i:PSSurface.restrict_to_level", &level_arg))
return NULL;
level = (cairo_ps_level_t)level_arg;
cairo_ps_surface_restrict_to_level (o->surface, level);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
ps_surface_set_eps (PycairoPSSurface *o, PyObject *args) {
PyObject *py_eps;
if (!PyArg_ParseTuple(args, "O!:PSSurface.set_eps",
&PyBool_Type, &py_eps))
return NULL;
cairo_ps_surface_set_eps (o->surface, (py_eps == Py_True));
RETURN_NULL_IF_CAIRO_SURFACE_ERROR(o->surface);
Py_RETURN_NONE;
}
static PyObject *
ps_surface_set_size (PycairoPSSurface *o, PyObject *args) {
double width_in_points, height_in_points;
if (!PyArg_ParseTuple(args, "dd:PSSurface.set_size",
&width_in_points, &height_in_points))
return NULL;
cairo_ps_surface_set_size (o->surface, width_in_points, height_in_points);
Py_RETURN_NONE;
}
static PyObject *
ps_get_levels (PyObject *self) {
PyObject *list, *num;
const cairo_ps_level_t *levels;
int i, num_levels;
Py_BEGIN_ALLOW_THREADS;
cairo_ps_get_levels (&levels, &num_levels);
Py_END_ALLOW_THREADS;
list = PyList_New (num_levels);
if (list == NULL)
return NULL;
for (i=0; i < num_levels; i++) {
num = CREATE_INT_ENUM (PSLevel, levels[i]);
if (num == NULL) {
Py_DECREF (list);
return NULL;
}
PyList_SET_ITEM (list, i, num);
}
return list;
}
static PyMethodDef ps_surface_methods[] = {
{"dsc_begin_page_setup",
(PyCFunction)ps_surface_dsc_begin_page_setup, METH_NOARGS },
{"dsc_begin_setup", (PyCFunction)ps_surface_dsc_begin_setup, METH_NOARGS },
{"dsc_comment", (PyCFunction)ps_surface_dsc_comment, METH_VARARGS },
{"get_eps", (PyCFunction)ps_surface_get_eps, METH_NOARGS },
{"ps_level_to_string", (PyCFunction)ps_level_to_string,
METH_VARARGS | METH_STATIC},
{"level_to_string", (PyCFunction)ps_level_to_string,
METH_VARARGS | METH_STATIC},
{"restrict_to_level", (PyCFunction)ps_surface_restrict_to_level,
METH_VARARGS },
{"set_eps", (PyCFunction)ps_surface_set_eps, METH_VARARGS },
{"set_size", (PyCFunction)ps_surface_set_size, METH_VARARGS },
{"get_levels", (PyCFunction)ps_get_levels, METH_NOARGS | METH_STATIC},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoPSSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.PSSurface", /* tp_name */
sizeof(PycairoPSSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
ps_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)ps_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_PS_SURFACE */
/* Class RecordingSurface(Surface) ---------------------------------------- */
#ifdef CAIRO_HAS_RECORDING_SURFACE
static PyObject *
recording_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
cairo_content_t content;
cairo_rectangle_t extents, *extents_ptr;
cairo_surface_t *sfc;
int content_arg;
PyObject *extents_tuple;
if (!PyArg_ParseTuple (args, "iO:RecordingSurface.__new__",
&content_arg, &extents_tuple))
return NULL;
content = (cairo_content_t)content_arg;
if (extents_tuple == Py_None) {
extents_ptr = NULL;
} else {
if (!PyArg_ParseTuple(extents_tuple, "dddd", &extents.x, &extents.y,
&extents.width, &extents.height)) {
PyErr_SetString(PyExc_TypeError,
"RecordingSurface() argument 2 must be a "
"4-tuple of float");
return NULL;
}
extents_ptr = &extents;
}
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_recording_surface_create (content, extents_ptr);
Py_END_ALLOW_THREADS;
return PycairoSurface_FromSurface (sfc, NULL);
}
static PyObject *
recording_surface_ink_extents (PycairoRecordingSurface *o) {
double x0, y0, width, height;
cairo_recording_surface_ink_extents(o->surface, &x0, &y0, &width, &height);
return Py_BuildValue("(dddd)", x0, y0, width, height);
}
static PyObject *
recording_surface_get_extents (PycairoRecordingSurface *o) {
cairo_rectangle_t extents;
cairo_bool_t result;
PyObject *rect, *args;
Py_BEGIN_ALLOW_THREADS;
result = cairo_recording_surface_get_extents (o->surface, &extents);
Py_END_ALLOW_THREADS;
if (!result) {
Py_RETURN_NONE;
}
args = Py_BuildValue(
"(dddd)", extents.x, extents.y, extents.width, extents.height);
if (args == NULL)
return NULL;
rect = PyObject_Call((PyObject *)&PycairoRectangle_Type, args, NULL);
Py_DECREF (args);
return rect;
}
static PyMethodDef recording_surface_methods[] = {
{"ink_extents", (PyCFunction)recording_surface_ink_extents, METH_NOARGS },
{"get_extents", (PyCFunction)recording_surface_get_extents, METH_NOARGS },
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoRecordingSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.RecordingSurface", /* tp_name */
sizeof(PycairoRecordingSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
recording_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)recording_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_RECORDING_SURFACE */
/* Class SVGSurface(Surface) ----------------------------------------------- */
#ifdef CAIRO_HAS_SVG_SURFACE
#include <cairo-svg.h>
static PyObject *
svg_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
double width_in_points, height_in_points;
PyObject *file;
cairo_surface_t *sfc;
char *name;
if (!PyArg_ParseTuple (args, "Odd:SVGSurface.__new__",
&file, &width_in_points, &height_in_points))
return NULL;
if (Pycairo_is_fspath (file) || file == Py_None) {
if (!PyArg_ParseTuple (args, "O&dd:SVGSurface.__new__",
Pycairo_fspath_none_converter, &name,
&width_in_points, &height_in_points))
return NULL;
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_svg_surface_create (name, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
PyMem_Free(name);
return PycairoSurface_FromSurface (sfc, NULL);
} else {
if (PyArg_ParseTuple (args, "O&dd:SVGSurface.__new__",
Pycairo_writer_converter, &file,
&width_in_points, &height_in_points)) {
Py_BEGIN_ALLOW_THREADS;
sfc = cairo_svg_surface_create_for_stream (
_write_func, file, width_in_points, height_in_points);
Py_END_ALLOW_THREADS;
return _surface_create_with_object (sfc, file);
} else {
PyErr_Clear ();
PyErr_SetString(PyExc_TypeError,
"SVGSurface argument 1 must be "
"None, or a filename (str), or "
"a file object, or an object that has a "
"\"write\" method (like StringIO).");
return NULL;
}
}
}
static PyObject *
svg_get_versions (PyObject *self) {
PyObject *list, *num;
const cairo_svg_version_t *versions;
int i, num_versions;
Py_BEGIN_ALLOW_THREADS;
cairo_svg_get_versions (&versions, &num_versions);
Py_END_ALLOW_THREADS;
list = PyList_New (num_versions);
if (list == NULL)
return NULL;
for (i=0; i < num_versions; i++) {
num = CREATE_INT_ENUM (SVGVersion, versions[i]);
if (num == NULL) {
Py_DECREF (list);
return NULL;
}
PyList_SET_ITEM (list, i, num);
}
return list;
}
static PyObject *
svg_version_to_string (PyObject *self, PyObject *args) {
cairo_svg_version_t version;
int version_arg;
const char *version_string;
if (!PyArg_ParseTuple (args, "i:SVGSurface.version_to_string", &version_arg))
return NULL;
version = (cairo_svg_version_t)version_arg;
Py_BEGIN_ALLOW_THREADS;
version_string = cairo_svg_version_to_string (version);
Py_END_ALLOW_THREADS;
if (version_string == NULL) {
PyErr_SetString (PyExc_ValueError, "invalid version");
return NULL;
}
return PYCAIRO_PyUnicode_FromString (version_string);
}
static PyObject *
svg_surface_restrict_to_version (PycairoPDFSurface *o, PyObject *args) {
cairo_svg_version_t version;
int version_arg;
if (!PyArg_ParseTuple (args, "i:SVGSurface.restrict_to_version",
&version_arg))
return NULL;
version = (cairo_svg_version_t)version_arg;
Py_BEGIN_ALLOW_THREADS;
cairo_svg_surface_restrict_to_version (o->surface, version);
Py_END_ALLOW_THREADS;
RETURN_NULL_IF_CAIRO_SURFACE_ERROR (o->surface);
Py_RETURN_NONE;
}
static PyMethodDef svg_surface_methods[] = {
{"get_versions", (PyCFunction)svg_get_versions, METH_NOARGS | METH_STATIC},
{"version_to_string", (PyCFunction)svg_version_to_string,
METH_VARARGS | METH_STATIC},
{"restrict_to_version", (PyCFunction)svg_surface_restrict_to_version,
METH_VARARGS},
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoSVGSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.SVGSurface", /* tp_name */
sizeof(PycairoSVGSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
svg_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)svg_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_SVG_SURFACE */
#ifdef CAIRO_HAS_WIN32_SURFACE
#include <cairo-win32.h>
static int
convert_pyobject_to_hdc (PyObject *obj, HDC* addr) {
HDC temp = PyLong_AsVoidPtr(obj);
if (PyErr_Occurred() != NULL)
return 0;
*addr = temp;
return 1;
}
/* Class Win32Surface(Surface) -------------------------------------------- */
static PyObject *
win32_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
HDC hdc;
if (!PyArg_ParseTuple(args, "O&:Win32Surface.__new__",
convert_pyobject_to_hdc, &hdc))
return NULL;
return PycairoSurface_FromSurface (
cairo_win32_surface_create (hdc), NULL);
}
static PyMethodDef win32_surface_methods[] = {
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoWin32Surface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.Win32Surface", /* tp_name */
sizeof(PycairoWin32Surface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
win32_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)win32_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
/* Class Win32PrintingSurface(Surface) ------------------------------------ */
static PyObject *
win32_printing_surface_new (PyTypeObject *type, PyObject *args,
PyObject *kwds) {
HDC hdc;
if (!PyArg_ParseTuple(args, "O&:Win32PrintingSurface.__new__",
convert_pyobject_to_hdc, &hdc))
return NULL;
return PycairoSurface_FromSurface (
cairo_win32_printing_surface_create (hdc), NULL);
}
static PyMethodDef win32_printing_surface_methods[] = {
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoWin32PrintingSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.Win32PrintingSurface", /* tp_name */
sizeof(PycairoWin32PrintingSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
win32_printing_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)win32_printing_surface_new,/* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_WIN32_SURFACE */
/* Class XCBSurface(Surface) --------------------------------------------- */
#ifdef CAIRO_HAS_XCB_SURFACE
#include <cairo-xcb.h>
#ifdef HAVE_XPYB
/** Convert a Python object from xpyb to a C struct matching libxcb type.
* The object must be referenced if you want to keep returned data away from
* garbage collection.
* @param obj The object to convert.
* @param len The size of the object read by Python.
* @return A pointer to that data.
*/
const void *
xpyb2struct(PyObject *obj, Py_ssize_t *len)
{
const void *data;
#if PY_MAJOR_VERSION >= 3
// buffer function disabled
return NULL;
#endif
if (PyObject_AsReadBuffer(obj, &data, len) < 0)
return NULL;
return data;
}
static int
have_xpyb(void)
{
static int have_xpyb = -1;
if(have_xpyb == -1) {
/* Get type from xpyb */
xpyb_IMPORT;
/* Some types are not defined in the CAPI */
PyObject *xpyb_module = PyImport_ImportModule("xcb.xproto");
if (xpyb_module) {
PyObject *dict = PyModule_GetDict(xpyb_module);
xpybVISUALTYPE_type = PyDict_GetItemString(dict, "VISUALTYPE");
Py_DECREF(xpyb_module);
have_xpyb = 1;
}
else
have_xpyb = 0;
}
return have_xpyb;
}
#endif
static PyObject *
xcb_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
#ifdef HAVE_XPYB
int width, height;
xcb_drawable_t drawable;
PyObject *visual;
xpybConn *conn;
if(!have_xpyb())
return NULL;
if (!PyArg_ParseTuple(args, "O!IO!ii:XCBSurface.__new__",
xpyb_CAPI->xpybConn_type, &conn,
&drawable,
xpybVISUALTYPE_type, &visual,
&width, &height))
return NULL;
/* Convert Python object VISUALTYPE to a xcb_visualtype_t */
Py_ssize_t length;
xcb_visualtype_t *visualtype = (xcb_visualtype_t *) xpyb2struct(visual, &length);
if (length < sizeof(xcb_visualtype_t))
return NULL;
return PycairoSurface_FromSurface (
cairo_xcb_surface_create (conn->conn, drawable, visualtype,
width, height), NULL);
#else
PyErr_SetString(PyExc_TypeError,
"pycairo was not compiled with xpyb support");
return NULL;
#endif
}
static PyObject *
xcb_surface_set_size (PycairoXCBSurface *o, PyObject *args) {
int width, height;
if (!PyArg_ParseTuple(args, "ii:XCBSurface.set_size", &width, &height))
return NULL;
cairo_xcb_surface_set_size (o->surface, width, height);
Py_RETURN_NONE;
}
static PyMethodDef xcb_surface_methods[] = {
{"set_size", (PyCFunction)xcb_surface_set_size, METH_VARARGS },
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoXCBSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.XCBSurface", /* tp_name */
sizeof(PycairoXCBSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
xcb_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)xcb_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_XCB_SURFACE */
/* Class XlibSurface(Surface) --------------------------------------------- */
#ifdef CAIRO_HAS_XLIB_SURFACE
#include <cairo-xlib.h>
static PyObject *
xlib_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
PyErr_SetString(PyExc_TypeError,
"The XlibSurface type cannot be directly instantiated");
return NULL;
}
static PyObject *
xlib_surface_get_depth (PycairoXlibSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_xlib_surface_get_depth (o->surface));
}
static PyObject *
xlib_surface_get_height (PycairoXlibSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_xlib_surface_get_height (o->surface));
}
static PyObject *
xlib_surface_get_width (PycairoXlibSurface *o) {
return PYCAIRO_PyLong_FromLong (cairo_xlib_surface_get_width (o->surface));
}
static PyMethodDef xlib_surface_methods[] = {
{"get_depth", (PyCFunction)xlib_surface_get_depth, METH_NOARGS },
{"get_height",(PyCFunction)xlib_surface_get_height, METH_NOARGS },
{"get_width", (PyCFunction)xlib_surface_get_width, METH_NOARGS },
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoXlibSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.XlibSurface", /* tp_name */
sizeof(PycairoXlibSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
xlib_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)xlib_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_XLIB_SURFACE */
#ifdef CAIRO_HAS_TEE_SURFACE
#include <cairo-tee.h>
static PyObject *
tee_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
PyObject *pysurface;
if (!PyArg_ParseTuple (args, "O!:TeeSurface.__new__",
&PycairoSurface_Type, &pysurface))
return NULL;
return PycairoSurface_FromSurface (
cairo_tee_surface_create(((PycairoSurface*)pysurface)->surface),
NULL);
}
static PyObject *
tee_surface_add (PycairoTeeSurface *obj, PyObject *args) {
PyObject *pysurface;
if (!PyArg_ParseTuple(args, "O!:TeeSurface.add",
&PycairoSurface_Type, &pysurface))
return NULL;
cairo_tee_surface_add (obj->surface, ((PycairoSurface*)pysurface)->surface);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR (obj->surface);
Py_RETURN_NONE;
}
static PyObject *
tee_surface_remove (PycairoTeeSurface *obj, PyObject *args) {
PyObject *pysurface;
if (!PyArg_ParseTuple(args, "O!:TeeSurface.remove",
&PycairoSurface_Type, &pysurface))
return NULL;
cairo_tee_surface_remove (obj->surface, ((PycairoSurface*)pysurface)->surface);
RETURN_NULL_IF_CAIRO_SURFACE_ERROR (obj->surface);
Py_RETURN_NONE;
}
static PyObject *
tee_surface_index (PycairoTeeSurface *obj, PyObject *args) {
unsigned int index;
if (!PyArg_ParseTuple(args, "I:TeeSurface.index", &index))
return NULL;
return PycairoSurface_FromSurface (
cairo_surface_reference (cairo_tee_surface_index (obj->surface, index)),
NULL);
}
static PyMethodDef tee_surface_methods[] = {
{"add", (PyCFunction)tee_surface_add, METH_VARARGS },
{"remove", (PyCFunction)tee_surface_remove, METH_VARARGS },
{"index", (PyCFunction)tee_surface_index, METH_VARARGS },
{NULL, NULL, 0, NULL},
};
PyTypeObject PycairoTeeSurface_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"cairo.TeeSurface", /* tp_name */
sizeof(PycairoTeeSurface), /* tp_basicsize */
0, /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
tee_surface_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
&PycairoSurface_Type, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
(newfunc)tee_surface_new, /* tp_new */
0, /* tp_free */
0, /* tp_is_gc */
0, /* tp_bases */
};
#endif /* CAIRO_HAS_TEE_SURFACE */