diff options
Diffstat (limited to 'gi/pygi-foreign-cairo.c')
-rw-r--r-- | gi/pygi-foreign-cairo.c | 549 |
1 files changed, 520 insertions, 29 deletions
diff --git a/gi/pygi-foreign-cairo.c b/gi/pygi-foreign-cairo.c index 3fe6a39..aa01157 100644 --- a/gi/pygi-foreign-cairo.c +++ b/gi/pygi-foreign-cairo.c @@ -21,20 +21,21 @@ * IN THE SOFTWARE. */ -#include <cairo.h> #include <Python.h> +#include <cairo.h> +#include <py3cairo.h> -#if PY_VERSION_HEX < 0x03000000 -#include <pycairo.h> -static Pycairo_CAPI_t *Pycairo_CAPI; -#else -#include <pycairo/py3cairo.h> -#endif - +#include <cairo-gobject.h> -#include "pygi-foreign.h" +/* Limit includes from PyGI to APIs which do not have link dependencies + * (pygobject.h and pygi-foreign-api.h) since _gi_cairo is built as a separate + * shared library that interacts with PyGI through a PyCapsule API at runtime. + */ +#include <pygi-foreign-api.h> -#include <pyglib-python-compat.h> +/* + * cairo_t marshaling + */ static PyObject * cairo_context_to_arg (PyObject *value, @@ -44,27 +45,37 @@ cairo_context_to_arg (PyObject *value, { cairo_t *cr; - g_assert (transfer == GI_TRANSFER_NOTHING); + if (!PyObject_TypeCheck (value, &PycairoContext_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Context"); + return NULL; + } cr = PycairoContext_GET (value); if (!cr) { return NULL; } + if (transfer != GI_TRANSFER_NOTHING) + cr = cairo_reference (cr); + arg->v_pointer = cr; Py_RETURN_NONE; } static PyObject * -cairo_context_from_arg (GIInterfaceInfo *interface_info, gpointer data) +cairo_context_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) { cairo_t *context = (cairo_t*) data; - cairo_reference (context); + if (transfer == GI_TRANSFER_NOTHING) + cairo_reference (context); return PycairoContext_FromContext (context, &PycairoContext_Type, NULL); } + static PyObject * cairo_context_release (GIBaseInfo *base_info, gpointer struct_) @@ -73,6 +84,43 @@ cairo_context_release (GIBaseInfo *base_info, Py_RETURN_NONE; } +static int +cairo_context_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_t *cr; + + if (!PyObject_TypeCheck (obj, &PycairoContext_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Context"); + return -1; + } + + cr = PycairoContext_GET (obj); + if (!cr) { + return -1; + } + + /* PycairoContext_GET returns a borrowed reference, use set_boxed + * to add new ref to the context which will be managed by the GValue. */ + g_value_set_boxed (value, cr); + return 0; +} + +static PyObject * +cairo_context_from_gvalue (const GValue *value) +{ + /* PycairoContext_FromContext steals a ref, so we dup it out of the GValue. */ + cairo_t *cr = g_value_dup_boxed (value); + if (!cr) { + Py_RETURN_NONE; + } + + return PycairoContext_FromContext (cr, &PycairoContext_Type, NULL); +} + + +/* + * cairo_surface_t marshaling + */ static PyObject * cairo_surface_to_arg (PyObject *value, @@ -82,7 +130,10 @@ cairo_surface_to_arg (PyObject *value, { cairo_surface_t *surface; - g_assert (transfer == GI_TRANSFER_NOTHING); + if (!PyObject_TypeCheck (value, &PycairoSurface_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Surface"); + return NULL; + } surface = ( (PycairoSurface*) value)->surface; if (!surface) { @@ -90,16 +141,22 @@ cairo_surface_to_arg (PyObject *value, return NULL; } + if (transfer != GI_TRANSFER_NOTHING) + surface = cairo_surface_reference (surface); + arg->v_pointer = surface; Py_RETURN_NONE; } static PyObject * -cairo_surface_from_arg (GIInterfaceInfo *interface_info, gpointer data) +cairo_surface_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) { cairo_surface_t *surface = (cairo_surface_t*) data; - cairo_surface_reference (surface); + if (transfer == GI_TRANSFER_NOTHING) + cairo_surface_reference (surface); return PycairoSurface_FromSurface (surface, NULL); } @@ -112,6 +169,59 @@ cairo_surface_release (GIBaseInfo *base_info, Py_RETURN_NONE; } +static int +cairo_surface_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_surface_t *surface; + + if (!PyObject_TypeCheck (obj, &PycairoSurface_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Surface"); + return -1; + } + + surface = ((PycairoSurface*) obj)->surface; + if (!surface) { + return -1; + } + + /* surface is a borrowed reference, use set_boxed + * to add new ref to the context which will be managed by the GValue. */ + g_value_set_boxed (value, surface); + return 0; +} + +static PyObject * +cairo_surface_from_gvalue (const GValue *value) +{ + /* PycairoSurface_FromSurface steals a ref, so we dup it out of the GValue. */ + cairo_surface_t *surface = g_value_dup_boxed (value); + if (!surface) { + Py_RETURN_NONE; + } + + return PycairoSurface_FromSurface (surface, NULL); +} + + +/* + * cairo_path_t marshaling + */ + +static cairo_path_t * +_cairo_path_copy (cairo_path_t *path) { + cairo_t *cr; + cairo_surface_t *surface; + cairo_path_t *copy; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0); + cr = cairo_create (surface); + cairo_append_path (cr, path); + copy = cairo_copy_path (cr); + cairo_destroy (cr); + cairo_surface_destroy (surface); + + return copy; +} static PyObject * cairo_path_to_arg (PyObject *value, @@ -121,7 +231,10 @@ cairo_path_to_arg (PyObject *value, { cairo_path_t *path; - g_assert (transfer == GI_TRANSFER_NOTHING); + if (!PyObject_TypeCheck (value, &PycairoPath_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Path"); + return NULL; + } path = ( (PycairoPath*) value)->path; if (!path) { @@ -129,15 +242,25 @@ cairo_path_to_arg (PyObject *value, return NULL; } + if (transfer != GI_TRANSFER_NOTHING) + path = _cairo_path_copy (path); + arg->v_pointer = path; Py_RETURN_NONE; } static PyObject * -cairo_path_from_arg (GIInterfaceInfo *interface_info, gpointer data) +cairo_path_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) { cairo_path_t *path = (cairo_path_t*) data; + if (transfer == GI_TRANSFER_NOTHING) { + PyErr_SetString(PyExc_TypeError, "Unsupported annotation (transfer none) for cairo.Path return"); + return NULL; + } + return PycairoPath_FromPath (path); } @@ -149,6 +272,46 @@ cairo_path_release (GIBaseInfo *base_info, Py_RETURN_NONE; } + +/* + * cairo_font_face_t marshaling + */ + +static int +cairo_font_face_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_font_face_t *font_face; + + if (!PyObject_TypeCheck (obj, &PycairoFontFace_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.FontFace"); + return -1; + } + + font_face = ((PycairoFontFace*) obj)->font_face; + if (!font_face) { + return -1; + } + + g_value_set_boxed (value, font_face); + return 0; +} + +static PyObject * +cairo_font_face_from_gvalue (const GValue *value) +{ + cairo_font_face_t *font_face = g_value_dup_boxed (value); + if (!font_face) { + Py_RETURN_NONE; + } + + return PycairoFontFace_FromFontFace (font_face); +} + + +/* + * cairo_font_options_t marshaling + */ + static PyObject * cairo_font_options_to_arg (PyObject *value, GIInterfaceInfo *interface_info, @@ -157,7 +320,10 @@ cairo_font_options_to_arg (PyObject *value, { cairo_font_options_t *font_options; - g_assert (transfer == GI_TRANSFER_NOTHING); + if (!PyObject_TypeCheck (value, &PycairoFontOptions_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.FontOptions"); + return NULL; + } font_options = ( (PycairoFontOptions*) value)->font_options; if (!font_options) { @@ -165,16 +331,24 @@ cairo_font_options_to_arg (PyObject *value, return NULL; } + if (transfer != GI_TRANSFER_NOTHING) + font_options = cairo_font_options_copy (font_options); + arg->v_pointer = font_options; Py_RETURN_NONE; } static PyObject * -cairo_font_options_from_arg (GIInterfaceInfo *interface_info, gpointer data) +cairo_font_options_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) { cairo_font_options_t *font_options = (cairo_font_options_t*) data; - return PycairoFontOptions_FromFontOptions (cairo_font_options_copy (font_options)); + if (transfer == GI_TRANSFER_NOTHING) + font_options = cairo_font_options_copy (font_options); + + return PycairoFontOptions_FromFontOptions (font_options); } static PyObject * @@ -185,17 +359,297 @@ cairo_font_options_release (GIBaseInfo *base_info, Py_RETURN_NONE; } -static PyMethodDef _gi_cairo_functions[] = { {0,} }; -PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo") + +/* + * scaled_font_t marshaling + */ + +static int +cairo_scaled_font_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_scaled_font_t *scaled_font; + + if (!PyObject_TypeCheck (obj, &PycairoScaledFont_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.ScaledFont"); + return -1; + } + + scaled_font = ((PycairoScaledFont*) obj)->scaled_font; + if (!scaled_font) { + return -1; + } + + /* scaled_font is a borrowed reference, use set_boxed + * to add new ref to the context which will be managed by the GValue. */ + g_value_set_boxed (value, scaled_font); + return 0; +} + +static PyObject * +cairo_scaled_font_from_gvalue (const GValue *value) +{ + /* PycairoScaledFont_FromScaledFont steals a ref, so we dup it out of the GValue. */ + cairo_scaled_font_t *scaled_font = g_value_dup_boxed (value); + if (!scaled_font) { + Py_RETURN_NONE; + } + + return PycairoScaledFont_FromScaledFont (scaled_font); +} + + +/* + * cairo_pattern_t marshaling + */ + +static PyObject * +cairo_pattern_to_arg (PyObject *value, + GIInterfaceInfo *interface_info, + GITransfer transfer, + GIArgument *arg) +{ + cairo_pattern_t *pattern; + + if (!PyObject_TypeCheck (value, &PycairoPattern_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Pattern"); + return NULL; + } + + pattern = ((PycairoPattern*) value)->pattern; + if (!pattern) { + PyErr_SetString (PyExc_ValueError, "Pattern instance wrapping a NULL pattern"); + return NULL; + } + + if (transfer != GI_TRANSFER_NOTHING) + pattern = cairo_pattern_reference (pattern); + + arg->v_pointer = pattern; + Py_RETURN_NONE; +} + +static PyObject * +cairo_pattern_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) +{ + cairo_pattern_t *pattern = (cairo_pattern_t*) data; + + if (transfer == GI_TRANSFER_NOTHING) + pattern = cairo_pattern_reference (pattern); + + return PycairoPattern_FromPattern (pattern, NULL); +} + +static PyObject * +cairo_pattern_release (GIBaseInfo *base_info, + gpointer struct_) +{ + cairo_pattern_destroy ( (cairo_pattern_t*) struct_); + Py_RETURN_NONE; +} + +static int +cairo_pattern_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_pattern_t *pattern; + + if (!PyObject_TypeCheck (obj, &PycairoPattern_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Pattern"); + return -1; + } + + pattern = ((PycairoPattern*) obj)->pattern; + if (!pattern) { + return -1; + } + + /* pattern is a borrowed reference, use set_boxed + * to add new ref to the context which will be managed by the GValue. */ + g_value_set_boxed (value, pattern); + return 0; +} + +static PyObject * +cairo_pattern_from_gvalue (const GValue *value) { -#if PY_VERSION_HEX < 0x03000000 - Pycairo_IMPORT; + /* PycairoPattern_FromPattern steals a ref, so we dup it out of the GValue. */ + cairo_pattern_t *pattern = g_value_dup_boxed (value); + if (!pattern) { + Py_RETURN_NONE; + } + + return PycairoPattern_FromPattern (pattern, NULL); +} + +static PyObject * +cairo_region_to_arg (PyObject *value, + GIInterfaceInfo *interface_info, + GITransfer transfer, + GIArgument *arg) +{ + cairo_region_t *region; + + if (!PyObject_TypeCheck (value, &PycairoRegion_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Region"); + return NULL; + } + + region = ( (PycairoRegion*) value)->region; + if (!region) { + PyErr_SetString (PyExc_ValueError, "Region instance wrapping a NULL region"); + return NULL; + } + + if (transfer != GI_TRANSFER_NOTHING) + region = cairo_region_copy (region); + + arg->v_pointer = region; + Py_RETURN_NONE; +} + +static PyObject * +cairo_region_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) +{ + cairo_region_t *region = (cairo_region_t*) data; + + if (transfer == GI_TRANSFER_NOTHING) + cairo_region_reference (region); + + return PycairoRegion_FromRegion (region); +} + +static PyObject * +cairo_region_release (GIBaseInfo *base_info, + gpointer struct_) +{ + cairo_region_destroy ( (cairo_region_t*) struct_); + Py_RETURN_NONE; +} + +static PyObject * +cairo_matrix_from_arg (GIInterfaceInfo *interface_info, + GITransfer transfer, + gpointer data) +{ + cairo_matrix_t *matrix = (cairo_matrix_t*) data; + + if (transfer != GI_TRANSFER_NOTHING) { + PyErr_SetString(PyExc_TypeError, "Unsupported annotation (transfer full) for cairo.Matrix"); + return NULL; + } + + if (matrix == NULL) { + /* NULL in case of caller-allocates */ + cairo_matrix_t temp = {0}; + return PycairoMatrix_FromMatrix (&temp); + } + + return PycairoMatrix_FromMatrix (matrix); +} + +static PyObject * +cairo_matrix_to_arg (PyObject *value, + GIInterfaceInfo *interface_info, + GITransfer transfer, + GIArgument *arg) +{ + cairo_matrix_t *matrix; + + if (!PyObject_TypeCheck (value, &PycairoMatrix_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Matrix"); + return NULL; + } + + matrix = &(( (PycairoMatrix*) value)->matrix); + + arg->v_pointer = matrix; + Py_RETURN_NONE; +} + +static PyObject * +cairo_matrix_release (GIBaseInfo *base_info, + gpointer struct_) +{ + Py_RETURN_NONE; +} + +static int +cairo_matrix_to_gvalue (GValue *value, PyObject *obj) +{ + cairo_matrix_t *matrix; + + if (!PyObject_TypeCheck (obj, &PycairoMatrix_Type)) { + PyErr_SetString (PyExc_TypeError, "Expected cairo.Matrix"); + return -1; + } + + matrix = &(( (PycairoMatrix*) obj)->matrix); + if (!matrix) { + return -1; + } + + g_value_set_boxed (value, matrix); + return 0; +} + +static PyObject * +cairo_matrix_from_gvalue (const GValue *value) +{ + cairo_matrix_t *matrix = g_value_get_boxed(value); + if (!matrix) { + Py_RETURN_NONE; + } + + return PycairoMatrix_FromMatrix (matrix); +} + +#ifdef __GNUC__ +#define PYGI_MODINIT_FUNC __attribute__((visibility("default"))) PyMODINIT_FUNC #else - import_cairo(); +#define PYGI_MODINIT_FUNC PyMODINIT_FUNC #endif +static PyMethodDef _gi_cairo_functions[] = { {0,} }; + +static struct PyModuleDef __gi_cairomodule = { + PyModuleDef_HEAD_INIT, + "_gi_cairo", + NULL, + -1, + _gi_cairo_functions, + NULL, + NULL, + NULL, + NULL +}; + +PYGI_MODINIT_FUNC PyInit__gi_cairo (void); + +PYGI_MODINIT_FUNC PyInit__gi_cairo (void) +{ + PyObject *module; + module = PyModule_Create (&__gi_cairomodule); + + PyObject *gobject_mod; + + import_cairo(); + if (Pycairo_CAPI == NULL) - return PYGLIB_MODULE_ERROR_RETURN; + return NULL; + + gobject_mod = pygobject_init (3, 13, 2); + if (gobject_mod == NULL) + return NULL; + Py_DECREF (gobject_mod); + + pygi_register_foreign_struct ("cairo", + "Matrix", + cairo_matrix_to_arg, + cairo_matrix_from_arg, + cairo_matrix_release); pygi_register_foreign_struct ("cairo", "Context", @@ -220,5 +674,42 @@ PYGLIB_MODULE_START(_gi_cairo, "_gi_cairo") cairo_font_options_to_arg, cairo_font_options_from_arg, cairo_font_options_release); -} -PYGLIB_MODULE_END; + + pygi_register_foreign_struct ("cairo", + "Pattern", + cairo_pattern_to_arg, + cairo_pattern_from_arg, + cairo_pattern_release); + + pygi_register_foreign_struct ("cairo", + "Region", + cairo_region_to_arg, + cairo_region_from_arg, + cairo_region_release); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_MATRIX, + cairo_matrix_from_gvalue, + cairo_matrix_to_gvalue); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_CONTEXT, + cairo_context_from_gvalue, + cairo_context_to_gvalue); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SURFACE, + cairo_surface_from_gvalue, + cairo_surface_to_gvalue); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_FONT_FACE, + cairo_font_face_from_gvalue, + cairo_font_face_to_gvalue); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_SCALED_FONT, + cairo_scaled_font_from_gvalue, + cairo_scaled_font_to_gvalue); + + pyg_register_gtype_custom (CAIRO_GOBJECT_TYPE_PATTERN, + cairo_pattern_from_gvalue, + cairo_pattern_to_gvalue); + + return module; +}
\ No newline at end of file |