[Commit] cairo/src cairo-xlib.h, NONE, 1.1 cairo_xlib_surface.c, NONE, 1.1 Makefile.am, 1.8, 1.9 cairo.c, 1.18, 1.19 cairo.h, 1.17, 1.18 cairo_font.c, 1.7, 1.8 cairo_gstate.c, 1.16, 1.17 cairo_surface.c, 1.12, 1.13 cairoint.h, 1.24, 1.25

Jamey Sharp commit at keithp.com
Tue Sep 30 19:56:25 PDT 2003


Committed by: jamey

Update of /local/src/CVS/cairo/src
In directory home.keithp.com:/tmp/cvs-serv19511/src

Modified Files:
	Makefile.am cairo.c cairo.h cairo_font.c cairo_gstate.c 
	cairo_surface.c cairoint.h 
Added Files:
	cairo-xlib.h cairo_xlib_surface.c 
Log Message:
Virtualized the font and surface backend implementations.


--- NEW FILE: cairo-xlib.h ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: cairo_xlib_surface.c ---
(This appears to be a binary file; contents omitted.)

Index: Makefile.am
===================================================================
RCS file: /local/src/CVS/cairo/src/Makefile.am,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- Makefile.am	5 Sep 2003 22:29:49 -0000	1.8
+++ Makefile.am	1 Oct 2003 01:56:22 -0000	1.9
@@ -1,5 +1,5 @@
 lib_LTLIBRARIES = libcairo.la
-include_HEADERS = cairo.h
+include_HEADERS = cairo.h cairo-xlib.h
 
 libcairo_la_SOURCES = \
 	cairo.c \
@@ -18,6 +18,7 @@
 	cairo_slope.c \
 	cairo_spline.c \
 	cairo_surface.c \
+	cairo_xlib_surface.c \
 	cairo_traps.c \
 	cairoint.h
 

Index: cairo.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- cairo.c	30 Sep 2003 21:15:28 -0000	1.18
+++ cairo.c	1 Oct 2003 01:56:22 -0000	1.19
@@ -172,30 +172,6 @@
 slim_hidden_def(cairo_set_target_surface);
 
 void
-cairo_set_target_drawable (cairo_t	*cr,
-			   Display	*dpy,
-			   Drawable	drawable)
-{
-    cairo_surface_t *surface;
-
-    if (cr->status && cr->status != CAIRO_STATUS_NO_TARGET_SURFACE)
-	return;
-
-    surface = cairo_surface_create_for_drawable (dpy, drawable,
-					  DefaultVisual (dpy, DefaultScreen (dpy)),
-					  0,
-					  DefaultColormap (dpy, DefaultScreen (dpy)));
-    if (surface == NULL) {
-	cr->status = CAIRO_STATUS_NO_MEMORY;
-	return;
-    }
-
-    cairo_set_target_surface (cr, surface);
-
-    cairo_surface_destroy (surface);
-}
-
-void
 cairo_set_target_image (cairo_t		*cr,
 			char		*data,
 			cairo_format_t	format,

Index: cairo.h
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- cairo.h	30 Sep 2003 18:39:07 -0000	1.17
+++ cairo.h	1 Oct 2003 01:56:22 -0000	1.18
@@ -85,11 +85,6 @@
 } cairo_format_t;
 
 extern void __external_linkage
-cairo_set_target_drawable (cairo_t	*cr,
-			   Display	*dpy,
-			   Drawable	drawable);
-
-extern void __external_linkage
 cairo_set_target_image (cairo_t	*cr,
 			char		*data,
 			cairo_format_t	format,
@@ -427,18 +422,6 @@
 
 /* Surface mainpulation */
 
-/* XXX: This is a mess from the user's POV. Should the Visual or the
-   cairo_format_t control what render format is used? Maybe I can have
-   cairo_surface_create_for_window with a visual, and
-   cairo_surface_create_for_pixmap with a cairo_format_t. Would that work?
-*/
-extern cairo_surface_t * __external_linkage
-cairo_surface_create_for_drawable (Display		*dpy,
-				   Drawable		drawable,
-				   Visual		*visual,
-				   cairo_format_t	format,
-				   Colormap		colormap);
-
 extern cairo_surface_t * __external_linkage
 cairo_surface_create_for_image (char		*data,
 				cairo_format_t	format,

Index: cairo_font.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_font.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- cairo_font.c	29 Sep 2003 15:36:30 -0000	1.7
+++ cairo_font.c	1 Oct 2003 01:56:22 -0000	1.8
@@ -25,41 +25,41 @@
  * Author: Carl D. Worth <cworth at isi.edu>
  */
 
-#include <string.h>
-
 #include "cairoint.h"
 
 void
-_cairo_font_init (cairo_font_t *font)
+_cairo_font_init (cairo_font_t *font, const struct cairo_font_backend *backend)
 {
     font->key = (unsigned char *) strdup (CAIRO_FONT_KEY_DEFAULT);
-
-    font->dpy = NULL;
-    font->xft_font = NULL;
-
     cairo_matrix_set_identity (&font->matrix);
+
+    font->backend = backend;
 }
 
 cairo_status_t
 _cairo_font_init_copy (cairo_font_t *font, cairo_font_t *other)
 {
-    *font = *other;
-
     if (other->key) {
 	font->key = (unsigned char *) strdup ((char *) other->key);
 	if (font->key == NULL)
 	    return CAIRO_STATUS_NO_MEMORY;
     }
+    font->matrix = other->matrix;
 
-    if (other->xft_font) {
-	font->xft_font = XftFontCopy (other->dpy, other->xft_font);
-	if (font->xft_font == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
-    }
+    font->backend = other->backend;
 
     return CAIRO_STATUS_SUCCESS;
 }
 
+cairo_font_t *
+_cairo_font_copy (cairo_font_t *font)
+{
+    if (!font->backend->copy)
+	return 0;
+
+    return font->backend->copy (font);
+}
+
 void
 _cairo_font_fini (cairo_font_t *font)
 {
@@ -69,18 +69,15 @@
 
     _cairo_matrix_fini (&font->matrix);
 
-    if (font->xft_font)
-	XftFontClose (font->dpy, font->xft_font);
-
-    font->xft_font = NULL;
+    if (font->backend->close)
+	font->backend->close (font);
 }
 
 cairo_status_t
 _cairo_font_select (cairo_font_t *font, const char *key)
 {
-    if (font->xft_font)
-	XftFontClose (font->dpy, font->xft_font);
-    font->xft_font = NULL;
+    if (font->backend->close)
+	font->backend->close (font);
 
     if (font->key)
 	free (font->key);
@@ -114,69 +111,31 @@
 }
 
 cairo_status_t
-_cairo_font_resolve_xft_font (cairo_font_t *font, cairo_gstate_t *gstate, XftFont **xft_font)
+_cairo_font_text_extents (cairo_font_t *font,
+			  cairo_matrix_t *ctm,
+			  const unsigned char *utf8,
+			  double *x, double *y,
+			  double *width, double *height,
+			  double *dx, double *dy)
 {
-    FcPattern	*pattern;
-    FcPattern	*match;
-    FcResult	result;
-    cairo_matrix_t	matrix;
-    FcMatrix	fc_matrix;
-    double	expansion;
-    double	font_size;
-    
-    if (font->xft_font) {
-	*xft_font = font->xft_font;
+    if (!font->backend->text_extents)
 	return CAIRO_STATUS_SUCCESS;
-    }
-    
-    pattern = FcNameParse (font->key);
 
-    matrix = gstate->ctm;
-
-    cairo_matrix_multiply (&matrix, &font->matrix, &matrix);
-
-    /* Pull the scale factor out of the final matrix and use it to set
-       the direct pixelsize of the font. This enables freetype to
-       perform proper hinting at any size. */
-
-    /* XXX: The determinant gives an area expansion factor, so the
-       math below should be correct for the (common) case of uniform
-       X/Y scaling. Is there anything different we would want to do
-       for non-uniform X/Y scaling?
-
-       XXX: Actually, the reasoning above is bogus. A transformation
-       such as scale (N, 1/N) will give an expansion_factor of 1. So,
-       with the code below we'll end up with font_size == 1 instead of
-       N, (so the hinting will be all wrong). I think we want to use
-       the maximum eigen value rather than the square root of the
-       determinant.
-
-    */
-    _cairo_matrix_compute_determinant (&matrix, &expansion);
-    font_size = sqrt (fabs (expansion));
-
-    FcPatternAddDouble (pattern, "pixelsize", font_size);
-    cairo_matrix_scale (&matrix, 1.0 / font_size, 1.0 / font_size);
-
-    fc_matrix.xx = matrix.m[0][0];
-    fc_matrix.xy = matrix.m[0][1];
-    fc_matrix.yx = matrix.m[1][0];
-    fc_matrix.yy = matrix.m[1][1];
-
-    FcPatternAddMatrix (pattern, "matrix", &fc_matrix);
-
-    /* XXX: Need to make a generic (non-Xft) backend for text. */
-    /*      When I do that I can throw away these Display pointers */
-    font->dpy = gstate->surface->dpy;
-    match = XftFontMatch (font->dpy, DefaultScreen (font->dpy), pattern, &result);
-    if (!match)
-	return 0;
-    
-    font->xft_font = XftFontOpenPattern (font->dpy, match);
-
-    *xft_font = font->xft_font;
+    return font->backend->text_extents (font, ctm, utf8, x, y, width, height, dx, dy);
+}
 
-    FcPatternDestroy (pattern);
+cairo_status_t
+_cairo_font_show_text (cairo_font_t		*font,
+		       cairo_matrix_t		*ctm,
+		       cairo_operator_t		operator,
+		       cairo_surface_t		*source,
+		       cairo_surface_t		*surface,
+		       double			x,
+		       double			y,
+		       const unsigned char	*utf8)
+{
+    if (!font->backend->show_text)
+	return CAIRO_STATUS_SUCCESS;
 
-    return CAIRO_STATUS_SUCCESS;
+    return font->backend->show_text (font, ctm, operator, source, surface, x, y, utf8);
 }

Index: cairo_gstate.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_gstate.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- cairo_gstate.c	30 Sep 2003 20:15:09 -0000	1.16
+++ cairo_gstate.c	1 Oct 2003 01:56:22 -0000	1.17
@@ -74,7 +74,7 @@
     gstate->num_dashes = 0;
     gstate->dash_offset = 0.0;
 
-    _cairo_font_init (&gstate->font);
+    gstate->font = NULL;
 
     gstate->surface = NULL;
     gstate->source = NULL;
@@ -121,9 +121,11 @@
 	memcpy (gstate->dash, other->dash, other->num_dashes * sizeof (double));
     }
     
-    status = _cairo_font_init_copy (&gstate->font, &other->font);
-    if (status)
+    gstate->font = _cairo_font_copy (other->font);
+    if (!gstate->font) {
+	status = CAIRO_STATUS_NO_MEMORY;
 	goto CLEANUP_DASHES;
+    }
 
     cairo_surface_reference (gstate->surface);
     cairo_surface_reference (gstate->source);
@@ -142,7 +144,7 @@
   CLEANUP_PATH:
     _cairo_path_fini (&gstate->path);
   CLEANUP_FONT:
-    _cairo_font_fini (&gstate->font);
+    _cairo_font_fini (gstate->font);
   CLEANUP_DASHES:
     free (gstate->dash);
     gstate->dash = NULL;
@@ -153,7 +155,7 @@
 void
 _cairo_gstate_fini (cairo_gstate_t *gstate)
 {
-    _cairo_font_fini (&gstate->font);
+    _cairo_font_fini (gstate->font);
 
     cairo_surface_destroy (gstate->surface);
     gstate->surface = NULL;
@@ -1353,13 +1355,13 @@
 cairo_status_t
 _cairo_gstate_select_font (cairo_gstate_t *gstate, const char *key)
 {
-    return _cairo_font_select (&gstate->font, key);
+    return _cairo_font_select (gstate->font, key);
 }
 
 cairo_status_t
 _cairo_gstate_scale_font (cairo_gstate_t *gstate, double scale)
 {
-    return _cairo_font_scale (&gstate->font, scale);
+    return _cairo_font_scale (gstate->font, scale);
 }
 
 cairo_status_t
@@ -1367,7 +1369,7 @@
 			      double a, double b,
 			      double c, double d)
 {
-    return _cairo_font_transform (&gstate->font,
+    return _cairo_font_transform (gstate->font,
 				  a, b, c, d);
 }
 
@@ -1378,45 +1380,17 @@
 			    double *width, double *height,
 			    double *dx, double *dy)
 {
-    XftFont *xft_font;
-    XGlyphInfo extents;
-
-    if (gstate->surface->dpy == 0)
-	return CAIRO_STATUS_SUCCESS;
-
-    _cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
-
-    /* XXX: Need to make a generic (non-Xft) backend for text. */
-    XftTextExtentsUtf8 (gstate->surface->dpy,
-			xft_font,
-			utf8,
-			strlen ((char *) utf8),
-			&extents);
-
-    /* XXX: What are the semantics of XftTextExtents? Specifically,
-       what does it do with x/y? I think we actually need to use the
-       gstate's current point in here somewhere. */
-    *x = extents.x;
-    *y = extents.y;
-    *width = extents.width;
-    *height = extents.height;
-    *dx = extents.xOff;
-    *dy = extents.yOff;
-
-    return CAIRO_STATUS_SUCCESS;
+    return _cairo_font_text_extents (gstate->font, &gstate->ctm, utf8,
+	    			     x, y, width, height, dx, dy);
 }
 
 cairo_status_t
 _cairo_gstate_show_text (cairo_gstate_t *gstate, const unsigned char *utf8)
 {
     cairo_status_t status;
-    XftFont *xft_font;
     double x, y;
     cairo_matrix_t user_to_source, device_to_source;
 
-    if (gstate->surface->dpy == 0)
-	return CAIRO_STATUS_SUCCESS;
-
     /* XXX: I believe this is correct, but it would be much more clear
        to have some explicit current_point accesor functions, (one for
        user- and one for device-space). */
@@ -1429,8 +1403,6 @@
 	cairo_matrix_transform_point (&gstate->ctm, &x, &y);
     }
 
-    _cairo_font_resolve_xft_font (&gstate->font, gstate, &xft_font);
-
     status = _cairo_gstate_ensure_source (gstate);
     if (status)
 	return status;
@@ -1444,22 +1416,15 @@
 	cairo_surface_set_matrix (gstate->source, &device_to_source);
     }
 
-    /* XXX: Need to make a generic (non-Xft) backend for text. */
-    XftTextRenderUtf8 (gstate->surface->dpy,
-		       gstate->operator,
-		       gstate->source->picture,
-		       xft_font,
-		       gstate->surface->picture,
-		       0, 0,
-		       x, y,
-		       utf8,
-		       strlen ((char *) utf8));
+    status = _cairo_font_show_text (gstate->font, &gstate->ctm,
+				    gstate->operator, gstate->source,
+				    gstate->surface, x, y, utf8);
 
     /* restore the matrix originally in the source surface */
     if (! gstate->source_is_solid)
 	cairo_surface_set_matrix (gstate->source, &user_to_source);
 
-    return CAIRO_STATUS_SUCCESS;
+    return status;
 }
 
 cairo_status_t

Index: cairo_surface.c
===================================================================
RCS file: /local/src/CVS/cairo/src/cairo_surface.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- cairo_surface.c	30 Sep 2003 14:58:58 -0000	1.12
+++ cairo_surface.c	1 Oct 2003 01:56:22 -0000	1.13
@@ -37,35 +37,6 @@
     }
 };
 
-#define CAIRO_SURFACE_RENDER_AT_LEAST(surface, major, minor) \
-	(((surface)->render_major > major) ? 1		  \
-	 : ((surface)->render_major == major) ? ((surface)->render_minor >= minor) : 0)
-
-#define CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
-#define CAIRO_SURFACE_RENDER_HAS_COMPOSITE(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 0)
-
-#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
-#define CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLES(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 1)
-
-#define CAIRO_SURFACE_RENDER_HAS_DISJOINT(surface)			CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
-#define CAIRO_SURFACE_RENDER_HAS_CONJOINT(surface)			CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 2)
-
-#define CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
-#define CAIRO_SURFACE_RENDER_HAS_TRIANGLES(surface)		CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
-#define CAIRO_SURFACE_RENDER_HAS_TRISTRIP(surface)			CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
-#define CAIRO_SURFACE_RENDER_HAS_TRIFAN(surface)			CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 4)
-
-#define CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM(surface)	CAIRO_SURFACE_RENDER_AT_LEAST((surface), 0, 6)
-
-static IcFormat *
-_create_icformat_for_visual (Visual *visual)
-{
-    return IcFormatCreateMasks (32, 0,
-				visual->red_mask,
-				visual->green_mask,
-				visual->blue_mask);
-}
-
 static IcFormat *
 _create_icformat_for_format (cairo_format_t format)
 {
@@ -87,67 +58,31 @@
     }
 }
 
-cairo_surface_t *
-cairo_surface_create_for_drawable (Display		*dpy,
-				   Drawable		drawable,
-				   Visual		*visual,
-				   cairo_format_t	format,
-				   Colormap		colormap)
+void
+_cairo_surface_init (cairo_surface_t			*surface,
+		     int				width,
+		     int				height,
+		     cairo_format_t			format,
+		     const struct cairo_surface_backend	*backend)
 {
-    cairo_surface_t *surface;
+    surface->width = width;
+    surface->height = height;
 
-    surface = malloc (sizeof (cairo_surface_t));
-    if (surface == NULL)
-	return NULL;
+    surface->image_data = NULL;
 
     /* XXX: We should really get this value from somewhere like Xft.dpy */
+    /* Assume a default until the user lets us know otherwise */
     surface->ppm = 3780;
     surface->ref_count = 1;
     surface->repeat = 0;
 
-    surface->dpy = dpy;
-    surface->image_data = NULL;
-    surface->icimage = NULL;
-
-    surface->type = CAIRO_SURFACE_TYPE_DRAWABLE;
     surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
 
-    surface->gc = 0;
-    surface->drawable = drawable;
-    surface->owns_pixmap = 0;
-    surface->visual = visual;
-
-    if (! XRenderQueryVersion (dpy, &surface->render_major, &surface->render_minor)) {
-	surface->render_major = -1;
-	surface->render_minor = -1;
-    }
-
-    if (visual)
-	surface->icformat = _create_icformat_for_visual (visual);
-    else
-	surface->icformat = _create_icformat_for_format (format);
-
-    /* XXX: I'm currently ignoring the colormap. Is that bad? */
-    if (CAIRO_SURFACE_RENDER_HAS_CREATE_PICTURE (surface))
-	surface->picture = XRenderCreatePicture (dpy, drawable,
-						 visual ?
-						 XRenderFindVisualFormat (dpy, visual) :
-						 XRenderFindStandardFormat (dpy, format),
-						 0, NULL);
-    else
-	surface->picture = 0;
-
-    surface->ximage = NULL;
-
-    /* XXX: How to get the proper width/height? Force a roundtrip? And
-       how can we track the width/height properly? Shall we give up on
-       supporting Windows and only allow drawing to pixmaps? */
-    surface->width = 0;
-    surface->height = 0;
+    surface->icimage = NULL;
+    surface->icformat = _create_icformat_for_format (format);
 
-    return surface;
+    surface->backend = backend;
 }
-slim_hidden_def(cairo_surface_create_for_drawable);
 
 static int
 cairo_format_bpp (cairo_format_t format)
@@ -167,6 +102,8 @@
     }
 }
 
+static const struct cairo_surface_backend cairo_icimage_surface_backend;
+
 cairo_surface_t *
 cairo_surface_create_for_image (char		*data,
 				cairo_format_t	format,
@@ -180,18 +117,7 @@
     if (surface == NULL)
 	return NULL;
 
-    surface->icformat = _create_icformat_for_format (format);
-
-    /* Assume a default until the user lets us know otherwise */
-    surface->ppm = 3780;
-    surface->ref_count = 1;
-    surface->repeat = 0;
-
-    surface->dpy = NULL;
-    surface->image_data = NULL;
-
-    surface->width = width;
-    surface->height = height;
+    _cairo_surface_init (surface, width, height, format, &cairo_icimage_surface_backend);
 
     surface->icimage = IcImageCreateForData ((IcBits *) data,
 					     surface->icformat,
@@ -203,19 +129,6 @@
 	return NULL;
     }
 
-    surface->type = CAIRO_SURFACE_TYPE_ICIMAGE;
-    surface->xtransform = CAIRO_XTRANSFORM_IDENTITY;
-
-    surface->gc = 0;
-    surface->drawable = 0;
-    surface->owns_pixmap = 0;
-    surface->visual = NULL;
-    surface->render_major = -1;
-    surface->render_minor = -1;
-
-    surface->picture = 0;
-    surface->ximage = NULL;
-
     return surface;
 }
 slim_hidden_def(cairo_surface_create_for_image);
@@ -229,22 +142,6 @@
     return cairo_surface_create_similar_solid (other, format, width, height, 0, 0, 0, 0);
 }
 
-static int
-_CAIRO_FORMAT_DEPTH (cairo_format_t format)
-{
-    switch (format) {
-    case CAIRO_FORMAT_A1:
-	return 1;
-    case CAIRO_FORMAT_A8:
-	return 8;
-    case CAIRO_FORMAT_RGB24:
-	return 24;
-    case CAIRO_FORMAT_ARGB32:
-    default:
-	return 32;
-    }
-}
-
 cairo_surface_t *
 cairo_surface_create_similar_solid (cairo_surface_t	*other,
 				    cairo_format_t	format,
@@ -258,28 +155,10 @@
     cairo_surface_t *surface = NULL;
     cairo_color_t color;
 
-    /* XXX: There's a pretty lame heuristic here. This assumes that
-     * all non-Render X servers do not support depth-32 pixmaps, (and
-     * that they do support depths 1, 8, and 24). Obviously, it would
-     * be much better to check the depths that are actually
-     * supported. */
-    if (other->dpy
-	&& (CAIRO_SURFACE_RENDER_HAS_COMPOSITE (other)
-	    || format != CAIRO_FORMAT_ARGB32)) {
-	Display *dpy = other->dpy;
-	int scr = DefaultScreen (dpy);
-
-	Pixmap pix = XCreatePixmap (dpy,
-				    DefaultRootWindow (dpy),
-				    width, height,
-				    _CAIRO_FORMAT_DEPTH (format));
+    if (other->backend->create_similar)
+	surface = other->backend->create_similar (other, format, width, height);
 
-	surface = cairo_surface_create_for_drawable (dpy, pix,
-						     NULL,
-						     format,
-						     DefaultColormap (dpy, scr));
-	surface->owns_pixmap = 1;
-    } else {
+    if (!surface) {
 	char *data;
 	int stride;
 
@@ -325,149 +204,35 @@
     if (surface->ref_count)
 	return;
 
-    if (surface->picture)
-	XRenderFreePicture (surface->dpy, surface->picture);
-
-    if (surface->owns_pixmap)
-	XFreePixmap (surface->dpy, surface->drawable);
-
     if (surface->icformat)
 	IcFormatDestroy (surface->icformat);
-	
+
     if (surface->icimage)
 	IcImageDestroy (surface->icimage);
 
+    if (surface->backend->destroy)
+	surface->backend->destroy (surface);
+
     if (surface->image_data)
 	free (surface->image_data);
     surface->image_data = NULL;
 
-    surface->dpy = 0;
-
     free (surface);
 }
 slim_hidden_def(cairo_surface_destroy);
 
-static void
-_cairo_surface_ensure_gc (cairo_surface_t *surface)
-{
-    if (surface->gc)
-	return;
-
-    surface->gc = XCreateGC (surface->dpy, surface->drawable, 0, NULL);
-}
-
-static cairo_status_t
-_cairo_x11_surface_put_image (cairo_surface_t       *surface,
-			      char                   *data,
-			      int                    width,
-			      int                    height,
-			      int                    stride)
-{
-    if (surface->picture) {
-	XImage *image;
-	unsigned bitmap_pad;
-	
-	/* XXX: This is obviously bogus. depth needs to be figured out for real */
-	int depth = 32;
-
-	if (depth > 16)
-	    bitmap_pad = 32;
-	else if (depth > 8)
-	    bitmap_pad = 16;
-	else
-	    bitmap_pad = 8;
-
-	image = XCreateImage(surface->dpy,
-			     DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
-			     depth, ZPixmap, 0,
-			     data, width, height,
-			     bitmap_pad,
-			     stride);
-	if (image == NULL)
-	    return CAIRO_STATUS_NO_MEMORY;
-
-	_cairo_surface_ensure_gc (surface);
-	XPutImage(surface->dpy, surface->drawable, surface->gc,
-		  image, 0, 0, 0, 0, width, height);
-
-	/* Foolish XDestroyImage thinks it can free my data, but I won't
-	   stand for it. */
-	image->data = NULL;
-	XDestroyImage(image);
-    } else {
-	/* XXX: Need to implement the IcImage method of setting a picture. memcpy? */
-    }
-    
-    return CAIRO_STATUS_SUCCESS;
-}
-
 void
 _cairo_surface_pull_image (cairo_surface_t *surface)
 {
-    Window root_ignore;
-    int x_ignore, y_ignore, bwidth_ignore, depth_ignore;
-
-    if (surface == NULL)
-	return;
-
-    if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
-	return;
-
-    if (surface->icimage) {
-	IcImageDestroy (surface->icimage);
-	surface->icimage = NULL;
-    }
-
-    XGetGeometry(surface->dpy, 
-		 surface->drawable, 
-		 &root_ignore, &x_ignore, &y_ignore,
-		 &surface->width, &surface->height,
-		 &bwidth_ignore, &depth_ignore);
-
-    surface->ximage = XGetImage (surface->dpy,
-				 surface->drawable,
-				 0, 0,
-				 surface->width, surface->height,
-				 AllPlanes, ZPixmap);
-
-    surface->icimage = IcImageCreateForData ((IcBits *)(surface->ximage->data),
-					     surface->icformat,
-					     surface->ximage->width, 
-					     surface->ximage->height,
-					     surface->ximage->bits_per_pixel, 
-					     surface->ximage->bytes_per_line);
-     
-    IcImageSetRepeat (surface->icimage, surface->repeat);
-    /* XXX: Evil cast here... */
-    IcImageSetTransform (surface->icimage, (IcTransform *) &(surface->xtransform));
-    
-    /* XXX: Add support here for pictures with external alpha. */
+    if (surface->backend->pull_image)
+	surface->backend->pull_image (surface);
 }
 
 void
 _cairo_surface_push_image (cairo_surface_t *surface)
 {
-    if (surface == NULL)
-	return;
-
-    if (surface->type == CAIRO_SURFACE_TYPE_ICIMAGE)
-	return;
-
-    if (surface->ximage == NULL)
-	return;
-
-    _cairo_surface_ensure_gc (surface);
-    XPutImage (surface->dpy,
-	       surface->drawable,
-	       surface->gc,
-	       surface->ximage,
-	       0, 0,
-	       0, 0,
-	       surface->width,
-	       surface->height);
-
-    XDestroyImage(surface->ximage);
-    surface->ximage = NULL;
+    if (surface->backend->push_image)
+	surface->backend->push_image (surface);
 }
 
 /* XXX: We may want to move to projective matrices at some point. If
@@ -476,6 +241,7 @@
 cairo_status_t
 cairo_surface_set_matrix (cairo_surface_t *surface, cairo_matrix_t *matrix)
 {
+    cairo_status_t ret = CAIRO_STATUS_SUCCESS;
     XTransform *xtransform = &surface->xtransform;
 
     xtransform->matrix[0][0] = XDoubleToFixed (matrix->m[0][0]);
@@ -490,19 +256,15 @@
     xtransform->matrix[2][1] = 0;
     xtransform->matrix[2][2] = XDoubleToFixed (1);
 
-    if (surface->picture) {
-	if (CAIRO_SURFACE_RENDER_HAS_PICTURE_TRANSFORM (surface))
-	    XRenderSetPictureTransform (surface->dpy, surface->picture, xtransform);
-	/* XXX: Need support here if using an old RENDER without support
-           for SetPictureTransform */
-    }
+    if (surface->backend->set_matrix)
+	ret = surface->backend->set_matrix (surface);
 
     /* XXX: This cast should only occur with a #define hint from libic that it is OK */
     if (surface->icimage) {
 	IcImageSetTransform (surface->icimage, (IcTransform *) xtransform);
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    return ret;
 }
 slim_hidden_def(cairo_surface_set_matrix);
 
@@ -523,41 +285,17 @@
 }
 slim_hidden_def(cairo_surface_get_matrix);
 
-/* XXX: The Render specification has capitalized versions of these
-   strings. However, the current implementation is case-sensitive and
-   expects lowercase versions. */
-static char *
-_render_filter_name (cairo_filter_t filter)
-{
-    switch (filter) {
-    case CAIRO_FILTER_FAST:
-	return "fast";
-    case CAIRO_FILTER_GOOD:
-	return "good";
-    case CAIRO_FILTER_BEST:
-	return "best";
-    case CAIRO_FILTER_NEAREST:
-	return "nearest";
-    case CAIRO_FILTER_BILINEAR:
-	return "bilinear";
-    default:
-	return "best";
-    }
-}
-
 cairo_status_t
 cairo_surface_set_filter (cairo_surface_t *surface, cairo_filter_t filter)
 {
-    if (surface->picture) {
-	XRenderSetPictureFilter (surface->dpy, surface->picture,
-				 _render_filter_name (filter), NULL, 0);
-    }
-
     if (surface->icimage) {
 	IcImageSetFilter (surface->icimage, filter);
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    if (!surface->backend->set_filter)
+	return CAIRO_STATUS_SUCCESS;
+
+    return surface->backend->set_filter (surface, filter);
 }
 
 /* XXX: NYI
@@ -580,21 +318,14 @@
 {
     surface->repeat = repeat;
 
-    if (surface->picture) {
-	unsigned long mask;
-	XRenderPictureAttributes pa;
-	
-	mask = CPRepeat;
-	pa.repeat = repeat;
-
-	XRenderChangePicture (surface->dpy, surface->picture, mask, &pa);
-    }
-
     if (surface->icimage) {
 	IcImageSetRepeat (surface->icimage, repeat);
     }
 
-    return CAIRO_STATUS_SUCCESS;
+    if (!surface->backend->set_repeat)
+	return CAIRO_STATUS_SUCCESS;
+
+    return surface->backend->set_repeat (surface, repeat);
 }
 slim_hidden_def(cairo_surface_set_repeat);
 
@@ -612,58 +343,25 @@
 			  unsigned int		width,
 			  unsigned int		height)
 {
-    if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
-	&& CAIRO_SURFACE_RENDER_HAS_COMPOSITE (dst)
-	&& (mask == NULL || mask->dpy == dst->dpy)
-	&& (src->type == CAIRO_SURFACE_TYPE_ICIMAGE || src->dpy == dst->dpy)) {
-
-	cairo_surface_t *src_on_server = NULL;
-
-	if (src->type == CAIRO_SURFACE_TYPE_ICIMAGE) {
-	    cairo_matrix_t matrix;
-	    src_on_server = cairo_surface_create_similar (dst, CAIRO_FORMAT_ARGB32,
-							  IcImageGetWidth (src->icimage),
-							  IcImageGetHeight (src->icimage));
-	    if (src_on_server == NULL)
-		return;
-
-	    cairo_surface_get_matrix (src, &matrix);
-	    cairo_surface_set_matrix (src_on_server, &matrix);
-
-	    _cairo_x11_surface_put_image (src_on_server,
-					  (char *) IcImageGetData (src->icimage),
-					  IcImageGetWidth (src->icimage),
-					  IcImageGetHeight (src->icimage),
-					  IcImageGetStride (src->icimage));
-	}
+    if (dst->backend->composite
+	&& (dst->backend->composite (operator, src, mask, dst, src_x, src_y, mask_x, mask_y, dst_x, dst_y, width, height) >= 0))
+	return;
 
-	XRenderComposite (dst->dpy, operator,
-			  src_on_server ? src_on_server->picture : src->picture,
-			  mask ? mask->picture : 0,
-			  dst->picture,
-			  src_x, src_y,
-			  mask_x, mask_y,
-			  dst_x, dst_y,
-			  width, height);
-	
-	
-    } else {
-	_cairo_surface_pull_image (src);
-	if (mask)
-	    _cairo_surface_pull_image (mask);
-	_cairo_surface_pull_image (dst);
+    _cairo_surface_pull_image (src);
+    if (mask)
+	_cairo_surface_pull_image (mask);
+    _cairo_surface_pull_image (dst);
 
-	IcComposite (operator,
-		     src->icimage,
-		     mask ? mask->icimage : NULL,
-		     dst->icimage,
-		     src_x, src_y,
-		     mask_x, mask_y,
-		     dst_x, dst_y,
-		     width, height);
+    IcComposite (operator,
+		 src->icimage,
+		 mask ? mask->icimage : NULL,
+		 dst->icimage,
+		 src_x, src_y,
+		 mask_x, mask_y,
+		 dst_x, dst_y,
+		 width, height);
 
-	_cairo_surface_push_image (dst);
-    }
+    _cairo_surface_push_image (dst);
 }
 
 void
@@ -692,38 +390,27 @@
 				cairo_rectangle_t	*rects,
 				int			num_rects)
 {
+    IcColor ic_color;
+
     if (num_rects == 0)
 	return;
 
-    if (surface->type == CAIRO_SURFACE_TYPE_DRAWABLE
-	&& CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface)) {
-
-	XRenderColor render_color;
-	render_color.red   = color->red_short;
-	render_color.green = color->green_short;
-	render_color.blue  = color->blue_short;
-	render_color.alpha = color->alpha_short;
-
-	/* XXX: This XRectangle cast is evil... it needs to go away somehow. */
-	XRenderFillRectangles (surface->dpy, operator, surface->picture,
-			       &render_color, (XRectangle *) rects, num_rects);
-
-    } else {
-	IcColor ic_color;
+    if (surface->backend->fill_rectangles
+	&& (surface->backend->fill_rectangles (surface, operator, color, rects, num_rects) >= 0))
+	return;
 
-	ic_color.red   = color->red_short;
-	ic_color.green = color->green_short;
-	ic_color.blue  = color->blue_short;
-	ic_color.alpha = color->alpha_short;
+    ic_color.red   = color->red_short;
+    ic_color.green = color->green_short;
+    ic_color.blue  = color->blue_short;
+    ic_color.alpha = color->alpha_short;
 
-	_cairo_surface_pull_image (surface);
+    _cairo_surface_pull_image (surface);
 
-	/* XXX: The IcRectangle cast is evil... it needs to go away somehow. */
-	IcFillRectangles (operator, surface->icimage,
-			  &ic_color, (IcRectangle *) rects, num_rects);
+    /* XXX: The IcRectangle cast is evil... it needs to go away somehow. */
+    IcFillRectangles (operator, surface->icimage,
+		      &ic_color, (IcRectangle *) rects, num_rects);
 
-	_cairo_surface_push_image (surface);
-    }
+    _cairo_surface_push_image (surface);
 }
 
 void
@@ -735,23 +422,17 @@
 				     cairo_trapezoid_t		*traps,
 				     int			num_traps)
 {
-    if (dst->type == CAIRO_SURFACE_TYPE_DRAWABLE
-	&& CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst)
-	&& src->dpy == dst->dpy) {
+    if (dst->backend->composite_trapezoids
+	&& (dst->backend->composite_trapezoids (operator, src, dst, xSrc, ySrc, traps, num_traps) >= 0))
+	return;
 
-	/* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
-	XRenderCompositeTrapezoids (dst->dpy, operator, src->picture, dst->picture,
-				    XRenderFindStandardFormat (dst->dpy, PictStandardA8),
-				    xSrc, ySrc, (XTrapezoid *) traps, num_traps);
-    } else {
-	_cairo_surface_pull_image (src);
-	_cairo_surface_pull_image (dst);
+    _cairo_surface_pull_image (src);
+    _cairo_surface_pull_image (dst);
 
-	/* XXX: The IcTrapezoid cast is evil and needs to go away somehow. */
-	IcCompositeTrapezoids (operator, src->icimage, dst->icimage,
-			       xSrc, ySrc, (IcTrapezoid *) traps, num_traps);
+    /* XXX: The IcTrapezoid cast is evil and needs to go away somehow. */
+    IcCompositeTrapezoids (operator, src->icimage, dst->icimage,
+			   xSrc, ySrc, (IcTrapezoid *) traps, num_traps);
 
-	_cairo_surface_push_image (dst);
-    }
+    _cairo_surface_push_image (dst);
 }
 

Index: cairoint.h
===================================================================
RCS file: /local/src/CVS/cairo/src/cairoint.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- cairoint.h	30 Sep 2003 20:15:09 -0000	1.24
+++ cairoint.h	1 Oct 2003 01:56:22 -0000	1.25
@@ -37,10 +37,9 @@
 #define _CAIROINT_H_
 
 #include <assert.h>
-
+#include <stdlib.h>
+#include <string.h>
 #include <math.h>
-#include <X11/Xlibint.h>
-#include <X11/Xft/Xft.h>
 
 #include "cairo.h"
 
@@ -226,10 +225,44 @@
     cairo_pen_vertex_t *vertex;
 } cairo_pen_t;
 
-typedef enum cairo_surface_type {
-    CAIRO_SURFACE_TYPE_DRAWABLE,
-    CAIRO_SURFACE_TYPE_ICIMAGE
-} cairo_surface_type_t;
+typedef struct cairo_color cairo_color_t;
+
+struct cairo_surface_backend {
+    cairo_surface_t *(*create_similar) (cairo_surface_t	*surface,
+					cairo_format_t	format,
+					int		width,
+					int		height);
+    void (*destroy) (cairo_surface_t *surface);
+    void (*pull_image) (cairo_surface_t *surface);
+    void (*push_image) (cairo_surface_t *surface);
+    cairo_status_t (*set_matrix) (cairo_surface_t *surface);
+    cairo_status_t (*set_filter) (cairo_surface_t *surface, cairo_filter_t filter);
+    cairo_status_t (*set_repeat) (cairo_surface_t *surface, int repeat);
+    int (*composite) (cairo_operator_t	operator,
+		      cairo_surface_t	*src,
+		      cairo_surface_t	*mask,
+		      cairo_surface_t	*dst,
+		      int		src_x,
+		      int		src_y,
+		      int		mask_x,
+		      int		mask_y,
+		      int		dst_x,
+		      int		dst_y,
+		      unsigned int	width,
+		      unsigned int	height);
+    int (*fill_rectangles) (cairo_surface_t	*surface,
+			    cairo_operator_t	operator,
+			    const cairo_color_t	*color,
+			    cairo_rectangle_t	*rects,
+			    int			num_rects);
+    int (*composite_trapezoids) (cairo_operator_t	operator,
+				 cairo_surface_t	*src,
+				 cairo_surface_t	*dst,
+				 int			xSrc,
+				 int			ySrc,
+				 cairo_trapezoid_t	*traps,
+				 int			num_traps);
+};
 
 struct cairo_surface {
     int width;
@@ -241,25 +274,12 @@
     unsigned int ref_count;
     int repeat;
 
-    cairo_surface_type_t type;
     XTransform xtransform;
 
-    /* For TYPE_DRAWABLE */
-    Display *dpy;
-    GC gc;
-    Drawable drawable;
-    Visual *visual;
-    int owns_pixmap;
-
-    int render_major;
-    int render_minor;
-
-    Picture picture;
-    XImage *ximage;
-
-    /* For TYPE_ICIMAGE */
     IcImage *icimage;
     IcFormat *icformat;
+
+    const struct cairo_surface_backend *backend;
 };
 
 /* XXX: Right now, the cairo_color structure puts unpremultiplied
@@ -268,7 +288,7 @@
    madness). I'm still working on a cleaner API, but in the meantime,
    at least this does prevent precision loss in color when changing
    alpha. */
-typedef struct cairo_color {
+struct cairo_color {
     double red;
     double green;
     double blue;
@@ -278,7 +298,7 @@
     unsigned short green_short;
     unsigned short blue_short;
     unsigned short alpha_short;
-} cairo_color_t;
+};
 
 struct cairo_matrix {
     double m[3][2];
@@ -290,17 +310,35 @@
     int traps_size;
 } cairo_traps_t;
 
+typedef struct cairo_font cairo_font_t;
+
+struct cairo_font_backend {
+    cairo_font_t *(*copy) (cairo_font_t *other);
+    void (*close) (cairo_font_t *font);
+    cairo_status_t (*text_extents) (cairo_font_t *font,
+				    cairo_matrix_t *ctm,
+				    const unsigned char *utf8,
+				    double *x, double *y,
+				    double *width, double *height,
+				    double *dx, double *dy);
+    cairo_status_t (*show_text) (cairo_font_t		*font,
+				 cairo_matrix_t		*ctm,
+				 cairo_operator_t	operator,
+				 cairo_surface_t	*source,
+				 cairo_surface_t	*surface,
+				 double			x,
+				 double			y,
+				 const unsigned char	*utf8);
+};
+
 #define CAIRO_FONT_KEY_DEFAULT		"serif"
 
-typedef struct cairo_font {
+struct cairo_font {
     unsigned char *key;
-
-    double scale;
     cairo_matrix_t matrix;
 
-    Display *dpy;
-    XftFont *xft_font;
-} cairo_font_t;
+    const struct cairo_font_backend *backend;
+};
 
 #define CAIRO_GSTATE_OPERATOR_DEFAULT	CAIRO_OPERATOR_OVER
 #define CAIRO_GSTATE_TOLERANCE_DEFAULT	0.1
@@ -336,7 +374,7 @@
     int num_dashes;
     double dash_offset;
 
-    cairo_font_t font;
+    cairo_font_t *font;
 
     cairo_surface_t *surface;
 
@@ -636,11 +674,14 @@
 
 /* cairo_font.c */
 extern void __internal_linkage
-_cairo_font_init (cairo_font_t *font);
+_cairo_font_init (cairo_font_t *font, const struct cairo_font_backend *backend);
 
 extern cairo_status_t __internal_linkage
 _cairo_font_init_copy (cairo_font_t *font, cairo_font_t *other);
 
+extern cairo_font_t * __internal_linkage
+_cairo_font_copy (cairo_font_t *font);
+
 extern void __internal_linkage
 _cairo_font_fini (cairo_font_t *font);
 
@@ -656,7 +697,22 @@
 		       double c, double d);
 
 extern cairo_status_t __internal_linkage
-_cairo_font_resolve_xft_font (cairo_font_t *font, cairo_gstate_t *gstate, XftFont **xft_font);
+_cairo_font_text_extents (cairo_font_t *font,
+			  cairo_matrix_t *ctm,
+			  const unsigned char *utf8,
+			  double *x, double *y,
+			  double *width, double *height,
+			  double *dx, double *dy);
+
+extern cairo_status_t __internal_linkage
+_cairo_font_show_text (cairo_font_t		*font,
+		       cairo_matrix_t		*ctm,
+		       cairo_operator_t		operator,
+		       cairo_surface_t		*source,
+		       cairo_surface_t		*surface,
+		       double			x,
+		       double			y,
+		       const unsigned char	*utf8);
 
 /* cairo_path.c */
 extern void __internal_linkage
@@ -702,6 +758,13 @@
 
 /* cairo_surface.c */
 extern void __internal_linkage
+_cairo_surface_init (cairo_surface_t			*surface,
+		     int				width,
+		     int				height,
+		     cairo_format_t			format,
+		     const struct cairo_surface_backend	*backend);
+
+extern void __internal_linkage
 _cairo_surface_fill_rectangle (cairo_surface_t	*surface,
 			       cairo_operator_t	operator,
 			       cairo_color_t	*color,
@@ -889,7 +952,6 @@
 slim_hidden_proto(cairo_restore)
 slim_hidden_proto(cairo_save)
 slim_hidden_proto(cairo_set_target_surface)
-slim_hidden_proto(cairo_surface_create_for_drawable)
 slim_hidden_proto(cairo_surface_create_for_image)
 slim_hidden_proto(cairo_surface_create_similar_solid)
 slim_hidden_proto(cairo_surface_destroy)




More information about the Commit mailing list