/* -*- mode: C; c-basic-offset: 2 -*-
*
* Copyright © 2003 James Henstridge
* Copyright © 2004-2011 Steven 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 .
*/
#define PY_SSIZE_T_CLEAN
#include
#include "config.h"
#include "private.h"
/* to read CAIRO_PDF_VERSION_* constants */
#ifdef CAIRO_HAS_PDF_SURFACE
# include
#endif
/* to read CAIRO_PS_LEVEL_* constants */
#ifdef CAIRO_HAS_PS_SURFACE
# include
#endif
/* for XCB api */
#if defined(CAIRO_HAS_XCB_SURFACE) && defined(HAVE_XPYB)
xpyb_CAPI_t *xpyb_CAPI;
PyObject *xpybVISUALTYPE_type;
#endif
/* A module specific exception */
PyObject *CairoError = NULL;
int
Pycairo_Check_Status (cairo_status_t status) {
if (PyErr_Occurred() != NULL)
return 1;
switch (status) {
case CAIRO_STATUS_SUCCESS:
return 0;
/* if appropriate - translate the status string into Python,
* else - use cairo_status_to_string()
*/
case CAIRO_STATUS_NO_MEMORY:
PyErr_NoMemory();
break;
case CAIRO_STATUS_READ_ERROR:
case CAIRO_STATUS_WRITE_ERROR:
PyErr_SetString(PyExc_IOError, cairo_status_to_string (status));
break;
case CAIRO_STATUS_INVALID_RESTORE:
PyErr_SetString(CairoError, "Context.restore without matching "
"Context.save");
break;
case CAIRO_STATUS_INVALID_POP_GROUP:
PyErr_SetString(CairoError, "Context.pop_group without matching "
"Context.push_group");
break;
default:
PyErr_SetString(CairoError, cairo_status_to_string (status));
}
return 1;
}
/* C API. Clients get at this via import_cairo(), defined in pycairo.h.
*/
static Pycairo_CAPI_t CAPI = {
&PycairoContext_Type,
PycairoContext_FromContext,
&PycairoFontFace_Type,
&PycairoToyFontFace_Type,
PycairoFontFace_FromFontFace,
&PycairoFontOptions_Type,
PycairoFontOptions_FromFontOptions,
&PycairoMatrix_Type,
PycairoMatrix_FromMatrix,
&PycairoPath_Type,
PycairoPath_FromPath,
&PycairoPattern_Type,
&PycairoSolidPattern_Type,
&PycairoSurfacePattern_Type,
&PycairoGradient_Type,
&PycairoLinearGradient_Type,
&PycairoRadialGradient_Type,
PycairoPattern_FromPattern,
&PycairoScaledFont_Type,
PycairoScaledFont_FromScaledFont,
&PycairoSurface_Type,
#ifdef CAIRO_HAS_IMAGE_SURFACE
&PycairoImageSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
&PycairoPDFSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_PS_SURFACE
&PycairoPSSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_RECORDING_SURFACE
&PycairoRecordingSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
&PycairoSVGSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
&PycairoWin32Surface_Type,
&PycairoWin32PrintingSurface_Type,
#else
0,
0,
#endif
#ifdef CAIRO_HAS_XCB_SURFACE
&PycairoXCBSurface_Type,
#else
0,
#endif
#ifdef CAIRO_HAS_XLIB_SURFACE
&PycairoXlibSurface_Type,
#else
0,
#endif
PycairoSurface_FromSurface,
Pycairo_Check_Status,
};
static PyObject *
pycairo_cairo_version (PyObject *self) {
return PyLong_FromLong (cairo_version());
}
static PyObject *
pycairo_cairo_version_string (PyObject *self) {
return PyUnicode_FromString (cairo_version_string());
}
//static PyMethodDef cairo_functions[] = {
static PyMethodDef cairo_methods[] = {
{"cairo_version", (PyCFunction)pycairo_cairo_version, METH_NOARGS},
{"cairo_version_string", (PyCFunction)pycairo_cairo_version_string,
METH_NOARGS},
{NULL, NULL, 0, NULL},
};
// Module initialization
struct cairo_state {
PyObject *ErrorObject;
};
#define GETSTATE(m) ((struct cairo_state*)PyModule_GetState(m))
static int
cairo_traverse(PyObject *m, visitproc v, void *arg)
{
// Py_VISIT(GETSTATE(m)->ErrorObject);
/* gives error
ImportError: ./_cairo.so: undefined symbol: visit
*/
return 0;
}
static int
cairo_clear(PyObject *m)
{
Py_CLEAR(GETSTATE(m)->ErrorObject);
return 0;
}
static struct PyModuleDef cairomodule = {
PyModuleDef_HEAD_INIT,
"cairo",
NULL,
sizeof(struct cairo_state),
cairo_methods,
0, /* m_reload */
cairo_traverse,
cairo_clear,
0, /* m_free - not needed, since all is done in m_clear */
};
PyObject *
PyInit__cairo(void)
{
if (PyType_Ready(&PycairoContext_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoFontFace_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoToyFontFace_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoFontOptions_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoMatrix_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoPath_Type) < 0)
return NULL;
PycairoPathiter_Type.tp_iter=&PyObject_SelfIter;
if (PyType_Ready(&PycairoPathiter_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoPattern_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoSolidPattern_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoSurfacePattern_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoGradient_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoLinearGradient_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoRadialGradient_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoScaledFont_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoSurface_Type) < 0)
return NULL;
#ifdef CAIRO_HAS_IMAGE_SURFACE
if (PyType_Ready(&PycairoImageSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
if (PyType_Ready(&PycairoPDFSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_PS_SURFACE
if (PyType_Ready(&PycairoPSSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_RECORDING_SURFACE
if (PyType_Ready(&PycairoRecordingSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
if (PyType_Ready(&PycairoSVGSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
if (PyType_Ready(&PycairoWin32Surface_Type) < 0)
return NULL;
if (PyType_Ready(&PycairoWin32PrintingSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_XCB_SURFACE
if (PyType_Ready(&PycairoXCBSurface_Type) < 0)
return NULL;
#endif
#ifdef CAIRO_HAS_XLIB_SURFACE
if (PyType_Ready(&PycairoXlibSurface_Type) < 0)
return NULL;
#endif
PyObject *m = PyModule_Create(&cairomodule);
if (m==NULL)
return NULL;
GETSTATE(m)->ErrorObject = PyErr_NewException("cairo.Error", NULL, NULL);
if (GETSTATE(m)->ErrorObject == NULL) {
Py_DECREF(m);
return NULL;
}
PyModule_AddStringConstant(m, "version", VERSION);
PyModule_AddObject(m, "version_info",
Py_BuildValue("(iii)",
PYCAIRO_VERSION_MAJOR,
PYCAIRO_VERSION_MINOR,
PYCAIRO_VERSION_MICRO
));
Py_INCREF(&PycairoContext_Type);
PyModule_AddObject(m, "Context", (PyObject *)&PycairoContext_Type);
Py_INCREF(&PycairoFontFace_Type);
PyModule_AddObject(m, "FontFace",(PyObject *)&PycairoFontFace_Type);
Py_INCREF(&PycairoToyFontFace_Type);
PyModule_AddObject(m, "ToyFontFace",(PyObject *)&PycairoToyFontFace_Type);
Py_INCREF(&PycairoFontOptions_Type);
PyModule_AddObject(m, "FontOptions",(PyObject *)&PycairoFontOptions_Type);
Py_INCREF(&PycairoMatrix_Type);
PyModule_AddObject(m, "Matrix", (PyObject *)&PycairoMatrix_Type);
Py_INCREF(&PycairoPath_Type);
/* Don't add Path object since it is not accessed directly as 'cairo.Path'
* PyModule_AddObject(m, "Path", (PyObject *)&PycairoPath_Type);
*/
Py_INCREF(&PycairoPattern_Type);
PyModule_AddObject(m, "Pattern", (PyObject *)&PycairoPattern_Type);
Py_INCREF(&PycairoSolidPattern_Type);
PyModule_AddObject(m, "SolidPattern",
(PyObject *)&PycairoSolidPattern_Type);
Py_INCREF(&PycairoSurfacePattern_Type);
PyModule_AddObject(m, "SurfacePattern",
(PyObject *)&PycairoSurfacePattern_Type);
Py_INCREF(&PycairoGradient_Type);
PyModule_AddObject(m, "Gradient", (PyObject *)&PycairoGradient_Type);
Py_INCREF(&PycairoLinearGradient_Type);
PyModule_AddObject(m, "LinearGradient",
(PyObject *)&PycairoLinearGradient_Type);
Py_INCREF(&PycairoRadialGradient_Type);
PyModule_AddObject(m, "RadialGradient",
(PyObject *)&PycairoRadialGradient_Type);
Py_INCREF(&PycairoScaledFont_Type);
PyModule_AddObject(m, "ScaledFont", (PyObject *)&PycairoScaledFont_Type);
Py_INCREF(&PycairoSurface_Type);
PyModule_AddObject(m, "Surface", (PyObject *)&PycairoSurface_Type);
#ifdef CAIRO_HAS_IMAGE_SURFACE
Py_INCREF(&PycairoImageSurface_Type);
PyModule_AddObject(m, "ImageSurface",
(PyObject *)&PycairoImageSurface_Type);
#endif
#ifdef CAIRO_HAS_PDF_SURFACE
Py_INCREF(&PycairoPDFSurface_Type);
PyModule_AddObject(m, "PDFSurface", (PyObject *)&PycairoPDFSurface_Type);
#endif
#ifdef CAIRO_HAS_PS_SURFACE
Py_INCREF(&PycairoPSSurface_Type);
PyModule_AddObject(m, "PSSurface", (PyObject *)&PycairoPSSurface_Type);
#endif
#ifdef CAIRO_HAS_RECORDING_SURFACE
Py_INCREF(&PycairoRecordingSurface_Type);
PyModule_AddObject(m, "RecordingSurface",
(PyObject *)&PycairoRecordingSurface_Type);
#endif
#ifdef CAIRO_HAS_SVG_SURFACE
Py_INCREF(&PycairoSVGSurface_Type);
PyModule_AddObject(m, "SVGSurface", (PyObject *)&PycairoSVGSurface_Type);
#endif
#ifdef CAIRO_HAS_WIN32_SURFACE
Py_INCREF(&PycairoWin32Surface_Type);
PyModule_AddObject(m, "Win32Surface",
(PyObject *)&PycairoWin32Surface_Type);
Py_INCREF(&PycairoWin32PrintingSurface_Type);
PyModule_AddObject(m, "Win32PrintingSurface",
(PyObject *)&PycairoWin32PrintingSurface_Type);
#endif
#ifdef CAIRO_HAS_XCB_SURFACE
Py_INCREF(&PycairoXCBSurface_Type);
PyModule_AddObject(m, "XCBSurface",
(PyObject *)&PycairoXCBSurface_Type);
#endif
#ifdef CAIRO_HAS_XLIB_SURFACE
Py_INCREF(&PycairoXlibSurface_Type);
PyModule_AddObject(m, "XlibSurface",
(PyObject *)&PycairoXlibSurface_Type);
#endif
/* constants */
#if CAIRO_HAS_ATSUI_FONT
PyModule_AddIntConstant(m, "HAS_ATSUI_FONT", 1);
#else
PyModule_AddIntConstant(m, "HAS_ATSUI_FONT", 0);
#endif
#if CAIRO_HAS_FT_FONT
PyModule_AddIntConstant(m, "HAS_FT_FONT", 1);
#else
PyModule_AddIntConstant(m, "HAS_FT_FONT", 0);
#endif
#if CAIRO_HAS_GLITZ_SURFACE
PyModule_AddIntConstant(m, "HAS_GLITZ_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_GLITZ_SURFACE", 0);
#endif
#if CAIRO_HAS_IMAGE_SURFACE
PyModule_AddIntConstant(m, "HAS_IMAGE_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_IMAGE_SURFACE", 0);
#endif
#if CAIRO_HAS_PDF_SURFACE
PyModule_AddIntConstant(m, "HAS_PDF_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_PDF_SURFACE", 0);
#endif
#if CAIRO_HAS_PNG_FUNCTIONS
PyModule_AddIntConstant(m, "HAS_PNG_FUNCTIONS", 1);
#else
PyModule_AddIntConstant(m, "HAS_PNG_FUNCTIONS", 0);
#endif
#if CAIRO_HAS_PS_SURFACE
PyModule_AddIntConstant(m, "HAS_PS_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_PS_SURFACE", 0);
#endif
#if CAIRO_HAS_RECORDING_SURFACE
PyModule_AddIntConstant(m, "HAS_RECORDING_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_RECORDING_SURFACE", 0);
#endif
#if CAIRO_HAS_SVG_SURFACE
PyModule_AddIntConstant(m, "HAS_SVG_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_SVG_SURFACE", 0);
#endif
#if CAIRO_HAS_USER_FONT
PyModule_AddIntConstant(m, "HAS_USER_FONT", 1);
#else
PyModule_AddIntConstant(m, "HAS_USER_FONT", 0);
#endif
#if CAIRO_HAS_QUARTZ_SURFACE
PyModule_AddIntConstant(m, "HAS_QUARTZ_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_QUARTZ_SURFACE", 0);
#endif
#if CAIRO_HAS_WIN32_FONT
PyModule_AddIntConstant(m, "HAS_WIN32_FONT", 1);
#else
PyModule_AddIntConstant(m, "HAS_WIN32_FONT", 0);
#endif
#if CAIRO_HAS_WIN32_SURFACE
PyModule_AddIntConstant(m, "HAS_WIN32_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_WIN32_SURFACE", 0);
#endif
#if CAIRO_HAS_XCB_SURFACE
PyModule_AddIntConstant(m, "HAS_XCB_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_XCB_SURFACE", 0);
#endif
#if CAIRO_HAS_XLIB_SURFACE
PyModule_AddIntConstant(m, "HAS_XLIB_SURFACE", 1);
#else
PyModule_AddIntConstant(m, "HAS_XLIB_SURFACE", 0);
#endif
#define CONSTANT(x) PyModule_AddIntConstant(m, #x, CAIRO_##x)
CONSTANT(ANTIALIAS_DEFAULT);
CONSTANT(ANTIALIAS_NONE);
CONSTANT(ANTIALIAS_GRAY);
CONSTANT(ANTIALIAS_SUBPIXEL);
CONSTANT(CONTENT_COLOR);
CONSTANT(CONTENT_ALPHA);
CONSTANT(CONTENT_COLOR_ALPHA);
CONSTANT(EXTEND_NONE);
CONSTANT(EXTEND_REPEAT);
CONSTANT(EXTEND_REFLECT);
CONSTANT(EXTEND_PAD);
CONSTANT(FILL_RULE_WINDING);
CONSTANT(FILL_RULE_EVEN_ODD);
CONSTANT(FILTER_FAST);
CONSTANT(FILTER_GOOD);
CONSTANT(FILTER_BEST);
CONSTANT(FILTER_NEAREST);
CONSTANT(FILTER_BILINEAR);
CONSTANT(FILTER_GAUSSIAN);
CONSTANT(FONT_WEIGHT_NORMAL);
CONSTANT(FONT_WEIGHT_BOLD);
CONSTANT(FONT_SLANT_NORMAL);
CONSTANT(FONT_SLANT_ITALIC);
CONSTANT(FONT_SLANT_OBLIQUE);
CONSTANT(FORMAT_ARGB32);
CONSTANT(FORMAT_RGB24);
CONSTANT(FORMAT_A8);
CONSTANT(FORMAT_A1);
CONSTANT(FORMAT_RGB16_565);
CONSTANT(HINT_METRICS_DEFAULT);
CONSTANT(HINT_METRICS_OFF);
CONSTANT(HINT_METRICS_ON);
CONSTANT(HINT_STYLE_DEFAULT);
CONSTANT(HINT_STYLE_NONE);
CONSTANT(HINT_STYLE_SLIGHT);
CONSTANT(HINT_STYLE_MEDIUM);
CONSTANT(HINT_STYLE_FULL);
CONSTANT(LINE_CAP_BUTT);
CONSTANT(LINE_CAP_ROUND);
CONSTANT(LINE_CAP_SQUARE);
CONSTANT(LINE_JOIN_MITER);
CONSTANT(LINE_JOIN_ROUND);
CONSTANT(LINE_JOIN_BEVEL);
CONSTANT(OPERATOR_CLEAR);
CONSTANT(OPERATOR_SOURCE);
CONSTANT(OPERATOR_OVER);
CONSTANT(OPERATOR_IN);
CONSTANT(OPERATOR_OUT);
CONSTANT(OPERATOR_ATOP);
CONSTANT(OPERATOR_DEST);
CONSTANT(OPERATOR_DEST_OVER);
CONSTANT(OPERATOR_DEST_IN);
CONSTANT(OPERATOR_DEST_OUT);
CONSTANT(OPERATOR_DEST_ATOP);
CONSTANT(OPERATOR_XOR);
CONSTANT(OPERATOR_ADD);
CONSTANT(OPERATOR_SATURATE);
CONSTANT(OPERATOR_MULTIPLY);
CONSTANT(OPERATOR_SCREEN);
CONSTANT(OPERATOR_OVERLAY);
CONSTANT(OPERATOR_DARKEN);
CONSTANT(OPERATOR_LIGHTEN);
CONSTANT(OPERATOR_COLOR_DODGE);
CONSTANT(OPERATOR_COLOR_BURN);
CONSTANT(OPERATOR_HARD_LIGHT);
CONSTANT(OPERATOR_SOFT_LIGHT);
CONSTANT(OPERATOR_DIFFERENCE);
CONSTANT(OPERATOR_EXCLUSION);
CONSTANT(OPERATOR_HSL_HUE);
CONSTANT(OPERATOR_HSL_SATURATION);
CONSTANT(OPERATOR_HSL_COLOR);
CONSTANT(OPERATOR_HSL_LUMINOSITY);
CONSTANT(PATH_MOVE_TO);
CONSTANT(PATH_LINE_TO);
CONSTANT(PATH_CURVE_TO);
CONSTANT(PATH_CLOSE_PATH);
#ifdef CAIRO_HAS_PDF_SURFACE
CONSTANT(PDF_VERSION_1_4);
CONSTANT(PDF_VERSION_1_5);
#endif
#ifdef CAIRO_HAS_PS_SURFACE
CONSTANT(PS_LEVEL_2);
CONSTANT(PS_LEVEL_3);
#endif
CONSTANT(SUBPIXEL_ORDER_DEFAULT);
CONSTANT(SUBPIXEL_ORDER_RGB);
CONSTANT(SUBPIXEL_ORDER_BGR);
CONSTANT(SUBPIXEL_ORDER_VRGB);
CONSTANT(SUBPIXEL_ORDER_VBGR);
#undef CONSTANT
/* Create a Capsule containing the CAPI pointer */
PyObject *T = PyCapsule_New((void *)(&CAPI), "cairo.CAPI", 0);
if (T != NULL) {
PyModule_AddObject(m, "CAPI", T);
}
return m;
}