[cairo] Re: pycairo: set_pattern currently disabled

Maarten Breddels dmon at xs4all.nl
Fri Nov 12 07:41:31 PST 2004


I had about the same code, plus some extra laying around, so I made a 
diff, the ChangeLog should say it all. Btw, i noticed that there is no 
cairo_surface_current_current_repeat/cairo_surface_current_get_repeat, 
is it for a reason, or is it missing?
I also created a demo to test out the cairo_current_path in python, 
which seems to work fine, image included :)
I hope the diff is ok.

-Maarten Breddels
-------------- next part --------------
? build
? build.bat
? cairoapi.txt
? mychanges
? pycairo-pattern.c
? pycairo.diff
? python-cairo.diff
? setup.py
? examples/demo.py
? examples/gradient.py
? examples/gtk-demo.py
? examples/hoeba.txt
? examples/png-demo.png
? examples/png-demo.py
? examples/ps-demo.ps
? examples/ps-demo.py
? examples/text3d.py
? examples/warpedtext.png
? examples/warpedtext.py
? examples/win32-demo.py
? examples/wxPython-demo.py
Index: ChangeLog
===================================================================
RCS file: /cvs/cairo/pycairo/ChangeLog,v
retrieving revision 1.16
diff -u -r1.16 ChangeLog
--- ChangeLog	11 Nov 2004 15:32:12 -0000	1.16
+++ ChangeLog	12 Nov 2004 14:20:47 -0000
@@ -1,3 +1,23 @@
+2004-11-12  Maarten Breddels <dmon at xs4all.nl>
+
+	* added win32_surface_create, ps_surface_create, png_surface_create
+
+	* added constants, FILTER_GAUSSIAN, EXTEND_NONE, EXTEND_REPEAT, EXTEND_REFLECT
+	And methods to Cairo class:
+		in_stroke, in_fill, stroke_extents, fill_extents, init_clip
+		current_path, current_path_flat, text_path
+	still missing are:
+		show_glyphs
+		current_font_extents
+		glyph_extents
+		glyph_path
+
+	* updated Pattern class with all getters/setters
+	And some minor stuff, so that pycairo_pattern_new should work
+
+	* updated Surface class with all getters/getters
+
+
 2004-11-11  Steve Chaplin  <steve1097 at yahoo.com.au>
 
 	* examples/cairo-demo.py: Move the missing 6th row into view.
@@ -19,7 +39,7 @@
 	* examples/cairo-knockout.py: Bring up-to-date with latest
 	cairo-knockout.c. Now uses cairo_arc rather than custom arc
 	approximation, and now uses new cairo.set_pattern.
-	
+
 	* cairo/pycairo.h: Add declaration for struct PyCairoPattern.
 
 	* cairo/pycairo-context.c (pycairo_set_pattern): Re-enable
@@ -31,7 +51,7 @@
 
 2004-11-02  Carl Worth  <cworth at cworth.org>
 
-	* examples/spiral.py: 	
+	* examples/spiral.py:
 	* examples/hering.py: New examples from Steve Chaplin to
 	demonstrate PNG and PS output.
 
Index: cairo/cairomodule.c
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/cairomodule.c,v
retrieving revision 1.5
diff -u -r1.5 cairomodule.c
--- cairo/cairomodule.c	4 Nov 2004 14:45:35 -0000	1.5
+++ cairo/cairomodule.c	12 Nov 2004 13:58:32 -0000
@@ -37,7 +37,7 @@
 }
 
 static PyObject *
-pycairo_surface_create_for_image(PyObject *self, PyObject *args)
+pycairo_image_surface_create_for_data(PyObject *self, PyObject *args)
 {
     char *data;
     cairo_format_t format;
@@ -77,7 +77,7 @@
 	return NULL;
     }
 
-    surface = cairo_surface_create_for_image(data, format,
+    surface = cairo_image_surface_create_for_data(data, format,
 					     width, height, stride);
     if (!surface)
 	return PyErr_NoMemory();
@@ -86,10 +86,119 @@
     return pycairo_surface_new(surface);
 }
 
+
+#ifdef CAIRO_HAS_WIN32_SURFACE
+static PyObject *
+pycairo_win32_surface_create(PyObject *self, PyObject *args)
+{
+    char* title;
+    int width, height;
+    cairo_surface_t *surface;
+
+    if (!PyArg_ParseTuple(args, "sii|i:win32_surface_create",
+			  &title, &width, &height))
+	return NULL;
+
+    if (width <= 0) {
+	PyErr_SetString(PyExc_ValueError, "width must be positive");
+	return NULL;
+    }
+    if (height <= 0) {
+	PyErr_SetString(PyExc_ValueError, "height must be positive");
+	return NULL;
+    }
+
+    surface = cairo_win32_surface_create(title, width, height);
+    if (!surface)
+	return PyErr_NoMemory();
+
+    return pycairo_surface_new(surface);
+}
+#endif
+
+#ifdef CAIRO_HAS_PS_SURFACE
+static PyObject *
+pycairo_ps_surface_create(PyObject *self, PyObject *args)
+{
+	PyObject *file_object;
+    int width_inches, height_inches, x_pixels_per_inch, y_pixels_per_inch;
+    cairo_surface_t *surface;
+
+    if (!PyArg_ParseTuple(args, "O!iii|i:ps_surface_create",
+			  &PyFile_Type, &file_object, &width_inches, &height_inches, &x_pixels_per_inch, &y_pixels_per_inch))
+	return NULL;
+    if (width_inches <= 0) {
+	PyErr_SetString(PyExc_ValueError, "width_inches must be positive");
+	return NULL;
+    }
+    if (height_inches <= 0) {
+	PyErr_SetString(PyExc_ValueError, "height_inches must be positive");
+	return NULL;
+    }
+    if (x_pixels_per_inch <= 0) {
+	PyErr_SetString(PyExc_ValueError, "x_pixels_per_inch must be positive");
+	return NULL;
+    }
+    if (y_pixels_per_inch <= 0) {
+	PyErr_SetString(PyExc_ValueError, "y_pixels_per_inch must be positive");
+	return NULL;
+	}
+    surface = cairo_ps_surface_create(PyFile_AsFile(file_object), width_inches, height_inches, x_pixels_per_inch, y_pixels_per_inch);
+    if (!surface)
+	return PyErr_NoMemory();
+
+    return pycairo_surface_new(surface);
+}
+#endif
+
+#ifdef CAIRO_HAS_PNG_SURFACE
+static PyObject *
+pycairo_png_surface_create(PyObject *self, PyObject *args)
+{
+	PyObject *file_object;
+    cairo_format_t format;
+    int width, height;
+    cairo_surface_t *surface;
+
+    if (!PyArg_ParseTuple(args, "O!iii:png_surface_create",
+			  &PyFile_Type, &file_object, &format, &width, &height))
+	return NULL;
+
+    if (width <= 0) {
+	PyErr_SetString(PyExc_ValueError, "width must be positive");
+	return NULL;
+    }
+    if (height <= 0) {
+	PyErr_SetString(PyExc_ValueError, "height must be positive");
+	return NULL;
+    }
+
+    surface = cairo_png_surface_create(PyFile_AsFile(file_object), format, width, height);
+    if (!surface)
+	return PyErr_NoMemory();
+
+    return pycairo_surface_new(surface);
+}
+#endif
+
 static PyMethodDef cairo_functions[] = {
-    { "surface_create_for_image",
-      (PyCFunction)pycairo_surface_create_for_image, METH_VARARGS },
-    { NULL, NULL, 0 }
+	/* this is the old function name, should use image_surface_create_for_data */
+    { "surface_create_for_image", (PyCFunction)pycairo_image_surface_create_for_data, METH_VARARGS, "this is the old function name, should use image_surface_create_for_data" },
+    { "image_surface_create_for_data", (PyCFunction)pycairo_image_surface_create_for_data, METH_VARARGS, "" },
+
+    #ifdef CAIRO_HAS_WIN32_SURFACE
+    { "win32_surface_create", (PyCFunction)pycairo_win32_surface_create, METH_VARARGS, "" },
+    #endif
+
+    #ifdef CAIRO_HAS_PS_SURFACE
+    { "ps_surface_create", (PyCFunction)pycairo_ps_surface_create, METH_VARARGS, "" },
+    #endif
+
+    #ifdef CAIRO_HAS_PNG_SURFACE
+    { "png_surface_create", (PyCFunction)pycairo_png_surface_create, METH_VARARGS, "" },
+    #endif
+
+    { NULL, NULL, 0, 0 }
 };
 
 static struct _PyCairo_FunctionStruct api = {
@@ -102,6 +211,8 @@
     pycairo_font_new,
     &PyCairoContext_Type,
     pycairo_context_new,
+    &PyCairoPattern_Type,
+    pycairo_pattern_new,
 };
 
 DL_EXPORT(void)
@@ -122,6 +233,7 @@
     INIT_TYPE(PyCairoFont_Type);
     INIT_TYPE(PyCairoContext_Type);
 
+
 #undef INIT_TYPE
 
     mod = Py_InitModule("cairo._cairo", cairo_functions);
@@ -173,6 +285,7 @@
     CONSTANT(FILTER_BEST);
     CONSTANT(FILTER_NEAREST);
     CONSTANT(FILTER_BILINEAR);
+    CONSTANT(FILTER_GAUSSIAN);
 
     CONSTANT(FONT_WEIGHT_NORMAL);
     CONSTANT(FONT_WEIGHT_BOLD);
@@ -180,6 +293,10 @@
     CONSTANT(FONT_SLANT_NORMAL);
     CONSTANT(FONT_SLANT_ITALIC);
     CONSTANT(FONT_SLANT_OBLIQUE);
+
+    CONSTANT(EXTEND_NONE);
+    CONSTANT(EXTEND_REPEAT);
+    CONSTANT(EXTEND_REFLECT);
 #undef CONSTANT
 
 }
Index: cairo/pycairo-context.c
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo-context.c,v
retrieving revision 1.7
diff -u -r1.7 pycairo-context.c
--- cairo/pycairo-context.c	4 Nov 2004 14:45:35 -0000	1.7
+++ cairo/pycairo-context.c	12 Nov 2004 13:55:04 -0000
@@ -111,6 +111,7 @@
 cairo_set_target_image();
 #endif
 
+#ifdef CAIRO_HAS_PS_SURFACE
 static PyObject *
 pycairo_set_target_ps(PyCairoContext *self, PyObject *args)
 {
@@ -120,12 +121,12 @@
 
     if (!PyArg_ParseTuple(args, "O!dddd:Context.set_target_ps",
 			  &PyFile_Type, &file_object,
-			  &width_inches, &height_inches, 
+			  &width_inches, &height_inches,
 			  &x_pixels_per_inch, &y_pixels_per_inch))
 	return NULL;
 
     cairo_set_target_ps(self->ctx, PyFile_AsFile(file_object),
-			width_inches, height_inches, 
+			width_inches, height_inches,
 			x_pixels_per_inch, y_pixels_per_inch);
     if (pycairo_check_status(cairo_status(self->ctx)))
 	return NULL;
@@ -133,7 +134,9 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
+#endif
 
+#ifdef CAIRO_HAS_PNG_SURFACE
 static PyObject *
 pycairo_set_target_png(PyCairoContext *self, PyObject *args)
 {
@@ -141,12 +144,12 @@
     cairo_format_t format;
     int width, height;
 
-    if (!PyArg_ParseTuple(args, "O!iii:Context.set_target_png", 
-			  &PyFile_Type, &file_object, &format, &width, 
+    if (!PyArg_ParseTuple(args, "O!iii:Context.set_target_png",
+			  &PyFile_Type, &file_object, &format, &width,
 			  &height))
 	return NULL;
 
-    cairo_set_target_png(self->ctx, PyFile_AsFile(file_object), format, 
+    cairo_set_target_png(self->ctx, PyFile_AsFile(file_object), format,
 			 width, height);
     if (pycairo_check_status(cairo_status(self->ctx)))
 	return NULL;
@@ -154,6 +157,7 @@
     Py_INCREF(Py_None);
     return Py_None;
 }
+#endif
 
 static PyObject *
 pycairo_set_operator(PyCairoContext *self, PyObject *args)
@@ -823,20 +827,259 @@
     return Py_None;
 }
 
+static PyObject *
+pycairo_in_stroke(PyCairoContext *self, PyObject *args)
+{
+    double x, y;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "dd:Context.in_stroke", &x, &y))
+	return NULL;
+
+    result = cairo_in_stroke(self->ctx, x, y);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+	if(result)
+	{
+	    Py_INCREF(Py_True);
+	    return Py_True;
+	}
+	else
+	{
+	    Py_INCREF(Py_False);
+	    return Py_False;
+	}
+}
+
+static PyObject *
+pycairo_in_fill(PyCairoContext *self, PyObject *args)
+{
+    double x, y;
+    int result;
+
+    if (!PyArg_ParseTuple(args, "dd:Context.in_fill", &x, &y))
+	return NULL;
+
+    result = cairo_in_fill(self->ctx, x, y);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+	if(result)
+	{
+	    Py_INCREF(Py_True);
+	    return Py_True;
+	}
+	else
+	{
+	    Py_INCREF(Py_False);
+	    return Py_False;
+	}
+}
+
+static PyObject *
+pycairo_stroke_extents(PyCairoContext *self, PyObject *args)
+{
+	double x1, y1, x2, y2;
+	cairo_stroke_extents(self->ctx, &x1, &y1, &x2, &y2);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+	return Py_BuildValue("(dddd)", x1, y1, x2, y2);
+}
+
+static PyObject *
+pycairo_fill_extents(PyCairoContext *self, PyObject *args)
+{
+	double x1, y1, x2, y2;
+	cairo_fill_extents(self->ctx, &x1, &y1, &x2, &y2);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+	return Py_BuildValue("(dddd)", x1, y1, x2, y2);
+}
+
+static PyObject *
+pycairo_init_clip(PyCairoContext *self, PyObject *args)
+{
+	cairo_init_clip(self->ctx);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+typedef struct {
+	PyObject* move_to;
+	PyObject* line_to;
+	PyObject* curve_to;
+	PyObject* close_path;
+} py_path_callbacks;
+
+void py_wrapper_move_to(py_path_callbacks *callbacks, double x, double y)
+{
+	PyObject *arglist;
+    PyObject *result;
+    if(!PyErr_Occurred())
+    {
+		arglist = Py_BuildValue("(dd)", x, y);
+		result = PyEval_CallObject(callbacks->move_to, arglist);
+	    Py_DECREF(arglist);
+		if(result != NULL)
+			Py_DECREF(result);
+	}
+}
+
+void py_wrapper_line_to(py_path_callbacks *callbacks, double x, double y)
+{
+	PyObject *arglist;
+    PyObject *result;
+    if(!PyErr_Occurred())
+    {
+		arglist = Py_BuildValue("(dd)", x, y);
+		result = PyEval_CallObject(callbacks->line_to, arglist);
+	    Py_DECREF(arglist);
+		if(result != NULL)
+			Py_DECREF(result);
+	}
+}
+
+void py_wrapper_curve_to(py_path_callbacks *callbacks, double x1, double y1, double x2, double y2, double x3, double y3)
+{
+	PyObject *arglist;
+    PyObject *result;
+    if(!PyErr_Occurred())
+    {
+		arglist = Py_BuildValue("(dddddd)", x1, y1, x2, y2, x3, y3);
+		result = PyEval_CallObject(callbacks->curve_to, arglist);
+	    Py_DECREF(arglist);
+		if(result != NULL)
+			Py_DECREF(result);
+	}
+}
+
+void py_wrapper_close_path(py_path_callbacks *callbacks)
+{
+    PyObject *arglist;
+    PyObject *result;
+    if(!PyErr_Occurred())
+    {
+    	arglist = Py_BuildValue("()");
+		result = PyEval_CallObject(callbacks->close_path, arglist);
+	    Py_DECREF(arglist);
+		if(result != NULL)
+			Py_DECREF(result);
+	}
+}
+
+
+static PyObject *
+pycairo_current_path(PyCairoContext *self, PyObject *args)
+{
+    py_path_callbacks callbacks;
+
+    if(!PyArg_ParseTuple(args, "OOOO:Context.current_path_flat",
+			  &callbacks.move_to, &callbacks.line_to, &callbacks.curve_to, &callbacks.close_path))
+	return NULL;
+
+	if(!PyCallable_Check(callbacks.move_to))
+	{
+		PyErr_SetString(PyExc_TypeError, "move_to must be callable");
+		return NULL;
+	}
+
+	if(!PyCallable_Check(callbacks.line_to))
+	{
+		PyErr_SetString(PyExc_TypeError, "line_to must be callable");
+		return NULL;
+	}
+
+	if(!PyCallable_Check(callbacks.curve_to))
+	{
+		PyErr_SetString(PyExc_TypeError, "curve_to must be callable");
+		return NULL;
+	}
+
+	if(!PyCallable_Check(callbacks.close_path))
+	{
+		PyErr_SetString(PyExc_TypeError, "close_path must be callable");
+		return NULL;
+	}
+
+	cairo_current_path(self->ctx, py_wrapper_move_to, py_wrapper_line_to, py_wrapper_curve_to, py_wrapper_close_path, &callbacks);
+	if(PyErr_Occurred())
+		return NULL;
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pycairo_current_path_flat(PyCairoContext *self, PyObject *args)
+{
+    py_path_callbacks callbacks;
+
+    if(!PyArg_ParseTuple(args, "OOO:Context.current_path_flat",
+			  &callbacks.move_to, &callbacks.line_to, &callbacks.close_path))
+	return NULL;
+
+	if(!PyCallable_Check(callbacks.move_to))
+	{
+		PyErr_SetString(PyExc_TypeError, "move_to must be callable");
+		return NULL;
+	}
+
+	if(!PyCallable_Check(callbacks.line_to))
+	{
+		PyErr_SetString(PyExc_TypeError, "line_to must be callable");
+		return NULL;
+	}
+
+	if(!PyCallable_Check(callbacks.close_path))
+	{
+		PyErr_SetString(PyExc_TypeError, "close_path must be callable");
+		return NULL;
+	}
+
+	cairo_current_path_flat(self->ctx, py_wrapper_move_to, py_wrapper_line_to, py_wrapper_close_path, &callbacks);
+	if(PyErr_Occurred())
+		return NULL;
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pycairo_text_path(PyCairoContext *self, PyObject *args)
+{
+    const unsigned char *utf8;
+
+    if (!PyArg_ParseTuple(args, "s:Context.text_path", &utf8))
+	return NULL;
+
+    cairo_text_path(self->ctx, utf8);
+    if (pycairo_check_status(cairo_status(self->ctx)))
+	return NULL;
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
 static PyMethodDef pycairo_methods[] = {
     { "copy", (PyCFunction)pycairo_copy, METH_VARARGS },
     { "save", (PyCFunction)pycairo_save, METH_NOARGS },
     { "restore", (PyCFunction)pycairo_restore, METH_NOARGS },
     { "set_target_surface", (PyCFunction)pycairo_set_target_surface,
       METH_VARARGS },
+#ifdef CAIRO_HAS_PS_SURFACE
     { "set_target_ps", (PyCFunction)pycairo_set_target_ps,
       METH_VARARGS},
+#endif
+#ifdef CAIRO_HAS_PNG_SURFACE
     { "set_target_png", (PyCFunction)pycairo_set_target_png,
+#endif
       METH_VARARGS },
     { "set_operator", (PyCFunction)pycairo_set_operator, METH_VARARGS },
     { "set_rgb_color", (PyCFunction)pycairo_set_rgb_color, METH_VARARGS },
-    { "set_alpha", (PyCFunction)pycairo_set_alpha, METH_VARARGS },
     { "set_pattern", (PyCFunction)pycairo_set_pattern, METH_VARARGS },
+    { "set_alpha", (PyCFunction)pycairo_set_alpha, METH_VARARGS },
     { "set_tolerance", (PyCFunction)pycairo_set_tolerance, METH_VARARGS },
     { "set_fill_rule", (PyCFunction)pycairo_set_fill_rule, METH_VARARGS },
     { "set_line_width", (PyCFunction)pycairo_set_line_width, METH_VARARGS },
@@ -873,14 +1116,26 @@
     { "fill", (PyCFunction)pycairo_fill, METH_NOARGS },
     { "copy_page", (PyCFunction)pycairo_copy_page, METH_NOARGS },
     { "show_page", (PyCFunction)pycairo_show_page, METH_NOARGS },
+    { "in_stroke", (PyCFunction)pycairo_in_stroke, METH_NOARGS },
+    { "in_fill", (PyCFunction)pycairo_in_fill, METH_NOARGS },
+    { "stroke_extents", (PyCFunction)pycairo_stroke_extents, METH_NOARGS },
+    { "fill_extents", (PyCFunction)pycairo_fill_extents, METH_NOARGS },
+    { "init_clip", (PyCFunction)pycairo_init_clip, METH_NOARGS },
     { "clip", (PyCFunction)pycairo_clip, METH_NOARGS },
     { "select_font", (PyCFunction)pycairo_select_font, METH_VARARGS },
     { "scale_font", (PyCFunction)pycairo_scale_font, METH_VARARGS },
     { "transform_font", (PyCFunction)pycairo_transform_font, METH_VARARGS },
     { "show_text", (PyCFunction)pycairo_show_text, METH_VARARGS },
+    /* TODO: { "show_glyphs", (PyCFunction)pycairo_show_glyphs, METH_NOARGS }, */
+    /* TODO: { "current_font_extents", (PyCFunction)pycairo_current_font_extents, METH_NOARGS }, */
     { "set_font", (PyCFunction)pycairo_set_font, METH_VARARGS },
     { "text_extents", (PyCFunction)pycairo_text_extents, METH_VARARGS },
+    /* TODO: { "glyph_extents", (PyCFunction)pycairo_glyph_extents, METH_NOARGS }, */
+    { "text_path", (PyCFunction)pycairo_text_path, METH_VARARGS },
+    /* TODO: { "glyph_path", (PyCFunction)pycairo_glyph_path, METH_VARARGS }, */
     { "show_surface", (PyCFunction)pycairo_show_surface, METH_VARARGS },
+    { "current_path", (PyCFunction)pycairo_current_path, METH_VARARGS },
+    { "current_path_flat", (PyCFunction)pycairo_current_path_flat, METH_VARARGS },
     { NULL, NULL, 0 }
 };
 
@@ -914,6 +1169,20 @@
 }
 
 static PyObject *
+pycairo_current_pattern(PyCairoContext *self)
+{
+    cairo_pattern_t *pattern;
+
+    pattern = cairo_current_pattern(self->ctx);
+    if (!pattern) {
+	Py_INCREF(Py_None);
+	return Py_None;
+    }
+    cairo_pattern_reference(pattern);
+    return pycairo_pattern_new(pattern);
+}
+
+static PyObject *
 pycairo_current_alpha(PyCairoContext *self)
 {
     return PyFloat_FromDouble(cairo_current_alpha(self->ctx));
@@ -994,6 +1263,7 @@
     { "font", (getter)pycairo_current_font, (setter)0 },
     { "operator", (getter)pycairo_current_operator, (setter)0 },
     { "rgb_color", (getter)pycairo_current_rgb_color, (setter)0 },
+    { "pattern", (getter)pycairo_current_pattern, (setter)0 },
     { "alpha", (getter)pycairo_current_alpha, (setter)0 },
     { "tolerance", (getter)pycairo_current_tolerance, (setter)0 },
     { "point", (getter)pycairo_current_point, (setter)0 },
Index: cairo/pycairo-pattern.c
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo-pattern.c,v
retrieving revision 1.1
diff -u -r1.1 pycairo-pattern.c
--- cairo/pycairo-pattern.c	4 Nov 2004 14:45:35 -0000	1.1
+++ cairo/pycairo-pattern.c	12 Nov 2004 13:45:14 -0000
@@ -6,22 +6,25 @@
 #include "pycairo-private.h"
 
 PyObject *
-pycairo_pattern_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+pycairo_pattern_new(cairo_pattern_t *pattern)
 {
     PyCairoPattern *self;
 
-    self = (PyCairoPattern *)type->tp_alloc(type, 0);
-
-    if (self != NULL) {
-      self->pattern = NULL;
+    self = PyObject_New(PyCairoPattern, &PyCairoPattern_Type);
+    if (!self) {
+	cairo_pattern_destroy(pattern);
+	return NULL;
     }
+
+    self->pattern = pattern;
+
     return (PyObject *)self;
 }
 
 static int
 pycairo_pattern_init(PyCairoPattern *self, PyObject *args, PyObject *kwargs)
 {
-    static char *kwlist[] = { "x0", "y0", "x1", "y1", 
+    static char *kwlist[] = { "x0", "y0", "x1", "y1",
 			      "cx0", "cy0", "radius0", "cx1", "cy1", "radius1",
 			      "surface",
 			      NULL };
@@ -79,41 +82,109 @@
 	PyObject_Del(self);
 }
 
-
-/* Pattern methods */
 static PyObject *
 pycairo_pattern_add_color_stop(PyCairoPattern *self, PyObject *args)
 {
     double offset, red, green, blue, alpha;
-    cairo_status_t status;
 
-    if (!PyArg_ParseTuple(args, "ddddd:Pattern.add_color_stop",    
-			  &offset, &red, &green, &blue, &alpha))
+    if (!PyArg_ParseTuple(args, "ddddd:Pattern.add_color_stop",
+    			&offset, &red, &green, &blue, &alpha))
+	return NULL;
+
+    cairo_pattern_add_color_stop(self->pattern, offset, red, green, blue, alpha);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pycairo_pattern_set_matrix(PyCairoPattern *self, PyObject *args)
+{
+    PyCairoMatrix *matrix;
+
+    if (!PyArg_ParseTuple(args, "O!:Pattern.set_matrix",
+			  &PyCairoMatrix_Type, &matrix))
 	return NULL;
 
-    status = cairo_pattern_add_color_stop (self->pattern, offset, red, green, 
-					   blue, alpha);
-    if (pycairo_check_status(status))
+    cairo_pattern_set_matrix(self->pattern, matrix->matrix);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+pycairo_pattern_set_extend(PyCairoPattern *self, PyObject *args)
+{
+    int extend;
+
+    if (!PyArg_ParseTuple(args, "i:Pattern.set_extend", &extend))
 	return NULL;
 
+    cairo_pattern_set_extend(self->pattern, extend);
     Py_INCREF(Py_None);
     return Py_None;
 }
 
+static PyObject *
+pycairo_pattern_set_filter(PyCairoPattern *self, PyObject *args)
+{
+    int filter;
+
+    if (!PyArg_ParseTuple(args, "i:Pattern.set_filter", &filter))
+	return NULL;
+
+    cairo_pattern_set_filter(self->pattern, filter);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
 
 static PyMethodDef pycairo_pattern_methods[] = {
-    { "add_color_stop", (PyCFunction)pycairo_pattern_add_color_stop,
-      METH_VARARGS },
+    { "add_color_stop", (PyCFunction)pycairo_pattern_add_color_stop, METH_VARARGS },
+    { "set_matrix", (PyCFunction)pycairo_pattern_set_matrix, METH_VARARGS },
+    { "set_extend", (PyCFunction)pycairo_pattern_set_extend, METH_VARARGS },
+    { "set_filter", (PyCFunction)pycairo_pattern_set_filter, METH_VARARGS },
     { NULL, NULL, 0 }
 };
 
+static PyObject *
+pycairo_pattern_get_matrix(PyCairoPattern *self)
+{
+    cairo_matrix_t *matrix;
+
+    matrix = cairo_matrix_create();
+    if (!matrix)
+	return PyErr_NoMemory();
+    cairo_pattern_get_matrix(self->pattern, matrix);
+    return pycairo_matrix_new(matrix);
+}
+
+static PyObject *
+pycairo_pattern_get_extend(PyCairoPattern *self)
+{
+    return PyInt_FromLong(cairo_pattern_get_extend(self->pattern));
+}
+
+static PyObject *
+pycairo_pattern_get_filter(PyCairoPattern *self)
+{
+    return PyInt_FromLong(cairo_pattern_get_filter(self->pattern));
+}
+
+
+static PyGetSetDef pycairo_pattern_getsets[] = {
+    { "matrix", (getter)pycairo_pattern_get_matrix, (setter)0 },
+    { "extend", (getter)pycairo_pattern_get_extend, (setter)0 },
+    { "filter", (getter)pycairo_pattern_get_filter, (setter)0 },
+    { NULL, (getter)0, (setter)0 }
+};
+
+
 PyTypeObject PyCairoPattern_Type = {
     PyObject_HEAD_INIT(NULL)
     0,                                  /* ob_size */
-    "cairo.Pattern",                    /* tp_name */
-    sizeof(PyCairoPattern),             /* tp_basicsize */
+    "cairo.Pattern",                       /* tp_name */
+    sizeof(PyCairoPattern),                /* tp_basicsize */
     0,                                  /* tp_itemsize */
-    (destructor)pycairo_pattern_dealloc, /* tp_dealloc */
+    /* methods */
+    (destructor)pycairo_pattern_dealloc,   /* tp_dealloc */
     (printfunc)0,                       /* tp_print */
     (getattrfunc)0,                     /* tp_getattr */
     (setattrfunc)0,                     /* tp_setattr */
@@ -128,17 +199,17 @@
     (getattrofunc)0,                    /* tp_getattro */
     (setattrofunc)0,                    /* tp_setattro */
     0,                                  /* tp_as_buffer */
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-    "Pattern objects",                  /* tp_doc */
+    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
+    NULL, /* Documentation string */
     (traverseproc)0,                    /* tp_traverse */
     (inquiry)0,                         /* tp_clear */
     (richcmpfunc)0,                     /* tp_richcompare */
     0,                                  /* tp_weaklistoffset */
     (getiterfunc)0,                     /* tp_iter */
     (iternextfunc)0,                    /* tp_iternext */
-    pycairo_pattern_methods,            /* tp_methods */
+    pycairo_pattern_methods,               /* tp_methods */
     0,                                  /* tp_members */
-    0,                                  /* tp_getset */
+    pycairo_pattern_getsets,               /* tp_getset */
     (PyTypeObject *)0,                  /* tp_base */
     (PyObject *)0,                      /* tp_dict */
     0,                                  /* tp_descr_get */
@@ -146,7 +217,7 @@
     0,                                  /* tp_dictoffset */
     (initproc)pycairo_pattern_init,     /* tp_init */
     (allocfunc)0,                       /* tp_alloc */
-    pycairo_pattern_new,                /* tp_new */
+    (newfunc)0,                         /* tp_new */
     0,                                  /* tp_free */
     (inquiry)0,                         /* tp_is_gc */
     (PyObject *)0,                      /* tp_bases */
Index: cairo/pycairo-private.h
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo-private.h,v
retrieving revision 1.3
diff -u -r1.3 pycairo-private.h
--- cairo/pycairo-private.h	4 Nov 2004 14:45:35 -0000	1.3
+++ cairo/pycairo-private.h	12 Nov 2004 14:13:41 -0000
@@ -21,8 +21,7 @@
 PyObject *pycairo_matrix_new(cairo_matrix_t *matrix);
 PyObject *pycairo_context_new(cairo_t *ctx);
 PyObject *pycairo_surface_new(cairo_surface_t *surface);
-/*PyObject *pycairo_pattern_new(cairo_pattern_t *pattern); */
-PyObject *pycairo_pattern_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
+PyObject *pycairo_pattern_new(cairo_pattern_t *pattern);
 PyObject *pycairo_font_new(cairo_font_t *font);
 
 #endif
Index: cairo/pycairo-surface.c
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo-surface.c,v
retrieving revision 1.3
diff -u -r1.3 pycairo-surface.c
--- cairo/pycairo-surface.c	14 Nov 2003 15:32:10 -0000	1.3
+++ cairo/pycairo-surface.c	12 Nov 2004 13:52:26 -0000
@@ -80,18 +80,6 @@
 }
 
 static PyObject *
-pycairo_surface_get_matrix(PyCairoSurface *self)
-{
-    cairo_matrix_t *matrix;
-
-    matrix = cairo_matrix_create();
-    if (!matrix)
-	return PyErr_NoMemory();
-    cairo_surface_get_matrix(self->surface, matrix);
-    return pycairo_matrix_new(matrix);
-}
-
-static PyObject *
 pycairo_surface_set_filter(PyCairoSurface *self, PyObject *args)
 {
     cairo_filter_t filter;
@@ -109,11 +97,35 @@
       METH_VARARGS },
     { "set_repeat", (PyCFunction)pycairo_surface_set_repeat, METH_VARARGS },
     { "set_matrix", (PyCFunction)pycairo_surface_set_matrix, METH_VARARGS },
-    { "get_matrix", (PyCFunction)pycairo_surface_get_matrix, METH_VARARGS },
     { "set_filter", (PyCFunction)pycairo_surface_set_filter, METH_VARARGS },
     { NULL, NULL, 0 }
 };
 
+static PyObject *
+pycairo_surface_get_matrix(PyCairoSurface *self)
+{
+    cairo_matrix_t *matrix;
+
+    matrix = cairo_matrix_create();
+    if (!matrix)
+	return PyErr_NoMemory();
+    cairo_surface_get_matrix(self->surface, matrix);
+    return pycairo_matrix_new(matrix);
+}
+
+static PyObject *
+pycairo_surface_get_filter(PyCairoSurface *self)
+{
+    return PyInt_FromLong(cairo_surface_get_filter(self->surface));
+}
+
+static PyGetSetDef pycairo_surface_getsets[] = {
+	/* for some reason, there is no cairo_surface_get_repeat */
+    { "matrix", (getter)pycairo_surface_get_matrix, (setter)0 },
+    { "filter", (PyCFunction)pycairo_surface_get_filter, (setter)0 },
+    { NULL, (getter)0, (setter)0 }
+};
+
 PyTypeObject PyCairoSurface_Type = {
     PyObject_HEAD_INIT(NULL)
     0,                                  /* ob_size */
@@ -146,7 +158,7 @@
     (iternextfunc)0,                    /* tp_iternext */
     pycairo_surface_methods,            /* tp_methods */
     0,                                  /* tp_members */
-    0,                                  /* tp_getset */
+    pycairo_surface_getsets,            /* tp_getset */
     (PyTypeObject *)0,                  /* tp_base */
     (PyObject *)0,                      /* tp_dict */
     0,                                  /* tp_descr_get */
Index: cairo/pycairo.h
===================================================================
RCS file: /cvs/cairo/pycairo/cairo/pycairo.h,v
retrieving revision 1.4
diff -u -r1.4 pycairo.h
--- cairo/pycairo.h	4 Nov 2004 14:45:35 -0000	1.4
+++ cairo/pycairo.h	12 Nov 2004 15:39:22 -0000
@@ -41,6 +41,8 @@
     PyObject *(* font_new)(cairo_font_t *font);
     PyTypeObject *context_type;
     PyObject *(* context_new)(cairo_t *ctx);
+    PyTypeObject *pattern_type;
+    PyObject *(* pattern_new)(cairo_pattern_t *ctx);
 };
 
 #ifndef _INSIDE_PYCAIRO_
@@ -60,6 +62,8 @@
 #define pycairo_font_new  (_PyCairo_API->font_new)
 #define PyCairoContext_Type *(_PyCairo_API->context_type)
 #define pycairo_context_new  (_PyCairo_API->context_new)
+#define PyCairoPattern_Type *(_PyCairo_API->pattern_type)
+#define pycairo_pattern_new  (_PyCairo_API->pattern_new)
 
 #define init_pycairo() { \
     PyObject *pycairo = PyImport_ImportModule("cairo._cairo"); \
-------------- next part --------------
A non-text attachment was scrubbed...
Name: warpedtext.png
Type: image/png
Size: 41794 bytes
Desc: not available
Url : http://lists.freedesktop.org/archives/cairo/attachments/20041112/a441542c/warpedtext.png
-------------- next part --------------
import cairo
import math

class PathWarp(object):
	def __init__(self, function, ctx):
		self.function = function
		self.ctx = ctx

	def lineto(self, x, y):
		x, y = self.function(x, y)
		self.ctx.line_to(x, y)

	def moveto(self, x, y):
		if self.first:
			self.ctx.new_path()
			self.first = False
		x, y = self.function(x, y)
		self.ctx.move_to(x, y)

	def curveto(self, x1, y1, x2, y2, x3, y3):
		x1, y1 = self.function(x1, y1)
		x2, y2 = self.function(x2, y2)
		x3, y3 = self.function(x3, y3)
		self.ctx.curve_to(x1, y1, x2, y2, x3, y3)

	def closepath(self):
		self.ctx.close_path()

	def warpPath(self):
		self.first = True
		self.ctx.current_path(self.moveto, self.lineto, self.curveto, self.closepath)


WIDTH, HEIGHT = 512, 512
file = open("warpedtext.png", "wb")

ctx = cairo.Context()
ctx.set_target_png(file, cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
ctx.identity_matrix()

solidpattern = ctx.pattern

# background
pat = cairo.Pattern(x0=0.0, y0=0.0, x1=0, y1=HEIGHT)
pat.add_color_stop (1, 0, 0, 0, 1)
pat.add_color_stop (0, 1, 1, 1, 1)

ctx.rectangle (0,0,WIDTH,HEIGHT)
ctx.set_pattern (pat)
ctx.fill ()

# foreground
ctx.set_pattern (solidpattern)
ctx.set_rgb_color(1,1,1)

# spiral text
ctx.scale_font(80)
ctx.move_to(0, 0)
ctx.text_path("pycairo - " + "spam " * 5)
def spiral(x, y):
theta0 = -math.pi * 3 / 4
	theta = x / WIDTH * math.pi * 2 + theta0
	radius = y + 200 - x/7
	xnew = radius*math.cos(theta)
	ynew = radius*math.sin(-theta)
	return xnew + WIDTH/2, ynew + HEIGHT/2
warp = PathWarp(spiral, ctx)
warp.warpPath()
ctx.fill()
ctx.new_path()

# curly text
ctx.move_to(0, 0)
ctx.set_rgb_color(0.3, 0.3, 0.3)
text = "I am curly :)"
ctx.text_path(text)
textwidth, textheight = ctx.text_extents(text)[2:4]
def curl(x, y):
	xn = x - textwidth/2
	yn = y - textheight/2
	xnew = xn
	ynew = y +	xn ** 3 / ((textwidth/2)**3) * 70
	return xnew + WIDTH/2, ynew + HEIGHT*2/5
warp = PathWarp(curl, ctx)
warp.warpPath()
ctx.fill()


ctx.show_page()



More information about the cairo mailing list