--- /dev/null
+Description: Add support for cairo_region_t
+ This patch fix missing support for cairo_region_t.
+Author: Bug Fly
+Origin: https://bugs.freedesktop.org/attachment.cgi?id=61553
+Bug-Debian: http://bugs.debian.org/688079
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/py3cairo/+bug/1028115
+Last-Update: 2012-08-20
+Applied-Upstream: http://cgit.freedesktop.org/pycairo/commit/?id=75e82a1b3f495a3abbc78e50a5c66356d320fb15
+
+--- py3cairo-1.10.0+dfsg.orig/doc/pycairo_c_api.rst
++++ py3cairo-1.10.0+dfsg/doc/pycairo_c_api.rst
+@@ -51,6 +51,8 @@ Objects::
+ PycairoGradient
+ PycairoLinearGradient
+ PycairoRadialGradient
++ PycairoRectangleInt
++ PycairoRegion
+ PycairoScaledFont
+ PycairoSurface
+ PycairoImageSurface
+@@ -78,6 +80,8 @@ Types::
+ PyTypeObject *Gradient_Type;
+ PyTypeObject *LinearGradient_Type;
+ PyTypeObject *RadialGradient_Type;
++ PyTypeObject *RectangleInt_Type;
++ PyTypeObject *Region_Type;
+ PyTypeObject *ScaledFont_Type;
+ PyTypeObject *Surface_Type;
+ PyTypeObject *ImageSurface_Type;
+@@ -115,6 +119,12 @@ Functions
+ .. c:function:: PyObject * PycairoPattern_FromPattern(cairo_pattern_t *pattern, PyObject *base)
+
+
++.. c:function:: PyObject * PycairoRectangleInt_FromRectangleInt(const cairo_rectangle_int_t *rectangle_int)
++
++
++.. c:function:: PyObject * PycairoRegion_FromRegion(const cairo_region_t *region)
++
++
+ .. c:function:: PyObject * PycairoScaledFont_FromScaledFont(cairo_scaled_font_t *scaled_font)
+
+
+--- py3cairo-1.10.0+dfsg.orig/doc/reference/index.rst
++++ py3cairo-1.10.0+dfsg/doc/reference/index.rst
+@@ -15,5 +15,6 @@ Reference
+ matrix
+ paths
+ patterns
++ region
+ surfaces
+ text
+--- /dev/null
++++ py3cairo-1.10.0+dfsg/doc/reference/region.rst
+@@ -0,0 +1,52 @@
++.. _region:
++
++******
++Region
++******
++Region — Representing a pixel-aligned area
++
++.. currentmodule:: cairo
++
++
++class Region()
++==============
++*Region* is a simple graphical data type representing an area of
++integer-aligned rectangles. They are often used on raster surfaces to track
++areas of interest, such as change or clip areas.
++
++
++.. class:: Region([rectangle_int|rectangle_ints])
++
++ :param rectangle_int: a rectangle or a list of rectangle
++ :type rectangle_int: :class:`RectangleInt` or [:class:`RectangleInt`]
++
++ Allocates a new empty region object or a region object with the containing
++ rectangle(s).
++
++
++ .. method:: copy()
++
++ :returns: A newly allocated :class:`Region`.
++ :raises: :exc:`NoMemory` if memory cannot be allocated.
++
++ Allocates a new *Region* object copying the area from original.
++
++
++class RectangleInt()
++====================
++*RectangleInt* is a data structure for holding a rectangle with integer
++coordinates.
++
++
++.. class:: RectangleInt(x=0, y=0, width=0, height=0)
++
++ :param x: X coordinate of the left side of the rectangle
++ :type x: int
++ :param y: Y coordinate of the the top side of the rectangle
++ :type y: int
++ :param width: width of the rectangle
++ :type width: int
++ :param height: height of the rectangle
++ :type height: int
++
++ Allocates a new *RectangleInt* object.
+--- /dev/null
++++ py3cairo-1.10.0+dfsg/src/region.c
+@@ -0,0 +1,598 @@
++/* -*- mode: C; c-basic-offset: 2 -*-
++ *
++ * Copyright © 2005,2010 Steve Chaplin
++ *
++ * This file is part of pycairo.
++ *
++ * Pycairo is free software: you can redistribute it and/or modify it under
++ * the terms of the GNU Lesser General Public License version 3 as published
++ * by the Free Software Foundation.
++ *
++ * Pycairo is distributed in the hope that it will be useful, but WITHOUT ANY
++ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
++ * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
++ * more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public License
++ * along with pycairo. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#define PY_SSIZE_T_CLEAN
++#include <Python.h>
++#include "structmember.h"
++
++#include "config.h"
++#include "private.h"
++
++/* PycairoRectangleInt_FromRectangleInt
++ * Create a new PycairoRectangleInt from a cairo_rectangle_int_t
++ * rectangle_int - a cairo_rectangle_int_t to 'wrap' into a Python object.
++ * rectangle_int is unreferenced if the PycairoRectangleInt creation
++ * fails.
++ * Return value: New reference or NULL on failure
++ */
++PyObject *
++PycairoRectangleInt_FromRectangleInt (cairo_rectangle_int_t *rectangle_int) {
++ PyObject *o;
++
++ assert (rectangle_int != NULL);
++
++ o = PycairoRectangleInt_Type.tp_alloc (&PycairoRectangleInt_Type, 0);
++ if (o)
++ ((PycairoRectangleInt *)o)->rectangle_int = *rectangle_int;
++ return o;
++}
++
++static void
++rectangle_int_dealloc(PycairoRectangleInt *o) {
++#ifdef DEBUG
++ printf("rectangle_int_dealloc start\n");
++#endif
++ //o->ob_type->tp_free((PyObject *)o);
++ Py_TYPE(o)->tp_free(o);
++#ifdef DEBUG
++ printf("rectangle_int_dealloc end\n");
++#endif
++}
++
++static PyObject *
++rectangle_int_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
++ static char *kwlist[] = { "x", "y", "width", "height", NULL };
++ int x, y, w, h;
++ x = y = w = h = 0;
++ cairo_rectangle_int_t rect;
++
++ if (!PyArg_ParseTupleAndKeywords(args, kwds,
++ "|iiii:RectangleInt.__new__", kwlist,
++ &x, &y, &w, &h))
++ return NULL;
++
++ rect.x = x;
++ rect.y = y;
++ rect.width = w;
++ rect.height = h;
++
++ return PycairoRectangleInt_FromRectangleInt(&rect);
++}
++
++static PyObject *
++rectangle_int_str(PycairoRectangleInt *rect_o) {
++ PyObject *s;
++ cairo_rectangle_int_t *rect = &(rect_o->rectangle_int);
++ char buf[80];
++ PyOS_snprintf(buf, sizeof(buf), "cairo.RectangleInt(%d, %d, %d, %d)",
++ rect->x, rect->y, rect->width, rect->height);
++ s = PyUnicode_FromString(buf);
++ return s;
++}
++
++static PyObject *
++rectangle_int_richcompare(PycairoRectangleInt *self,
++ PycairoRectangleInt *other, int op) {
++ int res = 0;
++ PyObject *b;
++
++ if (op != Py_EQ && op != Py_NE) {
++ PyErr_SetString(PyExc_TypeError, "Only support testing for == or !=");
++ return NULL;
++ }
++ if (!PyObject_IsInstance((PyObject*)other,
++ (PyObject*)&PycairoRectangleInt_Type)) {
++ res = 0;
++ }
++ else if (
++ self->rectangle_int.x == other->rectangle_int.x &&
++ self->rectangle_int.y == other->rectangle_int.y &&
++ self->rectangle_int.width == other->rectangle_int.width &&
++ self->rectangle_int.height == other->rectangle_int.height
++ )
++ res = 1;
++ res = op == Py_NE ? !res : res;
++ b = res ? Py_True : Py_False;
++ Py_INCREF(b);
++
++ return b;
++}
++
++static PyMemberDef RectangleInt_members[] = {
++ {"x", T_INT, sizeof(PyObject), 0,
++ "X coordinate of the left side of the rectangle"},
++ {"y", T_INT, sizeof(PyObject)+sizeof(int), 0,
++ "Y coordinate of the the top side of the rectangle"},
++ {"width", T_INT, sizeof(PyObject)+sizeof(int)*2, 0,
++ "width of the rectangle"},
++ {"height", T_INT, sizeof(PyObject)+sizeof(int)*3, 0,
++ "height of the rectangle"},
++ {NULL}
++};
++
++PyTypeObject PycairoRectangleInt_Type = {
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
++ "cairo.RectangleInt", /* tp_name */
++ sizeof(PycairoRectangleInt), /* tp_basicsize */
++ 0, /* tp_itemsize */
++ (destructor)rectangle_int_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)rectangle_int_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 */
++ (richcmpfunc)rectangle_int_richcompare, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ 0, /* tp_iter */
++ 0, /* tp_iternext */
++ 0, /* tp_methods */
++ RectangleInt_members, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ 0, /* tp_init */
++ 0, /* tp_alloc */
++ (newfunc)rectangle_int_new, /* tp_new */
++};
++
++/* PycairoRegion_FromRegion
++ * Create a new PycairoRegion from a cairo_region_t
++ * region - a cairo_region_t to 'wrap' into a Python object.
++ * region is unreferenced if the PycairoRegion creation fails, or if
++ * region is in an error status.
++ * Return value: New reference or NULL on failure
++ */
++PyObject *
++PycairoRegion_FromRegion (cairo_region_t *region) {
++ PyObject *o;
++
++ assert (region != NULL);
++
++ if (Pycairo_Check_Status (cairo_region_status(region))) {
++ cairo_region_destroy (region);
++ return NULL;
++ }
++
++ o = PycairoRegion_Type.tp_alloc (&PycairoRegion_Type, 0);
++ if (o)
++ ((PycairoRegion *)o)->region = region;
++ else
++ cairo_region_destroy (region);
++ return o;
++}
++
++static void
++region_dealloc(PycairoRegion *o) {
++#ifdef DEBUG
++ printf("region_dealloc start\n");
++#endif
++ if (o->region) {
++ cairo_region_destroy(o->region);
++ o->region = NULL;
++ }
++ //o->ob_type->tp_free((PyObject *)o);
++ Py_TYPE(o)->tp_free(o);
++#ifdef DEBUG
++ printf("region_dealloc end\n");
++#endif
++}
++
++static PyObject *
++region_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
++ PyObject *s = NULL;
++ PycairoRectangleInt *rect_obj = NULL;
++ cairo_region_t *region = NULL;
++ cairo_rectangle_int_t *rect = NULL;
++
++ if (PyArg_ParseTuple(args, "|O!:Region.__new__",
++ &PycairoRectangleInt_Type, &rect_obj)) {
++ if (rect_obj != NULL) {
++ region = cairo_region_create_rectangle(&(rect_obj->rectangle_int));
++ }
++ } else if (!PyArg_ParseTuple(args, "|O:Region.__new__", &s)) {
++ PyErr_SetString(PyExc_TypeError,
++ "argument must be a RectangleInt or a sequence of RectangleInt.");
++ return NULL;
++ }
++ PyErr_Clear(); /* Clear possible err in the 1st arg parser. */
++
++ /* list of rectangle_int or no args */
++ if (s != NULL) {
++ int i;
++ int rect_size;
++ PyObject *seq = NULL;
++ seq = PySequence_Fast (s,
++ "argument must be a RectangleInt or a sequence of RectangleInt.");
++ if (seq == NULL) {
++ return NULL;
++ }
++ rect_size = PySequence_Fast_GET_SIZE(seq);
++ rect = PyMem_Malloc (rect_size * sizeof(cairo_rectangle_int_t));
++ if (rect == NULL) {
++ Py_DECREF(seq);
++ return PyErr_NoMemory();
++ }
++
++ for(i=0; i<rect_size; i++) {
++ PyObject *obj_tmp = PySequence_Fast_GET_ITEM(seq, i);
++ if (PyObject_IsInstance(obj_tmp,
++ (PyObject*)&PycairoRectangleInt_Type) != 1) {
++ Py_DECREF(seq);
++ PyMem_Free(rect);
++ return NULL;
++ }
++ rect_obj = (PycairoRectangleInt*) obj_tmp;
++ rect[i] = rect_obj->rectangle_int;
++ }
++
++ region = cairo_region_create_rectangles(rect, rect_size);
++
++ Py_DECREF(seq);
++ PyMem_Free(rect);
++ }
++
++ if (region == NULL) {
++ region = cairo_region_create();
++ }
++
++ RETURN_NULL_IF_CAIRO_REGION_ERROR(region);
++ return PycairoRegion_FromRegion(region);
++}
++
++PyObject *
++region_copy (PycairoRegion *o) {
++ cairo_region_t *res;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_copy (o->region);
++ Py_END_ALLOW_THREADS;
++ RETURN_NULL_IF_CAIRO_REGION_ERROR(res);
++ return PycairoRegion_FromRegion(res);
++}
++
++
++PyObject *
++region_get_extents (PycairoRegion *o) {
++ cairo_rectangle_int_t rect;
++ Py_BEGIN_ALLOW_THREADS;
++ cairo_region_get_extents(o->region, &rect);
++ Py_END_ALLOW_THREADS;
++
++ return PycairoRectangleInt_FromRectangleInt(&rect);
++}
++
++
++PyObject *
++region_num_rectangles (PycairoRegion *o) {
++ int res;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_num_rectangles(o->region);
++ Py_END_ALLOW_THREADS;
++ return Py_BuildValue("i", res);
++}
++
++
++PyObject *
++region_get_rectangle (PycairoRegion *o, PyObject *args) {
++ cairo_rectangle_int_t rect;
++ int i;
++ int total;
++ if (!PyArg_ParseTuple (args, "i:Region.get_rectangle", &i))
++ return NULL;
++ total = cairo_region_num_rectangles(o->region);
++ if (i >= total || i < 0) {
++ if ( i < 0)
++ PyErr_SetString(PyExc_ValueError, "index must be a positive number");
++ else
++ PyErr_SetString(PyExc_ValueError, "index is to big for the region");
++ return NULL;
++ }
++ Py_BEGIN_ALLOW_THREADS;
++ cairo_region_get_rectangle(o->region, i, &rect);
++ Py_END_ALLOW_THREADS;
++ return PycairoRectangleInt_FromRectangleInt(&rect);
++}
++
++
++PyObject *
++region_is_empty (PycairoRegion *o) {
++ cairo_bool_t res;
++ PyObject *b;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_is_empty(o->region);
++ Py_END_ALLOW_THREADS;
++ b = res ? Py_True : Py_False;
++ Py_INCREF(b);
++ return b;
++}
++
++
++PyObject *
++region_contains_point (PycairoRegion *o, PyObject *args) {
++ int x, y;
++ cairo_bool_t res;
++ PyObject *b;
++ if (!PyArg_ParseTuple (args, "ii:Region.contains_point", &x, &y))
++ return NULL;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_contains_point(o->region, x, y);
++ Py_END_ALLOW_THREADS;
++ b = res ? Py_True : Py_False;
++ Py_INCREF(b);
++ return b;
++}
++
++
++PyObject *
++region_contains_rectangle (PycairoRegion *o, PyObject *args) {
++ cairo_region_overlap_t res;
++ PycairoRectangleInt *rect_int;
++ if (!PyArg_ParseTuple (args, "O!:Region.contains_rectangle",
++ &PycairoRectangleInt_Type, &rect_int))
++ return NULL;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_contains_rectangle(o->region, &(rect_int->rectangle_int));
++ Py_END_ALLOW_THREADS;
++ return Py_BuildValue("i", res);
++}
++
++
++PyObject *
++region_equal (PycairoRegion *o, PyObject *args) {
++ cairo_bool_t res;
++ PyObject *b;
++ PycairoRegion *region_obj;
++ if (!PyArg_ParseTuple (args, "O!:Region.equal",
++ &PycairoRegion_Type, ®ion_obj))
++ return NULL;
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_equal (o->region, region_obj->region);
++ Py_END_ALLOW_THREADS;
++ b = res ? Py_True : Py_False;
++ Py_INCREF(b);
++ return b;
++}
++
++static PyObject *
++region_richcompare(PycairoRegion *self, PycairoRegion *other, int op) {
++ int res = 0;
++ PyObject *b;
++
++ if (op != Py_EQ && op != Py_NE) {
++ PyErr_SetString(PyExc_TypeError, "Only support testing for == or !=");
++ return NULL;
++ }
++ if (!PyObject_IsInstance((PyObject*)other, (PyObject*)&PycairoRegion_Type)) {
++ res = 0;
++ } else {
++ res = cairo_region_equal (self->region, other->region);
++ }
++
++ res = op == Py_NE ? !res : res;
++ b = res ? Py_True : Py_False;
++ Py_INCREF(b);
++
++ return b;
++}
++
++PyObject *
++region_translate (PycairoRegion *o, PyObject *args) {
++ int x, y;
++ if (!PyArg_ParseTuple (args, "ii:Region.translate", &x, &y))
++ return NULL;
++ Py_BEGIN_ALLOW_THREADS;
++ cairo_region_translate (o->region, x, y);
++ Py_END_ALLOW_THREADS;
++ Py_RETURN_NONE;
++}
++
++
++PyObject *
++region_intersect (PycairoRegion *o, PyObject *args) {
++ cairo_status_t res;
++ PyObject *other;
++ if (!PyArg_ParseTuple (args, "O:Region.intersect", &other))
++ return NULL;
++
++ if (PyObject_IsInstance(other, (PyObject*)&PycairoRegion_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_intersect(o->region,
++ ((PycairoRegion *)other)->region);
++ Py_END_ALLOW_THREADS;
++ } else if (PyObject_IsInstance(other,
++ (PyObject*)&PycairoRectangleInt_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_intersect_rectangle(o->region,
++ &(((PycairoRectangleInt *)other)->rectangle_int));
++ Py_END_ALLOW_THREADS;
++ } else {
++ PyErr_SetString(PyExc_TypeError,
++ "argument must be a Region or a RectangleInt.");
++ return NULL;
++ }
++
++ RETURN_NULL_IF_CAIRO_ERROR(res);
++ Py_RETURN_NONE;
++}
++
++PyObject *
++region_subtract (PycairoRegion *o, PyObject *args) {
++ cairo_status_t res;
++ PyObject *other;
++ if (!PyArg_ParseTuple (args, "O:Region.subtract", &other))
++ return NULL;
++
++ if (PyObject_IsInstance(other, (PyObject*)&PycairoRegion_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_subtract(o->region,
++ ((PycairoRegion *)other)->region);
++ Py_END_ALLOW_THREADS;
++ } else if (PyObject_IsInstance(other,
++ (PyObject*)&PycairoRectangleInt_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_subtract_rectangle(o->region,
++ &(((PycairoRectangleInt *)other)->rectangle_int));
++ Py_END_ALLOW_THREADS;
++ } else {
++ PyErr_SetString(PyExc_TypeError,
++ "argument must be a Region or a RectangleInt.");
++ return NULL;
++ }
++ RETURN_NULL_IF_CAIRO_ERROR(res);
++ Py_RETURN_NONE;
++}
++
++PyObject *
++region_union (PycairoRegion *o, PyObject *args) {
++ cairo_status_t res;
++ PyObject *other;
++ if (!PyArg_ParseTuple (args, "O:Region.union", &other))
++ return NULL;
++
++ if (PyObject_IsInstance(other, (PyObject*)&PycairoRegion_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_union(o->region,
++ ((PycairoRegion *)other)->region);
++ Py_END_ALLOW_THREADS;
++ } else if (PyObject_IsInstance(other,
++ (PyObject*)&PycairoRectangleInt_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_union_rectangle(o->region,
++ &(((PycairoRectangleInt *)other)->rectangle_int));
++ Py_END_ALLOW_THREADS;
++ } else {
++ PyErr_SetString(PyExc_TypeError,
++ "argument must be a Region or a RectangleInt.");
++ return NULL;
++ }
++ RETURN_NULL_IF_CAIRO_ERROR(res);
++ Py_RETURN_NONE;
++}
++
++PyObject *
++region_xor (PycairoRegion *o, PyObject *args) {
++ cairo_status_t res;
++ PyObject *other;
++ if (!PyArg_ParseTuple (args, "O:Region.xorg", &other))
++ return NULL;
++
++ if (PyObject_IsInstance(other, (PyObject*)&PycairoRegion_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_xor(o->region,
++ ((PycairoRegion *)other)->region);
++ Py_END_ALLOW_THREADS;
++ } else if (PyObject_IsInstance(other,
++ (PyObject*)&PycairoRectangleInt_Type) == 1) {
++ Py_BEGIN_ALLOW_THREADS;
++ res = cairo_region_xor_rectangle(o->region,
++ &(((PycairoRectangleInt *)other)->rectangle_int));
++ Py_END_ALLOW_THREADS;
++ } else {
++ PyErr_SetString(PyExc_TypeError,
++ "argument must be a Region or a RectangleInt.");
++ return NULL;
++ }
++ RETURN_NULL_IF_CAIRO_ERROR(res);
++ Py_RETURN_NONE;
++}
++
++static PyMethodDef region_methods[] = {
++ /* methods never exposed in a language binding:
++ * cairo_region_destroy()
++ * cairo_region_get_type()
++ * cairo_region_reference()
++ *
++ * cairo_region_status()
++ * - not needed since Pycairo handles status checking
++ *
++ * _(intersect/subtract/union/xor)_rectangle are merged with the region
++ * ones.
++ */
++ {"copy", (PyCFunction)region_copy, METH_NOARGS },
++ {"get_extents", (PyCFunction)region_get_extents, METH_NOARGS },
++ {"num_rectangles", (PyCFunction)region_num_rectangles, METH_NOARGS },
++ {"get_rectangle", (PyCFunction)region_get_rectangle, METH_VARARGS },
++ {"is_empty", (PyCFunction)region_is_empty, METH_NOARGS },
++ {"contains_point", (PyCFunction)region_contains_point, METH_VARARGS },
++ {"contains_rectangle", (PyCFunction)region_contains_rectangle,
++ METH_VARARGS },
++ {"equal", (PyCFunction)region_equal, METH_VARARGS },
++ {"translate", (PyCFunction)region_translate, METH_VARARGS },
++ {"intersect", (PyCFunction)region_intersect, METH_VARARGS },
++ {"subtract", (PyCFunction)region_subtract, METH_VARARGS },
++ {"union", (PyCFunction)region_union, METH_VARARGS },
++ {"xor", (PyCFunction)region_xor, METH_VARARGS },
++ {NULL, NULL, 0, NULL},
++};
++
++PyTypeObject PycairoRegion_Type = {
++ PyVarObject_HEAD_INIT(&PyType_Type, 0)
++ "cairo.Region", /* tp_name */
++ sizeof(PycairoRegion), /* tp_basicsize */
++ 0, /* tp_itemsize */
++ (destructor)region_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 */
++ (richcmpfunc)region_richcompare, /* tp_richcompare */
++ 0, /* tp_weaklistoffset */
++ 0, /* tp_iter */
++ 0, /* tp_iternext */
++ region_methods, /* tp_methods */
++ 0, /* tp_members */
++ 0, /* tp_getset */
++ 0, /* tp_base */
++ 0, /* tp_dict */
++ 0, /* tp_descr_get */
++ 0, /* tp_descr_set */
++ 0, /* tp_dictoffset */
++ 0, /* tp_init */
++ 0, /* tp_alloc */
++ (newfunc)region_new, /* tp_new */
++};
+--- py3cairo-1.10.0+dfsg.orig/src/py3cairo.h
++++ py3cairo-1.10.0+dfsg/src/py3cairo.h
+@@ -67,6 +67,16 @@ typedef struct {
+
+ typedef struct {
+ PyObject_HEAD
++ cairo_rectangle_int_t rectangle_int;
++} PycairoRectangleInt;
++
++typedef struct {
++ PyObject_HEAD
++ cairo_region_t *region;
++} PycairoRegion;
++
++typedef struct {
++ PyObject_HEAD
+ cairo_scaled_font_t *scaled_font;
+ } PycairoScaledFont;
+
+@@ -129,6 +139,14 @@ typedef struct {
+
+ /* misc functions */
+ int (*Check_Status)(cairo_status_t status);
++
++ PyTypeObject *RectangleInt_Type;
++ PyObject *(*RectangleInt_FromRectangleInt)(
++ const cairo_rectangle_int_t *rectangle_int);
++
++ PyTypeObject *Region_Type;
++ PyObject *(*Region_FromRegion)(const cairo_region_t *region);
++
+ } Pycairo_CAPI_t;
+
+
+@@ -156,6 +174,13 @@ typedef struct {
+ #define PycairoRadialGradient_Type *(Pycairo_CAPI->RadialGradient_Type)
+ #define PycairoPattern_FromPattern (Pycairo_CAPI->Pattern_FromPattern)
+
++#define PycairoRectangleInt_Type *(Pycairo_CAPI->RectangleInt_Type)
++#define PycairoRectangleInt_FromRectangleInt \
++ (Pycairo_CAPI->RectangleInt_FromRectangleInt)
++
++#define PycairoRegion_Type *(Pycairo_CAPI->Region_Type)
++#define PycairoRegion_FromRegion (Pycairo_CAPI->Region_FromRegion)
++
+ #define PycairoScaledFont_Type *(Pycairo_CAPI->ScaledFont_Type)
+ #define PycairoScaledFont_FromScaledFont \
+ (Pycairo_CAPI->ScaledFont_FromScaledFont)
+--- py3cairo-1.10.0+dfsg.orig/src/cairomodule.c
++++ py3cairo-1.10.0+dfsg/src/cairomodule.c
+@@ -141,6 +141,12 @@ static Pycairo_CAPI_t CAPI = {
+ PycairoSurface_FromSurface,
+
+ Pycairo_Check_Status,
++
++ &PycairoRectangleInt_Type,
++ PycairoRectangleInt_FromRectangleInt,
++
++ &PycairoRegion_Type,
++ PycairoRegion_FromRegion,
+ };
+
+ static PyObject *
+@@ -230,6 +236,12 @@ PyInit__cairo(void)
+ if (PyType_Ready(&PycairoRadialGradient_Type) < 0)
+ return NULL;
+
++ if (PyType_Ready(&PycairoRectangleInt_Type) < 0)
++ return NULL;
++
++ if (PyType_Ready(&PycairoRegion_Type) < 0)
++ return NULL;
++
+ if (PyType_Ready(&PycairoScaledFont_Type) < 0)
+ return NULL;
+
+@@ -315,6 +327,12 @@ PyInit__cairo(void)
+ PyModule_AddObject(m, "RadialGradient",
+ (PyObject *)&PycairoRadialGradient_Type);
+
++ Py_INCREF(&PycairoRectangleInt_Type);
++ PyModule_AddObject(m, "RectangleInt", (PyObject *)&PycairoRectangleInt_Type);
++
++ Py_INCREF(&PycairoRegion_Type);
++ PyModule_AddObject(m, "Region", (PyObject *)&PycairoRegion_Type);
++
+ Py_INCREF(&PycairoScaledFont_Type);
+ PyModule_AddObject(m, "ScaledFont", (PyObject *)&PycairoScaledFont_Type);
+
+@@ -519,6 +537,10 @@ PyInit__cairo(void)
+ CONSTANT(PS_LEVEL_3);
+ #endif
+
++ CONSTANT(REGION_OVERLAP_IN);
++ CONSTANT(REGION_OVERLAP_OUT);
++ CONSTANT(REGION_OVERLAP_PART);
++
+ CONSTANT(SUBPIXEL_ORDER_DEFAULT);
+ CONSTANT(SUBPIXEL_ORDER_RGB);
+ CONSTANT(SUBPIXEL_ORDER_BGR);
+--- py3cairo-1.10.0+dfsg.orig/src/wscript
++++ py3cairo-1.10.0+dfsg/src/wscript
+@@ -25,6 +25,7 @@ def build(ctx):
+ 'font.c',
+ 'path.c',
+ 'pattern.c',
++ 'region.c',
+ 'matrix.c',
+ 'surface.c',
+ ],
+--- py3cairo-1.10.0+dfsg.orig/src/private.h
++++ py3cairo-1.10.0+dfsg/src/private.h
+@@ -60,6 +60,13 @@ extern PyTypeObject PycairoLinearGradien
+ extern PyTypeObject PycairoRadialGradient_Type;
+ PyObject *PycairoPattern_FromPattern (cairo_pattern_t *pattern,
+ PyObject *base);
++
++extern PyTypeObject PycairoRectangleInt_Type;
++PyObject *PycairoRectangleInt_FromRectangleInt (
++ cairo_rectangle_int_t *rectangle_int);
++
++extern PyTypeObject PycairoRegion_Type;
++PyObject *PycairoRegion_FromRegion (cairo_region_t *region);
+
+ extern PyTypeObject PycairoScaledFont_Type;
+ PyObject *PycairoScaledFont_FromScaledFont (cairo_scaled_font_t *scaled_font);
+@@ -153,6 +160,15 @@ int Pycairo_Check_Status (cairo_status_t
+ if (status != CAIRO_STATUS_SUCCESS) { \
+ Pycairo_Check_Status (status); \
+ return NULL; \
++ } \
++ } while (0)
++
++#define RETURN_NULL_IF_CAIRO_REGION_ERROR(region) \
++ do { \
++ cairo_status_t status = cairo_region_status (region); \
++ if (status != CAIRO_STATUS_SUCCESS) { \
++ Pycairo_Check_Status (status); \
++ return NULL; \
+ } \
+ } while (0)
+
+--- py3cairo-1.10.0+dfsg.orig/test/api_test.py
++++ py3cairo-1.10.0+dfsg/test/api_test.py
+@@ -84,3 +84,65 @@ def test_surface():
+
+ def test_text():
+ pass
++
++
++def test_region():
++ a = cairo.Region()
++ assert a.is_empty() == True
++ assert a.num_rectangles() == 0
++
++ b = cairo.RectangleInt(1, 2, 10, 12)
++ d = cairo.RectangleInt(1, 1, 10, 12)
++ e = cairo.RectangleInt(1, 3, 8, 12)
++ assert (b.x, b.y, b.width, b.height) == (1, 2, 10, 12)
++ c = cairo.Region((b, e))
++ assert not c.is_empty()
++ assert c.num_rectangles() == 2
++ assert c.get_rectangle(1).y == 14
++
++ ex = c.get_extents()
++ assert ex == cairo.RectangleInt(1, 2, 10, 13)
++ assert c.contains_rectangle(d) == cairo.REGION_OVERLAP_PART
++
++ c.translate(10, 20)
++ assert c.contains_rectangle(d) == cairo.REGION_OVERLAP_OUT
++ assert c.get_rectangle(1) == cairo.RectangleInt(11, 34, 8, 1)
++
++ cp = c.copy()
++ assert c.num_rectangles() == cp.num_rectangles()
++ assert c.get_rectangle(0) == cp.get_rectangle(0)
++ assert c == cp
++ assert 3 != c
++ assert c != "test"
++
++ c = cairo.Region((b, e))
++ c.intersect(d)
++ assert c.num_rectangles() == 1
++ assert c.get_rectangle(0) == cairo.RectangleInt(1, 2, 10, 11)
++
++ c = cairo.Region((b, e))
++ c.subtract(d)
++ assert c.num_rectangles() == 2
++ assert c == cairo.Region([
++ cairo.RectangleInt(1, 13, 10, 1), cairo.RectangleInt(1, 14, 8, 1) ])
++
++ d = cairo.Region(d)
++ c = cairo.Region((b, e))
++ c.subtract(d)
++ assert c.num_rectangles() == 2
++ assert c.get_rectangle(0) == cairo.RectangleInt(1, 13, 10, 1)
++
++ c = cairo.Region((b, e))
++ c.union(d)
++ assert c.num_rectangles() == 2
++ assert c == cairo.Region([
++ cairo.RectangleInt(1, 1, 10, 13), cairo.RectangleInt(1, 14, 8, 1) ])
++
++ c = cairo.Region((b, e))
++ c.xor(d)
++ assert c.num_rectangles() == 3
++ assert c == cairo.Region([
++ cairo.RectangleInt(1, 1, 10, 1),
++ cairo.RectangleInt(1, 14, 8, 1),
++ cairo.RectangleInt(1, 13, 10, 1),
++ ])