1 /* -*- mode: C; c-basic-offset: 2 -*-
2  *
3  * Pycairo - Python bindings for cairo
4  *
5  * Copyright © 2003 James Henstridge, Steven Chaplin
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it either under the terms of the GNU Lesser General Public
9  * License version 2.1 as published by the Free Software Foundation
10  * (the "LGPL") or, at your option, under the terms of the Mozilla
11  * Public License Version 1.1 (the "MPL"). If you do not alter this
12  * notice, a recipient may use your version of this file under either
13  * the MPL or the LGPL.
14  *
15  * You should have received a copy of the LGPL along with this library
16  * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  * You should have received a copy of the MPL along with this library
19  * in the file COPYING-MPL-1.1
20  *
21  * The contents of this file are subject to the Mozilla Public License
22  * Version 1.1 (the "License"); you may not use this file except in
23  * compliance with the License. You may obtain a copy of the License at
24  * http://www.mozilla.org/MPL/
25  *
26  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27  * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28  * the specific language governing rights and limitations.
29  */
30 
31 #define PY_SSIZE_T_CLEAN
32 #include <Python.h>
33 
34 #include "private.h"
35 
36 PyObject *
PycairoContext_FromContext(cairo_t * ctx,PyTypeObject * type,PyObject * base)37 PycairoContext_FromContext(cairo_t *ctx, PyTypeObject *type, PyObject *base) {
38   PyObject *o;
39 
40   assert (ctx != NULL);
41 
42   if (Pycairo_Check_Status (cairo_status (ctx))) {
43     cairo_destroy (ctx);
44     return NULL;
45   }
46 
47   o = PycairoContext_Type.tp_alloc (type, 0);
48   if (o) {
49     ((PycairoContext *)o)->ctx = ctx;
50     Py_XINCREF(base);
51     ((PycairoContext *)o)->base = base;
52   } else {
53     cairo_destroy (ctx);
54   }
55   return o;
56 }
57 
58 static void
pycairo_dealloc(PycairoContext * o)59 pycairo_dealloc(PycairoContext *o) {
60   if (o->ctx) {
61     cairo_destroy(o->ctx);
62     o->ctx = NULL;
63   }
64   Py_CLEAR(o->base);
65   Py_TYPE(o)->tp_free(o);
66 }
67 
68 static PyObject *
pycairo_new(PyTypeObject * type,PyObject * args,PyObject * kwds)69 pycairo_new (PyTypeObject *type, PyObject *args, PyObject *kwds) {
70   PycairoSurface *s;
71   if (!PyArg_ParseTuple(args, "O!:Context.__new__",
72 			&PycairoSurface_Type, &s))
73     return NULL;
74   return PycairoContext_FromContext (cairo_create (s->surface), type, NULL);
75 }
76 
77 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
78 static PyObject *
pycairo_tag_begin(PycairoContext * o,PyObject * args)79 pycairo_tag_begin (PycairoContext *o, PyObject *args) {
80     const char *tag_name;
81     const char *attributes;
82 
83     if (!PyArg_ParseTuple (args,
84             PYCAIRO_ENC_TEXT_FORMAT PYCAIRO_ENC_TEXT_FORMAT
85             ":Context.tag_begin", "utf-8",
86             &tag_name, "utf-8", &attributes))
87         return NULL;
88 
89     Py_BEGIN_ALLOW_THREADS;
90     cairo_tag_begin (o->ctx, tag_name, attributes);
91     Py_END_ALLOW_THREADS;
92 
93     PyMem_Free((void *)tag_name);
94     PyMem_Free((void *)attributes);
95 
96     RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
97     Py_RETURN_NONE;
98 }
99 
100 static PyObject *
pycairo_tag_end(PycairoContext * o,PyObject * args)101 pycairo_tag_end (PycairoContext *o, PyObject *args) {
102     const char *tag_name;
103 
104     if (!PyArg_ParseTuple (args,
105             PYCAIRO_ENC_TEXT_FORMAT ":Context.tag_end", "utf-8",
106             &tag_name))
107         return NULL;
108 
109       Py_BEGIN_ALLOW_THREADS;
110       cairo_tag_end (o->ctx, tag_name);
111       Py_END_ALLOW_THREADS;
112 
113       PyMem_Free((void *)tag_name);
114 
115       RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
116       Py_RETURN_NONE;
117 }
118 #endif
119 
120 static PyObject *
pycairo_append_path(PycairoContext * o,PyObject * args)121 pycairo_append_path (PycairoContext *o, PyObject *args) {
122   PycairoPath *p;
123 
124   if (!PyArg_ParseTuple(args, "O!:Context.append_path",
125 			&PycairoPath_Type, &p))
126     return NULL;
127 
128   Py_BEGIN_ALLOW_THREADS;
129   cairo_append_path (o->ctx, p->path);
130   Py_END_ALLOW_THREADS;
131   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
132   Py_RETURN_NONE;
133 }
134 
135 static PyObject *
pycairo_arc(PycairoContext * o,PyObject * args)136 pycairo_arc (PycairoContext *o, PyObject *args) {
137   double xc, yc, radius, angle1, angle2;
138 
139   if (!PyArg_ParseTuple (args, "ddddd:Context.arc",
140 			 &xc, &yc, &radius, &angle1, &angle2))
141     return NULL;
142 
143   cairo_arc (o->ctx, xc, yc, radius, angle1, angle2);
144   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
145   Py_RETURN_NONE;
146 }
147 
148 static PyObject *
pycairo_arc_negative(PycairoContext * o,PyObject * args)149 pycairo_arc_negative (PycairoContext *o, PyObject *args) {
150   double xc, yc, radius, angle1, angle2;
151 
152   if (!PyArg_ParseTuple (args, "ddddd:Context.arc_negative",
153 			 &xc, &yc, &radius, &angle1, &angle2))
154     return NULL;
155 
156   cairo_arc_negative (o->ctx, xc, yc, radius, angle1, angle2);
157   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
158   Py_RETURN_NONE;
159 }
160 
161 static PyObject *
pycairo_clip(PycairoContext * o,PyObject * ignored)162 pycairo_clip (PycairoContext *o, PyObject *ignored) {
163   Py_BEGIN_ALLOW_THREADS;
164   cairo_clip (o->ctx);
165   Py_END_ALLOW_THREADS;
166   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
167   Py_RETURN_NONE;
168 }
169 
170 static PyObject *
pycairo_clip_extents(PycairoContext * o,PyObject * ignored)171 pycairo_clip_extents (PycairoContext *o, PyObject *ignored) {
172   double x1, y1, x2, y2;
173   cairo_clip_extents (o->ctx, &x1, &y1, &x2, &y2);
174   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
175   return Py_BuildValue("(dddd)", x1, y1, x2, y2);
176 }
177 
178 static PyObject *
pycairo_clip_preserve(PycairoContext * o,PyObject * ignored)179 pycairo_clip_preserve (PycairoContext *o, PyObject *ignored) {
180   Py_BEGIN_ALLOW_THREADS;
181   cairo_clip_preserve (o->ctx);
182   Py_END_ALLOW_THREADS;
183   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
184   Py_RETURN_NONE;
185 }
186 
187 static PyObject *
pycairo_in_clip(PycairoContext * o,PyObject * args)188 pycairo_in_clip (PycairoContext *o, PyObject *args) {
189   double x, y;
190   cairo_bool_t result;
191 
192   if (!PyArg_ParseTuple (args, "dd:Context.in_clip", &x, &y))
193     return NULL;
194 
195   Py_BEGIN_ALLOW_THREADS;
196   result = cairo_in_clip (o->ctx, x, y);
197   Py_END_ALLOW_THREADS;
198 
199   return PyBool_FromLong(result);
200 }
201 
202 static PyObject *
pycairo_close_path(PycairoContext * o,PyObject * ignored)203 pycairo_close_path (PycairoContext *o, PyObject *ignored) {
204   Py_BEGIN_ALLOW_THREADS;
205   cairo_close_path (o->ctx);
206   Py_END_ALLOW_THREADS;
207   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
208   Py_RETURN_NONE;
209 }
210 
211 static PyObject *
pycairo_copy_clip_rectangle_list(PycairoContext * o,PyObject * ignored)212 pycairo_copy_clip_rectangle_list (PycairoContext *o, PyObject *ignored) {
213   int i;
214   PyObject *rv = NULL;
215   PyObject *rect = NULL;
216   cairo_rectangle_t *r;
217 
218   cairo_rectangle_list_t *rlist = cairo_copy_clip_rectangle_list (o->ctx);
219   if (rlist->status != CAIRO_STATUS_SUCCESS) {
220     Pycairo_Check_Status (rlist->status);
221     goto exit;
222   }
223 
224   rv = PyList_New(rlist->num_rectangles);
225   if (rv == NULL)
226     goto exit;
227 
228   for (i = 0, r = rlist->rectangles; i < rlist->num_rectangles; i++, r++) {
229     PyObject *py_rect = Py_BuildValue("(dddd)", r->x, r->y,
230                                       r->width, r->height);
231     if (py_rect == NULL) {
232       Py_CLEAR(rv);
233       goto exit;
234     }
235     rect = PyObject_Call((PyObject *)&PycairoRectangle_Type, py_rect, NULL);
236     Py_DECREF (py_rect);
237     if (rect == NULL) {
238         Py_CLEAR(rv);
239         goto exit;
240     }
241     PyList_SET_ITEM (rv, i, rect);
242   }
243  exit:
244   cairo_rectangle_list_destroy(rlist);
245   return rv;
246 }
247 
248 static PyObject *
pycairo_copy_page(PycairoContext * o,PyObject * ignored)249 pycairo_copy_page (PycairoContext *o, PyObject *ignored) {
250   Py_BEGIN_ALLOW_THREADS;
251   cairo_copy_page (o->ctx);
252   Py_END_ALLOW_THREADS;
253   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
254   Py_RETURN_NONE;
255 }
256 
257 static PyObject *
pycairo_copy_path(PycairoContext * o,PyObject * ignored)258 pycairo_copy_path (PycairoContext *o, PyObject *ignored) {
259   cairo_path_t *cp;
260   Py_BEGIN_ALLOW_THREADS;
261   cp = cairo_copy_path (o->ctx);
262   Py_END_ALLOW_THREADS;
263   return PycairoPath_FromPath (cp);
264 }
265 
266 static PyObject *
pycairo_copy_path_flat(PycairoContext * o,PyObject * ignored)267 pycairo_copy_path_flat (PycairoContext *o, PyObject *ignored) {
268   cairo_path_t *cp;
269   Py_BEGIN_ALLOW_THREADS;
270   cp = cairo_copy_path_flat (o->ctx);
271   Py_END_ALLOW_THREADS;
272   return PycairoPath_FromPath (cp);
273 }
274 
275 static PyObject *
pycairo_curve_to(PycairoContext * o,PyObject * args)276 pycairo_curve_to (PycairoContext *o, PyObject *args) {
277   double x1, y1, x2, y2, x3, y3;
278 
279   if (!PyArg_ParseTuple (args, "dddddd:Context.curve_to",
280 			 &x1, &y1, &x2, &y2, &x3, &y3))
281     return NULL;
282 
283   cairo_curve_to (o->ctx, x1, y1, x2, y2, x3, y3);
284   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
285   Py_RETURN_NONE;
286 }
287 
288 static PyObject *
pycairo_device_to_user(PycairoContext * o,PyObject * args)289 pycairo_device_to_user(PycairoContext *o, PyObject *args) {
290   double x, y;
291 
292   if (!PyArg_ParseTuple(args, "dd:Context.device_to_user", &x, &y))
293     return NULL;
294 
295   cairo_device_to_user(o->ctx, &x, &y);
296   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
297   return Py_BuildValue("(dd)", x, y);
298 }
299 
300 static PyObject *
pycairo_device_to_user_distance(PycairoContext * o,PyObject * args)301 pycairo_device_to_user_distance (PycairoContext *o, PyObject *args) {
302   double dx, dy;
303 
304   if (!PyArg_ParseTuple (args, "dd:Context.device_to_user_distance",
305 			 &dx, &dy))
306     return NULL;
307 
308   cairo_device_to_user_distance (o->ctx, &dx, &dy);
309   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
310   return Py_BuildValue("(dd)", dx, dy);
311 }
312 
313 static PyObject *
pycairo_fill(PycairoContext * o,PyObject * ignored)314 pycairo_fill (PycairoContext *o, PyObject *ignored) {
315   Py_BEGIN_ALLOW_THREADS;
316   cairo_fill (o->ctx);
317   Py_END_ALLOW_THREADS;
318   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
319   Py_RETURN_NONE;
320 }
321 
322 static PyObject *
pycairo_fill_extents(PycairoContext * o,PyObject * ignored)323 pycairo_fill_extents (PycairoContext *o, PyObject *ignored) {
324   double x1, y1, x2, y2;
325   cairo_fill_extents (o->ctx, &x1, &y1, &x2, &y2);
326   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
327   return Py_BuildValue("(dddd)", x1, y1, x2, y2);
328 }
329 
330 static PyObject *
pycairo_fill_preserve(PycairoContext * o,PyObject * ignored)331 pycairo_fill_preserve (PycairoContext *o, PyObject *ignored) {
332   Py_BEGIN_ALLOW_THREADS;
333   cairo_fill_preserve (o->ctx);
334   Py_END_ALLOW_THREADS;
335   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
336   Py_RETURN_NONE;
337 }
338 
339 static PyObject *
pycairo_font_extents(PycairoContext * o,PyObject * ignored)340 pycairo_font_extents (PycairoContext *o, PyObject *ignored) {
341   cairo_font_extents_t e;
342 
343   cairo_font_extents (o->ctx, &e);
344   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
345   return Py_BuildValue("(ddddd)", e.ascent, e.descent, e.height,
346 		       e.max_x_advance, e.max_y_advance);
347 }
348 
349 static PyObject *
pycairo_get_antialias(PycairoContext * o,PyObject * ignored)350 pycairo_get_antialias (PycairoContext *o, PyObject *ignored) {
351   RETURN_INT_ENUM (Antialias, cairo_get_antialias (o->ctx));
352 }
353 
354 static PyObject *
pycairo_get_current_point(PycairoContext * o,PyObject * ignored)355 pycairo_get_current_point (PycairoContext *o, PyObject *ignored) {
356   double x, y;
357   cairo_get_current_point (o->ctx, &x, &y);
358   return Py_BuildValue("(dd)", x, y);
359 }
360 
361 static PyObject *
pycairo_get_dash(PycairoContext * o,PyObject * ignored)362 pycairo_get_dash (PycairoContext *o, PyObject *ignored) {
363   double *dashes = NULL, offset;
364   int count, i;
365   PyObject *py_dashes = NULL, *rv = NULL;
366 
367   count = cairo_get_dash_count (o->ctx);
368   if (count < 0) {
369     PyErr_SetString (PyExc_RuntimeError, "invalid dash return");
370     return NULL;
371   }
372   dashes = PyMem_Malloc ((unsigned int)count * sizeof(double));
373   if (dashes == NULL)
374     return PyErr_NoMemory();
375 
376   cairo_get_dash (o->ctx, dashes, &offset);
377   py_dashes = PyTuple_New(count);
378   if (py_dashes == NULL)
379     goto exit;
380 
381   for (i = 0; i < count; i++) {
382     PyObject *dash = PyFloat_FromDouble(dashes[i]);
383     if (dash == NULL)
384       goto exit;
385     PyTuple_SET_ITEM (py_dashes, i, dash);
386   }
387   rv = Py_BuildValue("(Od)", py_dashes, offset);
388 
389  exit:
390   PyMem_Free (dashes);
391   Py_XDECREF(py_dashes);
392   return rv;
393 }
394 
395 static PyObject *
pycairo_get_dash_count(PycairoContext * o,PyObject * ignored)396 pycairo_get_dash_count (PycairoContext *o, PyObject *ignored) {
397   return PYCAIRO_PyLong_FromLong (cairo_get_dash_count (o->ctx));
398 }
399 
400 static PyObject *
pycairo_get_fill_rule(PycairoContext * o,PyObject * ignored)401 pycairo_get_fill_rule (PycairoContext *o, PyObject *ignored) {
402   RETURN_INT_ENUM(FillRule, cairo_get_fill_rule (o->ctx));
403 }
404 
405 static PyObject *
pycairo_get_font_face(PycairoContext * o,PyObject * ignored)406 pycairo_get_font_face (PycairoContext *o, PyObject *ignored) {
407   return PycairoFontFace_FromFontFace (
408        cairo_font_face_reference (cairo_get_font_face (o->ctx)));
409 }
410 
411 static PyObject *
pycairo_get_font_matrix(PycairoContext * o,PyObject * ignored)412 pycairo_get_font_matrix (PycairoContext *o, PyObject *ignored) {
413   cairo_matrix_t matrix;
414   cairo_get_font_matrix (o->ctx, &matrix);
415   return PycairoMatrix_FromMatrix (&matrix);
416 }
417 
418 static PyObject *
pycairo_get_font_options(PycairoContext * o,PyObject * ignored)419 pycairo_get_font_options (PycairoContext *o, PyObject *ignored) {
420   cairo_font_options_t *options = cairo_font_options_create();
421   cairo_get_font_options (o->ctx, options);
422   /* there is no reference fn */
423   return PycairoFontOptions_FromFontOptions (options);
424 }
425 
426 static PyObject *
pycairo_get_group_target(PycairoContext * o,PyObject * ignored)427 pycairo_get_group_target (PycairoContext *o, PyObject *ignored) {
428   cairo_surface_t *surface = cairo_get_group_target (o->ctx);
429   return PycairoSurface_FromSurface (cairo_surface_reference (surface), NULL);
430 }
431 
432 static PyObject *
pycairo_get_line_cap(PycairoContext * o,PyObject * ignored)433 pycairo_get_line_cap (PycairoContext *o, PyObject *ignored) {
434   RETURN_INT_ENUM(LineCap, cairo_get_line_cap (o->ctx));
435 }
436 
437 static PyObject *
pycairo_get_line_join(PycairoContext * o,PyObject * ignored)438 pycairo_get_line_join (PycairoContext *o, PyObject *ignored) {
439   RETURN_INT_ENUM(LineJoin, cairo_get_line_join (o->ctx));
440 }
441 
442 static PyObject *
pycairo_get_line_width(PycairoContext * o,PyObject * ignored)443 pycairo_get_line_width (PycairoContext *o, PyObject *ignored) {
444   return PyFloat_FromDouble(cairo_get_line_width (o->ctx));
445 }
446 
447 static PyObject *
pycairo_get_matrix(PycairoContext * o,PyObject * ignored)448 pycairo_get_matrix (PycairoContext *o, PyObject *ignored) {
449   cairo_matrix_t matrix;
450   cairo_get_matrix (o->ctx, &matrix);
451   return PycairoMatrix_FromMatrix (&matrix);
452 }
453 
454 static PyObject *
pycairo_get_miter_limit(PycairoContext * o,PyObject * ignored)455 pycairo_get_miter_limit (PycairoContext *o, PyObject *ignored) {
456   return PyFloat_FromDouble (cairo_get_miter_limit (o->ctx));
457 }
458 
459 static PyObject *
pycairo_get_operator(PycairoContext * o,PyObject * ignored)460 pycairo_get_operator (PycairoContext *o, PyObject *ignored) {
461   RETURN_INT_ENUM(Operator, cairo_get_operator (o->ctx));
462 }
463 
464 static PyObject *
pycairo_get_scaled_font(PycairoContext * o,PyObject * ignored)465 pycairo_get_scaled_font (PycairoContext *o, PyObject *ignored) {
466   return PycairoScaledFont_FromScaledFont (
467 	   cairo_scaled_font_reference (cairo_get_scaled_font (o->ctx)));
468 }
469 
470 static PyObject *
pycairo_get_source(PycairoContext * o,PyObject * ignored)471 pycairo_get_source (PycairoContext *o, PyObject *ignored) {
472   return PycairoPattern_FromPattern (
473 	       cairo_pattern_reference (cairo_get_source (o->ctx)), NULL);
474 }
475 
476 static PyObject *
pycairo_get_target(PycairoContext * o,PyObject * ignored)477 pycairo_get_target (PycairoContext *o, PyObject *ignored) {
478   return PycairoSurface_FromSurface (
479 	       cairo_surface_reference (cairo_get_target (o->ctx)),
480 	       NULL);
481 }
482 
483 static PyObject *
pycairo_get_tolerance(PycairoContext * o,PyObject * ignored)484 pycairo_get_tolerance (PycairoContext *o, PyObject *ignored) {
485   return PyFloat_FromDouble (cairo_get_tolerance (o->ctx));
486 }
487 
488 static PyObject *
pycairo_glyph_extents(PycairoContext * o,PyObject * args)489 pycairo_glyph_extents (PycairoContext *o, PyObject *args) {
490   int num_glyphs = -1;
491   cairo_glyph_t *glyphs;
492   cairo_text_extents_t extents;
493   PyObject *py_object, *ext_args, *res;
494 
495   if (!PyArg_ParseTuple (args, "O|i:Context.glyph_extents",
496 			 &py_object, &num_glyphs))
497     return NULL;
498 
499   glyphs = _PycairoGlyphs_AsGlyphs (py_object, &num_glyphs);
500   if (glyphs == NULL)
501     return NULL;
502   cairo_glyph_extents (o->ctx, glyphs, num_glyphs, &extents);
503   PyMem_Free (glyphs);
504   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
505   ext_args = Py_BuildValue ("(dddddd)", extents.x_bearing, extents.y_bearing,
506                             extents.width, extents.height, extents.x_advance,
507                             extents.y_advance);
508   res = PyObject_Call ((PyObject *)&PycairoTextExtents_Type, ext_args, NULL);
509   Py_DECREF (ext_args);
510   return res;
511 }
512 
513 static PyObject *
pycairo_glyph_path(PycairoContext * o,PyObject * args)514 pycairo_glyph_path (PycairoContext *o, PyObject *args) {
515   int num_glyphs = -1;
516   cairo_glyph_t *glyphs;
517   PyObject *py_object;
518 
519   if (!PyArg_ParseTuple (args, "O|i:Context.glyph_path",
520 			 &py_object, &num_glyphs))
521     return NULL;
522 
523   glyphs = _PycairoGlyphs_AsGlyphs (py_object, &num_glyphs);
524   if (glyphs == NULL)
525     return NULL;
526   cairo_glyph_path (o->ctx, glyphs, num_glyphs);
527   PyMem_Free (glyphs);
528   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
529   Py_RETURN_NONE;
530 }
531 
532 static PyObject *
pycairo_has_current_point(PycairoContext * o,PyObject * ignored)533 pycairo_has_current_point (PycairoContext *o, PyObject *ignored) {
534   PyObject *b = cairo_has_current_point (o->ctx) ? Py_True : Py_False;
535   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
536   Py_INCREF(b);
537   return b;
538 }
539 
540 static PyObject *
pycairo_identity_matrix(PycairoContext * o,PyObject * ignored)541 pycairo_identity_matrix (PycairoContext *o, PyObject *ignored) {
542   cairo_identity_matrix (o->ctx);
543   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
544   Py_RETURN_NONE;
545 }
546 
547 static PyObject *
pycairo_in_fill(PycairoContext * o,PyObject * args)548 pycairo_in_fill (PycairoContext *o, PyObject *args) {
549   double x, y;
550   PyObject *result;
551 
552   if (!PyArg_ParseTuple (args, "dd:Context.in_fill", &x, &y))
553     return NULL;
554 
555   result = cairo_in_fill (o->ctx, x, y) ? Py_True : Py_False;
556   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
557   Py_INCREF(result);
558   return result;
559 }
560 
561 static PyObject *
pycairo_in_stroke(PycairoContext * o,PyObject * args)562 pycairo_in_stroke (PycairoContext *o, PyObject *args) {
563   double x, y;
564   PyObject *result;
565 
566   if (!PyArg_ParseTuple (args, "dd:Context.in_stroke", &x, &y))
567     return NULL;
568 
569   result = cairo_in_stroke (o->ctx, x, y) ? Py_True : Py_False;
570   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
571   Py_INCREF(result);
572   return result;
573 }
574 
575 static PyObject *
pycairo_line_to(PycairoContext * o,PyObject * args)576 pycairo_line_to (PycairoContext *o, PyObject *args) {
577   double x, y;
578 
579   if (!PyArg_ParseTuple (args, "dd:Context.line_to", &x, &y))
580     return NULL;
581 
582   cairo_line_to (o->ctx, x, y);
583   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
584   Py_RETURN_NONE;
585 }
586 
587 static PyObject *
pycairo_mask(PycairoContext * o,PyObject * args)588 pycairo_mask (PycairoContext *o, PyObject *args) {
589   PycairoPattern *p;
590 
591   if (!PyArg_ParseTuple(args, "O!:Context.mask", &PycairoPattern_Type, &p))
592     return NULL;
593 
594   Py_BEGIN_ALLOW_THREADS;
595   cairo_mask (o->ctx, p->pattern);
596   Py_END_ALLOW_THREADS;
597   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
598   Py_RETURN_NONE;
599 }
600 
601 static PyObject *
pycairo_mask_surface(PycairoContext * o,PyObject * args)602 pycairo_mask_surface (PycairoContext *o, PyObject *args) {
603   PycairoSurface *s;
604   double surface_x = 0.0, surface_y = 0.0;
605 
606   if (!PyArg_ParseTuple (args, "O!|dd:Context.mask_surface",
607 			 &PycairoSurface_Type, &s, &surface_x, &surface_y))
608     return NULL;
609 
610   Py_BEGIN_ALLOW_THREADS;
611   cairo_mask_surface (o->ctx, s->surface, surface_x, surface_y);
612   Py_END_ALLOW_THREADS;
613   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
614   Py_RETURN_NONE;
615 }
616 
617 static PyObject *
pycairo_move_to(PycairoContext * o,PyObject * args)618 pycairo_move_to (PycairoContext *o, PyObject *args) {
619   double x, y;
620 
621   if (!PyArg_ParseTuple (args, "dd:Context.move_to", &x, &y))
622     return NULL;
623 
624   cairo_move_to (o->ctx, x, y);
625   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
626   Py_RETURN_NONE;
627 }
628 
629 static PyObject *
pycairo_new_path(PycairoContext * o,PyObject * ignored)630 pycairo_new_path (PycairoContext *o, PyObject *ignored) {
631   cairo_new_path (o->ctx);
632   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
633   Py_RETURN_NONE;
634 }
635 
636 static PyObject *
pycairo_new_sub_path(PycairoContext * o,PyObject * ignored)637 pycairo_new_sub_path (PycairoContext *o, PyObject *ignored) {
638   cairo_new_sub_path (o->ctx);
639   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
640   Py_RETURN_NONE;
641 }
642 
643 static PyObject *
pycairo_paint(PycairoContext * o,PyObject * ignored)644 pycairo_paint (PycairoContext *o, PyObject *ignored) {
645   Py_BEGIN_ALLOW_THREADS;
646   cairo_paint (o->ctx);
647   Py_END_ALLOW_THREADS;
648   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
649   Py_RETURN_NONE;
650 }
651 
652 static PyObject *
pycairo_paint_with_alpha(PycairoContext * o,PyObject * args)653 pycairo_paint_with_alpha (PycairoContext *o, PyObject *args) {
654   double alpha;
655 
656   if (!PyArg_ParseTuple (args, "d:Context.paint_with_alpha", &alpha))
657     return NULL;
658 
659   Py_BEGIN_ALLOW_THREADS;
660   cairo_paint_with_alpha (o->ctx, alpha);
661   Py_END_ALLOW_THREADS;
662   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
663   Py_RETURN_NONE;
664 }
665 
666 static PyObject *
pycairo_path_extents(PycairoContext * o,PyObject * ignored)667 pycairo_path_extents (PycairoContext *o, PyObject *ignored) {
668   double x1, y1, x2, y2;
669   cairo_path_extents (o->ctx, &x1, &y1, &x2, &y2);
670   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
671   return Py_BuildValue("(dddd)", x1, y1, x2, y2);
672 }
673 
674 static PyObject *
pycairo_pop_group(PycairoContext * o,PyObject * ignored)675 pycairo_pop_group (PycairoContext *o, PyObject *ignored) {
676   return PycairoPattern_FromPattern (cairo_pop_group (o->ctx), NULL);
677 }
678 
679 static PyObject *
pycairo_pop_group_to_source(PycairoContext * o,PyObject * ignored)680 pycairo_pop_group_to_source (PycairoContext *o, PyObject *ignored) {
681   cairo_pop_group_to_source (o->ctx);
682   Py_RETURN_NONE;
683 }
684 
685 static PyObject *
pycairo_push_group(PycairoContext * o,PyObject * ignored)686 pycairo_push_group (PycairoContext *o, PyObject *ignored) {
687   cairo_push_group (o->ctx);
688   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
689   Py_RETURN_NONE;
690 }
691 
692 static PyObject *
pycairo_push_group_with_content(PycairoContext * o,PyObject * args)693 pycairo_push_group_with_content (PycairoContext *o, PyObject *args) {
694   cairo_content_t content;
695   int content_arg;
696 
697   if (!PyArg_ParseTuple (args, "i:Context.push_group_with_content",
698                          &content_arg))
699     return NULL;
700 
701   content = (cairo_content_t)content_arg;
702 
703   cairo_push_group_with_content (o->ctx, content);
704   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
705   Py_RETURN_NONE;
706 }
707 
708 static PyObject *
pycairo_rectangle(PycairoContext * o,PyObject * args)709 pycairo_rectangle (PycairoContext *o, PyObject *args) {
710   double x, y, width, height;
711 
712   if (!PyArg_ParseTuple (args, "dddd:Context.rectangle",
713 			 &x, &y, &width, &height))
714     return NULL;
715 
716   cairo_rectangle (o->ctx, x, y, width, height);
717   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
718   Py_RETURN_NONE;
719 }
720 
721 static PyObject *
pycairo_rel_curve_to(PycairoContext * o,PyObject * args)722 pycairo_rel_curve_to (PycairoContext *o, PyObject *args) {
723   double dx1, dy1, dx2, dy2, dx3, dy3;
724 
725   if (!PyArg_ParseTuple (args, "dddddd:Context.rel_curve_to",
726 			 &dx1, &dy1, &dx2, &dy2, &dx3, &dy3))
727     return NULL;
728 
729   cairo_rel_curve_to (o->ctx, dx1, dy1, dx2, dy2, dx3, dy3);
730   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
731   Py_RETURN_NONE;
732 }
733 
734 static PyObject *
pycairo_rel_line_to(PycairoContext * o,PyObject * args)735 pycairo_rel_line_to (PycairoContext *o, PyObject *args) {
736   double dx, dy;
737 
738   if (!PyArg_ParseTuple (args, "dd:Context.rel_line_to", &dx, &dy))
739     return NULL;
740 
741   cairo_rel_line_to (o->ctx, dx, dy);
742   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
743   Py_RETURN_NONE;
744 }
745 
746 static PyObject *
pycairo_rel_move_to(PycairoContext * o,PyObject * args)747 pycairo_rel_move_to (PycairoContext *o, PyObject *args) {
748   double dx, dy;
749 
750   if (!PyArg_ParseTuple (args, "dd:Context.rel_move_to", &dx, &dy))
751     return NULL;
752 
753   cairo_rel_move_to (o->ctx, dx, dy);
754   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
755   Py_RETURN_NONE;
756 }
757 
758 static PyObject *
pycairo_reset_clip(PycairoContext * o,PyObject * ignored)759 pycairo_reset_clip (PycairoContext *o, PyObject *ignored) {
760   cairo_reset_clip (o->ctx);
761   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
762   Py_RETURN_NONE;
763 }
764 
765 static PyObject *
pycairo_restore(PycairoContext * o,PyObject * ignored)766 pycairo_restore (PycairoContext *o, PyObject *ignored) {
767   cairo_restore (o->ctx);
768   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
769   Py_RETURN_NONE;
770 }
771 
772 static PyObject *
pycairo_rotate(PycairoContext * o,PyObject * args)773 pycairo_rotate (PycairoContext *o, PyObject *args) {
774   double angle;
775 
776   if (!PyArg_ParseTuple(args, "d:Context.rotate", &angle))
777     return NULL;
778 
779   cairo_rotate (o->ctx, angle);
780   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
781   Py_RETURN_NONE;
782 }
783 
784 static PyObject *
pycairo_save(PycairoContext * o,PyObject * ignored)785 pycairo_save (PycairoContext *o, PyObject *ignored) {
786   cairo_save (o->ctx);
787   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
788   Py_RETURN_NONE;
789 }
790 
791 static PyObject *
pycairo_scale(PycairoContext * o,PyObject * args)792 pycairo_scale (PycairoContext *o, PyObject *args) {
793   double sx, sy;
794 
795   if (!PyArg_ParseTuple (args, "dd:Context.scale", &sx, &sy))
796     return NULL;
797 
798   cairo_scale (o->ctx, sx, sy);
799   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
800   Py_RETURN_NONE;
801 }
802 
803 static PyObject *
pycairo_select_font_face(PycairoContext * o,PyObject * args)804 pycairo_select_font_face (PycairoContext *o, PyObject *args) {
805   const char *utf8;
806   cairo_font_slant_t slant;
807   cairo_font_weight_t weight;
808   int slant_arg = CAIRO_FONT_SLANT_NORMAL;
809   int weight_arg = CAIRO_FONT_WEIGHT_NORMAL;
810 
811   if (!PyArg_ParseTuple (args, PYCAIRO_ENC_TEXT_FORMAT "|ii:Context.select_font_face",
812                          "utf-8", &utf8, &slant_arg, &weight_arg))
813     return NULL;
814 
815   slant = (cairo_font_slant_t)slant_arg;
816   weight = (cairo_font_weight_t)weight_arg;
817 
818   cairo_select_font_face (o->ctx, utf8, slant, weight);
819   PyMem_Free((void *)utf8);
820   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
821   Py_RETURN_NONE;
822 }
823 
824 static PyObject *
pycairo_set_antialias(PycairoContext * o,PyObject * args)825 pycairo_set_antialias (PycairoContext *o, PyObject *args) {
826   cairo_antialias_t antialias;
827   int antialias_arg = CAIRO_ANTIALIAS_DEFAULT;
828 
829   if (!PyArg_ParseTuple (args, "|i:Context.set_antialias", &antialias_arg))
830     return NULL;
831 
832   antialias = (cairo_antialias_t)antialias_arg;
833 
834   cairo_set_antialias (o->ctx, antialias);
835   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
836   Py_RETURN_NONE;
837 }
838 
839 static PyObject *
pycairo_set_dash(PycairoContext * o,PyObject * args)840 pycairo_set_dash (PycairoContext *o, PyObject *args) {
841   double *dashes, offset = 0;
842   Py_ssize_t num_dashes, i;
843   PyObject *py_dashes;
844 
845   if (!PyArg_ParseTuple (args, "O|d:Context.set_dash", &py_dashes, &offset))
846     return NULL;
847 
848   py_dashes = PySequence_Fast (py_dashes,
849 			       "first argument must be a sequence");
850   if (py_dashes == NULL)
851     return NULL;
852 
853   num_dashes = PySequence_Fast_GET_SIZE(py_dashes);
854   if (num_dashes > INT_MAX) {
855       Py_DECREF (py_dashes);
856       PyErr_SetString (PyExc_ValueError, "dash sequence too large");
857       return NULL;
858   }
859   dashes = PyMem_Malloc ((unsigned int)num_dashes * sizeof(double));
860   if (dashes == NULL) {
861     Py_DECREF(py_dashes);
862     return PyErr_NoMemory();
863   }
864 
865   for (i = 0; i < num_dashes; i++) {
866     dashes[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(py_dashes, i));
867     if (PyErr_Occurred()) {
868       PyMem_Free (dashes);
869       Py_DECREF(py_dashes);
870       return NULL;
871     }
872   }
873   cairo_set_dash (o->ctx, dashes, (int)num_dashes, offset);
874   PyMem_Free (dashes);
875   Py_DECREF(py_dashes);
876   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
877   Py_RETURN_NONE;
878 }
879 
880 static PyObject *
pycairo_set_fill_rule(PycairoContext * o,PyObject * args)881 pycairo_set_fill_rule (PycairoContext *o, PyObject *args) {
882   cairo_fill_rule_t fill_rule;
883   int fill_rule_arg;
884 
885   if (!PyArg_ParseTuple (args, "i:Context.set_fill_rule", &fill_rule_arg))
886     return NULL;
887 
888   fill_rule = (cairo_fill_rule_t)fill_rule_arg;
889 
890   cairo_set_fill_rule (o->ctx, fill_rule);
891   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
892   Py_RETURN_NONE;
893 }
894 
895 static PyObject *
pycairo_set_font_face(PycairoContext * o,PyObject * obj)896 pycairo_set_font_face (PycairoContext *o, PyObject *obj) {
897   if (PyObject_TypeCheck(obj, &PycairoFontFace_Type))
898     cairo_set_font_face (o->ctx, ((PycairoFontFace *)obj)->font_face);
899   else if (obj == Py_None)
900     cairo_set_font_face (o->ctx, NULL);
901   else {
902     PyErr_SetString(PyExc_TypeError,
903 		    "Context.set_font_face() argument must be "
904 		    "cairo.FontFace or None");
905     return NULL;
906   }
907   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
908   Py_RETURN_NONE;
909 }
910 
911 static PyObject *
pycairo_set_font_matrix(PycairoContext * o,PyObject * args)912 pycairo_set_font_matrix (PycairoContext *o, PyObject *args) {
913   PycairoMatrix *matrix;
914 
915   if (!PyArg_ParseTuple (args, "O!:Context.set_font_matrix",
916 			 &PycairoMatrix_Type, &matrix))
917     return NULL;
918 
919   cairo_set_font_matrix (o->ctx, &matrix->matrix);
920   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
921   Py_RETURN_NONE;
922 }
923 
924 static PyObject *
pycairo_set_font_options(PycairoContext * o,PyObject * args)925 pycairo_set_font_options (PycairoContext *o, PyObject *args) {
926   PycairoFontOptions *options;
927 
928   if (!PyArg_ParseTuple (args, "O!:Context.set_font_options",
929 			 &PycairoFontOptions_Type, &options))
930     return NULL;
931 
932   cairo_set_font_options (o->ctx, options->font_options);
933   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
934   Py_RETURN_NONE;
935 }
936 
937 static PyObject *
pycairo_set_font_size(PycairoContext * o,PyObject * args)938 pycairo_set_font_size (PycairoContext *o, PyObject *args) {
939   double size;
940 
941   if (!PyArg_ParseTuple (args, "d:Context.set_font_size", &size))
942     return NULL;
943 
944   cairo_set_font_size (o->ctx, size);
945   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
946   Py_RETURN_NONE;
947 }
948 
949 static PyObject *
pycairo_set_line_cap(PycairoContext * o,PyObject * args)950 pycairo_set_line_cap (PycairoContext *o, PyObject *args) {
951   cairo_line_cap_t line_cap;
952   int line_cap_arg;
953 
954   if (!PyArg_ParseTuple (args, "i:Context.set_line_cap", &line_cap_arg))
955     return NULL;
956 
957   line_cap = (cairo_line_cap_t)line_cap_arg;
958 
959   cairo_set_line_cap (o->ctx, line_cap);
960   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
961   Py_RETURN_NONE;
962 }
963 
964 static PyObject *
pycairo_set_line_join(PycairoContext * o,PyObject * args)965 pycairo_set_line_join (PycairoContext *o, PyObject *args) {
966   cairo_line_join_t line_join;
967   int line_join_arg;
968 
969   if (!PyArg_ParseTuple (args, "i:Context.set_line_join", &line_join_arg))
970     return NULL;
971 
972   line_join = (cairo_line_join_t)line_join_arg;
973 
974   cairo_set_line_join (o->ctx, line_join);
975   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
976   Py_RETURN_NONE;
977 }
978 
979 static PyObject *
pycairo_set_line_width(PycairoContext * o,PyObject * args)980 pycairo_set_line_width (PycairoContext *o, PyObject *args) {
981   double width;
982 
983   if (!PyArg_ParseTuple (args, "d:Context.set_line_width", &width))
984     return NULL;
985 
986   cairo_set_line_width (o->ctx, width);
987   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
988   Py_RETURN_NONE;
989 }
990 
991 static PyObject *
pycairo_set_matrix(PycairoContext * o,PyObject * args)992 pycairo_set_matrix (PycairoContext *o, PyObject *args) {
993   PycairoMatrix *matrix;
994 
995   if (!PyArg_ParseTuple (args, "O!:Context.set_matrix",
996 			 &PycairoMatrix_Type, &matrix))
997     return NULL;
998 
999   cairo_set_matrix (o->ctx, &matrix->matrix);
1000   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1001   Py_RETURN_NONE;
1002 }
1003 
1004 static PyObject *
pycairo_set_miter_limit(PycairoContext * o,PyObject * args)1005 pycairo_set_miter_limit (PycairoContext *o, PyObject *args) {
1006   double limit;
1007 
1008   if (!PyArg_ParseTuple (args, "d:Context.set_miter_limit", &limit))
1009     return NULL;
1010 
1011   cairo_set_miter_limit (o->ctx, limit);
1012   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1013   Py_RETURN_NONE;
1014 }
1015 
1016 static PyObject *
pycairo_set_operator(PycairoContext * o,PyObject * args)1017 pycairo_set_operator(PycairoContext *o, PyObject *args) {
1018   cairo_operator_t operator;
1019   int operator_arg;
1020 
1021   if (!PyArg_ParseTuple (args, "i:Context.set_operator", &operator_arg))
1022     return NULL;
1023 
1024   operator = (cairo_operator_t)operator_arg;
1025 
1026   cairo_set_operator(o->ctx, operator);
1027   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1028   Py_RETURN_NONE;
1029 }
1030 
1031 static PyObject *
pycairo_set_scaled_font(PycairoContext * o,PyObject * args)1032 pycairo_set_scaled_font(PycairoContext *o, PyObject *args) {
1033   PycairoScaledFont *f;
1034   if (!PyArg_ParseTuple (args, "O!:Context.set_scaled_font",
1035 			 &PycairoScaledFont_Type, &f))
1036     return NULL;
1037 
1038   cairo_set_scaled_font(o->ctx, f->scaled_font);
1039   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1040   Py_RETURN_NONE;
1041 }
1042 
1043 static PyObject *
pycairo_set_source(PycairoContext * o,PyObject * args)1044 pycairo_set_source (PycairoContext *o, PyObject *args) {
1045   PycairoPattern *p;
1046 
1047   if (!PyArg_ParseTuple (args, "O!:Context.set_source",
1048 			 &PycairoPattern_Type, &p))
1049     return NULL;
1050 
1051   cairo_set_source (o->ctx, p->pattern);
1052   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1053   Py_RETURN_NONE;
1054 }
1055 
1056 static PyObject *
pycairo_set_source_rgb(PycairoContext * o,PyObject * args)1057 pycairo_set_source_rgb (PycairoContext *o, PyObject *args) {
1058   double red, green, blue;
1059 
1060   if (!PyArg_ParseTuple (args, "ddd:Context.set_source_rgb",
1061 			 &red, &green, &blue))
1062     return NULL;
1063 
1064   cairo_set_source_rgb (o->ctx, red, green, blue);
1065   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1066   Py_RETURN_NONE;
1067 }
1068 
1069 static PyObject *
pycairo_set_source_rgba(PycairoContext * o,PyObject * args)1070 pycairo_set_source_rgba (PycairoContext *o, PyObject *args) {
1071   double red, green, blue;
1072   double alpha = 1.0;
1073 
1074   if (!PyArg_ParseTuple (args, "ddd|d:Context.set_source_rgba",
1075 			 &red, &green, &blue, &alpha))
1076     return NULL;
1077 
1078   cairo_set_source_rgba (o->ctx, red, green, blue, alpha);
1079   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1080   Py_RETURN_NONE;
1081 }
1082 
1083 static PyObject *
pycairo_set_source_surface(PycairoContext * o,PyObject * args)1084 pycairo_set_source_surface (PycairoContext *o, PyObject *args) {
1085   PycairoSurface *surface;
1086   double x = 0.0, y = 0.0;
1087 
1088   if (!PyArg_ParseTuple (args, "O!|dd:Context.set_source_surface",
1089 			 &PycairoSurface_Type, &surface, &x, &y))
1090     return NULL;
1091 
1092   cairo_set_source_surface (o->ctx, surface->surface, x, y);
1093   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1094   Py_RETURN_NONE;
1095 }
1096 
1097 static PyObject *
pycairo_set_tolerance(PycairoContext * o,PyObject * args)1098 pycairo_set_tolerance (PycairoContext *o, PyObject *args) {
1099   double tolerance;
1100   if (!PyArg_ParseTuple (args, "d:Context.set_tolerance", &tolerance))
1101     return NULL;
1102   cairo_set_tolerance (o->ctx, tolerance);
1103   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1104   Py_RETURN_NONE;
1105 }
1106 
1107 static PyObject *
pycairo_show_glyphs(PycairoContext * o,PyObject * args)1108 pycairo_show_glyphs (PycairoContext *o, PyObject *args) {
1109   int num_glyphs = -1;
1110   cairo_glyph_t *glyphs;
1111   PyObject *py_object;
1112 
1113   if (!PyArg_ParseTuple (args, "O|i:Context.show_glyphs",
1114 			 &py_object, &num_glyphs))
1115     return NULL;
1116 
1117   glyphs = _PycairoGlyphs_AsGlyphs (py_object, &num_glyphs);
1118   if (glyphs == NULL)
1119     return NULL;
1120   Py_BEGIN_ALLOW_THREADS;
1121   cairo_show_glyphs (o->ctx, glyphs, num_glyphs);
1122   Py_END_ALLOW_THREADS;
1123   PyMem_Free (glyphs);
1124   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1125   Py_RETURN_NONE;
1126 }
1127 
1128 static PyObject *
pycairo_show_page(PycairoContext * o,PyObject * ignored)1129 pycairo_show_page (PycairoContext *o, PyObject *ignored) {
1130   Py_BEGIN_ALLOW_THREADS;
1131   cairo_show_page (o->ctx);
1132   Py_END_ALLOW_THREADS;
1133   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1134   Py_RETURN_NONE;
1135 }
1136 
1137 static PyObject *
pycairo_show_text(PycairoContext * o,PyObject * args)1138 pycairo_show_text (PycairoContext *o, PyObject *args) {
1139   const char *utf8;
1140 
1141   if (!PyArg_ParseTuple (args, PYCAIRO_ENC_TEXT_FORMAT ":Context.show_text", "utf-8", &utf8))
1142     return NULL;
1143 
1144   Py_BEGIN_ALLOW_THREADS;
1145   cairo_show_text (o->ctx, utf8);
1146   Py_END_ALLOW_THREADS;
1147 
1148   PyMem_Free((void *)utf8);
1149   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1150   Py_RETURN_NONE;
1151 }
1152 
1153 static PyObject *
pycairo_stroke(PycairoContext * o,PyObject * ignored)1154 pycairo_stroke (PycairoContext *o, PyObject *ignored) {
1155   Py_BEGIN_ALLOW_THREADS;
1156   cairo_stroke (o->ctx);
1157   Py_END_ALLOW_THREADS;
1158   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1159   Py_RETURN_NONE;
1160 }
1161 
1162 static PyObject *
pycairo_stroke_extents(PycairoContext * o,PyObject * ignored)1163 pycairo_stroke_extents (PycairoContext *o, PyObject *ignored) {
1164   double x1, y1, x2, y2;
1165   cairo_stroke_extents (o->ctx, &x1, &y1, &x2, &y2);
1166   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1167   return Py_BuildValue("(dddd)", x1, y1, x2, y2);
1168 }
1169 
1170 static PyObject *
pycairo_stroke_preserve(PycairoContext * o,PyObject * ignored)1171 pycairo_stroke_preserve (PycairoContext *o, PyObject *ignored) {
1172   Py_BEGIN_ALLOW_THREADS;
1173   cairo_stroke_preserve (o->ctx);
1174   Py_END_ALLOW_THREADS;
1175   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1176   Py_RETURN_NONE;
1177 }
1178 
1179 static PyObject *
pycairo_text_extents(PycairoContext * o,PyObject * args)1180 pycairo_text_extents (PycairoContext *o, PyObject *args) {
1181   cairo_text_extents_t extents;
1182   const char *utf8;
1183   PyObject *ext_args, *res;
1184 
1185   if (!PyArg_ParseTuple (args, PYCAIRO_ENC_TEXT_FORMAT ":Context.text_extents", "utf-8", &utf8))
1186     return NULL;
1187 
1188   cairo_text_extents (o->ctx, utf8, &extents);
1189   PyMem_Free((void *)utf8);
1190   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1191   ext_args =  Py_BuildValue ("(dddddd)", extents.x_bearing, extents.y_bearing,
1192                              extents.width, extents.height, extents.x_advance,
1193                              extents.y_advance);
1194   res = PyObject_Call ((PyObject *)&PycairoTextExtents_Type, ext_args, NULL);
1195   Py_DECREF (ext_args);
1196   return res;
1197 }
1198 
1199 static PyObject *
pycairo_text_path(PycairoContext * o,PyObject * args)1200 pycairo_text_path (PycairoContext *o, PyObject *args) {
1201   const char *utf8;
1202 
1203   if (!PyArg_ParseTuple (args, PYCAIRO_ENC_TEXT_FORMAT ":Context.text_path", "utf-8", &utf8))
1204     return NULL;
1205 
1206   cairo_text_path (o->ctx, utf8);
1207   PyMem_Free((void *)utf8);
1208   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1209   Py_RETURN_NONE;
1210 }
1211 
1212 static PyObject *
pycairo_transform(PycairoContext * o,PyObject * args)1213 pycairo_transform (PycairoContext *o, PyObject *args) {
1214   PycairoMatrix *matrix;
1215 
1216   if (!PyArg_ParseTuple (args, "O!:Context.transform",
1217 			 &PycairoMatrix_Type, &matrix))
1218     return NULL;
1219 
1220   cairo_transform (o->ctx, &matrix->matrix);
1221   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1222   Py_RETURN_NONE;
1223 }
1224 
1225 static PyObject *
pycairo_translate(PycairoContext * o,PyObject * args)1226 pycairo_translate (PycairoContext *o, PyObject *args) {
1227   double tx, ty;
1228 
1229   if (!PyArg_ParseTuple (args, "dd:Context.translate", &tx, &ty))
1230     return NULL;
1231 
1232   cairo_translate (o->ctx, tx, ty);
1233   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1234   Py_RETURN_NONE;
1235 }
1236 
1237 static PyObject *
pycairo_user_to_device(PycairoContext * o,PyObject * args)1238 pycairo_user_to_device (PycairoContext *o, PyObject *args) {
1239   double x, y;
1240 
1241   if (!PyArg_ParseTuple (args, "dd:Context.user_to_device", &x, &y))
1242     return NULL;
1243 
1244   cairo_user_to_device (o->ctx, &x, &y);
1245   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1246   return Py_BuildValue("(dd)", x, y);
1247 }
1248 
1249 static PyObject *
pycairo_user_to_device_distance(PycairoContext * o,PyObject * args)1250 pycairo_user_to_device_distance (PycairoContext *o, PyObject *args) {
1251   double dx, dy;
1252 
1253   if (!PyArg_ParseTuple (args, "dd:Context.user_to_device_distance",
1254 			 &dx, &dy))
1255     return NULL;
1256 
1257   cairo_user_to_device_distance (o->ctx, &dx, &dy);
1258   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR(o->ctx);
1259   return Py_BuildValue("(dd)", dx, dy);
1260 }
1261 
1262 static PyObject *
pycairo_show_text_glyphs(PycairoContext * o,PyObject * args)1263 pycairo_show_text_glyphs (PycairoContext *o, PyObject *args) {
1264   const char *utf8 = NULL;
1265   PyObject *glyphs_arg, *glyphs_seq = NULL;
1266   PyObject *clusters_arg, *clusters_seq = NULL;
1267   cairo_text_cluster_flags_t cluster_flags;
1268   int cluster_flags_arg;
1269   PyObject *py_item;
1270   cairo_glyph_t *glyphs = NULL;
1271   cairo_text_cluster_t *clusters = NULL;
1272   Py_ssize_t i, clusters_size, glyphs_size;
1273 
1274   if (!PyArg_ParseTuple (args,
1275       PYCAIRO_ENC_TEXT_FORMAT "OOi:Context.show_text_glyphs",
1276       "utf-8", &utf8, &glyphs_arg, &clusters_arg, &cluster_flags_arg))
1277     return NULL;
1278 
1279   cluster_flags = (cairo_text_cluster_flags_t)cluster_flags_arg;
1280 
1281   glyphs_seq = PySequence_Fast (glyphs_arg, "glyphs must be a sequence");
1282   if (glyphs_seq == NULL)
1283     goto error;
1284   glyphs_size = PySequence_Fast_GET_SIZE (glyphs_seq);
1285   if (glyphs_size > INT_MAX) {
1286     PyErr_SetString (PyExc_ValueError, "glyph sequence too large");
1287     goto error;
1288   }
1289   glyphs = cairo_glyph_allocate ((int)glyphs_size);
1290   if (glyphs_size && glyphs == NULL) {
1291     PyErr_NoMemory();
1292     goto error;
1293   }
1294   for (i=0; i < glyphs_size; i++) {
1295     py_item = PySequence_Fast_GET_ITEM (glyphs_seq, i);
1296     if (py_item == 0 || _PyGlyph_AsGlyph (py_item, &(glyphs[i])) != 0)
1297       goto error;
1298   }
1299   Py_CLEAR (glyphs_seq);
1300 
1301   clusters_seq = PySequence_Fast (clusters_arg, "clusters must be a sequence");
1302   if (clusters_seq == NULL)
1303     goto error;
1304   clusters_size = PySequence_Fast_GET_SIZE (clusters_seq);
1305   if (clusters_size > INT_MAX) {
1306     PyErr_SetString (PyExc_ValueError, "clusters sequence too large");
1307     goto error;
1308   }
1309   clusters = cairo_text_cluster_allocate ((int)clusters_size);
1310   if (clusters_size && clusters == NULL) {
1311     PyErr_NoMemory();
1312     goto error;
1313   }
1314   for (i=0; i < clusters_size; i++) {
1315     py_item = PySequence_Fast_GET_ITEM (clusters_seq, i);
1316     if (py_item == NULL ||
1317         _PyTextCluster_AsTextCluster (py_item, &(clusters[i])) != 0)
1318       goto error;
1319   }
1320   Py_CLEAR (clusters_seq);
1321 
1322   Py_BEGIN_ALLOW_THREADS;
1323   cairo_show_text_glyphs (
1324     o->ctx, utf8, -1, glyphs, (int)glyphs_size, clusters,
1325     (int)clusters_size, cluster_flags);
1326   Py_END_ALLOW_THREADS;
1327 
1328   PyMem_Free ((void *)utf8);
1329   utf8 = NULL;
1330   cairo_glyph_free (glyphs);
1331   cairo_text_cluster_free (clusters);
1332 
1333   RETURN_NULL_IF_CAIRO_CONTEXT_ERROR (o->ctx);
1334   Py_RETURN_NONE;
1335 error:
1336   PyMem_Free ((void *)utf8);
1337   cairo_glyph_free (glyphs);
1338   cairo_text_cluster_free (clusters);
1339   Py_XDECREF (glyphs_seq);
1340   Py_XDECREF (clusters_seq);
1341   return NULL;
1342 }
1343 
1344 static PyMethodDef pycairo_methods[] = {
1345   /* methods never exposed in a language binding:
1346    * cairo_destroy()
1347    * cairo_reference()
1348    * cairo_rectangle_list_destroy()
1349    *
1350    * cairo_status()
1351    * cairo_status_string()
1352    * - not needed since Pycairo calls Pycairo_Check_Status() to check
1353    *   for errors and raise exceptions
1354    */
1355 #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10)
1356   {"tag_begin",       (PyCFunction)pycairo_tag_begin,        METH_VARARGS},
1357   {"tag_end",         (PyCFunction)pycairo_tag_end,          METH_VARARGS},
1358 #endif
1359   {"append_path",     (PyCFunction)pycairo_append_path,      METH_VARARGS},
1360   {"arc",             (PyCFunction)pycairo_arc,              METH_VARARGS},
1361   {"arc_negative",    (PyCFunction)pycairo_arc_negative,     METH_VARARGS},
1362   {"clip",            (PyCFunction)pycairo_clip,             METH_NOARGS},
1363   {"clip_extents",    (PyCFunction)pycairo_clip_extents,     METH_NOARGS},
1364   {"clip_preserve",   (PyCFunction)pycairo_clip_preserve,    METH_NOARGS},
1365   {"close_path",      (PyCFunction)pycairo_close_path,       METH_NOARGS},
1366   {"copy_clip_rectangle_list", (PyCFunction)pycairo_copy_clip_rectangle_list,
1367    METH_NOARGS},
1368   {"copy_page",       (PyCFunction)pycairo_copy_page,        METH_NOARGS},
1369   {"copy_path",       (PyCFunction)pycairo_copy_path,        METH_NOARGS},
1370   {"copy_path_flat",  (PyCFunction)pycairo_copy_path_flat,   METH_NOARGS},
1371   {"curve_to",        (PyCFunction)pycairo_curve_to,         METH_VARARGS},
1372   {"device_to_user",  (PyCFunction)pycairo_device_to_user,   METH_VARARGS},
1373   {"device_to_user_distance", (PyCFunction)pycairo_device_to_user_distance,
1374    METH_VARARGS},
1375   {"fill",            (PyCFunction)pycairo_fill,             METH_NOARGS},
1376   {"fill_extents",    (PyCFunction)pycairo_fill_extents,     METH_NOARGS},
1377   {"fill_preserve",   (PyCFunction)pycairo_fill_preserve,    METH_NOARGS},
1378   {"font_extents",    (PyCFunction)pycairo_font_extents,     METH_NOARGS},
1379   {"get_antialias",   (PyCFunction)pycairo_get_antialias,    METH_NOARGS},
1380   {"get_current_point",(PyCFunction)pycairo_get_current_point,METH_NOARGS},
1381   {"get_dash",        (PyCFunction)pycairo_get_dash,         METH_NOARGS},
1382   {"get_dash_count",  (PyCFunction)pycairo_get_dash_count,   METH_NOARGS},
1383   {"get_fill_rule",   (PyCFunction)pycairo_get_fill_rule,    METH_NOARGS},
1384   {"get_font_face",   (PyCFunction)pycairo_get_font_face,    METH_NOARGS},
1385   {"get_font_matrix", (PyCFunction)pycairo_get_font_matrix,  METH_NOARGS},
1386   {"get_font_options",(PyCFunction)pycairo_get_font_options, METH_NOARGS},
1387   {"get_group_target",(PyCFunction)pycairo_get_group_target, METH_NOARGS},
1388   {"get_line_cap",    (PyCFunction)pycairo_get_line_cap,     METH_NOARGS},
1389   {"get_line_join",   (PyCFunction)pycairo_get_line_join,    METH_NOARGS},
1390   {"get_line_width",  (PyCFunction)pycairo_get_line_width,   METH_NOARGS},
1391   {"get_matrix",      (PyCFunction)pycairo_get_matrix,       METH_NOARGS},
1392   {"get_miter_limit", (PyCFunction)pycairo_get_miter_limit,  METH_NOARGS},
1393   {"get_operator",    (PyCFunction)pycairo_get_operator,     METH_NOARGS},
1394   {"get_scaled_font", (PyCFunction)pycairo_get_scaled_font,  METH_NOARGS},
1395   {"get_source",      (PyCFunction)pycairo_get_source,       METH_NOARGS},
1396   {"get_target",      (PyCFunction)pycairo_get_target,       METH_NOARGS},
1397   {"get_tolerance",   (PyCFunction)pycairo_get_tolerance,    METH_NOARGS},
1398   {"glyph_extents",   (PyCFunction)pycairo_glyph_extents,    METH_VARARGS},
1399   {"glyph_path",      (PyCFunction)pycairo_glyph_path,       METH_VARARGS},
1400   {"has_current_point",(PyCFunction)pycairo_has_current_point, METH_NOARGS},
1401   {"identity_matrix", (PyCFunction)pycairo_identity_matrix,  METH_NOARGS},
1402   {"in_clip",         (PyCFunction)pycairo_in_clip,          METH_VARARGS},
1403   {"in_fill",         (PyCFunction)pycairo_in_fill,          METH_VARARGS},
1404   {"in_stroke",       (PyCFunction)pycairo_in_stroke,        METH_VARARGS},
1405   {"line_to",         (PyCFunction)pycairo_line_to,          METH_VARARGS},
1406   {"mask",            (PyCFunction)pycairo_mask,             METH_VARARGS},
1407   {"mask_surface",    (PyCFunction)pycairo_mask_surface,     METH_VARARGS},
1408   {"move_to",         (PyCFunction)pycairo_move_to,          METH_VARARGS},
1409   {"new_path",        (PyCFunction)pycairo_new_path,         METH_NOARGS},
1410   {"new_sub_path",    (PyCFunction)pycairo_new_sub_path,     METH_NOARGS},
1411   {"paint",           (PyCFunction)pycairo_paint,            METH_NOARGS},
1412   {"paint_with_alpha",(PyCFunction)pycairo_paint_with_alpha, METH_VARARGS},
1413   {"path_extents",    (PyCFunction)pycairo_path_extents,     METH_NOARGS},
1414   {"pop_group",       (PyCFunction)pycairo_pop_group,        METH_NOARGS},
1415   {"pop_group_to_source", (PyCFunction)pycairo_pop_group_to_source,
1416    METH_NOARGS},
1417   {"push_group",      (PyCFunction)pycairo_push_group,       METH_NOARGS},
1418   {"push_group_with_content", (PyCFunction)pycairo_push_group_with_content,
1419    METH_VARARGS},
1420   {"rectangle",       (PyCFunction)pycairo_rectangle,        METH_VARARGS},
1421   {"rel_curve_to",    (PyCFunction)pycairo_rel_curve_to,     METH_VARARGS},
1422   {"rel_line_to",     (PyCFunction)pycairo_rel_line_to,      METH_VARARGS},
1423   {"rel_move_to",     (PyCFunction)pycairo_rel_move_to,      METH_VARARGS},
1424   {"reset_clip",      (PyCFunction)pycairo_reset_clip,       METH_NOARGS},
1425   {"restore",         (PyCFunction)pycairo_restore,          METH_NOARGS},
1426   {"rotate",          (PyCFunction)pycairo_rotate,           METH_VARARGS},
1427   {"save",            (PyCFunction)pycairo_save,             METH_NOARGS},
1428   {"scale",           (PyCFunction)pycairo_scale,            METH_VARARGS},
1429   {"select_font_face",(PyCFunction)pycairo_select_font_face, METH_VARARGS},
1430   {"set_antialias",   (PyCFunction)pycairo_set_antialias,    METH_VARARGS},
1431   {"set_dash",        (PyCFunction)pycairo_set_dash,         METH_VARARGS},
1432   {"set_fill_rule",   (PyCFunction)pycairo_set_fill_rule,    METH_VARARGS},
1433   {"set_font_face",   (PyCFunction)pycairo_set_font_face,    METH_O},
1434   {"set_font_matrix", (PyCFunction)pycairo_set_font_matrix,  METH_VARARGS},
1435   {"set_font_options",(PyCFunction)pycairo_set_font_options, METH_VARARGS},
1436   {"set_font_size",   (PyCFunction)pycairo_set_font_size,    METH_VARARGS},
1437   {"set_line_cap",    (PyCFunction)pycairo_set_line_cap,     METH_VARARGS},
1438   {"set_line_join",   (PyCFunction)pycairo_set_line_join,    METH_VARARGS},
1439   {"set_line_width",  (PyCFunction)pycairo_set_line_width,   METH_VARARGS},
1440   {"set_matrix",      (PyCFunction)pycairo_set_matrix,       METH_VARARGS},
1441   {"set_miter_limit", (PyCFunction)pycairo_set_miter_limit,  METH_VARARGS},
1442   {"set_operator",    (PyCFunction)pycairo_set_operator,     METH_VARARGS},
1443   {"set_scaled_font", (PyCFunction)pycairo_set_scaled_font,  METH_VARARGS},
1444   {"set_source",      (PyCFunction)pycairo_set_source,       METH_VARARGS},
1445   {"set_source_rgb",  (PyCFunction)pycairo_set_source_rgb,   METH_VARARGS},
1446   {"set_source_rgba", (PyCFunction)pycairo_set_source_rgba,  METH_VARARGS},
1447   {"set_source_surface",(PyCFunction)pycairo_set_source_surface, METH_VARARGS},
1448   {"set_tolerance",   (PyCFunction)pycairo_set_tolerance,    METH_VARARGS},
1449   {"show_glyphs",     (PyCFunction)pycairo_show_glyphs,      METH_VARARGS},
1450   {"show_page",       (PyCFunction)pycairo_show_page,        METH_NOARGS},
1451   {"show_text",       (PyCFunction)pycairo_show_text,        METH_VARARGS},
1452   {"stroke",          (PyCFunction)pycairo_stroke,           METH_NOARGS},
1453   {"stroke_extents",  (PyCFunction)pycairo_stroke_extents,   METH_NOARGS},
1454   {"stroke_preserve", (PyCFunction)pycairo_stroke_preserve,  METH_NOARGS},
1455   {"text_extents",    (PyCFunction)pycairo_text_extents,     METH_VARARGS},
1456   {"text_path",       (PyCFunction)pycairo_text_path,        METH_VARARGS},
1457   {"transform",       (PyCFunction)pycairo_transform,        METH_VARARGS},
1458   {"translate",       (PyCFunction)pycairo_translate,        METH_VARARGS},
1459   {"user_to_device",  (PyCFunction)pycairo_user_to_device,   METH_VARARGS},
1460   {"user_to_device_distance",(PyCFunction)pycairo_user_to_device_distance,
1461    METH_VARARGS},
1462   {"show_text_glyphs",(PyCFunction)pycairo_show_text_glyphs, METH_VARARGS},
1463   {NULL, NULL, 0, NULL},
1464 };
1465 
1466 static PyObject*
pycairo_richcompare(PyObject * self,PyObject * other,int op)1467 pycairo_richcompare (PyObject *self, PyObject *other, int op)
1468 {
1469   if (Py_TYPE(self) == Py_TYPE(other))
1470     return Pycairo_richcompare (
1471       ((PycairoContext *)self)->ctx,
1472       ((PycairoContext *)other)->ctx,
1473       op);
1474   else {
1475     Py_INCREF(Py_NotImplemented);
1476     return Py_NotImplemented;
1477   }
1478 }
1479 
1480 static PYCAIRO_Py_hash_t
pycairo_hash(PyObject * self)1481 pycairo_hash (PyObject *self)
1482 {
1483   return PYCAIRO_Py_hash_t_FromVoidPtr (((PycairoContext *)self)->ctx);
1484 }
1485 
1486 PyTypeObject PycairoContext_Type = {
1487   PyVarObject_HEAD_INIT(NULL, 0)
1488   "cairo.Context",                    /* tp_name */
1489   sizeof(PycairoContext),             /* tp_basicsize */
1490   0,                                  /* tp_itemsize */
1491   (destructor)pycairo_dealloc,        /* tp_dealloc */
1492   0,                                  /* tp_print */
1493   0,                                  /* tp_getattr */
1494   0,                                  /* tp_setattr */
1495   0,                                  /* tp_compare */
1496   0,                                  /* tp_repr */
1497   0,                                  /* tp_as_number */
1498   0,                                  /* tp_as_sequence */
1499   0,                                  /* tp_as_mapping */
1500   pycairo_hash,                       /* tp_hash */
1501   0,                                  /* tp_call */
1502   0,                                  /* tp_str */
1503   0,                                  /* tp_getattro */
1504   0,                                  /* tp_setattro */
1505   0,                                  /* tp_as_buffer */
1506   Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* tp_flags */
1507   0,                                  /* tp_doc */
1508   0,                                  /* tp_traverse */
1509   0,                                  /* tp_clear */
1510   pycairo_richcompare,                /* tp_richcompare */
1511   0,                                  /* tp_weaklistoffset */
1512   0,                                  /* tp_iter */
1513   0,                                  /* tp_iternext */
1514   pycairo_methods,                    /* tp_methods */
1515   0,                                  /* tp_members */
1516   0,                                  /* tp_getset */
1517   0,                                  /* tp_base */
1518   0,                                  /* tp_dict */
1519   0,                                  /* tp_descr_get */
1520   0,                                  /* tp_descr_set */
1521   0,                                  /* tp_dictoffset */
1522   0,                                  /* tp_init */
1523   0,                                  /* tp_alloc */
1524   (newfunc)pycairo_new,               /* tp_new */
1525   0,                                  /* tp_free */
1526   0,                                  /* tp_is_gc */
1527   0,                                  /* tp_bases */
1528 };
1529