From ac97a979a5a446749682effd127a6d9ba23ea26a Mon Sep 17 00:00:00 2001 From: Steve Chaplin Date: Tue, 25 Aug 2009 17:19:02 +0800 Subject: Remove 'pycairo-' prefix from filenames. --- src/Makefile.am | 16 +- src/cairomodule.c | 2 +- src/context.c | 1446 +++++++++++++++++++++++++++++++++++++++++++++++++ src/font.c | 611 +++++++++++++++++++++ src/matrix.c | 348 ++++++++++++ src/path.c | 329 +++++++++++ src/pattern.c | 598 ++++++++++++++++++++ src/private.h | 161 ++++++ src/pycairo-context.c | 1446 ------------------------------------------------- src/pycairo-font.c | 611 --------------------- src/pycairo-matrix.c | 348 ------------ src/pycairo-path.c | 329 ----------- src/pycairo-pattern.c | 598 -------------------- src/pycairo-private.h | 161 ------ src/pycairo-surface.c | 1218 ----------------------------------------- src/surface.c | 1218 +++++++++++++++++++++++++++++++++++++++++ 16 files changed, 4720 insertions(+), 4720 deletions(-) create mode 100644 src/context.c create mode 100644 src/font.c create mode 100644 src/matrix.c create mode 100644 src/path.c create mode 100644 src/pattern.c create mode 100644 src/private.h delete mode 100644 src/pycairo-context.c delete mode 100644 src/pycairo-font.c delete mode 100644 src/pycairo-matrix.c delete mode 100644 src/pycairo-path.c delete mode 100644 src/pycairo-pattern.c delete mode 100644 src/pycairo-private.h delete mode 100644 src/pycairo-surface.c create mode 100644 src/surface.c diff --git a/src/Makefile.am b/src/Makefile.am index 68a123f..2340563 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,12 +11,12 @@ _cairo_la_LDFLAGS = -module -avoid-version -export-symbols-regex init_cairo _cairo_la_LIBADD = $(CAIRO_LIBS) _cairo_la_CPPFLAGS = $(PYTHON_INCLUDES) $(CAIRO_CFLAGS) _cairo_la_SOURCES = \ + cairomodule.c \ + context.c \ + font.c \ + path.c \ + pattern.c \ + matrix.c \ + private.h \ pycairo.h \ - pycairo-private.h \ - pycairo-context.c \ - pycairo-font.c \ - pycairo-matrix.c \ - pycairo-path.c \ - pycairo-pattern.c \ - pycairo-surface.c \ - cairomodule.c + surface.c diff --git a/src/cairomodule.c b/src/cairomodule.c index 4c3b2f7..9cc506b 100644 --- a/src/cairomodule.c +++ b/src/cairomodule.c @@ -34,7 +34,7 @@ #ifdef HAVE_CONFIG_H # include #endif -#include "pycairo-private.h" +#include "private.h" /* to read CAIRO_PS_LEVEL_* constants */ #ifdef CAIRO_HAS_PS_SURFACE diff --git a/src/context.c b/src/context.c new file mode 100644 index 0000000..641addc --- /dev/null +++ b/src/context.c @@ -0,0 +1,1446 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2003 James Henstridge, 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 + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "private.h" + + +/* PycairoContext_FromContext + * Create a new PycairoContext from a cairo_t + * ctx - a cairo_t to 'wrap' into a Python object. + * It is unreferenced if the PycairoContext creation fails, or if + * the cairo_t has an error status. + * type - a pointer to the type to instantiate. + * It can be &PycairoContext_Type, or a PycairoContext_Type subtype. + * (cairo.Context or a cairo.Context subclass) + * base - the base object used to create the context, or NULL. + * it is referenced to keep it alive while the cairo_t is being used + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoContext_FromContext(cairo_t *ctx, PyTypeObject *type, PyObject *base) { + PyObject *o; + + assert (ctx != NULL); + + if (Pycairo_Check_Status (cairo_status (ctx))) { + cairo_destroy (ctx); + return NULL; + } + + o = PycairoContext_Type.tp_alloc (type, 0); + if (o) { + ((PycairoContext *)o)->ctx = ctx; + Py_XINCREF(base); + ((PycairoContext *)o)->base = base; + } else { + cairo_destroy (ctx); + } + return o; +} + +static void +pycairo_dealloc(PycairoContext *o) { + if (o->ctx) { + cairo_destroy(o->ctx); + o->ctx = NULL; + } + Py_CLEAR(o->base); + + o->ob_type->tp_free((PyObject *)o); +} + +static PyObject * +pycairo_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PycairoSurface *s; + if (!PyArg_ParseTuple(args, "O!:Context.__new__", + &PycairoSurface_Type, &s)) + return NULL; + return PycairoContext_FromContext (cairo_create (s->surface), type, NULL); +} + +static PyObject * +pycairo_append_path (PycairoContext *o, PyObject *args) { + PycairoPath *p; + + if (!PyArg_ParseTuple(args, "O!:Context.append_path", + &PycairoPath_Type, &p)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + cairo_append_path (o->ctx, p->path); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_arc (PycairoContext *o, PyObject *args) { + double xc, yc, radius, angle1, angle2; + + if (!PyArg_ParseTuple (args, "ddddd:Context.arc", + &xc, &yc, &radius, &angle1, &angle2)) + return NULL; + + cairo_arc (o->ctx, xc, yc, radius, angle1, angle2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_arc_negative (PycairoContext *o, PyObject *args) { + double xc, yc, radius, angle1, angle2; + + if (!PyArg_ParseTuple (args, "ddddd:Context.arc_negative", + &xc, &yc, &radius, &angle1, &angle2)) + return NULL; + + cairo_arc_negative (o->ctx, xc, yc, radius, angle1, angle2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_clip (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_clip (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_clip_extents (PycairoContext *o) { + double x1, y1, x2, y2; + cairo_clip_extents (o->ctx, &x1, &y1, &x2, &y2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddd)", x1, y1, x2, y2); +} + +static PyObject * +pycairo_clip_preserve (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_clip_preserve (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_close_path (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_close_path (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_copy_clip_rectangle_list (PycairoContext *o) { + int i; + PyObject *rv = NULL; + cairo_rectangle_t *r; + cairo_rectangle_list_t *rlist = cairo_copy_clip_rectangle_list (o->ctx); + if (rlist->status != CAIRO_STATUS_SUCCESS) { + Pycairo_Check_Status (rlist->status); + goto exit; + } + + rv = PyTuple_New(rlist->num_rectangles); + if (rv == NULL) + goto exit; + + for (i = 0, r = rlist->rectangles; i < rlist->num_rectangles; i++, r++) { + PyObject *py_rect = Py_BuildValue("(dddd)", r->x, r->y, + r->width, r->height); + if (py_rect == NULL) { + Py_CLEAR(rv); + goto exit; + } + PyTuple_SET_ITEM (rv, i, py_rect); + } + exit: + cairo_rectangle_list_destroy(rlist); + return rv; +} + +static PyObject * +pycairo_copy_page (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_copy_page (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_copy_path (PycairoContext *o) { + cairo_path_t *cp; + Py_BEGIN_ALLOW_THREADS; + cp = cairo_copy_path (o->ctx); + Py_END_ALLOW_THREADS; + return PycairoPath_FromPath (cp); +} + +static PyObject * +pycairo_copy_path_flat (PycairoContext *o) { + cairo_path_t *cp; + Py_BEGIN_ALLOW_THREADS; + cp = cairo_copy_path_flat (o->ctx); + Py_END_ALLOW_THREADS; + return PycairoPath_FromPath (cp); +} + +static PyObject * +pycairo_curve_to (PycairoContext *o, PyObject *args) { + double x1, y1, x2, y2, x3, y3; + + if (!PyArg_ParseTuple (args, "dddddd:Context.curve_to", + &x1, &y1, &x2, &y2, &x3, &y3)) + return NULL; + + cairo_curve_to (o->ctx, x1, y1, x2, y2, x3, y3); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_device_to_user(PycairoContext *o, PyObject *args) { + double x, y; + + if (!PyArg_ParseTuple(args, "dd:Context.device_to_user", &x, &y)) + return NULL; + + cairo_device_to_user(o->ctx, &x, &y); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dd)", x, y); +} + +static PyObject * +pycairo_device_to_user_distance (PycairoContext *o, PyObject *args) { + double dx, dy; + + if (!PyArg_ParseTuple (args, "dd:Context.device_to_user_distance", + &dx, &dy)) + return NULL; + + cairo_device_to_user_distance (o->ctx, &dx, &dy); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dd)", dx, dy); +} + +static PyObject * +pycairo_fill (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_fill (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_fill_extents (PycairoContext *o) { + double x1, y1, x2, y2; + cairo_fill_extents (o->ctx, &x1, &y1, &x2, &y2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddd)", x1, y1, x2, y2); +} + +static PyObject * +pycairo_fill_preserve (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_fill_preserve (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_font_extents (PycairoContext *o) { + cairo_font_extents_t e; + + cairo_font_extents (o->ctx, &e); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(ddddd)", e.ascent, e.descent, e.height, + e.max_x_advance, e.max_y_advance); +} + +static PyObject * +pycairo_get_antialias (PycairoContext *o) { + return PyInt_FromLong (cairo_get_antialias (o->ctx)); +} + +static PyObject * +pycairo_get_current_point (PycairoContext *o) { + double x, y; + cairo_get_current_point (o->ctx, &x, &y); + return Py_BuildValue("(dd)", x, y); +} + +static PyObject * +pycairo_get_dash (PycairoContext *o) { + double *dashes = NULL, offset; + int count, i; + PyObject *py_dashes = NULL, *rv = NULL; + + count = cairo_get_dash_count (o->ctx); + dashes = PyMem_Malloc (count * sizeof(double)); + if (dashes == NULL) + return PyErr_NoMemory(); + + cairo_get_dash (o->ctx, dashes, &offset); + py_dashes = PyTuple_New(count); + if (py_dashes == NULL) + goto exit; + + for (i = 0; i < count; i++) { + PyObject *dash = PyFloat_FromDouble(dashes[i]); + if (dash == NULL) + goto exit; + PyTuple_SET_ITEM (py_dashes, i, dash); + } + rv = Py_BuildValue("(Od)", py_dashes, offset); + + exit: + PyMem_Free (dashes); + Py_XDECREF(py_dashes); + return rv; +} + +static PyObject * +pycairo_get_dash_count (PycairoContext *o) { + return PyInt_FromLong (cairo_get_dash_count (o->ctx)); +} + +static PyObject * +pycairo_get_fill_rule (PycairoContext *o) { + return PyInt_FromLong(cairo_get_fill_rule (o->ctx)); +} + +static PyObject * +pycairo_get_font_face (PycairoContext *o) { + return PycairoFontFace_FromFontFace ( + cairo_font_face_reference (cairo_get_font_face (o->ctx))); +} + +static PyObject * +pycairo_get_font_matrix (PycairoContext *o) { + cairo_matrix_t matrix; + cairo_get_font_matrix (o->ctx, &matrix); + return PycairoMatrix_FromMatrix (&matrix); +} + +static PyObject * +pycairo_get_font_options (PycairoContext *o) { + cairo_font_options_t *options = cairo_font_options_create(); + cairo_get_font_options (o->ctx, options); + /* there is no reference fn */ + return PycairoFontOptions_FromFontOptions (options); +} + +static PyObject * +pycairo_get_group_target (PycairoContext *o) { + cairo_surface_t *surface = cairo_get_group_target (o->ctx); + if (surface != NULL) + return PycairoSurface_FromSurface (cairo_surface_reference (surface), + NULL); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_get_line_cap (PycairoContext *o) { + return PyInt_FromLong(cairo_get_line_cap (o->ctx)); +} + +static PyObject * +pycairo_get_line_join (PycairoContext *o) { + return PyInt_FromLong(cairo_get_line_join (o->ctx)); +} + +static PyObject * +pycairo_get_line_width (PycairoContext *o) { + return PyFloat_FromDouble(cairo_get_line_width (o->ctx)); +} + +static PyObject * +pycairo_get_matrix (PycairoContext *o) { + cairo_matrix_t matrix; + cairo_get_matrix (o->ctx, &matrix); + return PycairoMatrix_FromMatrix (&matrix); +} + +static PyObject * +pycairo_get_miter_limit (PycairoContext *o) { + return PyFloat_FromDouble (cairo_get_miter_limit (o->ctx)); +} + +static PyObject * +pycairo_get_operator (PycairoContext *o) { + return PyInt_FromLong (cairo_get_operator (o->ctx)); +} + +static PyObject * +pycairo_get_scaled_font (PycairoContext *o) { + return PycairoScaledFont_FromScaledFont ( + cairo_scaled_font_reference (cairo_get_scaled_font (o->ctx))); +} + +static PyObject * +pycairo_get_source (PycairoContext *o) { + return PycairoPattern_FromPattern ( + cairo_pattern_reference (cairo_get_source (o->ctx)), NULL); +} + +static PyObject * +pycairo_get_target (PycairoContext *o) { + return PycairoSurface_FromSurface ( + cairo_surface_reference (cairo_get_target (o->ctx)), + NULL); +} + +static PyObject * +pycairo_get_tolerance (PycairoContext *o) { + return PyFloat_FromDouble (cairo_get_tolerance (o->ctx)); +} + +/* read a Python sequence of (i,x,y) sequences + * return cairo_glyph_t * + * num_glyphs + * must call PyMem_Free(glyphs) when finished using the glyphs + */ +static cairo_glyph_t * +_PyGlyphs_AsGlyphs (PyObject *py_object, int *num_glyphs) +{ + int length, i; + cairo_glyph_t *glyphs = NULL, *glyph; + PyObject *py_glyphs, *py_seq = NULL; + + py_glyphs = PySequence_Fast (py_object, "glyphs must be a sequence"); + if (py_glyphs == NULL) + return NULL; + + length = PySequence_Fast_GET_SIZE(py_glyphs); + if (*num_glyphs < 0 || *num_glyphs > length) + *num_glyphs = length; + + glyphs = PyMem_Malloc (*num_glyphs * sizeof(cairo_glyph_t)); + if (glyphs == NULL) { + PyErr_NoMemory(); + goto error; + } + for (i = 0, glyph = glyphs; i < *num_glyphs; i++, glyph++) { + PyObject *py_item = PySequence_Fast_GET_ITEM(py_glyphs, i); + py_seq = PySequence_Fast (py_item, "glyph items must be a sequence"); + if (py_seq == NULL) + goto error; + if (PySequence_Fast_GET_SIZE(py_seq) != 3) { + PyErr_SetString(PyExc_ValueError, + "each glyph item must be an (i,x,y) sequence"); + goto error; + } + glyph->index = PyInt_AsLong(PySequence_Fast_GET_ITEM(py_seq, 0)); + glyph->x = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_seq, 1)); + glyph->y = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_seq, 2)); + if (PyErr_Occurred()) + goto error; + Py_DECREF(py_seq); + } + Py_DECREF(py_glyphs); + return glyphs; + error: + Py_DECREF(py_glyphs); + Py_XDECREF(py_seq); + PyMem_Free(glyphs); + return NULL; +} + +static PyObject * +pycairo_glyph_extents (PycairoContext *o, PyObject *args) { + int num_glyphs = -1; + cairo_glyph_t *glyphs; + cairo_text_extents_t extents; + PyObject *py_object; + + if (!PyArg_ParseTuple (args, "O|i:Context.glyph_extents", + &py_object, &num_glyphs)) + return NULL; + + glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); + if (glyphs == NULL) + return NULL; + cairo_glyph_extents (o->ctx, glyphs, num_glyphs, &extents); + PyMem_Free (glyphs); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, + extents.width, extents.height, extents.x_advance, + extents.y_advance); +} + +static PyObject * +pycairo_glyph_path (PycairoContext *o, PyObject *args) { + int num_glyphs = -1; + cairo_glyph_t *glyphs; + PyObject *py_object; + + if (!PyArg_ParseTuple (args, "O|i:Context.glyph_path", + &py_object, &num_glyphs)) + return NULL; + + glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); + if (glyphs == NULL) + return NULL; + cairo_glyph_path (o->ctx, glyphs, num_glyphs); + PyMem_Free (glyphs); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_has_current_point (PycairoContext *o) { + PyObject *b = cairo_has_current_point (o->ctx) ? Py_True : Py_False; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_INCREF(b); + return b; +} + +static PyObject * +pycairo_identity_matrix (PycairoContext *o) { + cairo_identity_matrix (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_in_fill (PycairoContext *o, PyObject *args) { + double x, y; + PyObject *result; + + if (!PyArg_ParseTuple (args, "dd:Context.in_fill", &x, &y)) + return NULL; + + result = cairo_in_fill (o->ctx, x, y) ? Py_True : Py_False; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_INCREF(result); + return result; +} + +static PyObject * +pycairo_in_stroke (PycairoContext *o, PyObject *args) { + double x, y; + PyObject *result; + + if (!PyArg_ParseTuple (args, "dd:Context.in_stroke", &x, &y)) + return NULL; + + result = cairo_in_stroke (o->ctx, x, y) ? Py_True : Py_False; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_INCREF(result); + return result; +} + +static PyObject * +pycairo_line_to (PycairoContext *o, PyObject *args) { + double x, y; + + if (!PyArg_ParseTuple (args, "dd:Context.line_to", &x, &y)) + return NULL; + + cairo_line_to (o->ctx, x, y); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_mask (PycairoContext *o, PyObject *args) { + PycairoPattern *p; + + if (!PyArg_ParseTuple(args, "O!:Context.mask", &PycairoPattern_Type, &p)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + cairo_mask (o->ctx, p->pattern); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_mask_surface (PycairoContext *o, PyObject *args) { + PycairoSurface *s; + double surface_x = 0.0, surface_y = 0.0; + + if (!PyArg_ParseTuple (args, "O!|dd:Context.mask_surface", + &PycairoSurface_Type, &s, &surface_x, &surface_y)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + cairo_mask_surface (o->ctx, s->surface, surface_x, surface_y); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_move_to (PycairoContext *o, PyObject *args) { + double x, y; + + if (!PyArg_ParseTuple (args, "dd:Context.move_to", &x, &y)) + return NULL; + + cairo_move_to (o->ctx, x, y); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_new_path (PycairoContext *o) { + cairo_new_path (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_new_sub_path (PycairoContext *o) { + cairo_new_sub_path (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_paint (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_paint (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_paint_with_alpha (PycairoContext *o, PyObject *args) { + double alpha; + + if (!PyArg_ParseTuple (args, "d:Context.paint_with_alpha", &alpha)) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + cairo_paint_with_alpha (o->ctx, alpha); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_path_extents (PycairoContext *o) { + double x1, y1, x2, y2; + cairo_path_extents (o->ctx, &x1, &y1, &x2, &y2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddd)", x1, y1, x2, y2); +} + +static PyObject * +pycairo_pop_group (PycairoContext *o) { + return PycairoPattern_FromPattern (cairo_pop_group (o->ctx), NULL); +} + +static PyObject * +pycairo_pop_group_to_source (PycairoContext *o) { + cairo_pop_group_to_source (o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_push_group (PycairoContext *o) { + cairo_push_group (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_push_group_with_content (PycairoContext *o, PyObject *args) { + cairo_content_t content; + + if (!PyArg_ParseTuple(args, "i:Context.push_group_with_content", + &content)) + return NULL; + cairo_push_group_with_content (o->ctx, content); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_rectangle (PycairoContext *o, PyObject *args) { + double x, y, width, height; + + if (!PyArg_ParseTuple (args, "dddd:Context.rectangle", + &x, &y, &width, &height)) + return NULL; + + cairo_rectangle (o->ctx, x, y, width, height); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_rel_curve_to (PycairoContext *o, PyObject *args) { + double dx1, dy1, dx2, dy2, dx3, dy3; + + if (!PyArg_ParseTuple (args, "dddddd:Context.rel_curve_to", + &dx1, &dy1, &dx2, &dy2, &dx3, &dy3)) + return NULL; + + cairo_rel_curve_to (o->ctx, dx1, dy1, dx2, dy2, dx3, dy3); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_rel_line_to (PycairoContext *o, PyObject *args) { + double dx, dy; + + if (!PyArg_ParseTuple (args, "dd:Context.rel_line_to", &dx, &dy)) + return NULL; + + cairo_rel_line_to (o->ctx, dx, dy); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_rel_move_to (PycairoContext *o, PyObject *args) { + double dx, dy; + + if (!PyArg_ParseTuple (args, "dd:Context.rel_move_to", &dx, &dy)) + return NULL; + + cairo_rel_move_to (o->ctx, dx, dy); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_reset_clip (PycairoContext *o) { + cairo_reset_clip (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_restore (PycairoContext *o) { + cairo_restore (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_rotate (PycairoContext *o, PyObject *args) { + double angle; + + if (!PyArg_ParseTuple(args, "d:Context.rotate", &angle)) + return NULL; + + cairo_rotate (o->ctx, angle); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_save (PycairoContext *o) { + cairo_save (o->ctx); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_scale (PycairoContext *o, PyObject *args) { + double sx, sy; + + if (!PyArg_ParseTuple (args, "dd:Context.scale", &sx, &sy)) + return NULL; + + cairo_scale (o->ctx, sx, sy); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_select_font_face (PycairoContext *o, PyObject *args) { + PyObject *obj; + PyObject *pyUTF8 = NULL; + const char *utf8family = NULL; + cairo_font_slant_t slant = CAIRO_FONT_SLANT_NORMAL; + cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL; + + if (!PyArg_ParseTuple(args, "O!|ii:Context.select_font_face", + &PyBaseString_Type, &obj, &slant, &weight)) + return NULL; + + /* accept str and unicode family, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8family = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8family = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "Context.select_font_face: family must be str or unicode"); + } + if (utf8family == NULL) + return NULL; + + cairo_select_font_face (o->ctx, utf8family, slant, weight); + Py_XDECREF(pyUTF8); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_antialias (PycairoContext *o, PyObject *args) { + cairo_antialias_t antialias = CAIRO_ANTIALIAS_DEFAULT; + + if (!PyArg_ParseTuple(args, "|i:Context.set_antialias", &antialias)) + return NULL; + + cairo_set_antialias (o->ctx, antialias); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_dash (PycairoContext *o, PyObject *args) { + double *dashes, offset = 0; + int num_dashes, i; + PyObject *py_dashes; + + if (!PyArg_ParseTuple (args, "O|d:Context.set_dash", &py_dashes, &offset)) + return NULL; + + py_dashes = PySequence_Fast (py_dashes, + "first argument must be a sequence"); + if (py_dashes == NULL) + return NULL; + + num_dashes = PySequence_Fast_GET_SIZE(py_dashes); + dashes = PyMem_Malloc (num_dashes * sizeof(double)); + if (dashes == NULL) { + Py_DECREF(py_dashes); + return PyErr_NoMemory(); + } + + for (i = 0; i < num_dashes; i++) { + dashes[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_dashes, i)); + if (PyErr_Occurred()) { + PyMem_Free (dashes); + Py_DECREF(py_dashes); + return NULL; + } + } + cairo_set_dash (o->ctx, dashes, num_dashes, offset); + PyMem_Free (dashes); + Py_DECREF(py_dashes); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_fill_rule (PycairoContext *o, PyObject *args) { + cairo_fill_rule_t fill_rule; + + if (!PyArg_ParseTuple (args, "i:Context.set_fill_rule", &fill_rule)) + return NULL; + + cairo_set_fill_rule (o->ctx, fill_rule); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_font_face (PycairoContext *o, PyObject *obj) { + if (PyObject_TypeCheck(obj, &PycairoFontFace_Type)) + cairo_set_font_face (o->ctx, ((PycairoFontFace *)obj)->font_face); + else if (obj == Py_None) + cairo_set_font_face (o->ctx, NULL); + else { + PyErr_SetString(PyExc_TypeError, + "Context.set_font_face() argument must be " + "cairo.FontFace or None"); + return NULL; + } + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_font_matrix (PycairoContext *o, PyObject *args) { + PycairoMatrix *matrix; + + if (!PyArg_ParseTuple (args, "O!:Context.set_font_matrix", + &PycairoMatrix_Type, &matrix)) + return NULL; + + cairo_set_font_matrix (o->ctx, &matrix->matrix); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_font_options (PycairoContext *o, PyObject *args) { + PycairoFontOptions *options; + + if (!PyArg_ParseTuple (args, "O!:Context.set_font_options", + &PycairoFontOptions_Type, &options)) + return NULL; + + cairo_set_font_options (o->ctx, options->font_options); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_font_size (PycairoContext *o, PyObject *args) { + double size; + + if (!PyArg_ParseTuple (args, "d:Context.set_font_size", &size)) + return NULL; + + cairo_set_font_size (o->ctx, size); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_line_cap (PycairoContext *o, PyObject *args) { + cairo_line_cap_t line_cap; + + if (!PyArg_ParseTuple (args, "i:Context.set_line_cap", &line_cap)) + return NULL; + + cairo_set_line_cap (o->ctx, line_cap); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_line_join (PycairoContext *o, PyObject *args) { + cairo_line_join_t line_join; + + if (!PyArg_ParseTuple (args, "i:Context.set_line_join", &line_join)) + return NULL; + + cairo_set_line_join (o->ctx, line_join); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_line_width (PycairoContext *o, PyObject *args) { + double width; + + if (!PyArg_ParseTuple (args, "d:Context.set_line_width", &width)) + return NULL; + + cairo_set_line_width (o->ctx, width); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_matrix (PycairoContext *o, PyObject *args) { + PycairoMatrix *matrix; + + if (!PyArg_ParseTuple (args, "O!:Context.set_matrix", + &PycairoMatrix_Type, &matrix)) + return NULL; + + cairo_set_matrix (o->ctx, &matrix->matrix); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_miter_limit (PycairoContext *o, PyObject *args) { + double limit; + + if (!PyArg_ParseTuple (args, "d:Context.set_miter_limit", &limit)) + return NULL; + + cairo_set_miter_limit (o->ctx, limit); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_operator(PycairoContext *o, PyObject *args) { + cairo_operator_t op; + + if (!PyArg_ParseTuple(args, "i:Context.set_operator", &op)) + return NULL; + + cairo_set_operator(o->ctx, op); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_scaled_font(PycairoContext *o, PyObject *args) { + PycairoScaledFont *f; + if (!PyArg_ParseTuple( args, "O!:Context.set_scaled_font", + &PycairoScaledFont_Type, &f)) + return NULL; + + cairo_set_scaled_font(o->ctx, f->scaled_font); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_source (PycairoContext *o, PyObject *args) { + PycairoPattern *p; + + if (!PyArg_ParseTuple( args, "O!:Context.set_source", + &PycairoPattern_Type, &p)) + return NULL; + + cairo_set_source (o->ctx, p->pattern); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_source_rgb (PycairoContext *o, PyObject *args) { + double red, green, blue; + + if (!PyArg_ParseTuple (args, "ddd:Context.set_source_rgb", + &red, &green, &blue)) + return NULL; + + cairo_set_source_rgb (o->ctx, red, green, blue); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_source_rgba (PycairoContext *o, PyObject *args) { + double red, green, blue; + double alpha = 1.0; + + if (!PyArg_ParseTuple (args, "ddd|d:Context.set_source_rgba", + &red, &green, &blue, &alpha)) + return NULL; + + cairo_set_source_rgba (o->ctx, red, green, blue, alpha); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_source_surface (PycairoContext *o, PyObject *args) { + PycairoSurface *surface; + double x = 0.0, y = 0.0; + + if (!PyArg_ParseTuple (args, "O!|dd:Context.set_source_surface", + &PycairoSurface_Type, &surface, &x, &y)) + return NULL; + + cairo_set_source_surface (o->ctx, surface->surface, x, y); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_set_tolerance (PycairoContext *o, PyObject *args) { + double tolerance; + if (!PyArg_ParseTuple (args, "d:Context.set_tolerance", &tolerance)) + return NULL; + cairo_set_tolerance (o->ctx, tolerance); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_show_glyphs (PycairoContext *o, PyObject *args) { + int num_glyphs = -1; + cairo_glyph_t *glyphs; + PyObject *py_object; + + if (!PyArg_ParseTuple (args, "O|i:Context.show_glyphs", + &py_object, &num_glyphs)) + return NULL; + + glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); + if (glyphs == NULL) + return NULL; + Py_BEGIN_ALLOW_THREADS; + cairo_show_glyphs (o->ctx, glyphs, num_glyphs); + Py_END_ALLOW_THREADS; + PyMem_Free (glyphs); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_show_page (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_show_page (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_show_text (PycairoContext *o, PyObject *obj) { + PyObject *pyUTF8 = NULL; + const char *utf8 = NULL; + + /* accept str and unicode text, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8 = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8 = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "Context.show_text: text must be str or unicode"); + } + if (utf8 == NULL) + return NULL; + + Py_BEGIN_ALLOW_THREADS; + cairo_show_text (o->ctx, utf8); + Py_END_ALLOW_THREADS; + Py_XDECREF(pyUTF8); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_stroke (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_stroke (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_stroke_extents (PycairoContext *o) { + double x1, y1, x2, y2; + cairo_stroke_extents (o->ctx, &x1, &y1, &x2, &y2); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddd)", x1, y1, x2, y2); +} + +static PyObject * +pycairo_stroke_preserve (PycairoContext *o) { + Py_BEGIN_ALLOW_THREADS; + cairo_stroke_preserve (o->ctx); + Py_END_ALLOW_THREADS; + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_text_extents (PycairoContext *o, PyObject *obj) { + cairo_text_extents_t extents; + PyObject *pyUTF8 = NULL; + const char *utf8 = NULL; + + /* accept str and unicode text, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8 = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8 = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "Context.text_extents: text must be str or unicode"); + } + if (utf8 == NULL) + return NULL; + + cairo_text_extents (o->ctx, utf8, &extents); + Py_XDECREF(pyUTF8); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, + extents.width, extents.height, extents.x_advance, + extents.y_advance); +} + +static PyObject * +pycairo_text_path (PycairoContext *o, PyObject *obj) { + PyObject *pyUTF8 = NULL; + const char *utf8 = NULL; + + /* accept str and unicode text, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8 = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8 = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "Context.text_path: text must be str or unicode"); + } + if (utf8 == NULL) + return NULL; + + cairo_text_path (o->ctx, utf8); + Py_XDECREF(pyUTF8); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_transform (PycairoContext *o, PyObject *args) { + PycairoMatrix *matrix; + + if (!PyArg_ParseTuple (args, "O!:Context.transform", + &PycairoMatrix_Type, &matrix)) + return NULL; + + cairo_transform (o->ctx, &matrix->matrix); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_translate (PycairoContext *o, PyObject *args) { + double tx, ty; + + if (!PyArg_ParseTuple (args, "dd:Context.translate", &tx, &ty)) + return NULL; + + cairo_translate (o->ctx, tx, ty); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + Py_RETURN_NONE; +} + +static PyObject * +pycairo_user_to_device (PycairoContext *o, PyObject *args) { + double x, y; + + if (!PyArg_ParseTuple (args, "dd:Context.user_to_device", &x, &y)) + return NULL; + + cairo_user_to_device (o->ctx, &x, &y); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dd)", x, y); +} + +static PyObject * +pycairo_user_to_device_distance (PycairoContext *o, PyObject *args) { + double dx, dy; + + if (!PyArg_ParseTuple (args, "dd:Context.user_to_device_distance", + &dx, &dy)) + return NULL; + + cairo_user_to_device_distance (o->ctx, &dx, &dy); + RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); + return Py_BuildValue("(dd)", dx, dy); +} + + +static PyMethodDef pycairo_methods[] = { + /* methods never exposed in a language binding: + * cairo_destroy() + * cairo_reference() + * cairo_rectangle_list_destroy() + * + * cairo_status() + * cairo_status_string() + * - not needed since Pycairo calls Pycairo_Check_Status() to check + * for errors and raise exceptions + */ + {"append_path", (PyCFunction)pycairo_append_path, METH_VARARGS}, + {"arc", (PyCFunction)pycairo_arc, METH_VARARGS}, + {"arc_negative", (PyCFunction)pycairo_arc_negative, METH_VARARGS}, + {"clip", (PyCFunction)pycairo_clip, METH_NOARGS}, + {"clip_extents", (PyCFunction)pycairo_clip_extents, METH_NOARGS}, + {"clip_preserve", (PyCFunction)pycairo_clip_preserve, METH_NOARGS}, + {"close_path", (PyCFunction)pycairo_close_path, METH_NOARGS}, + {"copy_clip_rectangle_list", (PyCFunction)pycairo_copy_clip_rectangle_list, + METH_NOARGS}, + {"copy_page", (PyCFunction)pycairo_copy_page, METH_NOARGS}, + {"copy_path", (PyCFunction)pycairo_copy_path, METH_NOARGS}, + {"copy_path_flat", (PyCFunction)pycairo_copy_path_flat, METH_NOARGS}, + {"curve_to", (PyCFunction)pycairo_curve_to, METH_VARARGS}, + {"device_to_user", (PyCFunction)pycairo_device_to_user, METH_VARARGS}, + {"device_to_user_distance", (PyCFunction)pycairo_device_to_user_distance, + METH_VARARGS}, + {"fill", (PyCFunction)pycairo_fill, METH_NOARGS}, + {"fill_extents", (PyCFunction)pycairo_fill_extents, METH_NOARGS}, + {"fill_preserve", (PyCFunction)pycairo_fill_preserve, METH_NOARGS}, + {"font_extents", (PyCFunction)pycairo_font_extents, METH_NOARGS}, + {"get_antialias", (PyCFunction)pycairo_get_antialias, METH_NOARGS}, + {"get_current_point",(PyCFunction)pycairo_get_current_point,METH_NOARGS}, + {"get_dash", (PyCFunction)pycairo_get_dash, METH_NOARGS}, + {"get_dash_count", (PyCFunction)pycairo_get_dash_count, METH_NOARGS}, + {"get_fill_rule", (PyCFunction)pycairo_get_fill_rule, METH_NOARGS}, + {"get_font_face", (PyCFunction)pycairo_get_font_face, METH_NOARGS}, + {"get_font_matrix", (PyCFunction)pycairo_get_font_matrix, METH_NOARGS}, + {"get_font_options",(PyCFunction)pycairo_get_font_options, METH_NOARGS}, + {"get_group_target",(PyCFunction)pycairo_get_group_target, METH_NOARGS}, + {"get_line_cap", (PyCFunction)pycairo_get_line_cap, METH_NOARGS}, + {"get_line_join", (PyCFunction)pycairo_get_line_join, METH_NOARGS}, + {"get_line_width", (PyCFunction)pycairo_get_line_width, METH_NOARGS}, + {"get_matrix", (PyCFunction)pycairo_get_matrix, METH_NOARGS}, + {"get_miter_limit", (PyCFunction)pycairo_get_miter_limit, METH_NOARGS}, + {"get_operator", (PyCFunction)pycairo_get_operator, METH_NOARGS}, + {"get_scaled_font", (PyCFunction)pycairo_get_scaled_font, METH_NOARGS}, + {"get_source", (PyCFunction)pycairo_get_source, METH_NOARGS}, + {"get_target", (PyCFunction)pycairo_get_target, METH_NOARGS}, + {"get_tolerance", (PyCFunction)pycairo_get_tolerance, METH_NOARGS}, + {"glyph_extents", (PyCFunction)pycairo_glyph_extents, METH_VARARGS}, + {"glyph_path", (PyCFunction)pycairo_glyph_path, METH_VARARGS}, + {"has_current_point",(PyCFunction)pycairo_has_current_point, METH_NOARGS}, + {"identity_matrix", (PyCFunction)pycairo_identity_matrix, METH_NOARGS}, + {"in_fill", (PyCFunction)pycairo_in_fill, METH_VARARGS}, + {"in_stroke", (PyCFunction)pycairo_in_stroke, METH_VARARGS}, + {"line_to", (PyCFunction)pycairo_line_to, METH_VARARGS}, + {"mask", (PyCFunction)pycairo_mask, METH_VARARGS}, + {"mask_surface", (PyCFunction)pycairo_mask_surface, METH_VARARGS}, + {"move_to", (PyCFunction)pycairo_move_to, METH_VARARGS}, + {"new_path", (PyCFunction)pycairo_new_path, METH_NOARGS}, + {"new_sub_path", (PyCFunction)pycairo_new_sub_path, METH_NOARGS}, + {"paint", (PyCFunction)pycairo_paint, METH_NOARGS}, + {"paint_with_alpha",(PyCFunction)pycairo_paint_with_alpha, METH_VARARGS}, + {"path_extents", (PyCFunction)pycairo_path_extents, METH_NOARGS}, + {"pop_group", (PyCFunction)pycairo_pop_group, METH_NOARGS}, + {"pop_group_to_source", (PyCFunction)pycairo_pop_group_to_source, + METH_NOARGS}, + {"push_group", (PyCFunction)pycairo_push_group, METH_NOARGS}, + {"push_group_with_content", (PyCFunction)pycairo_push_group_with_content, + METH_VARARGS}, + {"rectangle", (PyCFunction)pycairo_rectangle, METH_VARARGS}, + {"rel_curve_to", (PyCFunction)pycairo_rel_curve_to, METH_VARARGS}, + {"rel_line_to", (PyCFunction)pycairo_rel_line_to, METH_VARARGS}, + {"rel_move_to", (PyCFunction)pycairo_rel_move_to, METH_VARARGS}, + {"reset_clip", (PyCFunction)pycairo_reset_clip, METH_NOARGS}, + {"restore", (PyCFunction)pycairo_restore, METH_NOARGS}, + {"rotate", (PyCFunction)pycairo_rotate, METH_VARARGS}, + {"save", (PyCFunction)pycairo_save, METH_NOARGS}, + {"scale", (PyCFunction)pycairo_scale, METH_VARARGS}, + {"select_font_face",(PyCFunction)pycairo_select_font_face, METH_VARARGS}, + {"set_antialias", (PyCFunction)pycairo_set_antialias, METH_VARARGS}, + {"set_dash", (PyCFunction)pycairo_set_dash, METH_VARARGS}, + {"set_fill_rule", (PyCFunction)pycairo_set_fill_rule, METH_VARARGS}, + {"set_font_face", (PyCFunction)pycairo_set_font_face, METH_O}, + {"set_font_matrix", (PyCFunction)pycairo_set_font_matrix, METH_VARARGS}, + {"set_font_options",(PyCFunction)pycairo_set_font_options, METH_VARARGS}, + {"set_font_size", (PyCFunction)pycairo_set_font_size, METH_VARARGS}, + {"set_line_cap", (PyCFunction)pycairo_set_line_cap, METH_VARARGS}, + {"set_line_join", (PyCFunction)pycairo_set_line_join, METH_VARARGS}, + {"set_line_width", (PyCFunction)pycairo_set_line_width, METH_VARARGS}, + {"set_matrix", (PyCFunction)pycairo_set_matrix, METH_VARARGS}, + {"set_miter_limit", (PyCFunction)pycairo_set_miter_limit, METH_VARARGS}, + {"set_operator", (PyCFunction)pycairo_set_operator, METH_VARARGS}, + {"set_scaled_font", (PyCFunction)pycairo_set_scaled_font, METH_VARARGS}, + {"set_source", (PyCFunction)pycairo_set_source, METH_VARARGS}, + {"set_source_rgb", (PyCFunction)pycairo_set_source_rgb, METH_VARARGS}, + {"set_source_rgba", (PyCFunction)pycairo_set_source_rgba, METH_VARARGS}, + {"set_source_surface",(PyCFunction)pycairo_set_source_surface, METH_VARARGS}, + {"set_tolerance", (PyCFunction)pycairo_set_tolerance, METH_VARARGS}, + {"show_glyphs", (PyCFunction)pycairo_show_glyphs, METH_VARARGS}, + {"show_page", (PyCFunction)pycairo_show_page, METH_NOARGS}, + {"show_text", (PyCFunction)pycairo_show_text, METH_O}, + {"stroke", (PyCFunction)pycairo_stroke, METH_NOARGS}, + {"stroke_extents", (PyCFunction)pycairo_stroke_extents, METH_NOARGS}, + {"stroke_preserve", (PyCFunction)pycairo_stroke_preserve, METH_NOARGS}, + {"text_extents", (PyCFunction)pycairo_text_extents, METH_O}, + {"text_path", (PyCFunction)pycairo_text_path, METH_O}, + {"transform", (PyCFunction)pycairo_transform, METH_VARARGS}, + {"translate", (PyCFunction)pycairo_translate, METH_VARARGS}, + {"user_to_device", (PyCFunction)pycairo_user_to_device, METH_VARARGS}, + {"user_to_device_distance",(PyCFunction)pycairo_user_to_device_distance, + METH_VARARGS}, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoContext_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Context", /* tp_name */ + sizeof(PycairoContext), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pycairo_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 */ + 0, /* 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 */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pycairo_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)pycairo_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; diff --git a/src/font.c b/src/font.c new file mode 100644 index 0000000..0bde25f --- /dev/null +++ b/src/font.c @@ -0,0 +1,611 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2003 James Henstridge, 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 + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "private.h" + + +/* class cairo.FontFace --------------------------------------------------- */ + +/* PycairoFontFace_FromFontFace + * Create a new PycairoFontFace from a cairo_font_face_t + * font_face - a cairo_font_face_t to 'wrap' into a Python object. + * it is unreferenced if the PycairoFontFace creation fails + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoFontFace_FromFontFace (cairo_font_face_t *font_face) { + PyTypeObject *type = NULL; + PyObject *o; + + assert (font_face != NULL); + + if (Pycairo_Check_Status (cairo_font_face_status (font_face))) { + cairo_font_face_destroy (font_face); + return NULL; + } + + switch (cairo_font_face_get_type (font_face)) { + case CAIRO_FONT_TYPE_TOY: + type = &PycairoToyFontFace_Type; + break; + default: + type = &PycairoFontFace_Type; + break; + } + o = type->tp_alloc (type, 0); + if (o == NULL) + cairo_font_face_destroy (font_face); + else + ((PycairoFontFace *)o)->font_face = font_face; + return o; +} + +static void +font_face_dealloc (PycairoFontFace *o) { + if (o->font_face) { + cairo_font_face_destroy (o->font_face); + o->font_face = NULL; + } + o->ob_type->tp_free((PyObject *) o); +} + +static PyObject * +font_face_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyErr_SetString (PyExc_TypeError, "The FontFace type cannot be " + "instantiated directly, use Context.get_font_face()"); + return NULL; +} + +/* +static PyMethodDef font_face_methods[] = { + * methods never exposed in a language binding: + * cairo_font_face_destroy() + * cairo_font_face_get_user_data() + * cairo_font_face_get_type() + * cairo_font_face_reference() + * cairo_font_face_set_user_data(), + {NULL, NULL, 0, NULL}, +}; +*/ + +PyTypeObject PycairoFontFace_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.FontFace", /* tp_name */ + sizeof(PycairoFontFace), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)font_face_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 */ + 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 */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)font_face_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + + +/* class cairo.ToyFontFace ------------------------------------------------- */ + +static PyObject * +toy_font_face_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyObject *obj; + PyObject *pyUTF8 = NULL; + const char *utf8family = NULL; + cairo_font_slant_t slant = CAIRO_FONT_SLANT_NORMAL; + cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL; + + if (!PyArg_ParseTuple(args, "O!|ii:ToyFontFace.__new__", + &PyBaseString_Type, &obj, &slant, &weight)) + return NULL; + + /* accept str and unicode family, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8family = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8family = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "ToyFontFace.__new__: family must be str or unicode"); + } + if (utf8family == NULL) + return NULL; + + PyObject *o = PycairoFontFace_FromFontFace ( + cairo_toy_font_face_create (utf8family, slant, weight)); + Py_XDECREF(pyUTF8); + return o; +} + +static PyObject * +toy_font_get_family (PycairoToyFontFace *o) { + return PyString_FromString (cairo_toy_font_face_get_family (o->font_face)); +} + +static PyObject * +toy_font_get_slant (PycairoToyFontFace *o) { + return PyInt_FromLong (cairo_toy_font_face_get_slant (o->font_face)); +} + +static PyObject * +toy_font_get_weight (PycairoToyFontFace *o) { + return PyInt_FromLong (cairo_toy_font_face_get_weight (o->font_face)); +} + +static PyMethodDef toy_font_face_methods[] = { + {"get_family", (PyCFunction)toy_font_get_family, METH_NOARGS}, + {"get_slant", (PyCFunction)toy_font_get_slant, METH_NOARGS}, + {"get_weight", (PyCFunction)toy_font_get_weight, METH_NOARGS}, + {NULL, NULL, 0, NULL}, +}; + + +PyTypeObject PycairoToyFontFace_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.ToyFontFace", /* tp_name */ + sizeof(PycairoToyFontFace), /* 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 */ + toy_font_face_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoFontFace_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)toy_font_face_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + + +/* class cairo.ScaledFont ------------------------------------------------- */ + +/* PycairoScaledFont_FromScaledFont + * Create a new PycairoScaledFont from a cairo_scaled_font_t + * scaled_font - a cairo_scaled_font_t to 'wrap' into a Python object. + * it is unreferenced if the PycairoScaledFont creation fails + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoScaledFont_FromScaledFont (cairo_scaled_font_t *scaled_font) { + PyObject *o; + + assert (scaled_font != NULL); + + if (Pycairo_Check_Status (cairo_scaled_font_status (scaled_font))) { + cairo_scaled_font_destroy (scaled_font); + return NULL; + } + + o = PycairoScaledFont_Type.tp_alloc (&PycairoScaledFont_Type, 0); + if (o == NULL) + cairo_scaled_font_destroy (scaled_font); + else + ((PycairoScaledFont *)o)->scaled_font = scaled_font; + return o; +} + +static void +scaled_font_dealloc(PycairoScaledFont *o) { + if (o->scaled_font) { + cairo_scaled_font_destroy (o->scaled_font); + o->scaled_font = NULL; + } + o->ob_type->tp_free((PyObject *) o); +} + +static PyObject * +scaled_font_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PycairoFontFace *ff; + PycairoFontOptions *fo; + PycairoMatrix *mx1, *mx2; + + if (!PyArg_ParseTuple(args, "O!O!O!O!:ScaledFont.__new__", + &PycairoFontFace_Type, &ff, + &PycairoMatrix_Type, &mx1, + &PycairoMatrix_Type, &mx2, + &PycairoFontOptions_Type, &fo)) + return NULL; + return PycairoScaledFont_FromScaledFont ( + cairo_scaled_font_create (ff->font_face, &mx1->matrix, + &mx2->matrix, fo->font_options)); +} + +static PyObject * +scaled_font_extents (PycairoScaledFont *o) { + cairo_font_extents_t e; + + cairo_scaled_font_extents (o->scaled_font, &e); + RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(o->scaled_font); + return Py_BuildValue ("(ddddd)", e.ascent, e.descent, e.height, + e.max_x_advance, e.max_y_advance); +} + +static PyObject * +scaled_font_get_font_face (PycairoScaledFont *o) { + return PycairoFontFace_FromFontFace ( + cairo_font_face_reference ( + cairo_scaled_font_get_font_face (o->scaled_font))); +} + +static PyObject * +scaled_font_get_scale_matrix (PycairoScaledFont *o) { + cairo_matrix_t matrix; + cairo_scaled_font_get_scale_matrix (o->scaled_font, &matrix); + return PycairoMatrix_FromMatrix (&matrix); +} + +static PyObject * +scaled_font_text_extents (PycairoScaledFont *o, PyObject *obj) { + cairo_text_extents_t extents; + PyObject *pyUTF8 = NULL; + const char *utf8 = NULL; + + /* accept str and unicode text, auto convert to utf8 as required */ + if (PyString_Check(obj)) { + /* A plain ASCII string is also a valid UTF-8 string */ + utf8 = PyString_AS_STRING(obj); + } else if (PyUnicode_Check(obj)) { + pyUTF8 = PyUnicode_AsUTF8String(obj); + if (pyUTF8 != NULL) { + utf8 = PyString_AS_STRING(pyUTF8); + } + } else { + PyErr_SetString(PyExc_TypeError, + "ScaledFont.text_extents: text must be str or unicode"); + } + if (utf8 == NULL) + return NULL; + + cairo_scaled_font_text_extents (o->scaled_font, utf8, &extents); + Py_XDECREF(pyUTF8); + RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(o->scaled_font); + return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, + extents.width, extents.height, extents.x_advance, + extents.y_advance); +} + +static PyMethodDef scaled_font_methods[] = { + /* methods never exposed in a language binding: + * cairo_scaled_font_destroy() + * cairo_scaled_font_get_type() + * cairo_scaled_font_reference() + * + * TODO if requested: + * cairo_scaled_font_get_ctm + * cairo_scaled_font_get_font_matrix + * cairo_scaled_font_get_font_options + * cairo_scaled_font_glyph_extents + * cairo_scaled_font_text_to_glyphs + */ + {"extents", (PyCFunction)scaled_font_extents, METH_NOARGS}, + {"get_font_face", (PyCFunction)scaled_font_get_font_face, METH_NOARGS}, + {"get_scale_matrix", (PyCFunction)scaled_font_get_scale_matrix, METH_VARARGS}, + {"text_extents", (PyCFunction)scaled_font_text_extents, METH_O}, + {NULL, NULL, 0, NULL}, +}; + + +PyTypeObject PycairoScaledFont_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.ScaledFont", /* tp_name */ + sizeof(PycairoScaledFont), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)scaled_font_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 */ + 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 */ + scaled_font_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)scaled_font_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + + +/* class cairo.FontOptions ------------------------------------------------ */ + +/* PycairoFontOptions_FromFontOptions + * Create a new PycairoFontOptions from a cairo_font_options_t + * font_options - a cairo_font_options_t to 'wrap' into a Python object. + * it is unreferenced if the PycairoFontOptions creation fails + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoFontOptions_FromFontOptions (cairo_font_options_t *font_options) { + PyObject *o; + + assert (font_options != NULL); + + if (Pycairo_Check_Status (cairo_font_options_status (font_options))) { + cairo_font_options_destroy (font_options); + return NULL; + } + + o = PycairoFontOptions_Type.tp_alloc (&PycairoFontOptions_Type, 0); + if (o == NULL) + cairo_font_options_destroy (font_options); + else + ((PycairoFontOptions *)o)->font_options = font_options; + return o; +} + +static void +font_options_dealloc(PycairoFontOptions *o) { + if (o->font_options) { + cairo_font_options_destroy (o->font_options); + o->font_options = NULL; + } + o->ob_type->tp_free((PyObject *) o); +} + +static PyObject * +font_options_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + return PycairoFontOptions_FromFontOptions (cairo_font_options_create()); +} + +static PyObject * +font_options_get_antialias (PycairoFontOptions *o) { + return PyInt_FromLong (cairo_font_options_get_antialias (o->font_options)); +} + +static PyObject * +font_options_get_hint_metrics (PycairoFontOptions *o) { + return PyInt_FromLong (cairo_font_options_get_hint_metrics + (o->font_options)); +} + +static PyObject * +font_options_get_hint_style (PycairoFontOptions *o) { + return PyInt_FromLong (cairo_font_options_get_hint_style + (o->font_options)); +} + +static PyObject * +font_options_get_subpixel_order (PycairoFontOptions *o) { + return PyInt_FromLong (cairo_font_options_get_subpixel_order + (o->font_options)); +} + +static PyObject * +font_options_set_antialias (PycairoFontOptions *o, PyObject *args) { + cairo_antialias_t aa = CAIRO_ANTIALIAS_DEFAULT; + + if (!PyArg_ParseTuple(args, "|i:FontOptions.set_antialias", &aa)) + return NULL; + + cairo_font_options_set_antialias (o->font_options, aa); + RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); + Py_RETURN_NONE; +} + +static PyObject * +font_options_set_hint_metrics (PycairoFontOptions *o, PyObject *args) { + cairo_hint_metrics_t hm = CAIRO_HINT_METRICS_DEFAULT; + + if (!PyArg_ParseTuple(args, "|i:FontOptions.set_hint_metrics", &hm)) + return NULL; + + cairo_font_options_set_hint_metrics (o->font_options, hm); + RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); + Py_RETURN_NONE; +} + +static PyObject * +font_options_set_hint_style (PycairoFontOptions *o, PyObject *args) { + cairo_hint_style_t hs = CAIRO_HINT_STYLE_DEFAULT; + + if (!PyArg_ParseTuple(args, "|i:FontOptions.set_hint_style", &hs)) + return NULL; + + cairo_font_options_set_hint_style (o->font_options, hs); + RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); + Py_RETURN_NONE; +} + +static PyObject * +font_options_set_subpixel_order (PycairoFontOptions *o, PyObject *args) { + cairo_subpixel_order_t so = CAIRO_SUBPIXEL_ORDER_DEFAULT; + + if (!PyArg_ParseTuple(args, "|i:FontOptions.set_subpixel_order", &so)) + return NULL; + + cairo_font_options_set_subpixel_order (o->font_options, so); + RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); + Py_RETURN_NONE; +} + + +static PyMethodDef font_options_methods[] = { + /* methods never exposed in a language binding: + * cairo_font_options_destroy() + * cairo_font_options_reference() + */ + /* TODO: */ + /* copy */ + /* hash */ + /* merge */ + /* equal (richcmp?) */ + {"get_antialias", (PyCFunction)font_options_get_antialias, METH_NOARGS}, + {"get_hint_metrics", (PyCFunction)font_options_get_hint_metrics, + METH_NOARGS}, + {"get_hint_style", (PyCFunction)font_options_get_hint_style, METH_NOARGS}, + {"get_subpixel_order",(PyCFunction)font_options_get_subpixel_order, + METH_NOARGS}, + {"set_antialias", (PyCFunction)font_options_set_antialias, METH_VARARGS}, + {"set_hint_metrics", (PyCFunction)font_options_set_hint_metrics, + METH_VARARGS}, + {"set_hint_style", (PyCFunction)font_options_set_hint_style, METH_VARARGS}, + {"set_subpixel_order",(PyCFunction)font_options_set_subpixel_order, + METH_VARARGS}, + {NULL, NULL, 0, NULL}, +}; + + +PyTypeObject PycairoFontOptions_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.FontOptions", /* tp_name */ + sizeof(PycairoFontOptions), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)font_options_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 */ + 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 */ + font_options_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)font_options_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; diff --git a/src/matrix.c b/src/matrix.c new file mode 100644 index 0000000..b404525 --- /dev/null +++ b/src/matrix.c @@ -0,0 +1,348 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2003 James Henstridge, 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 + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "private.h" + + +/* PycairoMatrix_FromMatrix + * Create a new PycairoMatrix from a cairo_matrix_t + * matrix - a cairo_matrix_t to 'wrap' into a Python object + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoMatrix_FromMatrix (const cairo_matrix_t *matrix) { + PyObject *o; + assert (matrix != NULL); + o = PycairoMatrix_Type.tp_alloc (&PycairoMatrix_Type, 0); + if (o != NULL) + ((PycairoMatrix *)o)->matrix = *matrix; + return o; +} + +static void +matrix_dealloc (PycairoMatrix *o) { + o->ob_type->tp_free((PyObject *)o); +} + +static PyObject * +matrix_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyObject *o; + static char *kwlist[] = { "xx", "yx", "xy", "yy", "x0", "y0", NULL }; + double xx = 1.0, yx = 0.0, xy = 0.0, yy = 1.0, x0 = 0.0, y0 = 0.0; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "|dddddd:Matrix.__init__", kwlist, + &xx, &yx, &xy, &yy, &x0, &y0)) + return NULL; + + o = type->tp_alloc(type, 0); + if (o) + cairo_matrix_init (&((PycairoMatrix *)o)->matrix, + xx, yx, xy, yy, x0, y0); + return o; +} + +static PyObject * +matrix_init_rotate (PyTypeObject *type, PyObject *args) { + cairo_matrix_t matrix; + double radians; + + if (!PyArg_ParseTuple(args, "d:Matrix.init_rotate", &radians)) + return NULL; + + cairo_matrix_init_rotate (&matrix, radians); + return PycairoMatrix_FromMatrix (&matrix); +} + +static PyObject * +matrix_invert (PycairoMatrix *o) { + if (Pycairo_Check_Status (cairo_matrix_invert (&o->matrix))) + return NULL; + Py_RETURN_NONE; +} + +/* cairo_matrix_multiply */ +static PyObject * +matrix_multiply (PycairoMatrix *o, PyObject *args) { + PycairoMatrix *mx2; + + if (!PyArg_ParseTuple(args, "O!:Matrix.multiply", + &PycairoMatrix_Type, &mx2)) + return NULL; + + cairo_matrix_t result; + cairo_matrix_multiply (&result, &o->matrix, &mx2->matrix); + return PycairoMatrix_FromMatrix (&result); +} + +/* standard matrix multiply, for use by '*' operator */ +static PyObject * +matrix_operator_multiply (PycairoMatrix *o, PycairoMatrix *o2) { + cairo_matrix_t result; + cairo_matrix_multiply (&result, &o->matrix, &o2->matrix); + return PycairoMatrix_FromMatrix (&result); +} + +static PyObject * +matrix_repr (PycairoMatrix *o) { + char buf[256]; + + PyOS_snprintf(buf, sizeof(buf), "cairo.Matrix(%g, %g, %g, %g, %g, %g)", + o->matrix.xx, o->matrix.yx, + o->matrix.xy, o->matrix.yy, + o->matrix.x0, o->matrix.y0); + return PyString_FromString(buf); +} + +static PyObject * +matrix_richcmp (PycairoMatrix *m1, PycairoMatrix *m2, int op) { + int equal; + PyObject *ret; + cairo_matrix_t *mx1 = &m1->matrix; + cairo_matrix_t *mx2 = &m2->matrix; + + if (!PyObject_TypeCheck(m2, &PycairoMatrix_Type) || + !(op == Py_EQ || op == Py_NE)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + equal = mx1->xx == mx2->xx && mx1->yx == mx2->yx && + mx1->xy == mx2->xy && mx1->yy == mx2->yy && + mx1->x0 == mx2->x0 && mx1->y0 == mx2->y0; + + if (op == Py_EQ) + ret = equal ? Py_True : Py_False; + else + ret = equal ? Py_False : Py_True; + Py_INCREF(ret); + return ret; +} + +static PyObject * +matrix_rotate (PycairoMatrix *o, PyObject *args) { + double radians; + + if (!PyArg_ParseTuple(args, "d:Matrix.rotate", &radians)) + return NULL; + + cairo_matrix_rotate (&o->matrix, radians); + Py_RETURN_NONE; +} + +static PyObject * +matrix_scale (PycairoMatrix *o, PyObject *args) { + double sx, sy; + + if (!PyArg_ParseTuple(args, "dd:Matrix.scale", &sx, &sy)) + return NULL; + + cairo_matrix_scale (&o->matrix, sx, sy); + Py_RETURN_NONE; +} + +static PyObject * +matrix_transform_distance (PycairoMatrix *o, PyObject *args) { + double dx, dy; + + if (!PyArg_ParseTuple(args, "dd:Matrix.transform_distance", &dx, &dy)) + return NULL; + + cairo_matrix_transform_distance (&o->matrix, &dx, &dy); + return Py_BuildValue("(dd)", dx, dy); +} + +static PyObject * +matrix_transform_point (PycairoMatrix *o, PyObject *args) { + double x, y; + + if (!PyArg_ParseTuple(args, "dd:Matrix.transform_point", &x, &y)) + return NULL; + + cairo_matrix_transform_point (&o->matrix, &x, &y); + return Py_BuildValue("(dd)", x, y); +} + +static PyObject * +matrix_translate (PycairoMatrix *o, PyObject *args) { + double tx, ty; + + if (!PyArg_ParseTuple(args, "dd:Matrix.translate", &tx, &ty)) + return NULL; + + cairo_matrix_translate (&o->matrix, tx, ty); + Py_RETURN_NONE; +} + +static PyObject * +matrix_item (PycairoMatrix *o, Py_ssize_t i) { + switch (i) { + case 0: + return Py_BuildValue("d", o->matrix.xx); + case 1: + return Py_BuildValue("d", o->matrix.yx); + case 2: + return Py_BuildValue("d", o->matrix.xy); + case 3: + return Py_BuildValue("d", o->matrix.yy); + case 4: + return Py_BuildValue("d", o->matrix.x0); + case 5: + return Py_BuildValue("d", o->matrix.y0); + default: + PyErr_SetString(PyExc_IndexError, "Matrix index out of range"); + return NULL; + } +} + +static PyNumberMethods matrix_as_number = { + (binaryfunc)0, /*nb_add*/ + (binaryfunc)0, /*nb_subtract*/ + (binaryfunc)matrix_operator_multiply, /*nb_multiply*/ + (binaryfunc)0, /*nb_divide*/ + (binaryfunc)0, /*nb_remainder*/ + (binaryfunc)0, /*nb_divmod*/ + (ternaryfunc)0, /*nb_power*/ + (unaryfunc)0, /*nb_negative*/ + (unaryfunc)0, /*nb_positive*/ + (unaryfunc)0, /*nb_absolute*/ + (inquiry)0, /*nb_nonzero*/ + (unaryfunc)0, /*nb_invert*/ + (binaryfunc)0, /*nb_lshift*/ + (binaryfunc)0, /*nb_rshift*/ + (binaryfunc)0, /*nb_and*/ + (binaryfunc)0, /*nb_xor*/ + (binaryfunc)0, /*nb_or*/ + (coercion)0, /*nb_coerce*/ + (unaryfunc)0, /*nb_int*/ + (unaryfunc)0, /*nb_long*/ + (unaryfunc)0, /*nb_float*/ + (unaryfunc)0, /*nb_oct*/ + (unaryfunc)0, /*nb_hex*/ + 0, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_divide*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + (binaryfunc)0, /* nb_floor_divide */ + 0, /* nb_true_divide */ + 0, /* nb_inplace_floor_divide */ + 0, /* nb_inplace_true_divide */ + (unaryfunc)0, /* nb_index */ +}; + +static PySequenceMethods matrix_as_sequence = { + 0, /* sq_length */ + 0, /* sq_concat */ + 0, /* sq_repeat */ + (ssizeargfunc)matrix_item, /* sq_item */ + 0, /* sq_slice */ + 0, /* sq_ass_item */ + 0, /* sq_ass_slice */ + 0, /* sq_contains */ +}; + +static PyMethodDef matrix_methods[] = { + /* Do not need to wrap all cairo_matrix_init_*() functions + * C API Matrix constructors Python equivalents + * cairo_matrix_init() cairo.Matrix(xx,yx,xy,yy,x0,y0) + * cairo_matrix_init_rotate() cairo.Matrix.init_rotate(radians) + + * cairo_matrix_init_identity() cairo.Matrix() + * cairo_matrix_init_translate() cairo.Matrix(x0=x0,y0=y0) + * cairo_matrix_init_scale() cairo.Matrix(xx=xx,yy=yy) + */ + {"init_rotate", (PyCFunction)matrix_init_rotate, METH_VARARGS | METH_CLASS }, + {"invert", (PyCFunction)matrix_invert, METH_NOARGS }, + {"multiply", (PyCFunction)matrix_multiply, METH_VARARGS }, + {"rotate", (PyCFunction)matrix_rotate, METH_VARARGS }, + {"scale", (PyCFunction)matrix_scale, METH_VARARGS }, + {"transform_distance",(PyCFunction)matrix_transform_distance, METH_VARARGS }, + {"transform_point", (PyCFunction)matrix_transform_point, METH_VARARGS }, + {"translate", (PyCFunction)matrix_translate, METH_VARARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoMatrix_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Matrix", /* tp_name */ + sizeof(PycairoMatrix), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)matrix_dealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_compare */ + (reprfunc)matrix_repr, /* tp_repr */ + &matrix_as_number, /* tp_as_number */ + &matrix_as_sequence, /* 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 */ + NULL, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + (richcmpfunc)matrix_richcmp, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + matrix_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)matrix_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; diff --git a/src/path.c b/src/path.c new file mode 100644 index 0000000..1ab47ec --- /dev/null +++ b/src/path.c @@ -0,0 +1,329 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2005 Steve 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 + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "private.h" + + +/* PycairoPath iterator object + * modelled on Python-2.4/Objects/rangeobject.c and tupleobject.c + */ + +/* PycairoPath_FromPath + * Create a new PycairoPath from a cairo_path_t + * path - a cairo_path_t to 'wrap' into a Python object. + * path is unreferenced if the PycairoPath creation fails, or if path + * is in an error status. + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoPath_FromPath (cairo_path_t *path) { + PyObject *o; + + assert (path != NULL); + + if (Pycairo_Check_Status (path->status)) { + cairo_path_destroy (path); + return NULL; + } + + o = PycairoPath_Type.tp_alloc (&PycairoPath_Type, 0); + if (o) + ((PycairoPath *)o)->path = path; + else + cairo_path_destroy (path); + return o; +} + +static void +path_dealloc(PycairoPath *p) { +#ifdef DEBUG + printf("path_dealloc start\n"); +#endif + if (p->path) { + cairo_path_destroy(p->path); + p->path = NULL; + } + p->ob_type->tp_free((PyObject *)p); +#ifdef DEBUG + printf("path_dealloc end\n"); +#endif +} + +static PyObject * +path_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + return type->tp_alloc(type, 0); + /* initializes memory to zeros */ +} + +static int +path_init(PycairoPath *p, PyObject *args, PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "The Path type cannot be instantiated, " + "use Context.copy_path()"); + return -1; +} + +static PyObject * +path_str(PycairoPath *p) { + PyObject *s, *pieces = NULL, *result = NULL; + cairo_path_t *path = p->path; + cairo_path_data_t *data; + int i, ret; + char buf[80]; + + pieces = PyList_New(0); + if (pieces == NULL) + goto Done; + + /* loop reading elements */ + for (i=0; i < path->num_data; i += path->data[i].header.length) { + data = &path->data[i]; + switch (data->header.type) { + + case CAIRO_PATH_MOVE_TO: + PyOS_snprintf(buf, sizeof(buf), "move_to %f %f", + data[1].point.x, data[1].point.y); + s = PyString_FromString(buf); + if (!s) + goto Done; + ret = PyList_Append(pieces, s); + Py_DECREF(s); + if (ret < 0) + goto Done; + break; + + case CAIRO_PATH_LINE_TO: + PyOS_snprintf(buf, sizeof(buf), "line_to %f %f", + data[1].point.x, data[1].point.y); + s = PyString_FromString(buf); + if (!s) + goto Done; + ret = PyList_Append(pieces, s); + Py_DECREF(s); + if (ret < 0) + goto Done; + break; + + case CAIRO_PATH_CURVE_TO: + PyOS_snprintf(buf, sizeof(buf), "curve_to %f %f %f %f %f %f", + data[1].point.x, data[1].point.y, + data[2].point.x, data[2].point.y, + data[3].point.x, data[3].point.y); + s = PyString_FromString(buf); + if (!s) + goto Done; + ret = PyList_Append(pieces, s); + Py_DECREF(s); + if (ret < 0) + goto Done; + break; + + case CAIRO_PATH_CLOSE_PATH: + s = PyString_FromString("close path"); + if (!s) + goto Done; + ret = PyList_Append(pieces, s); + Py_DECREF(s); + if (ret < 0) + goto Done; + break; + } + } + /* result = "\n".join(pieces) */ + s = PyString_FromString("\n"); + if (s == NULL) + goto Done; + result = _PyString_Join(s, pieces); + Py_DECREF(s); + +Done: + Py_XDECREF(pieces); + return result; +} + +static PyObject * path_iter(PyObject *seq); /* forward declaration */ + + +PyTypeObject PycairoPath_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Path", /* tp_name */ + sizeof(PycairoPath), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)path_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 */ + 0, /* tp_hash */ + 0, /* tp_call */ + (reprfunc)path_str, /* 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 */ + (getiterfunc)path_iter, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)path_init, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)path_new, /* tp_new */ +}; + +/*********************** PycairoPath Iterator **************************/ + +typedef struct { + PyObject_HEAD + int index; /* position within PycairoPath */ + PycairoPath *pypath; /* Set to NULL when iterator is exhausted */ +} PycairoPathiter; + +PyTypeObject PycairoPathiter_Type; + + +static void +pathiter_dealloc(PycairoPathiter *it) { + Py_XDECREF(it->pypath); + PyObject_Del(it); +} + +static PyObject * +path_iter(PyObject *pypath) { + PycairoPathiter *it; + + if (!PyObject_TypeCheck (pypath, &PycairoPath_Type)) { + PyErr_BadInternalCall(); + return NULL; + } + it = PyObject_New(PycairoPathiter, &PycairoPathiter_Type); + if (it == NULL) + return NULL; + + it->index = 0; + Py_INCREF(pypath); + it->pypath = (PycairoPath *)pypath; + return (PyObject *) it; +} + +static PyObject * +pathiter_next(PycairoPathiter *it) { + PycairoPath *pypath; + cairo_path_t *path; + + assert(it != NULL); + pypath = it->pypath; + if (pypath == NULL) + return NULL; + assert (PyObject_TypeCheck (pypath, &PycairoPath_Type)); + path = pypath->path; + + /* return the next path element, advance index */ + if (it->index < path->num_data) { + cairo_path_data_t *data = &path->data[it->index]; + int type = data->header.type; + + it->index += data[0].header.length; + + switch (type) { + case CAIRO_PATH_MOVE_TO: + case CAIRO_PATH_LINE_TO: + return Py_BuildValue("(i(dd))", type, + data[1].point.x, data[1].point.y); + case CAIRO_PATH_CURVE_TO: + return Py_BuildValue("(i(dddddd))", type, + data[1].point.x, data[1].point.y, + data[2].point.x, data[2].point.y, + data[3].point.x, data[3].point.y); + case CAIRO_PATH_CLOSE_PATH: + return Py_BuildValue("i()", type); + default: + PyErr_SetString(PyExc_RuntimeError, "unknown CAIRO_PATH type"); + return NULL; + } + } + + /* iterator has no remaining items */ + Py_DECREF(pypath); + it->pypath = NULL; + return NULL; +} + +PyTypeObject PycairoPathiter_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Pathiter", /* tp_name */ + sizeof(PycairoPathiter), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pathiter_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 */ + 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, /* PyObject_SelfIter, */ /* tp_iter */ + (iternextfunc)pathiter_next, /* tp_iternext */ + 0, /* tp_methods */ +}; diff --git a/src/pattern.c b/src/pattern.c new file mode 100644 index 0000000..ba9bf94 --- /dev/null +++ b/src/pattern.c @@ -0,0 +1,598 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2004-2006 Steve 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 + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "private.h" + + +/* Class Pattern ---------------------------------------------------------- */ + +/* PycairoPattern_FromPattern + * Create a new + * PycairoSolidPattern, + * PycairoSurfacePattern, + * PycairoLinearGradient, or + * PycairoRadialGradient from a cairo_pattern_t. + * pattern - a cairo_pattern_t to 'wrap' into a Python object. + * It is unreferenced if the PycairoPattern creation fails, or if the + * pattern has an error status. + * base - the base object used to create the pattern, or NULL. + * It is referenced to keep it alive while the cairo_pattern_t is being used. + * For PycairoSurfacePattern base should be the PycairoSurface, for other + # patterns it should be NULL. + * Return value: New reference or NULL on failure + */ +PyObject * +PycairoPattern_FromPattern (cairo_pattern_t *pattern, PyObject *base) { + PyTypeObject *type = NULL; + PyObject *o; + + assert (pattern != NULL); + + if (Pycairo_Check_Status (cairo_pattern_status (pattern))) { + cairo_pattern_destroy (pattern); + return NULL; + } + + switch (cairo_pattern_get_type (pattern)) { + case CAIRO_PATTERN_TYPE_SOLID: + type = &PycairoSolidPattern_Type; + break; + case CAIRO_PATTERN_TYPE_SURFACE: + type = &PycairoSurfacePattern_Type; + break; + case CAIRO_PATTERN_TYPE_LINEAR: + type = &PycairoLinearGradient_Type; + break; + case CAIRO_PATTERN_TYPE_RADIAL: + type = &PycairoRadialGradient_Type; + break; + default: + type = &PycairoPattern_Type; + break; + } + + o = type->tp_alloc(type, 0); + if (o == NULL) { + cairo_pattern_destroy (pattern); + } else { + ((PycairoPattern *)o)->pattern = pattern; + Py_XINCREF(base); + ((PycairoPattern *)o)->base = base; + } + return o; +} + +static void +pattern_dealloc (PycairoPattern *o) { + if (o->pattern) { + cairo_pattern_destroy (o->pattern); + o->pattern = NULL; + } + Py_CLEAR(o->base); + + o->ob_type->tp_free((PyObject *)o); +} + +static PyObject * +pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, + "The Pattern type cannot be instantiated"); + return NULL; +} + +static PyObject * +pattern_get_extend (PycairoPattern *o) { + return PyInt_FromLong (cairo_pattern_get_extend (o->pattern)); +} + +static PyObject * +pattern_get_matrix (PycairoPattern *o) { + cairo_matrix_t matrix; + cairo_pattern_get_matrix (o->pattern, &matrix); + return PycairoMatrix_FromMatrix (&matrix); +} + +static PyObject * +pattern_set_extend (PycairoPattern *o, PyObject *args) { + int extend; + + if (!PyArg_ParseTuple(args, "i:Pattern.set_extend", &extend)) + return NULL; + + cairo_pattern_set_extend (o->pattern, extend); + Py_RETURN_NONE; +} + +static PyObject * +pattern_set_matrix (PycairoPattern *o, PyObject *args) { + PycairoMatrix *m; + + if (!PyArg_ParseTuple (args, "O!:Pattern.set_matrix", + &PycairoMatrix_Type, &m)) + return NULL; + + cairo_pattern_set_matrix (o->pattern, &m->matrix); + Py_RETURN_NONE; +} + +static PyMethodDef pattern_methods[] = { + /* methods never exposed in a language binding: + * cairo_pattern_destroy() + * cairo_pattern_get_type() + * cairo_pattern_reference() + * + * cairo_pattern_status() + * - not needed since Pycairo handles status checking + */ + {"get_extend", (PyCFunction)pattern_get_extend, METH_NOARGS }, + {"get_matrix", (PyCFunction)pattern_get_matrix, METH_NOARGS }, + {"set_extend", (PyCFunction)pattern_set_extend, METH_VARARGS }, + {"set_matrix", (PyCFunction)pattern_set_matrix, METH_VARARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoPattern_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Pattern", /* tp_name */ + sizeof(PycairoPattern), /* tp_basicsize */ + 0, /* tp_itemsize */ + (destructor)pattern_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 */ + 0, /* 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 */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + pattern_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)pattern_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + + +/* Class SolidPattern ----------------------------------------------------- */ + +static PyObject * +solid_pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double r, g, b, a = 1.0; + if (!PyArg_ParseTuple (args, "ddd|d:SolidPattern.__new__", &r, &g, &b, &a)) + return NULL; + return PycairoPattern_FromPattern (cairo_pattern_create_rgba (r, g, b, a), + NULL); +} + +static PyObject * +solid_pattern_get_rgba (PycairoSolidPattern *o) { + double red, green, blue, alpha; + cairo_pattern_get_rgba (o->pattern, &red, &green, &blue, &alpha); + return Py_BuildValue("(dddd)", red, green, blue, alpha); +} + +static PyMethodDef solid_pattern_methods[] = { + {"get_rgba", (PyCFunction)solid_pattern_get_rgba, METH_NOARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoSolidPattern_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.SolidPattern", /* tp_name */ + sizeof(PycairoSolidPattern), /* 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 */ + solid_pattern_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoPattern_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)solid_pattern_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + +/* Class SurfacePattern --------------------------------------------------- */ + +static PyObject * +surface_pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PycairoSurface *s; + if (!PyArg_ParseTuple (args, "O!:SurfacePattern.__new__", + &PycairoSurface_Type, &s)) + return NULL; + return PycairoPattern_FromPattern ( + cairo_pattern_create_for_surface (s->surface), (PyObject *)s); +} + +static PyObject * +surface_pattern_get_filter (PycairoSurfacePattern *o) { + return PyInt_FromLong (cairo_pattern_get_filter (o->pattern)); +} + +static PyObject * +surface_pattern_get_surface (PycairoSurfacePattern *o) { + /* + cairo_surface_t *surface; + cairo_pattern_get_surface (o->pattern, &surface); + return PycairoSurface_FromSurface ( + cairo_surface_reference (surface), NULL); + */ + /* return the surface used to create the pattern */ + return Py_BuildValue("O", o->base); +} + +static PyObject * +surface_pattern_set_filter (PycairoSurfacePattern *o, PyObject *args) { + int filter; + + if (!PyArg_ParseTuple (args, "i:SurfacePattern.set_filter", &filter)) + return NULL; + + cairo_pattern_set_filter (o->pattern, filter); + Py_RETURN_NONE; +} + +static PyMethodDef surface_pattern_methods[] = { + {"get_filter", (PyCFunction)surface_pattern_get_filter, METH_NOARGS }, + {"get_surface", (PyCFunction)surface_pattern_get_surface, METH_NOARGS }, + {"set_filter", (PyCFunction)surface_pattern_set_filter, METH_VARARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoSurfacePattern_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.SurfacePattern", /* tp_name */ + sizeof(PycairoSurfacePattern), /* 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 */ + surface_pattern_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoPattern_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)surface_pattern_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + +/* Class Gradient --------------------------------------------------------- */ + +static PyObject * +gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, + "The Gradient type cannot be instantiated"); + return NULL; +} + +static PyObject * +gradient_add_color_stop_rgb (PycairoGradient *o, PyObject *args) { + double offset, red, green, blue; + if (!PyArg_ParseTuple(args, "dddd:Gradient.add_color_stop_rgb", + &offset, &red, &green, &blue)) + return NULL; + cairo_pattern_add_color_stop_rgb (o->pattern, offset, red, green, blue); + RETURN_NULL_IF_CAIRO_PATTERN_ERROR(o->pattern); + Py_RETURN_NONE; +} + +static PyObject * +gradient_add_color_stop_rgba (PycairoGradient *o, PyObject *args) { + double offset, red, green, blue, alpha; + if (!PyArg_ParseTuple(args, "ddddd:Gradient.add_color_stop_rgba", + &offset, &red, &green, &blue, &alpha)) + return NULL; + cairo_pattern_add_color_stop_rgba (o->pattern, offset, red, + green, blue, alpha); + RETURN_NULL_IF_CAIRO_PATTERN_ERROR(o->pattern); + Py_RETURN_NONE; +} + +static PyMethodDef gradient_methods[] = { + {"add_color_stop_rgb",(PyCFunction)gradient_add_color_stop_rgb, + METH_VARARGS }, + {"add_color_stop_rgba",(PyCFunction)gradient_add_color_stop_rgba, + METH_VARARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoGradient_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.Gradient", /* tp_name */ + sizeof(PycairoGradient), /* 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 | Py_TPFLAGS_BASETYPE,/* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + gradient_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoPattern_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)gradient_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + +/* Class LinearGradient --------------------------------------------------- */ + +static PyObject * +linear_gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double x0, y0, x1, y1; + if (!PyArg_ParseTuple(args, "dddd:LinearGradient.__new__", + &x0, &y0, &x1, &y1)) + return NULL; + return PycairoPattern_FromPattern ( + cairo_pattern_create_linear (x0, y0, x1, y1), NULL); +} + +static PyObject * +linear_gradient_get_linear_points (PycairoLinearGradient *o) { + double x0, y0, x1, y1; + cairo_pattern_get_linear_points (o->pattern, &x0, &y0, &x1, &y1); + return Py_BuildValue("(dddd)", x0, y0, x1, y1); +} + +static PyMethodDef linear_gradient_methods[] = { + {"get_linear_points", (PyCFunction)linear_gradient_get_linear_points, + METH_NOARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoLinearGradient_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.LinearGradient", /* tp_name */ + sizeof(PycairoLinearGradient), /* 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 */ + linear_gradient_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoGradient_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)linear_gradient_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; + +/* Class RadialGradient --------------------------------------------------- */ + +static PyObject * +radial_gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double cx0, cy0, radius0, cx1, cy1, radius1; + if (!PyArg_ParseTuple(args, "dddddd:RadialGradient.__new__", + &cx0, &cy0, &radius0, &cx1, &cy1, &radius1)) + return NULL; + return PycairoPattern_FromPattern ( + cairo_pattern_create_radial (cx0, cy0, radius0, cx1, cy1, radius1), + NULL); +} + +static PyObject * +radial_gradient_get_radial_circles (PycairoRadialGradient *o) { + double x0, y0, r0, x1, y1, r1; + cairo_pattern_get_radial_circles (o->pattern, &x0, &y0, &r0, + &x1, &y1, &r1); + return Py_BuildValue("(dddddd)", x0, y0, r0, x1, y1, r1); +} + +static PyMethodDef radial_gradient_methods[] = { + {"get_radial_circles", (PyCFunction)radial_gradient_get_radial_circles, + METH_NOARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoRadialGradient_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "cairo.RadialGradient", /* tp_name */ + sizeof(PycairoRadialGradient), /* 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 */ + radial_gradient_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PycairoGradient_Type, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)radial_gradient_new, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ + 0, /* tp_bases */ +}; diff --git a/src/private.h b/src/private.h new file mode 100644 index 0000000..5951104 --- /dev/null +++ b/src/private.h @@ -0,0 +1,161 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2003 James Henstridge, 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. + */ + +#ifndef _PYCAIRO_PRIVATE_H_ +#define _PYCAIRO_PRIVATE_H_ + +#ifdef _PYCAIRO_H_ +# error "don't include pycairo.h and pycairo-private.h together" +#endif + +#define _INSIDE_PYCAIRO_ +#include + +#include "pycairo.h" + + +extern PyObject *CairoError; + +extern PyTypeObject PycairoContext_Type; +PyObject *PycairoContext_FromContext (cairo_t *ctx, PyTypeObject *type, + PyObject *base); + +extern PyTypeObject PycairoFontFace_Type; +extern PyTypeObject PycairoToyFontFace_Type; +PyObject *PycairoFontFace_FromFontFace (cairo_font_face_t *font_face); + +extern PyTypeObject PycairoFontOptions_Type; +PyObject *PycairoFontOptions_FromFontOptions ( + cairo_font_options_t *font_options); + +extern PyTypeObject PycairoMatrix_Type; +PyObject *PycairoMatrix_FromMatrix (const cairo_matrix_t *matrix); + +extern PyTypeObject PycairoPath_Type; +PyObject *PycairoPath_FromPath (cairo_path_t *path); + +extern PyTypeObject PycairoPathiter_Type; + +extern PyTypeObject PycairoPattern_Type; +extern PyTypeObject PycairoSolidPattern_Type; +extern PyTypeObject PycairoSurfacePattern_Type; +extern PyTypeObject PycairoGradient_Type; +extern PyTypeObject PycairoLinearGradient_Type; +extern PyTypeObject PycairoRadialGradient_Type; +PyObject *PycairoPattern_FromPattern (cairo_pattern_t *pattern, + PyObject *base); + +extern PyTypeObject PycairoScaledFont_Type; +PyObject *PycairoScaledFont_FromScaledFont (cairo_scaled_font_t *scaled_font); + +extern PyTypeObject PycairoSurface_Type; +extern PyTypeObject PycairoImageSurface_Type; + +#if CAIRO_HAS_PDF_SURFACE +extern PyTypeObject PycairoPDFSurface_Type; +#endif + +#if CAIRO_HAS_PS_SURFACE +extern PyTypeObject PycairoPSSurface_Type; +#endif + +#if CAIRO_HAS_SVG_SURFACE +extern PyTypeObject PycairoSVGSurface_Type; +#endif + +#if CAIRO_HAS_WIN32_SURFACE +extern PyTypeObject PycairoWin32Surface_Type; +#endif + +#if CAIRO_HAS_XLIB_SURFACE +extern PyTypeObject PycairoXlibSurface_Type; +#endif + +PyObject *PycairoSurface_FromSurface (cairo_surface_t *surface, + PyObject *base); + +int Pycairo_Check_Status (cairo_status_t status); + +/* error checking macros */ +#define RETURN_NULL_IF_CAIRO_ERROR(status) \ + do { \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + +#define RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(ctx) \ + do { \ + cairo_status_t status = cairo_status (ctx); \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + +#define RETURN_NULL_IF_CAIRO_PATTERN_ERROR(pattern) \ + do { \ + cairo_status_t status = cairo_pattern_status (pattern); \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + +#define RETURN_NULL_IF_CAIRO_SURFACE_ERROR(surface) \ + do { \ + cairo_status_t status = cairo_surface_status (surface); \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + +#define RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(sc_font) \ + do { \ + cairo_status_t status = cairo_scaled_font_status (sc_font); \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + +#define RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(fo) \ + do { \ + cairo_status_t status = cairo_font_options_status (fo); \ + if (status != CAIRO_STATUS_SUCCESS) { \ + Pycairo_Check_Status (status); \ + return NULL; \ + } \ + } while (0) + + +#endif /* _PYCAIRO_PRIVATE_H_ */ diff --git a/src/pycairo-context.c b/src/pycairo-context.c deleted file mode 100644 index a5398d1..0000000 --- a/src/pycairo-context.c +++ /dev/null @@ -1,1446 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2003 James Henstridge, 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 - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "pycairo-private.h" - - -/* PycairoContext_FromContext - * Create a new PycairoContext from a cairo_t - * ctx - a cairo_t to 'wrap' into a Python object. - * It is unreferenced if the PycairoContext creation fails, or if - * the cairo_t has an error status. - * type - a pointer to the type to instantiate. - * It can be &PycairoContext_Type, or a PycairoContext_Type subtype. - * (cairo.Context or a cairo.Context subclass) - * base - the base object used to create the context, or NULL. - * it is referenced to keep it alive while the cairo_t is being used - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoContext_FromContext(cairo_t *ctx, PyTypeObject *type, PyObject *base) { - PyObject *o; - - assert (ctx != NULL); - - if (Pycairo_Check_Status (cairo_status (ctx))) { - cairo_destroy (ctx); - return NULL; - } - - o = PycairoContext_Type.tp_alloc (type, 0); - if (o) { - ((PycairoContext *)o)->ctx = ctx; - Py_XINCREF(base); - ((PycairoContext *)o)->base = base; - } else { - cairo_destroy (ctx); - } - return o; -} - -static void -pycairo_dealloc(PycairoContext *o) { - if (o->ctx) { - cairo_destroy(o->ctx); - o->ctx = NULL; - } - Py_CLEAR(o->base); - - o->ob_type->tp_free((PyObject *)o); -} - -static PyObject * -pycairo_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PycairoSurface *s; - if (!PyArg_ParseTuple(args, "O!:Context.__new__", - &PycairoSurface_Type, &s)) - return NULL; - return PycairoContext_FromContext (cairo_create (s->surface), type, NULL); -} - -static PyObject * -pycairo_append_path (PycairoContext *o, PyObject *args) { - PycairoPath *p; - - if (!PyArg_ParseTuple(args, "O!:Context.append_path", - &PycairoPath_Type, &p)) - return NULL; - - Py_BEGIN_ALLOW_THREADS; - cairo_append_path (o->ctx, p->path); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_arc (PycairoContext *o, PyObject *args) { - double xc, yc, radius, angle1, angle2; - - if (!PyArg_ParseTuple (args, "ddddd:Context.arc", - &xc, &yc, &radius, &angle1, &angle2)) - return NULL; - - cairo_arc (o->ctx, xc, yc, radius, angle1, angle2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_arc_negative (PycairoContext *o, PyObject *args) { - double xc, yc, radius, angle1, angle2; - - if (!PyArg_ParseTuple (args, "ddddd:Context.arc_negative", - &xc, &yc, &radius, &angle1, &angle2)) - return NULL; - - cairo_arc_negative (o->ctx, xc, yc, radius, angle1, angle2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_clip (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_clip (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_clip_extents (PycairoContext *o) { - double x1, y1, x2, y2; - cairo_clip_extents (o->ctx, &x1, &y1, &x2, &y2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddd)", x1, y1, x2, y2); -} - -static PyObject * -pycairo_clip_preserve (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_clip_preserve (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_close_path (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_close_path (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_copy_clip_rectangle_list (PycairoContext *o) { - int i; - PyObject *rv = NULL; - cairo_rectangle_t *r; - cairo_rectangle_list_t *rlist = cairo_copy_clip_rectangle_list (o->ctx); - if (rlist->status != CAIRO_STATUS_SUCCESS) { - Pycairo_Check_Status (rlist->status); - goto exit; - } - - rv = PyTuple_New(rlist->num_rectangles); - if (rv == NULL) - goto exit; - - for (i = 0, r = rlist->rectangles; i < rlist->num_rectangles; i++, r++) { - PyObject *py_rect = Py_BuildValue("(dddd)", r->x, r->y, - r->width, r->height); - if (py_rect == NULL) { - Py_CLEAR(rv); - goto exit; - } - PyTuple_SET_ITEM (rv, i, py_rect); - } - exit: - cairo_rectangle_list_destroy(rlist); - return rv; -} - -static PyObject * -pycairo_copy_page (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_copy_page (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_copy_path (PycairoContext *o) { - cairo_path_t *cp; - Py_BEGIN_ALLOW_THREADS; - cp = cairo_copy_path (o->ctx); - Py_END_ALLOW_THREADS; - return PycairoPath_FromPath (cp); -} - -static PyObject * -pycairo_copy_path_flat (PycairoContext *o) { - cairo_path_t *cp; - Py_BEGIN_ALLOW_THREADS; - cp = cairo_copy_path_flat (o->ctx); - Py_END_ALLOW_THREADS; - return PycairoPath_FromPath (cp); -} - -static PyObject * -pycairo_curve_to (PycairoContext *o, PyObject *args) { - double x1, y1, x2, y2, x3, y3; - - if (!PyArg_ParseTuple (args, "dddddd:Context.curve_to", - &x1, &y1, &x2, &y2, &x3, &y3)) - return NULL; - - cairo_curve_to (o->ctx, x1, y1, x2, y2, x3, y3); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_device_to_user(PycairoContext *o, PyObject *args) { - double x, y; - - if (!PyArg_ParseTuple(args, "dd:Context.device_to_user", &x, &y)) - return NULL; - - cairo_device_to_user(o->ctx, &x, &y); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dd)", x, y); -} - -static PyObject * -pycairo_device_to_user_distance (PycairoContext *o, PyObject *args) { - double dx, dy; - - if (!PyArg_ParseTuple (args, "dd:Context.device_to_user_distance", - &dx, &dy)) - return NULL; - - cairo_device_to_user_distance (o->ctx, &dx, &dy); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dd)", dx, dy); -} - -static PyObject * -pycairo_fill (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_fill (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_fill_extents (PycairoContext *o) { - double x1, y1, x2, y2; - cairo_fill_extents (o->ctx, &x1, &y1, &x2, &y2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddd)", x1, y1, x2, y2); -} - -static PyObject * -pycairo_fill_preserve (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_fill_preserve (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_font_extents (PycairoContext *o) { - cairo_font_extents_t e; - - cairo_font_extents (o->ctx, &e); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(ddddd)", e.ascent, e.descent, e.height, - e.max_x_advance, e.max_y_advance); -} - -static PyObject * -pycairo_get_antialias (PycairoContext *o) { - return PyInt_FromLong (cairo_get_antialias (o->ctx)); -} - -static PyObject * -pycairo_get_current_point (PycairoContext *o) { - double x, y; - cairo_get_current_point (o->ctx, &x, &y); - return Py_BuildValue("(dd)", x, y); -} - -static PyObject * -pycairo_get_dash (PycairoContext *o) { - double *dashes = NULL, offset; - int count, i; - PyObject *py_dashes = NULL, *rv = NULL; - - count = cairo_get_dash_count (o->ctx); - dashes = PyMem_Malloc (count * sizeof(double)); - if (dashes == NULL) - return PyErr_NoMemory(); - - cairo_get_dash (o->ctx, dashes, &offset); - py_dashes = PyTuple_New(count); - if (py_dashes == NULL) - goto exit; - - for (i = 0; i < count; i++) { - PyObject *dash = PyFloat_FromDouble(dashes[i]); - if (dash == NULL) - goto exit; - PyTuple_SET_ITEM (py_dashes, i, dash); - } - rv = Py_BuildValue("(Od)", py_dashes, offset); - - exit: - PyMem_Free (dashes); - Py_XDECREF(py_dashes); - return rv; -} - -static PyObject * -pycairo_get_dash_count (PycairoContext *o) { - return PyInt_FromLong (cairo_get_dash_count (o->ctx)); -} - -static PyObject * -pycairo_get_fill_rule (PycairoContext *o) { - return PyInt_FromLong(cairo_get_fill_rule (o->ctx)); -} - -static PyObject * -pycairo_get_font_face (PycairoContext *o) { - return PycairoFontFace_FromFontFace ( - cairo_font_face_reference (cairo_get_font_face (o->ctx))); -} - -static PyObject * -pycairo_get_font_matrix (PycairoContext *o) { - cairo_matrix_t matrix; - cairo_get_font_matrix (o->ctx, &matrix); - return PycairoMatrix_FromMatrix (&matrix); -} - -static PyObject * -pycairo_get_font_options (PycairoContext *o) { - cairo_font_options_t *options = cairo_font_options_create(); - cairo_get_font_options (o->ctx, options); - /* there is no reference fn */ - return PycairoFontOptions_FromFontOptions (options); -} - -static PyObject * -pycairo_get_group_target (PycairoContext *o) { - cairo_surface_t *surface = cairo_get_group_target (o->ctx); - if (surface != NULL) - return PycairoSurface_FromSurface (cairo_surface_reference (surface), - NULL); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_get_line_cap (PycairoContext *o) { - return PyInt_FromLong(cairo_get_line_cap (o->ctx)); -} - -static PyObject * -pycairo_get_line_join (PycairoContext *o) { - return PyInt_FromLong(cairo_get_line_join (o->ctx)); -} - -static PyObject * -pycairo_get_line_width (PycairoContext *o) { - return PyFloat_FromDouble(cairo_get_line_width (o->ctx)); -} - -static PyObject * -pycairo_get_matrix (PycairoContext *o) { - cairo_matrix_t matrix; - cairo_get_matrix (o->ctx, &matrix); - return PycairoMatrix_FromMatrix (&matrix); -} - -static PyObject * -pycairo_get_miter_limit (PycairoContext *o) { - return PyFloat_FromDouble (cairo_get_miter_limit (o->ctx)); -} - -static PyObject * -pycairo_get_operator (PycairoContext *o) { - return PyInt_FromLong (cairo_get_operator (o->ctx)); -} - -static PyObject * -pycairo_get_scaled_font (PycairoContext *o) { - return PycairoScaledFont_FromScaledFont ( - cairo_scaled_font_reference (cairo_get_scaled_font (o->ctx))); -} - -static PyObject * -pycairo_get_source (PycairoContext *o) { - return PycairoPattern_FromPattern ( - cairo_pattern_reference (cairo_get_source (o->ctx)), NULL); -} - -static PyObject * -pycairo_get_target (PycairoContext *o) { - return PycairoSurface_FromSurface ( - cairo_surface_reference (cairo_get_target (o->ctx)), - NULL); -} - -static PyObject * -pycairo_get_tolerance (PycairoContext *o) { - return PyFloat_FromDouble (cairo_get_tolerance (o->ctx)); -} - -/* read a Python sequence of (i,x,y) sequences - * return cairo_glyph_t * - * num_glyphs - * must call PyMem_Free(glyphs) when finished using the glyphs - */ -static cairo_glyph_t * -_PyGlyphs_AsGlyphs (PyObject *py_object, int *num_glyphs) -{ - int length, i; - cairo_glyph_t *glyphs = NULL, *glyph; - PyObject *py_glyphs, *py_seq = NULL; - - py_glyphs = PySequence_Fast (py_object, "glyphs must be a sequence"); - if (py_glyphs == NULL) - return NULL; - - length = PySequence_Fast_GET_SIZE(py_glyphs); - if (*num_glyphs < 0 || *num_glyphs > length) - *num_glyphs = length; - - glyphs = PyMem_Malloc (*num_glyphs * sizeof(cairo_glyph_t)); - if (glyphs == NULL) { - PyErr_NoMemory(); - goto error; - } - for (i = 0, glyph = glyphs; i < *num_glyphs; i++, glyph++) { - PyObject *py_item = PySequence_Fast_GET_ITEM(py_glyphs, i); - py_seq = PySequence_Fast (py_item, "glyph items must be a sequence"); - if (py_seq == NULL) - goto error; - if (PySequence_Fast_GET_SIZE(py_seq) != 3) { - PyErr_SetString(PyExc_ValueError, - "each glyph item must be an (i,x,y) sequence"); - goto error; - } - glyph->index = PyInt_AsLong(PySequence_Fast_GET_ITEM(py_seq, 0)); - glyph->x = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_seq, 1)); - glyph->y = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_seq, 2)); - if (PyErr_Occurred()) - goto error; - Py_DECREF(py_seq); - } - Py_DECREF(py_glyphs); - return glyphs; - error: - Py_DECREF(py_glyphs); - Py_XDECREF(py_seq); - PyMem_Free(glyphs); - return NULL; -} - -static PyObject * -pycairo_glyph_extents (PycairoContext *o, PyObject *args) { - int num_glyphs = -1; - cairo_glyph_t *glyphs; - cairo_text_extents_t extents; - PyObject *py_object; - - if (!PyArg_ParseTuple (args, "O|i:Context.glyph_extents", - &py_object, &num_glyphs)) - return NULL; - - glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); - if (glyphs == NULL) - return NULL; - cairo_glyph_extents (o->ctx, glyphs, num_glyphs, &extents); - PyMem_Free (glyphs); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, - extents.width, extents.height, extents.x_advance, - extents.y_advance); -} - -static PyObject * -pycairo_glyph_path (PycairoContext *o, PyObject *args) { - int num_glyphs = -1; - cairo_glyph_t *glyphs; - PyObject *py_object; - - if (!PyArg_ParseTuple (args, "O|i:Context.glyph_path", - &py_object, &num_glyphs)) - return NULL; - - glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); - if (glyphs == NULL) - return NULL; - cairo_glyph_path (o->ctx, glyphs, num_glyphs); - PyMem_Free (glyphs); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_has_current_point (PycairoContext *o) { - PyObject *b = cairo_has_current_point (o->ctx) ? Py_True : Py_False; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_INCREF(b); - return b; -} - -static PyObject * -pycairo_identity_matrix (PycairoContext *o) { - cairo_identity_matrix (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_in_fill (PycairoContext *o, PyObject *args) { - double x, y; - PyObject *result; - - if (!PyArg_ParseTuple (args, "dd:Context.in_fill", &x, &y)) - return NULL; - - result = cairo_in_fill (o->ctx, x, y) ? Py_True : Py_False; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_INCREF(result); - return result; -} - -static PyObject * -pycairo_in_stroke (PycairoContext *o, PyObject *args) { - double x, y; - PyObject *result; - - if (!PyArg_ParseTuple (args, "dd:Context.in_stroke", &x, &y)) - return NULL; - - result = cairo_in_stroke (o->ctx, x, y) ? Py_True : Py_False; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_INCREF(result); - return result; -} - -static PyObject * -pycairo_line_to (PycairoContext *o, PyObject *args) { - double x, y; - - if (!PyArg_ParseTuple (args, "dd:Context.line_to", &x, &y)) - return NULL; - - cairo_line_to (o->ctx, x, y); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_mask (PycairoContext *o, PyObject *args) { - PycairoPattern *p; - - if (!PyArg_ParseTuple(args, "O!:Context.mask", &PycairoPattern_Type, &p)) - return NULL; - - Py_BEGIN_ALLOW_THREADS; - cairo_mask (o->ctx, p->pattern); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_mask_surface (PycairoContext *o, PyObject *args) { - PycairoSurface *s; - double surface_x = 0.0, surface_y = 0.0; - - if (!PyArg_ParseTuple (args, "O!|dd:Context.mask_surface", - &PycairoSurface_Type, &s, &surface_x, &surface_y)) - return NULL; - - Py_BEGIN_ALLOW_THREADS; - cairo_mask_surface (o->ctx, s->surface, surface_x, surface_y); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_move_to (PycairoContext *o, PyObject *args) { - double x, y; - - if (!PyArg_ParseTuple (args, "dd:Context.move_to", &x, &y)) - return NULL; - - cairo_move_to (o->ctx, x, y); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_new_path (PycairoContext *o) { - cairo_new_path (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_new_sub_path (PycairoContext *o) { - cairo_new_sub_path (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_paint (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_paint (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_paint_with_alpha (PycairoContext *o, PyObject *args) { - double alpha; - - if (!PyArg_ParseTuple (args, "d:Context.paint_with_alpha", &alpha)) - return NULL; - - Py_BEGIN_ALLOW_THREADS; - cairo_paint_with_alpha (o->ctx, alpha); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_path_extents (PycairoContext *o) { - double x1, y1, x2, y2; - cairo_path_extents (o->ctx, &x1, &y1, &x2, &y2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddd)", x1, y1, x2, y2); -} - -static PyObject * -pycairo_pop_group (PycairoContext *o) { - return PycairoPattern_FromPattern (cairo_pop_group (o->ctx), NULL); -} - -static PyObject * -pycairo_pop_group_to_source (PycairoContext *o) { - cairo_pop_group_to_source (o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_push_group (PycairoContext *o) { - cairo_push_group (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_push_group_with_content (PycairoContext *o, PyObject *args) { - cairo_content_t content; - - if (!PyArg_ParseTuple(args, "i:Context.push_group_with_content", - &content)) - return NULL; - cairo_push_group_with_content (o->ctx, content); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_rectangle (PycairoContext *o, PyObject *args) { - double x, y, width, height; - - if (!PyArg_ParseTuple (args, "dddd:Context.rectangle", - &x, &y, &width, &height)) - return NULL; - - cairo_rectangle (o->ctx, x, y, width, height); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_rel_curve_to (PycairoContext *o, PyObject *args) { - double dx1, dy1, dx2, dy2, dx3, dy3; - - if (!PyArg_ParseTuple (args, "dddddd:Context.rel_curve_to", - &dx1, &dy1, &dx2, &dy2, &dx3, &dy3)) - return NULL; - - cairo_rel_curve_to (o->ctx, dx1, dy1, dx2, dy2, dx3, dy3); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_rel_line_to (PycairoContext *o, PyObject *args) { - double dx, dy; - - if (!PyArg_ParseTuple (args, "dd:Context.rel_line_to", &dx, &dy)) - return NULL; - - cairo_rel_line_to (o->ctx, dx, dy); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_rel_move_to (PycairoContext *o, PyObject *args) { - double dx, dy; - - if (!PyArg_ParseTuple (args, "dd:Context.rel_move_to", &dx, &dy)) - return NULL; - - cairo_rel_move_to (o->ctx, dx, dy); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_reset_clip (PycairoContext *o) { - cairo_reset_clip (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_restore (PycairoContext *o) { - cairo_restore (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_rotate (PycairoContext *o, PyObject *args) { - double angle; - - if (!PyArg_ParseTuple(args, "d:Context.rotate", &angle)) - return NULL; - - cairo_rotate (o->ctx, angle); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_save (PycairoContext *o) { - cairo_save (o->ctx); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_scale (PycairoContext *o, PyObject *args) { - double sx, sy; - - if (!PyArg_ParseTuple (args, "dd:Context.scale", &sx, &sy)) - return NULL; - - cairo_scale (o->ctx, sx, sy); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_select_font_face (PycairoContext *o, PyObject *args) { - PyObject *obj; - PyObject *pyUTF8 = NULL; - const char *utf8family = NULL; - cairo_font_slant_t slant = CAIRO_FONT_SLANT_NORMAL; - cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL; - - if (!PyArg_ParseTuple(args, "O!|ii:Context.select_font_face", - &PyBaseString_Type, &obj, &slant, &weight)) - return NULL; - - /* accept str and unicode family, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8family = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8family = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "Context.select_font_face: family must be str or unicode"); - } - if (utf8family == NULL) - return NULL; - - cairo_select_font_face (o->ctx, utf8family, slant, weight); - Py_XDECREF(pyUTF8); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_antialias (PycairoContext *o, PyObject *args) { - cairo_antialias_t antialias = CAIRO_ANTIALIAS_DEFAULT; - - if (!PyArg_ParseTuple(args, "|i:Context.set_antialias", &antialias)) - return NULL; - - cairo_set_antialias (o->ctx, antialias); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_dash (PycairoContext *o, PyObject *args) { - double *dashes, offset = 0; - int num_dashes, i; - PyObject *py_dashes; - - if (!PyArg_ParseTuple (args, "O|d:Context.set_dash", &py_dashes, &offset)) - return NULL; - - py_dashes = PySequence_Fast (py_dashes, - "first argument must be a sequence"); - if (py_dashes == NULL) - return NULL; - - num_dashes = PySequence_Fast_GET_SIZE(py_dashes); - dashes = PyMem_Malloc (num_dashes * sizeof(double)); - if (dashes == NULL) { - Py_DECREF(py_dashes); - return PyErr_NoMemory(); - } - - for (i = 0; i < num_dashes; i++) { - dashes[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_dashes, i)); - if (PyErr_Occurred()) { - PyMem_Free (dashes); - Py_DECREF(py_dashes); - return NULL; - } - } - cairo_set_dash (o->ctx, dashes, num_dashes, offset); - PyMem_Free (dashes); - Py_DECREF(py_dashes); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_fill_rule (PycairoContext *o, PyObject *args) { - cairo_fill_rule_t fill_rule; - - if (!PyArg_ParseTuple (args, "i:Context.set_fill_rule", &fill_rule)) - return NULL; - - cairo_set_fill_rule (o->ctx, fill_rule); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_font_face (PycairoContext *o, PyObject *obj) { - if (PyObject_TypeCheck(obj, &PycairoFontFace_Type)) - cairo_set_font_face (o->ctx, ((PycairoFontFace *)obj)->font_face); - else if (obj == Py_None) - cairo_set_font_face (o->ctx, NULL); - else { - PyErr_SetString(PyExc_TypeError, - "Context.set_font_face() argument must be " - "cairo.FontFace or None"); - return NULL; - } - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_font_matrix (PycairoContext *o, PyObject *args) { - PycairoMatrix *matrix; - - if (!PyArg_ParseTuple (args, "O!:Context.set_font_matrix", - &PycairoMatrix_Type, &matrix)) - return NULL; - - cairo_set_font_matrix (o->ctx, &matrix->matrix); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_font_options (PycairoContext *o, PyObject *args) { - PycairoFontOptions *options; - - if (!PyArg_ParseTuple (args, "O!:Context.set_font_options", - &PycairoFontOptions_Type, &options)) - return NULL; - - cairo_set_font_options (o->ctx, options->font_options); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_font_size (PycairoContext *o, PyObject *args) { - double size; - - if (!PyArg_ParseTuple (args, "d:Context.set_font_size", &size)) - return NULL; - - cairo_set_font_size (o->ctx, size); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_line_cap (PycairoContext *o, PyObject *args) { - cairo_line_cap_t line_cap; - - if (!PyArg_ParseTuple (args, "i:Context.set_line_cap", &line_cap)) - return NULL; - - cairo_set_line_cap (o->ctx, line_cap); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_line_join (PycairoContext *o, PyObject *args) { - cairo_line_join_t line_join; - - if (!PyArg_ParseTuple (args, "i:Context.set_line_join", &line_join)) - return NULL; - - cairo_set_line_join (o->ctx, line_join); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_line_width (PycairoContext *o, PyObject *args) { - double width; - - if (!PyArg_ParseTuple (args, "d:Context.set_line_width", &width)) - return NULL; - - cairo_set_line_width (o->ctx, width); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_matrix (PycairoContext *o, PyObject *args) { - PycairoMatrix *matrix; - - if (!PyArg_ParseTuple (args, "O!:Context.set_matrix", - &PycairoMatrix_Type, &matrix)) - return NULL; - - cairo_set_matrix (o->ctx, &matrix->matrix); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_miter_limit (PycairoContext *o, PyObject *args) { - double limit; - - if (!PyArg_ParseTuple (args, "d:Context.set_miter_limit", &limit)) - return NULL; - - cairo_set_miter_limit (o->ctx, limit); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_operator(PycairoContext *o, PyObject *args) { - cairo_operator_t op; - - if (!PyArg_ParseTuple(args, "i:Context.set_operator", &op)) - return NULL; - - cairo_set_operator(o->ctx, op); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_scaled_font(PycairoContext *o, PyObject *args) { - PycairoScaledFont *f; - if (!PyArg_ParseTuple( args, "O!:Context.set_scaled_font", - &PycairoScaledFont_Type, &f)) - return NULL; - - cairo_set_scaled_font(o->ctx, f->scaled_font); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_source (PycairoContext *o, PyObject *args) { - PycairoPattern *p; - - if (!PyArg_ParseTuple( args, "O!:Context.set_source", - &PycairoPattern_Type, &p)) - return NULL; - - cairo_set_source (o->ctx, p->pattern); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_source_rgb (PycairoContext *o, PyObject *args) { - double red, green, blue; - - if (!PyArg_ParseTuple (args, "ddd:Context.set_source_rgb", - &red, &green, &blue)) - return NULL; - - cairo_set_source_rgb (o->ctx, red, green, blue); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_source_rgba (PycairoContext *o, PyObject *args) { - double red, green, blue; - double alpha = 1.0; - - if (!PyArg_ParseTuple (args, "ddd|d:Context.set_source_rgba", - &red, &green, &blue, &alpha)) - return NULL; - - cairo_set_source_rgba (o->ctx, red, green, blue, alpha); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_source_surface (PycairoContext *o, PyObject *args) { - PycairoSurface *surface; - double x = 0.0, y = 0.0; - - if (!PyArg_ParseTuple (args, "O!|dd:Context.set_source_surface", - &PycairoSurface_Type, &surface, &x, &y)) - return NULL; - - cairo_set_source_surface (o->ctx, surface->surface, x, y); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_set_tolerance (PycairoContext *o, PyObject *args) { - double tolerance; - if (!PyArg_ParseTuple (args, "d:Context.set_tolerance", &tolerance)) - return NULL; - cairo_set_tolerance (o->ctx, tolerance); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_show_glyphs (PycairoContext *o, PyObject *args) { - int num_glyphs = -1; - cairo_glyph_t *glyphs; - PyObject *py_object; - - if (!PyArg_ParseTuple (args, "O|i:Context.show_glyphs", - &py_object, &num_glyphs)) - return NULL; - - glyphs = _PyGlyphs_AsGlyphs (py_object, &num_glyphs); - if (glyphs == NULL) - return NULL; - Py_BEGIN_ALLOW_THREADS; - cairo_show_glyphs (o->ctx, glyphs, num_glyphs); - Py_END_ALLOW_THREADS; - PyMem_Free (glyphs); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_show_page (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_show_page (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_show_text (PycairoContext *o, PyObject *obj) { - PyObject *pyUTF8 = NULL; - const char *utf8 = NULL; - - /* accept str and unicode text, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8 = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8 = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "Context.show_text: text must be str or unicode"); - } - if (utf8 == NULL) - return NULL; - - Py_BEGIN_ALLOW_THREADS; - cairo_show_text (o->ctx, utf8); - Py_END_ALLOW_THREADS; - Py_XDECREF(pyUTF8); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_stroke (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_stroke (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_stroke_extents (PycairoContext *o) { - double x1, y1, x2, y2; - cairo_stroke_extents (o->ctx, &x1, &y1, &x2, &y2); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddd)", x1, y1, x2, y2); -} - -static PyObject * -pycairo_stroke_preserve (PycairoContext *o) { - Py_BEGIN_ALLOW_THREADS; - cairo_stroke_preserve (o->ctx); - Py_END_ALLOW_THREADS; - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_text_extents (PycairoContext *o, PyObject *obj) { - cairo_text_extents_t extents; - PyObject *pyUTF8 = NULL; - const char *utf8 = NULL; - - /* accept str and unicode text, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8 = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8 = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "Context.text_extents: text must be str or unicode"); - } - if (utf8 == NULL) - return NULL; - - cairo_text_extents (o->ctx, utf8, &extents); - Py_XDECREF(pyUTF8); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, - extents.width, extents.height, extents.x_advance, - extents.y_advance); -} - -static PyObject * -pycairo_text_path (PycairoContext *o, PyObject *obj) { - PyObject *pyUTF8 = NULL; - const char *utf8 = NULL; - - /* accept str and unicode text, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8 = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8 = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "Context.text_path: text must be str or unicode"); - } - if (utf8 == NULL) - return NULL; - - cairo_text_path (o->ctx, utf8); - Py_XDECREF(pyUTF8); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_transform (PycairoContext *o, PyObject *args) { - PycairoMatrix *matrix; - - if (!PyArg_ParseTuple (args, "O!:Context.transform", - &PycairoMatrix_Type, &matrix)) - return NULL; - - cairo_transform (o->ctx, &matrix->matrix); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_translate (PycairoContext *o, PyObject *args) { - double tx, ty; - - if (!PyArg_ParseTuple (args, "dd:Context.translate", &tx, &ty)) - return NULL; - - cairo_translate (o->ctx, tx, ty); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - Py_RETURN_NONE; -} - -static PyObject * -pycairo_user_to_device (PycairoContext *o, PyObject *args) { - double x, y; - - if (!PyArg_ParseTuple (args, "dd:Context.user_to_device", &x, &y)) - return NULL; - - cairo_user_to_device (o->ctx, &x, &y); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dd)", x, y); -} - -static PyObject * -pycairo_user_to_device_distance (PycairoContext *o, PyObject *args) { - double dx, dy; - - if (!PyArg_ParseTuple (args, "dd:Context.user_to_device_distance", - &dx, &dy)) - return NULL; - - cairo_user_to_device_distance (o->ctx, &dx, &dy); - RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx); - return Py_BuildValue("(dd)", dx, dy); -} - - -static PyMethodDef pycairo_methods[] = { - /* methods never exposed in a language binding: - * cairo_destroy() - * cairo_reference() - * cairo_rectangle_list_destroy() - * - * cairo_status() - * cairo_status_string() - * - not needed since Pycairo calls Pycairo_Check_Status() to check - * for errors and raise exceptions - */ - {"append_path", (PyCFunction)pycairo_append_path, METH_VARARGS}, - {"arc", (PyCFunction)pycairo_arc, METH_VARARGS}, - {"arc_negative", (PyCFunction)pycairo_arc_negative, METH_VARARGS}, - {"clip", (PyCFunction)pycairo_clip, METH_NOARGS}, - {"clip_extents", (PyCFunction)pycairo_clip_extents, METH_NOARGS}, - {"clip_preserve", (PyCFunction)pycairo_clip_preserve, METH_NOARGS}, - {"close_path", (PyCFunction)pycairo_close_path, METH_NOARGS}, - {"copy_clip_rectangle_list", (PyCFunction)pycairo_copy_clip_rectangle_list, - METH_NOARGS}, - {"copy_page", (PyCFunction)pycairo_copy_page, METH_NOARGS}, - {"copy_path", (PyCFunction)pycairo_copy_path, METH_NOARGS}, - {"copy_path_flat", (PyCFunction)pycairo_copy_path_flat, METH_NOARGS}, - {"curve_to", (PyCFunction)pycairo_curve_to, METH_VARARGS}, - {"device_to_user", (PyCFunction)pycairo_device_to_user, METH_VARARGS}, - {"device_to_user_distance", (PyCFunction)pycairo_device_to_user_distance, - METH_VARARGS}, - {"fill", (PyCFunction)pycairo_fill, METH_NOARGS}, - {"fill_extents", (PyCFunction)pycairo_fill_extents, METH_NOARGS}, - {"fill_preserve", (PyCFunction)pycairo_fill_preserve, METH_NOARGS}, - {"font_extents", (PyCFunction)pycairo_font_extents, METH_NOARGS}, - {"get_antialias", (PyCFunction)pycairo_get_antialias, METH_NOARGS}, - {"get_current_point",(PyCFunction)pycairo_get_current_point,METH_NOARGS}, - {"get_dash", (PyCFunction)pycairo_get_dash, METH_NOARGS}, - {"get_dash_count", (PyCFunction)pycairo_get_dash_count, METH_NOARGS}, - {"get_fill_rule", (PyCFunction)pycairo_get_fill_rule, METH_NOARGS}, - {"get_font_face", (PyCFunction)pycairo_get_font_face, METH_NOARGS}, - {"get_font_matrix", (PyCFunction)pycairo_get_font_matrix, METH_NOARGS}, - {"get_font_options",(PyCFunction)pycairo_get_font_options, METH_NOARGS}, - {"get_group_target",(PyCFunction)pycairo_get_group_target, METH_NOARGS}, - {"get_line_cap", (PyCFunction)pycairo_get_line_cap, METH_NOARGS}, - {"get_line_join", (PyCFunction)pycairo_get_line_join, METH_NOARGS}, - {"get_line_width", (PyCFunction)pycairo_get_line_width, METH_NOARGS}, - {"get_matrix", (PyCFunction)pycairo_get_matrix, METH_NOARGS}, - {"get_miter_limit", (PyCFunction)pycairo_get_miter_limit, METH_NOARGS}, - {"get_operator", (PyCFunction)pycairo_get_operator, METH_NOARGS}, - {"get_scaled_font", (PyCFunction)pycairo_get_scaled_font, METH_NOARGS}, - {"get_source", (PyCFunction)pycairo_get_source, METH_NOARGS}, - {"get_target", (PyCFunction)pycairo_get_target, METH_NOARGS}, - {"get_tolerance", (PyCFunction)pycairo_get_tolerance, METH_NOARGS}, - {"glyph_extents", (PyCFunction)pycairo_glyph_extents, METH_VARARGS}, - {"glyph_path", (PyCFunction)pycairo_glyph_path, METH_VARARGS}, - {"has_current_point",(PyCFunction)pycairo_has_current_point, METH_NOARGS}, - {"identity_matrix", (PyCFunction)pycairo_identity_matrix, METH_NOARGS}, - {"in_fill", (PyCFunction)pycairo_in_fill, METH_VARARGS}, - {"in_stroke", (PyCFunction)pycairo_in_stroke, METH_VARARGS}, - {"line_to", (PyCFunction)pycairo_line_to, METH_VARARGS}, - {"mask", (PyCFunction)pycairo_mask, METH_VARARGS}, - {"mask_surface", (PyCFunction)pycairo_mask_surface, METH_VARARGS}, - {"move_to", (PyCFunction)pycairo_move_to, METH_VARARGS}, - {"new_path", (PyCFunction)pycairo_new_path, METH_NOARGS}, - {"new_sub_path", (PyCFunction)pycairo_new_sub_path, METH_NOARGS}, - {"paint", (PyCFunction)pycairo_paint, METH_NOARGS}, - {"paint_with_alpha",(PyCFunction)pycairo_paint_with_alpha, METH_VARARGS}, - {"path_extents", (PyCFunction)pycairo_path_extents, METH_NOARGS}, - {"pop_group", (PyCFunction)pycairo_pop_group, METH_NOARGS}, - {"pop_group_to_source", (PyCFunction)pycairo_pop_group_to_source, - METH_NOARGS}, - {"push_group", (PyCFunction)pycairo_push_group, METH_NOARGS}, - {"push_group_with_content", (PyCFunction)pycairo_push_group_with_content, - METH_VARARGS}, - {"rectangle", (PyCFunction)pycairo_rectangle, METH_VARARGS}, - {"rel_curve_to", (PyCFunction)pycairo_rel_curve_to, METH_VARARGS}, - {"rel_line_to", (PyCFunction)pycairo_rel_line_to, METH_VARARGS}, - {"rel_move_to", (PyCFunction)pycairo_rel_move_to, METH_VARARGS}, - {"reset_clip", (PyCFunction)pycairo_reset_clip, METH_NOARGS}, - {"restore", (PyCFunction)pycairo_restore, METH_NOARGS}, - {"rotate", (PyCFunction)pycairo_rotate, METH_VARARGS}, - {"save", (PyCFunction)pycairo_save, METH_NOARGS}, - {"scale", (PyCFunction)pycairo_scale, METH_VARARGS}, - {"select_font_face",(PyCFunction)pycairo_select_font_face, METH_VARARGS}, - {"set_antialias", (PyCFunction)pycairo_set_antialias, METH_VARARGS}, - {"set_dash", (PyCFunction)pycairo_set_dash, METH_VARARGS}, - {"set_fill_rule", (PyCFunction)pycairo_set_fill_rule, METH_VARARGS}, - {"set_font_face", (PyCFunction)pycairo_set_font_face, METH_O}, - {"set_font_matrix", (PyCFunction)pycairo_set_font_matrix, METH_VARARGS}, - {"set_font_options",(PyCFunction)pycairo_set_font_options, METH_VARARGS}, - {"set_font_size", (PyCFunction)pycairo_set_font_size, METH_VARARGS}, - {"set_line_cap", (PyCFunction)pycairo_set_line_cap, METH_VARARGS}, - {"set_line_join", (PyCFunction)pycairo_set_line_join, METH_VARARGS}, - {"set_line_width", (PyCFunction)pycairo_set_line_width, METH_VARARGS}, - {"set_matrix", (PyCFunction)pycairo_set_matrix, METH_VARARGS}, - {"set_miter_limit", (PyCFunction)pycairo_set_miter_limit, METH_VARARGS}, - {"set_operator", (PyCFunction)pycairo_set_operator, METH_VARARGS}, - {"set_scaled_font", (PyCFunction)pycairo_set_scaled_font, METH_VARARGS}, - {"set_source", (PyCFunction)pycairo_set_source, METH_VARARGS}, - {"set_source_rgb", (PyCFunction)pycairo_set_source_rgb, METH_VARARGS}, - {"set_source_rgba", (PyCFunction)pycairo_set_source_rgba, METH_VARARGS}, - {"set_source_surface",(PyCFunction)pycairo_set_source_surface, METH_VARARGS}, - {"set_tolerance", (PyCFunction)pycairo_set_tolerance, METH_VARARGS}, - {"show_glyphs", (PyCFunction)pycairo_show_glyphs, METH_VARARGS}, - {"show_page", (PyCFunction)pycairo_show_page, METH_NOARGS}, - {"show_text", (PyCFunction)pycairo_show_text, METH_O}, - {"stroke", (PyCFunction)pycairo_stroke, METH_NOARGS}, - {"stroke_extents", (PyCFunction)pycairo_stroke_extents, METH_NOARGS}, - {"stroke_preserve", (PyCFunction)pycairo_stroke_preserve, METH_NOARGS}, - {"text_extents", (PyCFunction)pycairo_text_extents, METH_O}, - {"text_path", (PyCFunction)pycairo_text_path, METH_O}, - {"transform", (PyCFunction)pycairo_transform, METH_VARARGS}, - {"translate", (PyCFunction)pycairo_translate, METH_VARARGS}, - {"user_to_device", (PyCFunction)pycairo_user_to_device, METH_VARARGS}, - {"user_to_device_distance",(PyCFunction)pycairo_user_to_device_distance, - METH_VARARGS}, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoContext_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Context", /* tp_name */ - sizeof(PycairoContext), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pycairo_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 */ - 0, /* 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 */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pycairo_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)pycairo_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; diff --git a/src/pycairo-font.c b/src/pycairo-font.c deleted file mode 100644 index ee01ec8..0000000 --- a/src/pycairo-font.c +++ /dev/null @@ -1,611 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2003 James Henstridge, 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 - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "pycairo-private.h" - - -/* class cairo.FontFace --------------------------------------------------- */ - -/* PycairoFontFace_FromFontFace - * Create a new PycairoFontFace from a cairo_font_face_t - * font_face - a cairo_font_face_t to 'wrap' into a Python object. - * it is unreferenced if the PycairoFontFace creation fails - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoFontFace_FromFontFace (cairo_font_face_t *font_face) { - PyTypeObject *type = NULL; - PyObject *o; - - assert (font_face != NULL); - - if (Pycairo_Check_Status (cairo_font_face_status (font_face))) { - cairo_font_face_destroy (font_face); - return NULL; - } - - switch (cairo_font_face_get_type (font_face)) { - case CAIRO_FONT_TYPE_TOY: - type = &PycairoToyFontFace_Type; - break; - default: - type = &PycairoFontFace_Type; - break; - } - o = type->tp_alloc (type, 0); - if (o == NULL) - cairo_font_face_destroy (font_face); - else - ((PycairoFontFace *)o)->font_face = font_face; - return o; -} - -static void -font_face_dealloc (PycairoFontFace *o) { - if (o->font_face) { - cairo_font_face_destroy (o->font_face); - o->font_face = NULL; - } - o->ob_type->tp_free((PyObject *) o); -} - -static PyObject * -font_face_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyErr_SetString (PyExc_TypeError, "The FontFace type cannot be " - "instantiated directly, use Context.get_font_face()"); - return NULL; -} - -/* -static PyMethodDef font_face_methods[] = { - * methods never exposed in a language binding: - * cairo_font_face_destroy() - * cairo_font_face_get_user_data() - * cairo_font_face_get_type() - * cairo_font_face_reference() - * cairo_font_face_set_user_data(), - {NULL, NULL, 0, NULL}, -}; -*/ - -PyTypeObject PycairoFontFace_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.FontFace", /* tp_name */ - sizeof(PycairoFontFace), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)font_face_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 */ - 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 */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)font_face_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - - -/* class cairo.ToyFontFace ------------------------------------------------- */ - -static PyObject * -toy_font_face_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *obj; - PyObject *pyUTF8 = NULL; - const char *utf8family = NULL; - cairo_font_slant_t slant = CAIRO_FONT_SLANT_NORMAL; - cairo_font_weight_t weight = CAIRO_FONT_WEIGHT_NORMAL; - - if (!PyArg_ParseTuple(args, "O!|ii:ToyFontFace.__new__", - &PyBaseString_Type, &obj, &slant, &weight)) - return NULL; - - /* accept str and unicode family, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8family = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8family = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "ToyFontFace.__new__: family must be str or unicode"); - } - if (utf8family == NULL) - return NULL; - - PyObject *o = PycairoFontFace_FromFontFace ( - cairo_toy_font_face_create (utf8family, slant, weight)); - Py_XDECREF(pyUTF8); - return o; -} - -static PyObject * -toy_font_get_family (PycairoToyFontFace *o) { - return PyString_FromString (cairo_toy_font_face_get_family (o->font_face)); -} - -static PyObject * -toy_font_get_slant (PycairoToyFontFace *o) { - return PyInt_FromLong (cairo_toy_font_face_get_slant (o->font_face)); -} - -static PyObject * -toy_font_get_weight (PycairoToyFontFace *o) { - return PyInt_FromLong (cairo_toy_font_face_get_weight (o->font_face)); -} - -static PyMethodDef toy_font_face_methods[] = { - {"get_family", (PyCFunction)toy_font_get_family, METH_NOARGS}, - {"get_slant", (PyCFunction)toy_font_get_slant, METH_NOARGS}, - {"get_weight", (PyCFunction)toy_font_get_weight, METH_NOARGS}, - {NULL, NULL, 0, NULL}, -}; - - -PyTypeObject PycairoToyFontFace_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.ToyFontFace", /* tp_name */ - sizeof(PycairoToyFontFace), /* 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 */ - toy_font_face_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoFontFace_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)toy_font_face_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - - -/* class cairo.ScaledFont ------------------------------------------------- */ - -/* PycairoScaledFont_FromScaledFont - * Create a new PycairoScaledFont from a cairo_scaled_font_t - * scaled_font - a cairo_scaled_font_t to 'wrap' into a Python object. - * it is unreferenced if the PycairoScaledFont creation fails - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoScaledFont_FromScaledFont (cairo_scaled_font_t *scaled_font) { - PyObject *o; - - assert (scaled_font != NULL); - - if (Pycairo_Check_Status (cairo_scaled_font_status (scaled_font))) { - cairo_scaled_font_destroy (scaled_font); - return NULL; - } - - o = PycairoScaledFont_Type.tp_alloc (&PycairoScaledFont_Type, 0); - if (o == NULL) - cairo_scaled_font_destroy (scaled_font); - else - ((PycairoScaledFont *)o)->scaled_font = scaled_font; - return o; -} - -static void -scaled_font_dealloc(PycairoScaledFont *o) { - if (o->scaled_font) { - cairo_scaled_font_destroy (o->scaled_font); - o->scaled_font = NULL; - } - o->ob_type->tp_free((PyObject *) o); -} - -static PyObject * -scaled_font_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PycairoFontFace *ff; - PycairoFontOptions *fo; - PycairoMatrix *mx1, *mx2; - - if (!PyArg_ParseTuple(args, "O!O!O!O!:ScaledFont.__new__", - &PycairoFontFace_Type, &ff, - &PycairoMatrix_Type, &mx1, - &PycairoMatrix_Type, &mx2, - &PycairoFontOptions_Type, &fo)) - return NULL; - return PycairoScaledFont_FromScaledFont ( - cairo_scaled_font_create (ff->font_face, &mx1->matrix, - &mx2->matrix, fo->font_options)); -} - -static PyObject * -scaled_font_extents (PycairoScaledFont *o) { - cairo_font_extents_t e; - - cairo_scaled_font_extents (o->scaled_font, &e); - RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(o->scaled_font); - return Py_BuildValue ("(ddddd)", e.ascent, e.descent, e.height, - e.max_x_advance, e.max_y_advance); -} - -static PyObject * -scaled_font_get_font_face (PycairoScaledFont *o) { - return PycairoFontFace_FromFontFace ( - cairo_font_face_reference ( - cairo_scaled_font_get_font_face (o->scaled_font))); -} - -static PyObject * -scaled_font_get_scale_matrix (PycairoScaledFont *o) { - cairo_matrix_t matrix; - cairo_scaled_font_get_scale_matrix (o->scaled_font, &matrix); - return PycairoMatrix_FromMatrix (&matrix); -} - -static PyObject * -scaled_font_text_extents (PycairoScaledFont *o, PyObject *obj) { - cairo_text_extents_t extents; - PyObject *pyUTF8 = NULL; - const char *utf8 = NULL; - - /* accept str and unicode text, auto convert to utf8 as required */ - if (PyString_Check(obj)) { - /* A plain ASCII string is also a valid UTF-8 string */ - utf8 = PyString_AS_STRING(obj); - } else if (PyUnicode_Check(obj)) { - pyUTF8 = PyUnicode_AsUTF8String(obj); - if (pyUTF8 != NULL) { - utf8 = PyString_AS_STRING(pyUTF8); - } - } else { - PyErr_SetString(PyExc_TypeError, - "ScaledFont.text_extents: text must be str or unicode"); - } - if (utf8 == NULL) - return NULL; - - cairo_scaled_font_text_extents (o->scaled_font, utf8, &extents); - Py_XDECREF(pyUTF8); - RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(o->scaled_font); - return Py_BuildValue("(dddddd)", extents.x_bearing, extents.y_bearing, - extents.width, extents.height, extents.x_advance, - extents.y_advance); -} - -static PyMethodDef scaled_font_methods[] = { - /* methods never exposed in a language binding: - * cairo_scaled_font_destroy() - * cairo_scaled_font_get_type() - * cairo_scaled_font_reference() - * - * TODO if requested: - * cairo_scaled_font_get_ctm - * cairo_scaled_font_get_font_matrix - * cairo_scaled_font_get_font_options - * cairo_scaled_font_glyph_extents - * cairo_scaled_font_text_to_glyphs - */ - {"extents", (PyCFunction)scaled_font_extents, METH_NOARGS}, - {"get_font_face", (PyCFunction)scaled_font_get_font_face, METH_NOARGS}, - {"get_scale_matrix", (PyCFunction)scaled_font_get_scale_matrix, METH_VARARGS}, - {"text_extents", (PyCFunction)scaled_font_text_extents, METH_O}, - {NULL, NULL, 0, NULL}, -}; - - -PyTypeObject PycairoScaledFont_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.ScaledFont", /* tp_name */ - sizeof(PycairoScaledFont), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)scaled_font_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 */ - 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 */ - scaled_font_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)scaled_font_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - - -/* class cairo.FontOptions ------------------------------------------------ */ - -/* PycairoFontOptions_FromFontOptions - * Create a new PycairoFontOptions from a cairo_font_options_t - * font_options - a cairo_font_options_t to 'wrap' into a Python object. - * it is unreferenced if the PycairoFontOptions creation fails - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoFontOptions_FromFontOptions (cairo_font_options_t *font_options) { - PyObject *o; - - assert (font_options != NULL); - - if (Pycairo_Check_Status (cairo_font_options_status (font_options))) { - cairo_font_options_destroy (font_options); - return NULL; - } - - o = PycairoFontOptions_Type.tp_alloc (&PycairoFontOptions_Type, 0); - if (o == NULL) - cairo_font_options_destroy (font_options); - else - ((PycairoFontOptions *)o)->font_options = font_options; - return o; -} - -static void -font_options_dealloc(PycairoFontOptions *o) { - if (o->font_options) { - cairo_font_options_destroy (o->font_options); - o->font_options = NULL; - } - o->ob_type->tp_free((PyObject *) o); -} - -static PyObject * -font_options_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - return PycairoFontOptions_FromFontOptions (cairo_font_options_create()); -} - -static PyObject * -font_options_get_antialias (PycairoFontOptions *o) { - return PyInt_FromLong (cairo_font_options_get_antialias (o->font_options)); -} - -static PyObject * -font_options_get_hint_metrics (PycairoFontOptions *o) { - return PyInt_FromLong (cairo_font_options_get_hint_metrics - (o->font_options)); -} - -static PyObject * -font_options_get_hint_style (PycairoFontOptions *o) { - return PyInt_FromLong (cairo_font_options_get_hint_style - (o->font_options)); -} - -static PyObject * -font_options_get_subpixel_order (PycairoFontOptions *o) { - return PyInt_FromLong (cairo_font_options_get_subpixel_order - (o->font_options)); -} - -static PyObject * -font_options_set_antialias (PycairoFontOptions *o, PyObject *args) { - cairo_antialias_t aa = CAIRO_ANTIALIAS_DEFAULT; - - if (!PyArg_ParseTuple(args, "|i:FontOptions.set_antialias", &aa)) - return NULL; - - cairo_font_options_set_antialias (o->font_options, aa); - RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); - Py_RETURN_NONE; -} - -static PyObject * -font_options_set_hint_metrics (PycairoFontOptions *o, PyObject *args) { - cairo_hint_metrics_t hm = CAIRO_HINT_METRICS_DEFAULT; - - if (!PyArg_ParseTuple(args, "|i:FontOptions.set_hint_metrics", &hm)) - return NULL; - - cairo_font_options_set_hint_metrics (o->font_options, hm); - RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); - Py_RETURN_NONE; -} - -static PyObject * -font_options_set_hint_style (PycairoFontOptions *o, PyObject *args) { - cairo_hint_style_t hs = CAIRO_HINT_STYLE_DEFAULT; - - if (!PyArg_ParseTuple(args, "|i:FontOptions.set_hint_style", &hs)) - return NULL; - - cairo_font_options_set_hint_style (o->font_options, hs); - RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); - Py_RETURN_NONE; -} - -static PyObject * -font_options_set_subpixel_order (PycairoFontOptions *o, PyObject *args) { - cairo_subpixel_order_t so = CAIRO_SUBPIXEL_ORDER_DEFAULT; - - if (!PyArg_ParseTuple(args, "|i:FontOptions.set_subpixel_order", &so)) - return NULL; - - cairo_font_options_set_subpixel_order (o->font_options, so); - RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(o->font_options); - Py_RETURN_NONE; -} - - -static PyMethodDef font_options_methods[] = { - /* methods never exposed in a language binding: - * cairo_font_options_destroy() - * cairo_font_options_reference() - */ - /* TODO: */ - /* copy */ - /* hash */ - /* merge */ - /* equal (richcmp?) */ - {"get_antialias", (PyCFunction)font_options_get_antialias, METH_NOARGS}, - {"get_hint_metrics", (PyCFunction)font_options_get_hint_metrics, - METH_NOARGS}, - {"get_hint_style", (PyCFunction)font_options_get_hint_style, METH_NOARGS}, - {"get_subpixel_order",(PyCFunction)font_options_get_subpixel_order, - METH_NOARGS}, - {"set_antialias", (PyCFunction)font_options_set_antialias, METH_VARARGS}, - {"set_hint_metrics", (PyCFunction)font_options_set_hint_metrics, - METH_VARARGS}, - {"set_hint_style", (PyCFunction)font_options_set_hint_style, METH_VARARGS}, - {"set_subpixel_order",(PyCFunction)font_options_set_subpixel_order, - METH_VARARGS}, - {NULL, NULL, 0, NULL}, -}; - - -PyTypeObject PycairoFontOptions_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.FontOptions", /* tp_name */ - sizeof(PycairoFontOptions), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)font_options_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 */ - 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 */ - font_options_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)font_options_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; diff --git a/src/pycairo-matrix.c b/src/pycairo-matrix.c deleted file mode 100644 index 6503c9a..0000000 --- a/src/pycairo-matrix.c +++ /dev/null @@ -1,348 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2003 James Henstridge, 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 - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "pycairo-private.h" - - -/* PycairoMatrix_FromMatrix - * Create a new PycairoMatrix from a cairo_matrix_t - * matrix - a cairo_matrix_t to 'wrap' into a Python object - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoMatrix_FromMatrix (const cairo_matrix_t *matrix) { - PyObject *o; - assert (matrix != NULL); - o = PycairoMatrix_Type.tp_alloc (&PycairoMatrix_Type, 0); - if (o != NULL) - ((PycairoMatrix *)o)->matrix = *matrix; - return o; -} - -static void -matrix_dealloc (PycairoMatrix *o) { - o->ob_type->tp_free((PyObject *)o); -} - -static PyObject * -matrix_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyObject *o; - static char *kwlist[] = { "xx", "yx", "xy", "yy", "x0", "y0", NULL }; - double xx = 1.0, yx = 0.0, xy = 0.0, yy = 1.0, x0 = 0.0, y0 = 0.0; - - if (!PyArg_ParseTupleAndKeywords(args, kwds, - "|dddddd:Matrix.__init__", kwlist, - &xx, &yx, &xy, &yy, &x0, &y0)) - return NULL; - - o = type->tp_alloc(type, 0); - if (o) - cairo_matrix_init (&((PycairoMatrix *)o)->matrix, - xx, yx, xy, yy, x0, y0); - return o; -} - -static PyObject * -matrix_init_rotate (PyTypeObject *type, PyObject *args) { - cairo_matrix_t matrix; - double radians; - - if (!PyArg_ParseTuple(args, "d:Matrix.init_rotate", &radians)) - return NULL; - - cairo_matrix_init_rotate (&matrix, radians); - return PycairoMatrix_FromMatrix (&matrix); -} - -static PyObject * -matrix_invert (PycairoMatrix *o) { - if (Pycairo_Check_Status (cairo_matrix_invert (&o->matrix))) - return NULL; - Py_RETURN_NONE; -} - -/* cairo_matrix_multiply */ -static PyObject * -matrix_multiply (PycairoMatrix *o, PyObject *args) { - PycairoMatrix *mx2; - - if (!PyArg_ParseTuple(args, "O!:Matrix.multiply", - &PycairoMatrix_Type, &mx2)) - return NULL; - - cairo_matrix_t result; - cairo_matrix_multiply (&result, &o->matrix, &mx2->matrix); - return PycairoMatrix_FromMatrix (&result); -} - -/* standard matrix multiply, for use by '*' operator */ -static PyObject * -matrix_operator_multiply (PycairoMatrix *o, PycairoMatrix *o2) { - cairo_matrix_t result; - cairo_matrix_multiply (&result, &o->matrix, &o2->matrix); - return PycairoMatrix_FromMatrix (&result); -} - -static PyObject * -matrix_repr (PycairoMatrix *o) { - char buf[256]; - - PyOS_snprintf(buf, sizeof(buf), "cairo.Matrix(%g, %g, %g, %g, %g, %g)", - o->matrix.xx, o->matrix.yx, - o->matrix.xy, o->matrix.yy, - o->matrix.x0, o->matrix.y0); - return PyString_FromString(buf); -} - -static PyObject * -matrix_richcmp (PycairoMatrix *m1, PycairoMatrix *m2, int op) { - int equal; - PyObject *ret; - cairo_matrix_t *mx1 = &m1->matrix; - cairo_matrix_t *mx2 = &m2->matrix; - - if (!PyObject_TypeCheck(m2, &PycairoMatrix_Type) || - !(op == Py_EQ || op == Py_NE)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; - } - - equal = mx1->xx == mx2->xx && mx1->yx == mx2->yx && - mx1->xy == mx2->xy && mx1->yy == mx2->yy && - mx1->x0 == mx2->x0 && mx1->y0 == mx2->y0; - - if (op == Py_EQ) - ret = equal ? Py_True : Py_False; - else - ret = equal ? Py_False : Py_True; - Py_INCREF(ret); - return ret; -} - -static PyObject * -matrix_rotate (PycairoMatrix *o, PyObject *args) { - double radians; - - if (!PyArg_ParseTuple(args, "d:Matrix.rotate", &radians)) - return NULL; - - cairo_matrix_rotate (&o->matrix, radians); - Py_RETURN_NONE; -} - -static PyObject * -matrix_scale (PycairoMatrix *o, PyObject *args) { - double sx, sy; - - if (!PyArg_ParseTuple(args, "dd:Matrix.scale", &sx, &sy)) - return NULL; - - cairo_matrix_scale (&o->matrix, sx, sy); - Py_RETURN_NONE; -} - -static PyObject * -matrix_transform_distance (PycairoMatrix *o, PyObject *args) { - double dx, dy; - - if (!PyArg_ParseTuple(args, "dd:Matrix.transform_distance", &dx, &dy)) - return NULL; - - cairo_matrix_transform_distance (&o->matrix, &dx, &dy); - return Py_BuildValue("(dd)", dx, dy); -} - -static PyObject * -matrix_transform_point (PycairoMatrix *o, PyObject *args) { - double x, y; - - if (!PyArg_ParseTuple(args, "dd:Matrix.transform_point", &x, &y)) - return NULL; - - cairo_matrix_transform_point (&o->matrix, &x, &y); - return Py_BuildValue("(dd)", x, y); -} - -static PyObject * -matrix_translate (PycairoMatrix *o, PyObject *args) { - double tx, ty; - - if (!PyArg_ParseTuple(args, "dd:Matrix.translate", &tx, &ty)) - return NULL; - - cairo_matrix_translate (&o->matrix, tx, ty); - Py_RETURN_NONE; -} - -static PyObject * -matrix_item (PycairoMatrix *o, Py_ssize_t i) { - switch (i) { - case 0: - return Py_BuildValue("d", o->matrix.xx); - case 1: - return Py_BuildValue("d", o->matrix.yx); - case 2: - return Py_BuildValue("d", o->matrix.xy); - case 3: - return Py_BuildValue("d", o->matrix.yy); - case 4: - return Py_BuildValue("d", o->matrix.x0); - case 5: - return Py_BuildValue("d", o->matrix.y0); - default: - PyErr_SetString(PyExc_IndexError, "Matrix index out of range"); - return NULL; - } -} - -static PyNumberMethods matrix_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)matrix_operator_multiply, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0, /*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - (unaryfunc)0, /*nb_invert*/ - (binaryfunc)0, /*nb_lshift*/ - (binaryfunc)0, /*nb_rshift*/ - (binaryfunc)0, /*nb_and*/ - (binaryfunc)0, /*nb_xor*/ - (binaryfunc)0, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)0, /*nb_int*/ - (unaryfunc)0, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)0, /*nb_oct*/ - (unaryfunc)0, /*nb_hex*/ - 0, /*nb_inplace_add*/ - 0, /*nb_inplace_subtract*/ - 0, /*nb_inplace_multiply*/ - 0, /*nb_inplace_divide*/ - 0, /*nb_inplace_remainder*/ - 0, /*nb_inplace_power*/ - 0, /*nb_inplace_lshift*/ - 0, /*nb_inplace_rshift*/ - 0, /*nb_inplace_and*/ - 0, /*nb_inplace_xor*/ - 0, /*nb_inplace_or*/ - (binaryfunc)0, /* nb_floor_divide */ - 0, /* nb_true_divide */ - 0, /* nb_inplace_floor_divide */ - 0, /* nb_inplace_true_divide */ - (unaryfunc)0, /* nb_index */ -}; - -static PySequenceMethods matrix_as_sequence = { - 0, /* sq_length */ - 0, /* sq_concat */ - 0, /* sq_repeat */ - (ssizeargfunc)matrix_item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - 0, /* sq_contains */ -}; - -static PyMethodDef matrix_methods[] = { - /* Do not need to wrap all cairo_matrix_init_*() functions - * C API Matrix constructors Python equivalents - * cairo_matrix_init() cairo.Matrix(xx,yx,xy,yy,x0,y0) - * cairo_matrix_init_rotate() cairo.Matrix.init_rotate(radians) - - * cairo_matrix_init_identity() cairo.Matrix() - * cairo_matrix_init_translate() cairo.Matrix(x0=x0,y0=y0) - * cairo_matrix_init_scale() cairo.Matrix(xx=xx,yy=yy) - */ - {"init_rotate", (PyCFunction)matrix_init_rotate, METH_VARARGS | METH_CLASS }, - {"invert", (PyCFunction)matrix_invert, METH_NOARGS }, - {"multiply", (PyCFunction)matrix_multiply, METH_VARARGS }, - {"rotate", (PyCFunction)matrix_rotate, METH_VARARGS }, - {"scale", (PyCFunction)matrix_scale, METH_VARARGS }, - {"transform_distance",(PyCFunction)matrix_transform_distance, METH_VARARGS }, - {"transform_point", (PyCFunction)matrix_transform_point, METH_VARARGS }, - {"translate", (PyCFunction)matrix_translate, METH_VARARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoMatrix_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Matrix", /* tp_name */ - sizeof(PycairoMatrix), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)matrix_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)matrix_repr, /* tp_repr */ - &matrix_as_number, /* tp_as_number */ - &matrix_as_sequence, /* 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 */ - NULL, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - (richcmpfunc)matrix_richcmp, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - matrix_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)matrix_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; diff --git a/src/pycairo-path.c b/src/pycairo-path.c deleted file mode 100644 index 7fbaed2..0000000 --- a/src/pycairo-path.c +++ /dev/null @@ -1,329 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2005 Steve 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 - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "pycairo-private.h" - - -/* PycairoPath iterator object - * modelled on Python-2.4/Objects/rangeobject.c and tupleobject.c - */ - -/* PycairoPath_FromPath - * Create a new PycairoPath from a cairo_path_t - * path - a cairo_path_t to 'wrap' into a Python object. - * path is unreferenced if the PycairoPath creation fails, or if path - * is in an error status. - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoPath_FromPath (cairo_path_t *path) { - PyObject *o; - - assert (path != NULL); - - if (Pycairo_Check_Status (path->status)) { - cairo_path_destroy (path); - return NULL; - } - - o = PycairoPath_Type.tp_alloc (&PycairoPath_Type, 0); - if (o) - ((PycairoPath *)o)->path = path; - else - cairo_path_destroy (path); - return o; -} - -static void -path_dealloc(PycairoPath *p) { -#ifdef DEBUG - printf("path_dealloc start\n"); -#endif - if (p->path) { - cairo_path_destroy(p->path); - p->path = NULL; - } - p->ob_type->tp_free((PyObject *)p); -#ifdef DEBUG - printf("path_dealloc end\n"); -#endif -} - -static PyObject * -path_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { - return type->tp_alloc(type, 0); - /* initializes memory to zeros */ -} - -static int -path_init(PycairoPath *p, PyObject *args, PyObject *kwds) { - PyErr_SetString(PyExc_TypeError, "The Path type cannot be instantiated, " - "use Context.copy_path()"); - return -1; -} - -static PyObject * -path_str(PycairoPath *p) { - PyObject *s, *pieces = NULL, *result = NULL; - cairo_path_t *path = p->path; - cairo_path_data_t *data; - int i, ret; - char buf[80]; - - pieces = PyList_New(0); - if (pieces == NULL) - goto Done; - - /* loop reading elements */ - for (i=0; i < path->num_data; i += path->data[i].header.length) { - data = &path->data[i]; - switch (data->header.type) { - - case CAIRO_PATH_MOVE_TO: - PyOS_snprintf(buf, sizeof(buf), "move_to %f %f", - data[1].point.x, data[1].point.y); - s = PyString_FromString(buf); - if (!s) - goto Done; - ret = PyList_Append(pieces, s); - Py_DECREF(s); - if (ret < 0) - goto Done; - break; - - case CAIRO_PATH_LINE_TO: - PyOS_snprintf(buf, sizeof(buf), "line_to %f %f", - data[1].point.x, data[1].point.y); - s = PyString_FromString(buf); - if (!s) - goto Done; - ret = PyList_Append(pieces, s); - Py_DECREF(s); - if (ret < 0) - goto Done; - break; - - case CAIRO_PATH_CURVE_TO: - PyOS_snprintf(buf, sizeof(buf), "curve_to %f %f %f %f %f %f", - data[1].point.x, data[1].point.y, - data[2].point.x, data[2].point.y, - data[3].point.x, data[3].point.y); - s = PyString_FromString(buf); - if (!s) - goto Done; - ret = PyList_Append(pieces, s); - Py_DECREF(s); - if (ret < 0) - goto Done; - break; - - case CAIRO_PATH_CLOSE_PATH: - s = PyString_FromString("close path"); - if (!s) - goto Done; - ret = PyList_Append(pieces, s); - Py_DECREF(s); - if (ret < 0) - goto Done; - break; - } - } - /* result = "\n".join(pieces) */ - s = PyString_FromString("\n"); - if (s == NULL) - goto Done; - result = _PyString_Join(s, pieces); - Py_DECREF(s); - -Done: - Py_XDECREF(pieces); - return result; -} - -static PyObject * path_iter(PyObject *seq); /* forward declaration */ - - -PyTypeObject PycairoPath_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Path", /* tp_name */ - sizeof(PycairoPath), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)path_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 */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)path_str, /* 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 */ - (getiterfunc)path_iter, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)path_init, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)path_new, /* tp_new */ -}; - -/*********************** PycairoPath Iterator **************************/ - -typedef struct { - PyObject_HEAD - int index; /* position within PycairoPath */ - PycairoPath *pypath; /* Set to NULL when iterator is exhausted */ -} PycairoPathiter; - -PyTypeObject PycairoPathiter_Type; - - -static void -pathiter_dealloc(PycairoPathiter *it) { - Py_XDECREF(it->pypath); - PyObject_Del(it); -} - -static PyObject * -path_iter(PyObject *pypath) { - PycairoPathiter *it; - - if (!PyObject_TypeCheck (pypath, &PycairoPath_Type)) { - PyErr_BadInternalCall(); - return NULL; - } - it = PyObject_New(PycairoPathiter, &PycairoPathiter_Type); - if (it == NULL) - return NULL; - - it->index = 0; - Py_INCREF(pypath); - it->pypath = (PycairoPath *)pypath; - return (PyObject *) it; -} - -static PyObject * -pathiter_next(PycairoPathiter *it) { - PycairoPath *pypath; - cairo_path_t *path; - - assert(it != NULL); - pypath = it->pypath; - if (pypath == NULL) - return NULL; - assert (PyObject_TypeCheck (pypath, &PycairoPath_Type)); - path = pypath->path; - - /* return the next path element, advance index */ - if (it->index < path->num_data) { - cairo_path_data_t *data = &path->data[it->index]; - int type = data->header.type; - - it->index += data[0].header.length; - - switch (type) { - case CAIRO_PATH_MOVE_TO: - case CAIRO_PATH_LINE_TO: - return Py_BuildValue("(i(dd))", type, - data[1].point.x, data[1].point.y); - case CAIRO_PATH_CURVE_TO: - return Py_BuildValue("(i(dddddd))", type, - data[1].point.x, data[1].point.y, - data[2].point.x, data[2].point.y, - data[3].point.x, data[3].point.y); - case CAIRO_PATH_CLOSE_PATH: - return Py_BuildValue("i()", type); - default: - PyErr_SetString(PyExc_RuntimeError, "unknown CAIRO_PATH type"); - return NULL; - } - } - - /* iterator has no remaining items */ - Py_DECREF(pypath); - it->pypath = NULL; - return NULL; -} - -PyTypeObject PycairoPathiter_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Pathiter", /* tp_name */ - sizeof(PycairoPathiter), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pathiter_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 */ - 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, /* PyObject_SelfIter, */ /* tp_iter */ - (iternextfunc)pathiter_next, /* tp_iternext */ - 0, /* tp_methods */ -}; diff --git a/src/pycairo-pattern.c b/src/pycairo-pattern.c deleted file mode 100644 index 2beda6a..0000000 --- a/src/pycairo-pattern.c +++ /dev/null @@ -1,598 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2004-2006 Steve 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 - -#ifdef HAVE_CONFIG_H -# include -#endif -#include "pycairo-private.h" - - -/* Class Pattern ---------------------------------------------------------- */ - -/* PycairoPattern_FromPattern - * Create a new - * PycairoSolidPattern, - * PycairoSurfacePattern, - * PycairoLinearGradient, or - * PycairoRadialGradient from a cairo_pattern_t. - * pattern - a cairo_pattern_t to 'wrap' into a Python object. - * It is unreferenced if the PycairoPattern creation fails, or if the - * pattern has an error status. - * base - the base object used to create the pattern, or NULL. - * It is referenced to keep it alive while the cairo_pattern_t is being used. - * For PycairoSurfacePattern base should be the PycairoSurface, for other - # patterns it should be NULL. - * Return value: New reference or NULL on failure - */ -PyObject * -PycairoPattern_FromPattern (cairo_pattern_t *pattern, PyObject *base) { - PyTypeObject *type = NULL; - PyObject *o; - - assert (pattern != NULL); - - if (Pycairo_Check_Status (cairo_pattern_status (pattern))) { - cairo_pattern_destroy (pattern); - return NULL; - } - - switch (cairo_pattern_get_type (pattern)) { - case CAIRO_PATTERN_TYPE_SOLID: - type = &PycairoSolidPattern_Type; - break; - case CAIRO_PATTERN_TYPE_SURFACE: - type = &PycairoSurfacePattern_Type; - break; - case CAIRO_PATTERN_TYPE_LINEAR: - type = &PycairoLinearGradient_Type; - break; - case CAIRO_PATTERN_TYPE_RADIAL: - type = &PycairoRadialGradient_Type; - break; - default: - type = &PycairoPattern_Type; - break; - } - - o = type->tp_alloc(type, 0); - if (o == NULL) { - cairo_pattern_destroy (pattern); - } else { - ((PycairoPattern *)o)->pattern = pattern; - Py_XINCREF(base); - ((PycairoPattern *)o)->base = base; - } - return o; -} - -static void -pattern_dealloc (PycairoPattern *o) { - if (o->pattern) { - cairo_pattern_destroy (o->pattern); - o->pattern = NULL; - } - Py_CLEAR(o->base); - - o->ob_type->tp_free((PyObject *)o); -} - -static PyObject * -pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyErr_SetString(PyExc_TypeError, - "The Pattern type cannot be instantiated"); - return NULL; -} - -static PyObject * -pattern_get_extend (PycairoPattern *o) { - return PyInt_FromLong (cairo_pattern_get_extend (o->pattern)); -} - -static PyObject * -pattern_get_matrix (PycairoPattern *o) { - cairo_matrix_t matrix; - cairo_pattern_get_matrix (o->pattern, &matrix); - return PycairoMatrix_FromMatrix (&matrix); -} - -static PyObject * -pattern_set_extend (PycairoPattern *o, PyObject *args) { - int extend; - - if (!PyArg_ParseTuple(args, "i:Pattern.set_extend", &extend)) - return NULL; - - cairo_pattern_set_extend (o->pattern, extend); - Py_RETURN_NONE; -} - -static PyObject * -pattern_set_matrix (PycairoPattern *o, PyObject *args) { - PycairoMatrix *m; - - if (!PyArg_ParseTuple (args, "O!:Pattern.set_matrix", - &PycairoMatrix_Type, &m)) - return NULL; - - cairo_pattern_set_matrix (o->pattern, &m->matrix); - Py_RETURN_NONE; -} - -static PyMethodDef pattern_methods[] = { - /* methods never exposed in a language binding: - * cairo_pattern_destroy() - * cairo_pattern_get_type() - * cairo_pattern_reference() - * - * cairo_pattern_status() - * - not needed since Pycairo handles status checking - */ - {"get_extend", (PyCFunction)pattern_get_extend, METH_NOARGS }, - {"get_matrix", (PyCFunction)pattern_get_matrix, METH_NOARGS }, - {"set_extend", (PyCFunction)pattern_set_extend, METH_VARARGS }, - {"set_matrix", (PyCFunction)pattern_set_matrix, METH_VARARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoPattern_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Pattern", /* tp_name */ - sizeof(PycairoPattern), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)pattern_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 */ - 0, /* 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 */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - pattern_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)pattern_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - - -/* Class SolidPattern ----------------------------------------------------- */ - -static PyObject * -solid_pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double r, g, b, a = 1.0; - if (!PyArg_ParseTuple (args, "ddd|d:SolidPattern.__new__", &r, &g, &b, &a)) - return NULL; - return PycairoPattern_FromPattern (cairo_pattern_create_rgba (r, g, b, a), - NULL); -} - -static PyObject * -solid_pattern_get_rgba (PycairoSolidPattern *o) { - double red, green, blue, alpha; - cairo_pattern_get_rgba (o->pattern, &red, &green, &blue, &alpha); - return Py_BuildValue("(dddd)", red, green, blue, alpha); -} - -static PyMethodDef solid_pattern_methods[] = { - {"get_rgba", (PyCFunction)solid_pattern_get_rgba, METH_NOARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoSolidPattern_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.SolidPattern", /* tp_name */ - sizeof(PycairoSolidPattern), /* 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 */ - solid_pattern_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoPattern_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)solid_pattern_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - -/* Class SurfacePattern --------------------------------------------------- */ - -static PyObject * -surface_pattern_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PycairoSurface *s; - if (!PyArg_ParseTuple (args, "O!:SurfacePattern.__new__", - &PycairoSurface_Type, &s)) - return NULL; - return PycairoPattern_FromPattern ( - cairo_pattern_create_for_surface (s->surface), (PyObject *)s); -} - -static PyObject * -surface_pattern_get_filter (PycairoSurfacePattern *o) { - return PyInt_FromLong (cairo_pattern_get_filter (o->pattern)); -} - -static PyObject * -surface_pattern_get_surface (PycairoSurfacePattern *o) { - /* - cairo_surface_t *surface; - cairo_pattern_get_surface (o->pattern, &surface); - return PycairoSurface_FromSurface ( - cairo_surface_reference (surface), NULL); - */ - /* return the surface used to create the pattern */ - return Py_BuildValue("O", o->base); -} - -static PyObject * -surface_pattern_set_filter (PycairoSurfacePattern *o, PyObject *args) { - int filter; - - if (!PyArg_ParseTuple (args, "i:SurfacePattern.set_filter", &filter)) - return NULL; - - cairo_pattern_set_filter (o->pattern, filter); - Py_RETURN_NONE; -} - -static PyMethodDef surface_pattern_methods[] = { - {"get_filter", (PyCFunction)surface_pattern_get_filter, METH_NOARGS }, - {"get_surface", (PyCFunction)surface_pattern_get_surface, METH_NOARGS }, - {"set_filter", (PyCFunction)surface_pattern_set_filter, METH_VARARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoSurfacePattern_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.SurfacePattern", /* tp_name */ - sizeof(PycairoSurfacePattern), /* 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 */ - surface_pattern_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoPattern_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)surface_pattern_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - -/* Class Gradient --------------------------------------------------------- */ - -static PyObject * -gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - PyErr_SetString(PyExc_TypeError, - "The Gradient type cannot be instantiated"); - return NULL; -} - -static PyObject * -gradient_add_color_stop_rgb (PycairoGradient *o, PyObject *args) { - double offset, red, green, blue; - if (!PyArg_ParseTuple(args, "dddd:Gradient.add_color_stop_rgb", - &offset, &red, &green, &blue)) - return NULL; - cairo_pattern_add_color_stop_rgb (o->pattern, offset, red, green, blue); - RETURN_NULL_IF_CAIRO_PATTERN_ERROR(o->pattern); - Py_RETURN_NONE; -} - -static PyObject * -gradient_add_color_stop_rgba (PycairoGradient *o, PyObject *args) { - double offset, red, green, blue, alpha; - if (!PyArg_ParseTuple(args, "ddddd:Gradient.add_color_stop_rgba", - &offset, &red, &green, &blue, &alpha)) - return NULL; - cairo_pattern_add_color_stop_rgba (o->pattern, offset, red, - green, blue, alpha); - RETURN_NULL_IF_CAIRO_PATTERN_ERROR(o->pattern); - Py_RETURN_NONE; -} - -static PyMethodDef gradient_methods[] = { - {"add_color_stop_rgb",(PyCFunction)gradient_add_color_stop_rgb, - METH_VARARGS }, - {"add_color_stop_rgba",(PyCFunction)gradient_add_color_stop_rgba, - METH_VARARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoGradient_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.Gradient", /* tp_name */ - sizeof(PycairoGradient), /* 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 | Py_TPFLAGS_BASETYPE,/* tp_flags */ - 0, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - gradient_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoPattern_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)gradient_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - -/* Class LinearGradient --------------------------------------------------- */ - -static PyObject * -linear_gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double x0, y0, x1, y1; - if (!PyArg_ParseTuple(args, "dddd:LinearGradient.__new__", - &x0, &y0, &x1, &y1)) - return NULL; - return PycairoPattern_FromPattern ( - cairo_pattern_create_linear (x0, y0, x1, y1), NULL); -} - -static PyObject * -linear_gradient_get_linear_points (PycairoLinearGradient *o) { - double x0, y0, x1, y1; - cairo_pattern_get_linear_points (o->pattern, &x0, &y0, &x1, &y1); - return Py_BuildValue("(dddd)", x0, y0, x1, y1); -} - -static PyMethodDef linear_gradient_methods[] = { - {"get_linear_points", (PyCFunction)linear_gradient_get_linear_points, - METH_NOARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoLinearGradient_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.LinearGradient", /* tp_name */ - sizeof(PycairoLinearGradient), /* 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 */ - linear_gradient_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoGradient_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)linear_gradient_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; - -/* Class RadialGradient --------------------------------------------------- */ - -static PyObject * -radial_gradient_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double cx0, cy0, radius0, cx1, cy1, radius1; - if (!PyArg_ParseTuple(args, "dddddd:RadialGradient.__new__", - &cx0, &cy0, &radius0, &cx1, &cy1, &radius1)) - return NULL; - return PycairoPattern_FromPattern ( - cairo_pattern_create_radial (cx0, cy0, radius0, cx1, cy1, radius1), - NULL); -} - -static PyObject * -radial_gradient_get_radial_circles (PycairoRadialGradient *o) { - double x0, y0, r0, x1, y1, r1; - cairo_pattern_get_radial_circles (o->pattern, &x0, &y0, &r0, - &x1, &y1, &r1); - return Py_BuildValue("(dddddd)", x0, y0, r0, x1, y1, r1); -} - -static PyMethodDef radial_gradient_methods[] = { - {"get_radial_circles", (PyCFunction)radial_gradient_get_radial_circles, - METH_NOARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoRadialGradient_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "cairo.RadialGradient", /* tp_name */ - sizeof(PycairoRadialGradient), /* 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 */ - radial_gradient_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PycairoGradient_Type, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - (newfunc)radial_gradient_new, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ -}; diff --git a/src/pycairo-private.h b/src/pycairo-private.h deleted file mode 100644 index 5951104..0000000 --- a/src/pycairo-private.h +++ /dev/null @@ -1,161 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2003 James Henstridge, 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. - */ - -#ifndef _PYCAIRO_PRIVATE_H_ -#define _PYCAIRO_PRIVATE_H_ - -#ifdef _PYCAIRO_H_ -# error "don't include pycairo.h and pycairo-private.h together" -#endif - -#define _INSIDE_PYCAIRO_ -#include - -#include "pycairo.h" - - -extern PyObject *CairoError; - -extern PyTypeObject PycairoContext_Type; -PyObject *PycairoContext_FromContext (cairo_t *ctx, PyTypeObject *type, - PyObject *base); - -extern PyTypeObject PycairoFontFace_Type; -extern PyTypeObject PycairoToyFontFace_Type; -PyObject *PycairoFontFace_FromFontFace (cairo_font_face_t *font_face); - -extern PyTypeObject PycairoFontOptions_Type; -PyObject *PycairoFontOptions_FromFontOptions ( - cairo_font_options_t *font_options); - -extern PyTypeObject PycairoMatrix_Type; -PyObject *PycairoMatrix_FromMatrix (const cairo_matrix_t *matrix); - -extern PyTypeObject PycairoPath_Type; -PyObject *PycairoPath_FromPath (cairo_path_t *path); - -extern PyTypeObject PycairoPathiter_Type; - -extern PyTypeObject PycairoPattern_Type; -extern PyTypeObject PycairoSolidPattern_Type; -extern PyTypeObject PycairoSurfacePattern_Type; -extern PyTypeObject PycairoGradient_Type; -extern PyTypeObject PycairoLinearGradient_Type; -extern PyTypeObject PycairoRadialGradient_Type; -PyObject *PycairoPattern_FromPattern (cairo_pattern_t *pattern, - PyObject *base); - -extern PyTypeObject PycairoScaledFont_Type; -PyObject *PycairoScaledFont_FromScaledFont (cairo_scaled_font_t *scaled_font); - -extern PyTypeObject PycairoSurface_Type; -extern PyTypeObject PycairoImageSurface_Type; - -#if CAIRO_HAS_PDF_SURFACE -extern PyTypeObject PycairoPDFSurface_Type; -#endif - -#if CAIRO_HAS_PS_SURFACE -extern PyTypeObject PycairoPSSurface_Type; -#endif - -#if CAIRO_HAS_SVG_SURFACE -extern PyTypeObject PycairoSVGSurface_Type; -#endif - -#if CAIRO_HAS_WIN32_SURFACE -extern PyTypeObject PycairoWin32Surface_Type; -#endif - -#if CAIRO_HAS_XLIB_SURFACE -extern PyTypeObject PycairoXlibSurface_Type; -#endif - -PyObject *PycairoSurface_FromSurface (cairo_surface_t *surface, - PyObject *base); - -int Pycairo_Check_Status (cairo_status_t status); - -/* error checking macros */ -#define RETURN_NULL_IF_CAIRO_ERROR(status) \ - do { \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - -#define RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(ctx) \ - do { \ - cairo_status_t status = cairo_status (ctx); \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - -#define RETURN_NULL_IF_CAIRO_PATTERN_ERROR(pattern) \ - do { \ - cairo_status_t status = cairo_pattern_status (pattern); \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - -#define RETURN_NULL_IF_CAIRO_SURFACE_ERROR(surface) \ - do { \ - cairo_status_t status = cairo_surface_status (surface); \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - -#define RETURN_NULL_IF_CAIRO_SCALED_FONT_ERROR(sc_font) \ - do { \ - cairo_status_t status = cairo_scaled_font_status (sc_font); \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - -#define RETURN_NULL_IF_CAIRO_FONT_OPTIONS_ERROR(fo) \ - do { \ - cairo_status_t status = cairo_font_options_status (fo); \ - if (status != CAIRO_STATUS_SUCCESS) { \ - Pycairo_Check_Status (status); \ - return NULL; \ - } \ - } while (0) - - -#endif /* _PYCAIRO_PRIVATE_H_ */ diff --git a/src/pycairo-surface.c b/src/pycairo-surface.c deleted file mode 100644 index a0cad36..0000000 --- a/src/pycairo-surface.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* -*- mode: C; c-basic-offset: 2 -*- - * - * Pycairo - Python bindings for cairo - * - * Copyright © 2003 James Henstridge, 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 - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include "pycairo-private.h" - - -/* Class Surface ---------------------------------------------------------- */ - -/* PycairoSurface_FromSurface - * Create a new - * PycairoImageSurface, - * PycairoPDFSurface, - * PycairoPSSurface, - * PycairoSVGSurface, - * PycairoWin32Surface, or - * PycairoXlibSurface from a cairo_surface_t. - * surface - a cairo_surface_t to 'wrap' into a Python object. - * It is unreferenced if the PycairoSurface creation fails, or if the - * cairo_surface_t has an error status. - * base - the base object used to create the surface, or NULL. - * It is referenced to keep it alive while the cairo_surface_t is being used. - * Return value: New reference or NULL on failure - */ -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)) { -#if CAIRO_HAS_IMAGE_SURFACE - case CAIRO_SURFACE_TYPE_IMAGE: - type = &PycairoImageSurface_Type; - break; -#endif -#if CAIRO_HAS_PDF_SURFACE - case CAIRO_SURFACE_TYPE_PDF: - type = &PycairoPDFSurface_Type; - break; -#endif -#if CAIRO_HAS_PS_SURFACE - case CAIRO_SURFACE_TYPE_PS: - type = &PycairoPSSurface_Type; - break; -#endif -#if CAIRO_HAS_SVG_SURFACE - case CAIRO_SURFACE_TYPE_SVG: - type = &PycairoSVGSurface_Type; - break; -#endif -#if CAIRO_HAS_WIN32_SURFACE - case CAIRO_SURFACE_TYPE_WIN32: - type = &PycairoWin32Surface_Type; - break; -#endif -#if CAIRO_HAS_XLIB_SURFACE - case CAIRO_SURFACE_TYPE_XLIB: - type = &PycairoXlibSurface_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", "(s#)", - data, (Py_ssize_t)length); - if (res == NULL) { - /* 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 void -surface_dealloc (PycairoSurface *o) { - if (o->surface) { - cairo_surface_destroy(o->surface); - o->surface = NULL; - } - Py_CLEAR(o->base); - - o->ob_type->tp_free((PyObject *)o); -} - -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; - - if (!PyArg_ParseTuple (args, "iii:Surface.create_similar", - &content, &width, &height)) - return NULL; - 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 PyInt_FromLong (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_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_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_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_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; -} - -#ifdef CAIRO_HAS_PNG_FUNCTIONS -/* METH_O */ -static PyObject * -surface_write_to_png (PycairoSurface *o, PyObject *file) { - cairo_status_t status; - - if (PyObject_TypeCheck (file, &PyBaseString_Type)) { - /* string (filename) argument */ - Py_BEGIN_ALLOW_THREADS; - status = cairo_surface_write_to_png (o->surface, - PyString_AsString(file)); - Py_END_ALLOW_THREADS; - - } else { /* file or file-like object argument */ - PyObject* writer = PyObject_GetAttrString (file, "write"); - if (writer == NULL || !PyCallable_Check (writer)) { - Py_XDECREF(writer); - PyErr_SetString(PyExc_TypeError, -"Surface.write_to_png takes one argument which must be a filename (str), file " -"object, or a file-like object which has a \"write\" method (like StringIO)"); - return NULL; - } - Py_DECREF(writer); - Py_BEGIN_ALLOW_THREADS; - status = cairo_surface_write_to_png_stream (o->surface, _write_func, - file); - Py_END_ALLOW_THREADS; - } - RETURN_NULL_IF_CAIRO_ERROR(status); - Py_RETURN_NONE; -} -#endif /* CAIRO_HAS_PNG_FUNCTIONS */ - - -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() - */ - {"copy_page", (PyCFunction)surface_copy_page, METH_NOARGS}, - {"create_similar", (PyCFunction)surface_create_similar, 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_fallback_resolution",(PyCFunction)surface_get_fallback_resolution, - METH_NOARGS}, - {"get_font_options",(PyCFunction)surface_get_font_options, 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_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_O }, -#endif - {NULL, NULL, 0, NULL}, -}; - - -PyTypeObject PycairoSurface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ - 0, /* 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 */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - surface_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - &PyBaseObject_Type, /* 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; - - if (!PyArg_ParseTuple (args, "iii:ImageSurface.__new__", - &format, &width, &height)) - return NULL; - return PycairoSurface_FromSurface ( - cairo_image_surface_create (format, width, height), - NULL); -} - -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; - - 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) - 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(CairoError, - "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 PycairoSurface_FromSurface(surface, obj); -} - - -#ifdef CAIRO_HAS_PNG_FUNCTIONS -static cairo_status_t -_read_func (void *closure, unsigned char *data, unsigned int length) { - char *buffer; - 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) { - /* an exception has occurred, it will be picked up later by - * Pycairo_Check_Status() - */ - goto end; - } - int ret = PyString_AsStringAndSize(pystr, &buffer, &str_length); - if (ret == -1 || str_length < length) { - goto end; - } - /* don't use strncpy() since png data may contain NUL bytes */ - memcpy (data, buffer, str_length); - status = CAIRO_STATUS_SUCCESS; - end: - Py_XDECREF(pystr); - PyGILState_Release(gstate); - return status; -} - -/* METH_O | METH_CLASS */ -static PyObject * -image_surface_create_from_png (PyTypeObject *type, PyObject *file) { - PyObject* reader; - cairo_surface_t *is; - - if (PyObject_TypeCheck (file, &PyBaseString_Type)) { - Py_BEGIN_ALLOW_THREADS; - is = cairo_image_surface_create_from_png (PyString_AsString(file)); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (is, NULL); - } - - /* file or file-like object argument */ - reader = PyObject_GetAttrString (file, "read"); - if (reader == NULL || !PyCallable_Check (reader)) { - Py_XDECREF(reader); - 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; - } - Py_DECREF(reader); - - Py_BEGIN_ALLOW_THREADS; - is = cairo_image_surface_create_from_png_stream (_read_func, file); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (is, 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; - if (!PyArg_ParseTuple(args, "ii:format_stride_for_width", &format, &width)) - return NULL; - return PyInt_FromLong (cairo_format_stride_for_width (format, width)); -} - -static PyObject * -image_surface_get_data (PycairoImageSurface *o) { - return PyBuffer_FromReadWriteObject((PyObject *)o, 0, Py_END_OF_BUFFER); -} - -static PyObject * -image_surface_get_format (PycairoImageSurface *o) { - return PyInt_FromLong (cairo_image_surface_get_format (o->surface)); -} - -static PyObject * -image_surface_get_height (PycairoImageSurface *o) { - return PyInt_FromLong (cairo_image_surface_get_height (o->surface)); -} - -static PyObject * -image_surface_get_stride (PycairoImageSurface *o) { - return PyInt_FromLong (cairo_image_surface_get_stride (o->surface)); -} - -static PyObject * -image_surface_get_width (PycairoImageSurface *o) { - return PyInt_FromLong (cairo_image_surface_get_width (o->surface)); -} - - -/* 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 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_O | 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 = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ - &image_surface_as_buffer, /* 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 */ - 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 */ -}; -#endif /* CAIRO_HAS_IMAGE_SURFACE */ - - -/* Class PDFSurface(Surface) ---------------------------------------------- */ -#ifdef CAIRO_HAS_PDF_SURFACE -#include - -static PyObject * -pdf_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double width_in_points, height_in_points; - PyObject *file, *writer; - cairo_surface_t *sfc; - - if (!PyArg_ParseTuple(args, "Odd:PDFSurface.__new__", - &file, &width_in_points, &height_in_points)) - return NULL; - - if (file == Py_None) { - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_pdf_surface_create (NULL, - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { - /* string (filename) argument */ - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_pdf_surface_create (PyString_AsString(file), - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - } - /* file or file-like object argument */ - writer = PyObject_GetAttrString (file, "write"); - if (writer == NULL || !PyCallable_Check (writer)) { - Py_XDECREF(writer); - PyErr_SetString(PyExc_TypeError, -"PDFSurface argument 1 must be\n" -" None, or\n" -" a filename (str), or\n" -" a file object, or\n" -" an object that has a \"write\" method (like StringIO)." - ); - return NULL; - } - Py_DECREF(writer); - - 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 PycairoSurface_FromSurface (sfc, file); -} - -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 PyMethodDef pdf_surface_methods[] = { - {"set_size", (PyCFunction)pdf_surface_set_size, METH_VARARGS }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoPDFSurface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ - - -/* Class PSSurface(Surface) ----------------------------------------------- */ -#ifdef CAIRO_HAS_PS_SURFACE -#include - -static PyObject * -ps_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double width_in_points, height_in_points; - PyObject *file, *writer; - cairo_surface_t *sfc; - - if (!PyArg_ParseTuple(args, "Odd:PSSurface.__new__", - &file, &width_in_points, &height_in_points)) - return NULL; - - if (file == Py_None) { - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_ps_surface_create (NULL, - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { - /* string (filename) argument */ - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_ps_surface_create (PyString_AsString(file), - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - } - /* else: file or file-like object argument */ - writer = PyObject_GetAttrString (file, "write"); - if (writer == NULL || !PyCallable_Check (writer)) { - Py_XDECREF(writer); - PyErr_SetString(PyExc_TypeError, -"PSSurface argument 1 must be\n" -" None, or\n" -" a filename (str), or\n" -" a file object, or\n" -" an object that has a \"write\" method (like StringIO)." - ); - return NULL; - } - Py_DECREF(writer); - - 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 PycairoSurface_FromSurface (sfc, file); -} - -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_surface_ps_level_to_string (PyObject *self, PyObject *args) { - int level; - if (!PyArg_ParseTuple(args, "i:ps_level_to_string", &level)) - return NULL; - const char *s = cairo_ps_level_to_string (level); - if (s == NULL){ - PyErr_SetString(CairoError, "ps_level_to_string: " - "invalid level argument"); - return NULL; - } - return PyString_FromString(s); -} - -static PyObject * -ps_surface_restrict_to_level (PycairoPSSurface *o, PyObject *args) { - int level; - - if (!PyArg_ParseTuple(args, "i:PSSurface.restrict_to_level", &level)) - return NULL; - 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 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_get_levels - not implemented yet*/ - {"ps_level_to_string", (PyCFunction)ps_surface_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 }, - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoPSSurface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 SVGSurface(Surface) ----------------------------------------------- */ -#ifdef CAIRO_HAS_SVG_SURFACE -#include - -static PyObject * -svg_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - double width_in_points, height_in_points; - PyObject *file, *writer; - cairo_surface_t *sfc; - - if (!PyArg_ParseTuple(args, "Odd:SVGSurface.__new__", - &file, &width_in_points, &height_in_points)) - return NULL; - - if (file == Py_None) { - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_svg_surface_create (NULL, - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { - /* string (filename) argument */ - Py_BEGIN_ALLOW_THREADS; - sfc = cairo_svg_surface_create (PyString_AsString(file), - width_in_points, height_in_points); - Py_END_ALLOW_THREADS; - return PycairoSurface_FromSurface (sfc, NULL); - } - /* else: file or file-like object argument */ - writer = PyObject_GetAttrString (file, "write"); - if (writer == NULL || !PyCallable_Check (writer)) { - Py_XDECREF(writer); - PyErr_SetString(PyExc_TypeError, -"SVGSurface argument 1 must be\n" -" None, or\n" -" a filename (str), or\n" -" a file object, or\n" -" an object that has a \"write\" method (like StringIO)." - ); - return NULL; - } - Py_DECREF(writer); - - 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 PycairoSurface_FromSurface (sfc, file); -} - -static PyMethodDef svg_surface_methods[] = { - /* TODO - * cairo_svg_surface_restrict_to_version - * cairo_svg_get_versions - * cairo_svg_version_to_string - */ - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoSVGSurface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ - - -/* Class Win32Surface(Surface) -------------------------------------------- */ -#if CAIRO_HAS_WIN32_SURFACE -#include - -static PyObject * -win32_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { - int hdc; - - if (!PyArg_ParseTuple(args, "i:Win32Surface.__new__", &hdc)) - return NULL; - return PycairoSurface_FromSurface ( - cairo_win32_surface_create ((HDC)hdc), NULL); -} - -static PyMethodDef win32_surface_methods[] = { - {NULL, NULL, 0, NULL}, -}; - -PyTypeObject PycairoWin32Surface_Type = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ -}; -#endif /* CAIRO_HAS_WIN32_SURFACE */ - - -/* Class XlibSurface(Surface) --------------------------------------------- */ -#ifdef CAIRO_HAS_XLIB_SURFACE -#include - -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 PyInt_FromLong (cairo_xlib_surface_get_depth (o->surface)); -} - -static PyObject * -xlib_surface_get_height (PycairoXlibSurface *o) { - return PyInt_FromLong (cairo_xlib_surface_get_height (o->surface)); -} - -static PyObject * -xlib_surface_get_width (PycairoXlibSurface *o) { - return PyInt_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 = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - "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 */ diff --git a/src/surface.c b/src/surface.c new file mode 100644 index 0000000..f2f05b8 --- /dev/null +++ b/src/surface.c @@ -0,0 +1,1218 @@ +/* -*- mode: C; c-basic-offset: 2 -*- + * + * Pycairo - Python bindings for cairo + * + * Copyright © 2003 James Henstridge, 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 + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "private.h" + + +/* Class Surface ---------------------------------------------------------- */ + +/* PycairoSurface_FromSurface + * Create a new + * PycairoImageSurface, + * PycairoPDFSurface, + * PycairoPSSurface, + * PycairoSVGSurface, + * PycairoWin32Surface, or + * PycairoXlibSurface from a cairo_surface_t. + * surface - a cairo_surface_t to 'wrap' into a Python object. + * It is unreferenced if the PycairoSurface creation fails, or if the + * cairo_surface_t has an error status. + * base - the base object used to create the surface, or NULL. + * It is referenced to keep it alive while the cairo_surface_t is being used. + * Return value: New reference or NULL on failure + */ +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)) { +#if CAIRO_HAS_IMAGE_SURFACE + case CAIRO_SURFACE_TYPE_IMAGE: + type = &PycairoImageSurface_Type; + break; +#endif +#if CAIRO_HAS_PDF_SURFACE + case CAIRO_SURFACE_TYPE_PDF: + type = &PycairoPDFSurface_Type; + break; +#endif +#if CAIRO_HAS_PS_SURFACE + case CAIRO_SURFACE_TYPE_PS: + type = &PycairoPSSurface_Type; + break; +#endif +#if CAIRO_HAS_SVG_SURFACE + case CAIRO_SURFACE_TYPE_SVG: + type = &PycairoSVGSurface_Type; + break; +#endif +#if CAIRO_HAS_WIN32_SURFACE + case CAIRO_SURFACE_TYPE_WIN32: + type = &PycairoWin32Surface_Type; + break; +#endif +#if CAIRO_HAS_XLIB_SURFACE + case CAIRO_SURFACE_TYPE_XLIB: + type = &PycairoXlibSurface_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", "(s#)", + data, (Py_ssize_t)length); + if (res == NULL) { + /* 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 void +surface_dealloc (PycairoSurface *o) { + if (o->surface) { + cairo_surface_destroy(o->surface); + o->surface = NULL; + } + Py_CLEAR(o->base); + + o->ob_type->tp_free((PyObject *)o); +} + +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; + + if (!PyArg_ParseTuple (args, "iii:Surface.create_similar", + &content, &width, &height)) + return NULL; + 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 PyInt_FromLong (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_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_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_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_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; +} + +#ifdef CAIRO_HAS_PNG_FUNCTIONS +/* METH_O */ +static PyObject * +surface_write_to_png (PycairoSurface *o, PyObject *file) { + cairo_status_t status; + + if (PyObject_TypeCheck (file, &PyBaseString_Type)) { + /* string (filename) argument */ + Py_BEGIN_ALLOW_THREADS; + status = cairo_surface_write_to_png (o->surface, + PyString_AsString(file)); + Py_END_ALLOW_THREADS; + + } else { /* file or file-like object argument */ + PyObject* writer = PyObject_GetAttrString (file, "write"); + if (writer == NULL || !PyCallable_Check (writer)) { + Py_XDECREF(writer); + PyErr_SetString(PyExc_TypeError, +"Surface.write_to_png takes one argument which must be a filename (str), file " +"object, or a file-like object which has a \"write\" method (like StringIO)"); + return NULL; + } + Py_DECREF(writer); + Py_BEGIN_ALLOW_THREADS; + status = cairo_surface_write_to_png_stream (o->surface, _write_func, + file); + Py_END_ALLOW_THREADS; + } + RETURN_NULL_IF_CAIRO_ERROR(status); + Py_RETURN_NONE; +} +#endif /* CAIRO_HAS_PNG_FUNCTIONS */ + + +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() + */ + {"copy_page", (PyCFunction)surface_copy_page, METH_NOARGS}, + {"create_similar", (PyCFunction)surface_create_similar, 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_fallback_resolution",(PyCFunction)surface_get_fallback_resolution, + METH_NOARGS}, + {"get_font_options",(PyCFunction)surface_get_font_options, 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_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_O }, +#endif + {NULL, NULL, 0, NULL}, +}; + + +PyTypeObject PycairoSurface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ + 0, /* 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 */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + surface_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + &PyBaseObject_Type, /* 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; + + if (!PyArg_ParseTuple (args, "iii:ImageSurface.__new__", + &format, &width, &height)) + return NULL; + return PycairoSurface_FromSurface ( + cairo_image_surface_create (format, width, height), + NULL); +} + +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; + + 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) + 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(CairoError, + "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 PycairoSurface_FromSurface(surface, obj); +} + + +#ifdef CAIRO_HAS_PNG_FUNCTIONS +static cairo_status_t +_read_func (void *closure, unsigned char *data, unsigned int length) { + char *buffer; + 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) { + /* an exception has occurred, it will be picked up later by + * Pycairo_Check_Status() + */ + goto end; + } + int ret = PyString_AsStringAndSize(pystr, &buffer, &str_length); + if (ret == -1 || str_length < length) { + goto end; + } + /* don't use strncpy() since png data may contain NUL bytes */ + memcpy (data, buffer, str_length); + status = CAIRO_STATUS_SUCCESS; + end: + Py_XDECREF(pystr); + PyGILState_Release(gstate); + return status; +} + +/* METH_O | METH_CLASS */ +static PyObject * +image_surface_create_from_png (PyTypeObject *type, PyObject *file) { + PyObject* reader; + cairo_surface_t *is; + + if (PyObject_TypeCheck (file, &PyBaseString_Type)) { + Py_BEGIN_ALLOW_THREADS; + is = cairo_image_surface_create_from_png (PyString_AsString(file)); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (is, NULL); + } + + /* file or file-like object argument */ + reader = PyObject_GetAttrString (file, "read"); + if (reader == NULL || !PyCallable_Check (reader)) { + Py_XDECREF(reader); + 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; + } + Py_DECREF(reader); + + Py_BEGIN_ALLOW_THREADS; + is = cairo_image_surface_create_from_png_stream (_read_func, file); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (is, 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; + if (!PyArg_ParseTuple(args, "ii:format_stride_for_width", &format, &width)) + return NULL; + return PyInt_FromLong (cairo_format_stride_for_width (format, width)); +} + +static PyObject * +image_surface_get_data (PycairoImageSurface *o) { + return PyBuffer_FromReadWriteObject((PyObject *)o, 0, Py_END_OF_BUFFER); +} + +static PyObject * +image_surface_get_format (PycairoImageSurface *o) { + return PyInt_FromLong (cairo_image_surface_get_format (o->surface)); +} + +static PyObject * +image_surface_get_height (PycairoImageSurface *o) { + return PyInt_FromLong (cairo_image_surface_get_height (o->surface)); +} + +static PyObject * +image_surface_get_stride (PycairoImageSurface *o) { + return PyInt_FromLong (cairo_image_surface_get_stride (o->surface)); +} + +static PyObject * +image_surface_get_width (PycairoImageSurface *o) { + return PyInt_FromLong (cairo_image_surface_get_width (o->surface)); +} + + +/* 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 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_O | 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 = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ + &image_surface_as_buffer, /* 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 */ + 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 */ +}; +#endif /* CAIRO_HAS_IMAGE_SURFACE */ + + +/* Class PDFSurface(Surface) ---------------------------------------------- */ +#ifdef CAIRO_HAS_PDF_SURFACE +#include + +static PyObject * +pdf_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double width_in_points, height_in_points; + PyObject *file, *writer; + cairo_surface_t *sfc; + + if (!PyArg_ParseTuple(args, "Odd:PDFSurface.__new__", + &file, &width_in_points, &height_in_points)) + return NULL; + + if (file == Py_None) { + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_pdf_surface_create (NULL, + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { + /* string (filename) argument */ + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_pdf_surface_create (PyString_AsString(file), + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + } + /* file or file-like object argument */ + writer = PyObject_GetAttrString (file, "write"); + if (writer == NULL || !PyCallable_Check (writer)) { + Py_XDECREF(writer); + PyErr_SetString(PyExc_TypeError, +"PDFSurface argument 1 must be\n" +" None, or\n" +" a filename (str), or\n" +" a file object, or\n" +" an object that has a \"write\" method (like StringIO)." + ); + return NULL; + } + Py_DECREF(writer); + + 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 PycairoSurface_FromSurface (sfc, file); +} + +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 PyMethodDef pdf_surface_methods[] = { + {"set_size", (PyCFunction)pdf_surface_set_size, METH_VARARGS }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoPDFSurface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ + + +/* Class PSSurface(Surface) ----------------------------------------------- */ +#ifdef CAIRO_HAS_PS_SURFACE +#include + +static PyObject * +ps_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double width_in_points, height_in_points; + PyObject *file, *writer; + cairo_surface_t *sfc; + + if (!PyArg_ParseTuple(args, "Odd:PSSurface.__new__", + &file, &width_in_points, &height_in_points)) + return NULL; + + if (file == Py_None) { + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_ps_surface_create (NULL, + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { + /* string (filename) argument */ + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_ps_surface_create (PyString_AsString(file), + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + } + /* else: file or file-like object argument */ + writer = PyObject_GetAttrString (file, "write"); + if (writer == NULL || !PyCallable_Check (writer)) { + Py_XDECREF(writer); + PyErr_SetString(PyExc_TypeError, +"PSSurface argument 1 must be\n" +" None, or\n" +" a filename (str), or\n" +" a file object, or\n" +" an object that has a \"write\" method (like StringIO)." + ); + return NULL; + } + Py_DECREF(writer); + + 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 PycairoSurface_FromSurface (sfc, file); +} + +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_surface_ps_level_to_string (PyObject *self, PyObject *args) { + int level; + if (!PyArg_ParseTuple(args, "i:ps_level_to_string", &level)) + return NULL; + const char *s = cairo_ps_level_to_string (level); + if (s == NULL){ + PyErr_SetString(CairoError, "ps_level_to_string: " + "invalid level argument"); + return NULL; + } + return PyString_FromString(s); +} + +static PyObject * +ps_surface_restrict_to_level (PycairoPSSurface *o, PyObject *args) { + int level; + + if (!PyArg_ParseTuple(args, "i:PSSurface.restrict_to_level", &level)) + return NULL; + 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 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_get_levels - not implemented yet*/ + {"ps_level_to_string", (PyCFunction)ps_surface_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 }, + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoPSSurface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 SVGSurface(Surface) ----------------------------------------------- */ +#ifdef CAIRO_HAS_SVG_SURFACE +#include + +static PyObject * +svg_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + double width_in_points, height_in_points; + PyObject *file, *writer; + cairo_surface_t *sfc; + + if (!PyArg_ParseTuple(args, "Odd:SVGSurface.__new__", + &file, &width_in_points, &height_in_points)) + return NULL; + + if (file == Py_None) { + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_svg_surface_create (NULL, + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + }else if (PyObject_TypeCheck (file, &PyBaseString_Type)) { + /* string (filename) argument */ + Py_BEGIN_ALLOW_THREADS; + sfc = cairo_svg_surface_create (PyString_AsString(file), + width_in_points, height_in_points); + Py_END_ALLOW_THREADS; + return PycairoSurface_FromSurface (sfc, NULL); + } + /* else: file or file-like object argument */ + writer = PyObject_GetAttrString (file, "write"); + if (writer == NULL || !PyCallable_Check (writer)) { + Py_XDECREF(writer); + PyErr_SetString(PyExc_TypeError, +"SVGSurface argument 1 must be\n" +" None, or\n" +" a filename (str), or\n" +" a file object, or\n" +" an object that has a \"write\" method (like StringIO)." + ); + return NULL; + } + Py_DECREF(writer); + + 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 PycairoSurface_FromSurface (sfc, file); +} + +static PyMethodDef svg_surface_methods[] = { + /* TODO + * cairo_svg_surface_restrict_to_version + * cairo_svg_get_versions + * cairo_svg_version_to_string + */ + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoSVGSurface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ + + +/* Class Win32Surface(Surface) -------------------------------------------- */ +#if CAIRO_HAS_WIN32_SURFACE +#include + +static PyObject * +win32_surface_new (PyTypeObject *type, PyObject *args, PyObject *kwds) { + int hdc; + + if (!PyArg_ParseTuple(args, "i:Win32Surface.__new__", &hdc)) + return NULL; + return PycairoSurface_FromSurface ( + cairo_win32_surface_create ((HDC)hdc), NULL); +} + +static PyMethodDef win32_surface_methods[] = { + {NULL, NULL, 0, NULL}, +}; + +PyTypeObject PycairoWin32Surface_Type = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ +}; +#endif /* CAIRO_HAS_WIN32_SURFACE */ + + +/* Class XlibSurface(Surface) --------------------------------------------- */ +#ifdef CAIRO_HAS_XLIB_SURFACE +#include + +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 PyInt_FromLong (cairo_xlib_surface_get_depth (o->surface)); +} + +static PyObject * +xlib_surface_get_height (PycairoXlibSurface *o) { + return PyInt_FromLong (cairo_xlib_surface_get_height (o->surface)); +} + +static PyObject * +xlib_surface_get_width (PycairoXlibSurface *o) { + return PyInt_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 = { + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ + "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 */ -- cgit v1.2.1