[cairo-commit] cairo-5c ChangeLog, 1.10, 1.11 Makefile.am, 1.4, 1.5 cairo-5c.h, 1.6, 1.7 cairo.5c, 1.4, 1.5 gstate.c, 1.4, 1.5 init.c, 1.7, 1.8 pattern.c, 1.1, 1.2 surface.c, 1.5, 1.6

Keith Packard commit at pdx.freedesktop.org
Sat Dec 18 00:16:31 PST 2004


Committed by: keithp

Update of /cvs/cairo/cairo-5c
In directory gabe:/tmp/cvs-serv20227

Modified Files:
	ChangeLog Makefile.am cairo-5c.h cairo.5c gstate.c init.c 
	pattern.c surface.c 
Log Message:
2004-12-18  Keith Packard  <keithp at keithp.com>

	* Makefile.am:
	* cairo.5c:
	* examples/animate.5c:
	* examples/draw.5c:
	* examples/pie.5c:
	* examples/rottext.5c:
	Fix examples to match API changes
	
	* gstate.c: (do_Cairo_transform_point),
	(do_Cairo_transform_distance), (do_Cairo_inverse_transform_point),
	(do_Cairo_inverse_transform_distance):
	transforms take point_t, return point_t
	
	* cairo-5c.h:
	* init.c: (nickle_init):
	* pattern.c: (do_Cairo_Pattern_create_for_surface),
	(premultiply_data), (create_surface_from_png),
	(do_Cairo_Pattern_create_png):
	* surface.c: (get_cairo_5c), (free_cairo_5c), (dirty_cairo_5c),
	(enable_cairo_5c), (disable_cairo_5c), (do_Cairo_new_png),
	(do_Cairo_new_scratch), (do_Cairo_dup), (do_Cairo_status):
	Add png loading, scratch surfaces and surface patterns


Index: ChangeLog
===================================================================
RCS file: /cvs/cairo/cairo-5c/ChangeLog,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -d -r1.10 -r1.11
--- ChangeLog	18 Dec 2004 01:09:40 -0000	1.10
+++ ChangeLog	18 Dec 2004 08:16:28 -0000	1.11
@@ -1,3 +1,28 @@
+2004-12-18  Keith Packard  <keithp at keithp.com>
+
+	* Makefile.am:
+	* cairo.5c:
+	* examples/animate.5c:
+	* examples/draw.5c:
+	* examples/pie.5c:
+	* examples/rottext.5c:
+	Fix examples to match API changes
+	
+	* gstate.c: (do_Cairo_transform_point),
+	(do_Cairo_transform_distance), (do_Cairo_inverse_transform_point),
+	(do_Cairo_inverse_transform_distance):
+	transforms take point_t, return point_t
+	
+	* cairo-5c.h:
+	* init.c: (nickle_init):
+	* pattern.c: (do_Cairo_Pattern_create_for_surface),
+	(premultiply_data), (create_surface_from_png),
+	(do_Cairo_Pattern_create_png):
+	* surface.c: (get_cairo_5c), (free_cairo_5c), (dirty_cairo_5c),
+	(enable_cairo_5c), (disable_cairo_5c), (do_Cairo_new_png),
+	(do_Cairo_new_scratch), (do_Cairo_dup), (do_Cairo_status):
+	Add png loading, scratch surfaces and surface patterns
+
 2004-12-17  Keith Packard  <keithp at keithp.com>
 
 	* Makefile.am:

Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo-5c/Makefile.am,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- Makefile.am	18 Dec 2004 01:09:40 -0000	1.4
+++ Makefile.am	18 Dec 2004 08:16:28 -0000	1.5
@@ -37,11 +37,11 @@
 
 libcairo_5c_la_SOURCES = \
 	cairo-5c.h \
+	init.c \
 	draw.c \
 	event.c \
 	gstate.c \
 	gtk.c \
-	init.c \
 	matrix.c \
 	pattern.c \
 	surface.c \

Index: cairo-5c.h
===================================================================
RCS file: /cvs/cairo/cairo-5c/cairo-5c.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- cairo-5c.h	18 Dec 2004 01:09:40 -0000	1.6
+++ cairo-5c.h	18 Dec 2004 08:16:28 -0000	1.7
@@ -43,7 +43,7 @@
 #include <unistd.h>
 #undef Atom
 
-typedef enum { CAIRO_5C_WINDOW, CAIRO_5C_PNG } cairo_5c_kind_t;
+typedef enum { CAIRO_5C_WINDOW, CAIRO_5C_PNG, CAIRO_5C_SCRATCH } cairo_5c_kind_t;
 
 typedef struct _cairo_5c_x_t {
     Display	*dpy;
@@ -68,6 +68,9 @@
 	struct {
 	    FILE	    *file;
 	} png;
+	struct {
+	    cairo_surface_t *surface;
+	} scratch;
     } u;
 } cairo_5c_t;
 
@@ -112,6 +115,12 @@
 do_Cairo_new_png (Value fv, Value wv, Value hv);
 
 Value
+do_Cairo_new_scratch (Value cov, Value wv, Value hv);
+
+Value
+do_Cairo_dup (Value cov);
+    
+Value
 do_Cairo_width (Value av);
 
 Value
@@ -341,6 +350,9 @@
 do_Cairo_set_pattern (Value cv, Value patv);
 
 Value
+do_Cairo_Pattern_create_png (Value filenamev);
+
+Value
 do_Cairo_Pattern_create_linear (Value x0v, Value y0v, Value x1v, Value y1v);
 
 Value
@@ -348,6 +360,9 @@
 				Value cx1v, Value cy1v, Value radius1v);
 
 Value
+do_Cairo_Pattern_create_for_surface (Value cv);
+
+Value
 do_Cairo_Pattern_add_color_stop (Value patv, Value offsetv,
 				 Value redv, Value greenv, Value bluev,
 				 Value alphav);

Index: cairo.5c
===================================================================
RCS file: /cvs/cairo/cairo-5c/cairo.5c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- cairo.5c	18 Dec 2004 01:09:40 -0000	1.4
+++ cairo.5c	18 Dec 2004 08:16:28 -0000	1.5
@@ -42,6 +42,9 @@
     public typedef void (real x, real y) line_to_func_t;
     public typedef void (real x1, real y1, real x2, real y2, real x3, real y3) curve_to_func_t;
     public typedef void () close_path_func_t;
+    public typedef struct { 
+	real hue, saturation, value;
+    } hsv_color_t;
     
     void walk_path (path_t  path,
 		    move_to_func_t move_to,
@@ -153,12 +156,31 @@
     }
 
     public void set_hsv_color (cairo_t cr, real h, real s, real v)
+	/*
+	 * Set color using HSV specification
+	 *  H: hue	    0 = red, 0.{3} = green, 0.{6} = blue
+	 *  S: satuation    0..1
+	 *  V: value	    0..1
+	 */
     {
 	set_rgb_color (cr, from_hsv (h, s, v) ...);
     }
 
-    public real[3] current_hsv_color (cairo_t cr)
+    public hsv_color_t current_hsv_color (cairo_t cr)
+	/*
+	 * Return current color using HSV specification
+	 *
+	 *  H: hue	    0 = red, 0.{3} = green, 0.{6} = blue
+	 *  S: satuation    0..1
+	 *  V: value	    0..1
+	 */
     {
-	return to_hsv (current_rgb_color (cr) ...);
+	rgb_color_t rgb = current_rgb_color (cr);
+	real[3]	    t = to_hsv (rgb.red, rgb.green, rgb.blue);
+	return (hsv_color_t) { 
+	    hue = t[0],
+	    saturation = t[1],
+	    value = t[2]
+	};
     }
 }

Index: gstate.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/gstate.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- gstate.c	18 Dec 2004 01:09:40 -0000	1.4
+++ gstate.c	18 Dec 2004 08:16:28 -0000	1.5
@@ -281,17 +281,18 @@
     cairo_5c_t	    *c5c = get_cairo_5c (cv);
     double	    x, y;
     Value	    ret;
-    static int	dims[1] = { 2 };
+    BoxPtr	    box;
 
     if (aborting)
 	RETURN(Void);
     
-    x = DoublePart (ArrayValueGet (&pv->array, 0), "invalid coordinate");
-    y = DoublePart (ArrayValueGet (&pv->array, 1), "invalid coordinate");
+    x = DoublePart (StructMemValue (pv, AtomId("x")), "invalid x coordinate");
+    y = DoublePart (StructMemValue (pv, AtomId("y")), "invalid y coordinate");
     cairo_transform_point (c5c->cr, &x, &y);
-    ret = NewArray (False, False, typePrim[rep_float], 1, dims);
-    ArrayValueSet(&ret->array, 0, NewDoubleFloat (x));
-    ArrayValueSet(&ret->array, 1, NewDoubleFloat (y));
+    ret = NewStruct (TypeCanon (typeCairoPoint)->structs.structs, False);
+    box = ret->structs.values;
+    BoxValueSet (box, 0, NewDoubleFloat (x));
+    BoxValueSet (box, 1, NewDoubleFloat (y));
     RETURN (ret);
 }
 
@@ -302,17 +303,18 @@
     cairo_5c_t	    *c5c = get_cairo_5c (cv);
     double	    x, y;
     Value	    ret;
-    static int	dims[1] = { 2 };
+    BoxPtr	    box;
 
     if (aborting)
 	RETURN(Void);
     
-    x = DoublePart (ArrayValueGet (&pv->array, 0), "invalid coordinate");
-    y = DoublePart (ArrayValueGet (&pv->array, 1), "invalid coordinate");
+    x = DoublePart (StructMemValue (pv, AtomId("x")), "invalid x coordinate");
+    y = DoublePart (StructMemValue (pv, AtomId("y")), "invalid y coordinate");
     cairo_transform_distance (c5c->cr, &x, &y);
-    ret = NewArray (False, False, typePrim[rep_float], 1, dims);
-    ArrayValueSet(&ret->array, 0, NewDoubleFloat (x));
-    ArrayValueSet(&ret->array, 1, NewDoubleFloat (y));
+    ret = NewStruct (TypeCanon (typeCairoPoint)->structs.structs, False);
+    box = ret->structs.values;
+    BoxValueSet (box, 0, NewDoubleFloat (x));
+    BoxValueSet (box, 1, NewDoubleFloat (y));
     RETURN (ret);
 }
 
@@ -323,17 +325,18 @@
     cairo_5c_t	    *c5c = get_cairo_5c (cv);
     double	    x, y;
     Value	    ret;
-    static int	dims[1] = { 2 };
+    BoxPtr	    box;
 
     if (aborting)
 	RETURN(Void);
     
-    x = DoublePart (ArrayValueGet (&pv->array, 0), "invalid coordinate");
-    y = DoublePart (ArrayValueGet (&pv->array, 1), "invalid coordinate");
+    x = DoublePart (StructMemValue (pv, AtomId("x")), "invalid x coordinate");
+    y = DoublePart (StructMemValue (pv, AtomId("y")), "invalid y coordinate");
     cairo_inverse_transform_point (c5c->cr, &x, &y);
-    ret = NewArray (False, False, typePrim[rep_float], 1, dims);
-    ArrayValueSet(&ret->array, 0, NewDoubleFloat (x));
-    ArrayValueSet(&ret->array, 1, NewDoubleFloat (y));
+    ret = NewStruct (TypeCanon (typeCairoPoint)->structs.structs, False);
+    box = ret->structs.values;
+    BoxValueSet (box, 0, NewDoubleFloat (x));
+    BoxValueSet (box, 1, NewDoubleFloat (y));
     RETURN (ret);
 }
 
@@ -344,17 +347,18 @@
     cairo_5c_t	    *c5c = get_cairo_5c (cv);
     double	    x, y;
     Value	    ret;
-    static int	dims[1] = { 2 };
+    BoxPtr	    box;
 
     if (aborting)
 	RETURN(Void);
     
-    x = DoublePart (ArrayValueGet (&pv->array, 0), "invalid coordinate");
-    y = DoublePart (ArrayValueGet (&pv->array, 1), "invalid coordinate");
+    x = DoublePart (StructMemValue (pv, AtomId("x")), "invalid x coordinate");
+    y = DoublePart (StructMemValue (pv, AtomId("y")), "invalid y coordinate");
     cairo_inverse_transform_distance (c5c->cr, &x, &y);
-    ret = NewArray (False, False, typePrim[rep_float], 1, dims);
-    ArrayValueSet(&ret->array, 0, NewDoubleFloat (x));
-    ArrayValueSet(&ret->array, 1, NewDoubleFloat (y));
+    ret = NewStruct (TypeCanon (typeCairoPoint)->structs.structs, False);
+    box = ret->structs.values;
+    BoxValueSet (box, 0, NewDoubleFloat (x));
+    BoxValueSet (box, 1, NewDoubleFloat (y));
     RETURN (ret);
 }
 

Index: init.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/init.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- init.c	18 Dec 2004 01:09:40 -0000	1.7
+++ init.c	18 Dec 2004 08:16:28 -0000	1.8
@@ -426,6 +426,10 @@
     };
 	
     static const struct fbuiltin_1 funcs_1[] = {
+	{ do_Cairo_dup, "dup", CAIRO_S, CAIRO_S, "\n"
+	    " cairo_t dup (cairo_t cairo)\n"
+	    "\n"
+	    " Creates another rendering context pointing at the same surface\n"},
 	{ do_Cairo_width, "width", "i", CAIRO_S, "\n"
 	    " void width (cairo_t cairo)\n"
 	    "\n"
@@ -669,6 +673,10 @@
 	    " cairo_t new_png (string filename, int width, int height)\n"
 	    "\n"
 	    " Create a cairo png file.\n" },
+	{ do_Cairo_new_scratch, "new_scratch", CAIRO_S, CAIRO_S "ii", "\n"
+	    " cairo_t new_scratch (cairo_t cr, int width, int height)\n"
+	    "\n"
+	    " Create a scratch surface related to the given surface.\n" },
 	{ do_Cairo_move_to, "move_to", "v", CAIRO_S "nn", "\n"
 	    " void move_to (cairo_t cr, real x, real y)\n"
 	    "\n"
@@ -753,6 +761,14 @@
     };
 
     static const struct fbuiltin_1 patfuncs_1[] = {
+	{ do_Cairo_Pattern_create_png, "create_png", PATTERN_S, "s", "\n"
+	    " pattern_t create_png (string filename)\n"
+	    "\n"
+	    " Returns a pattern containing the specified png image\n" },
+	{ do_Cairo_Pattern_create_for_surface, "create_for_surface", PATTERN_S, CAIRO_S, "\n"
+	    " pattern_t create_for_surface (cairo_t cr)\n"
+	    "\n"
+	    " Returns a pattern referencing the specified surface\n" },
 	{ do_Cairo_Pattern_get_matrix, "get_matrix", MATRIX_S, PATTERN_S, "\n"
 	    " matrix_t get_matrix (pattern_t pattern)\n"
 	    "\n"

Index: pattern.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/pattern.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- pattern.c	18 Dec 2004 01:09:40 -0000	1.1
+++ pattern.c	18 Dec 2004 08:16:28 -0000	1.2
@@ -33,6 +33,8 @@
  *      Keith Packard <keithp at keithp.com>
  */
 
+#include <png.h>
+#include <stdlib.h>
 #include "cairo-5c.h"
 
 static char CairoPatternId[] = "CairoPattern";
@@ -121,6 +123,192 @@
 }
 
 Value
+do_Cairo_Pattern_create_for_surface (Value cv)
+{
+    ENTER ();
+    cairo_5c_t	    *c5c = get_cairo_5c (cv);
+    cairo_surface_t *surface;
+
+    if (aborting)
+	RETURN (Void);
+    surface = cairo_current_target_surface (c5c->cr);
+    RETURN (make_pattern_value (cairo_pattern_create_for_surface (surface)));
+}
+
+static void
+premultiply_data (png_structp   png,
+                  png_row_infop row_info,
+                  png_bytep     data)
+{
+    int i;
+
+    for (i = 0; i < row_info->rowbytes; i += 4) {
+	unsigned char  *base = &data[i];
+	unsigned char  blue = base[0];
+	unsigned char  green = base[1];
+	unsigned char  red = base[2];
+	unsigned char  alpha = base[3];
+	unsigned long	p;
+
+	red = (unsigned) red * (unsigned) alpha / 255;
+	green = (unsigned) green * (unsigned) alpha / 255;
+	blue = (unsigned) blue * (unsigned) alpha / 255;
+	p = (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
+	memcpy (base, &p, sizeof (unsigned long));
+    }
+}
+
+struct cairo_matrix {
+    double m[3][2];
+};
+
+struct cairo_surface {
+    const void *backend;
+
+    unsigned int ref_count;
+
+    cairo_matrix_t matrix;
+    cairo_filter_t filter;
+    int repeat;
+};
+
+struct cairo_image_surface {
+    cairo_surface_t base;
+
+    /* libic-specific fields */
+    char *data;
+    int owns_data;
+
+    int width;
+    int height;
+    int stride;
+    int depth;
+
+    pixman_image_t *pixman_image;
+};
+
+static cairo_surface_t *
+create_surface_from_png (const char *filename)
+{
+    FILE	    *f;
+    cairo_surface_t *surface;
+    char	    *buffer;
+    png_structp	    png;
+    png_infop	    info;
+    png_bytepp	    rows;
+    int		    i;
+    png_uint_32	    width, height;
+    png_uint_32	    stride;
+    int		    depth, color, interlace;
+    
+    png = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+    if (png == NULL)
+	return NULL;
+    info = png_create_info_struct (png);
+    if (info == NULL)
+    {
+	png_destroy_read_struct (&png, NULL, NULL);
+	return NULL;
+    }
+    if (setjmp (png->jmpbuf))
+    {
+	png_destroy_read_struct (&png, &info, NULL);
+	return NULL;
+    }
+    f = fopen (filename, "rb");
+    if (f == NULL)
+    {
+	png_destroy_read_struct (&png, &info, NULL);
+	return NULL;
+    }
+    png_init_io (png, f);
+    png_read_info (png, info);
+    png_get_IHDR (png, info, &width, &height, &depth, &color, &interlace,
+		  NULL, NULL);
+
+    if (color == PNG_COLOR_TYPE_PALETTE && depth <= 8)
+	png_set_expand (png);
+
+    if (color == PNG_COLOR_TYPE_GRAY && depth < 8)
+	png_set_expand (png);
+
+    if (png_get_valid (png, info, PNG_INFO_tRNS))
+	png_set_expand (png);
+
+    if (depth == 16)
+	png_set_strip_16 (png);
+
+    if (depth < 8)
+	png_set_packing (png);
+
+    if (color == PNG_COLOR_TYPE_GRAY || color == PNG_COLOR_TYPE_GRAY_ALPHA)
+	png_set_gray_to_rgb (png);
+
+    if (interlace != PNG_INTERLACE_NONE)
+	png_set_interlace_handling (png);
+
+    png_set_bgr (png);
+    png_set_filler (png, 255, PNG_FILLER_AFTER);
+
+    png_set_read_user_transform_fn (png, premultiply_data);
+
+    png_read_update_info (png, info);
+
+    stride = width * 4;
+    buffer = malloc (stride * height);
+    
+    rows = malloc (sizeof (png_bytep) * height);
+
+    for (i = 0; i < height; i++)
+	rows[i] = (png_bytep) (buffer + i * stride);
+    
+    png_read_image (png, rows);
+    png_read_end (png, info);
+
+    free (rows);
+    fclose (f);
+    png_destroy_read_struct (&png, &info, NULL);
+
+    surface = cairo_surface_create_for_image (buffer, CAIRO_FORMAT_ARGB32, 
+					      width, height, stride);
+    if (!surface)
+    {
+	free (buffer);
+	return NULL;
+    }
+    
+    /*
+     * XXX hack internal structure contents to hand buffer to cairo 
+     */
+    ((struct cairo_image_surface *) surface)->owns_data = 1;
+    
+    return surface;
+}
+
+Value
+do_Cairo_Pattern_create_png (Value filenamev)
+{
+    ENTER ();
+    char	    *filename = StrzPart (filenamev, "invalid filename");
+    cairo_surface_t *image;
+    cairo_pattern_t *pattern;
+
+    if (aborting)
+	RETURN(Void);
+    image = create_surface_from_png (filename);
+    if (!image)
+    {
+	RaiseStandardException (exception_open_error,
+				"cannot read png file",
+				1, filenamev);
+	RETURN (Void);
+    }
+    pattern = cairo_pattern_create_for_surface (image);
+    cairo_surface_destroy (image);
+    RETURN (make_pattern_value (pattern));
+}
+
+Value
 do_Cairo_Pattern_add_color_stop (Value patv, Value offsetv,
 				 Value redv, Value greenv, Value bluev,
 				 Value alphav)

Index: surface.c
===================================================================
RCS file: /cvs/cairo/cairo-5c/surface.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- surface.c	17 Dec 2004 09:40:43 -0000	1.5
+++ surface.c	18 Dec 2004 08:16:28 -0000	1.6
@@ -68,6 +68,7 @@
 	}
 	break;
     case CAIRO_5C_PNG:
+    case CAIRO_5C_SCRATCH:
 	break;
     }
     return c5c;
@@ -87,6 +88,9 @@
 	case CAIRO_5C_PNG:
 	    fflush (c5c->u.png.file);
 	    break;
+	case CAIRO_5C_SCRATCH:
+	    cairo_surface_destroy (c5c->u.scratch.surface);
+	    break;
 	}
         free (c5c);
     }
@@ -100,6 +104,7 @@
 	dirty_x (c5c->u.window.x, 0, 0, 0, 0);
 	break;
     case CAIRO_5C_PNG:
+    case CAIRO_5C_SCRATCH:
 	break;
     }
 }
@@ -111,6 +116,7 @@
     case CAIRO_5C_WINDOW:
 	return enable_x (c5c->u.window.x);
     case CAIRO_5C_PNG:
+    case CAIRO_5C_SCRATCH:
 	break;
     }
     return True;
@@ -123,6 +129,7 @@
     case CAIRO_5C_WINDOW:
 	return disable_x (c5c->u.window.x);
     case CAIRO_5C_PNG:
+    case CAIRO_5C_SCRATCH:
 	break;
     }
     return True;
@@ -213,10 +220,16 @@
     cairo_set_target_png (c5c->cr, c5c->u.png.file,
 			  CAIRO_FORMAT_ARGB32, c5c->width,
 			  c5c->height);
+
+    cairo_save (c5c->cr); {
+	cairo_set_rgb_color (c5c->cr, 0, 0, 0);
+	cairo_set_alpha (c5c->cr, 0);
+	cairo_set_operator (c5c->cr, CAIRO_OPERATOR_SRC);
+	cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
+	cairo_fill (c5c->cr);
+    } cairo_restore (c5c->cr);
+
     cairo_set_rgb_color (c5c->cr, 0, 0, 0);
-    cairo_set_alpha (c5c->cr, 0);
-    cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
-    cairo_fill (c5c->cr);
 
     ret = NewForeign (CairoId, c5c, free_cairo_5c);
 
@@ -224,6 +237,71 @@
 }
 
 Value
+do_Cairo_new_scratch (Value cov, Value wv, Value hv)
+{
+    ENTER ();
+    cairo_5c_t	*c5co = get_cairo_5c (cov);
+    cairo_5c_t	*c5c;
+    int		width = IntPart (wv, "invalid width");
+    int		height = IntPart (hv, "invalid height");
+    Value	ret;
+    
+    if (aborting)
+	RETURN (Void);
+    
+    c5c = malloc (sizeof (cairo_5c_t));
+    if (!c5c)
+	RETURN (Void);
+
+    c5c->kind = CAIRO_5C_SCRATCH;
+
+    c5c->u.scratch.surface = cairo_surface_create_similar (cairo_current_target_surface (c5co->cr),
+							   CAIRO_FORMAT_ARGB32,
+							   width, height);
+    c5c->width = width;
+    c5c->height = height;
+    c5c->cr = cairo_create ();
+    cairo_set_target_surface (c5c->cr, c5c->u.scratch.surface);
+
+    cairo_save (c5c->cr); {
+	cairo_set_rgb_color (c5c->cr, 0, 0, 0);
+	cairo_set_alpha (c5c->cr, 0);
+	cairo_set_operator (c5c->cr, CAIRO_OPERATOR_SRC);
+	cairo_rectangle (c5c->cr, 0, 0, c5c->width, c5c->height);
+	cairo_fill (c5c->cr);
+    } cairo_restore (c5c->cr);
+
+    cairo_set_rgb_color (c5c->cr, 0, 0, 0);
+
+    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+
+    RETURN (ret);
+}
+
+Value
+do_Cairo_dup (Value cov)
+{
+    ENTER ();
+    cairo_5c_t	*c5co = get_cairo_5c (cov);
+    cairo_5c_t	*c5c;
+    Value	ret;
+    
+    if (aborting)
+	RETURN (Void);
+    
+    c5c = malloc (sizeof (cairo_5c_t));
+    if (!c5c)
+	RETURN (Void);
+
+    *c5c = *c5co;
+    c5c->cr = cairo_create ();
+    cairo_set_target_surface (c5c->cr, cairo_current_target_surface (c5co->cr));
+    ret = NewForeign (CairoId, c5c, free_cairo_5c);
+
+    RETURN (ret);
+}
+
+Value
 do_Cairo_width (Value av)
 {
     ENTER ();
@@ -252,7 +330,7 @@
 
     if (aborting)
 	return Void;
-    RETURN(NewInt (cairo_status (c5c->cr)));
+    RETURN(IntToEnum (typeCairoStatus, cairo_status (c5c->cr)));
 }
 
 Value




More information about the cairo-commit mailing list