[cairo] Disabling antialiased shape drawing

Billy Biggs vektor at dumbterm.net
Sun Aug 7 22:38:51 PDT 2005


  Attached is hopefully the final attempt at the patch.  The clipping
changes required that I pass the value around more than before.  This
patch also adds a test case, although libpixman and my X server give
rather different results. :)

  Good to go?

  -Billy

-------------- next part --------------
Index: doc/public/cairo-sections.txt
===================================================================
RCS file: /cvs/cairo/cairo/doc/public/cairo-sections.txt,v
retrieving revision 1.29
diff -p -u -r1.29 cairo-sections.txt
--- doc/public/cairo-sections.txt	5 Aug 2005 17:46:40 -0000	1.29
+++ doc/public/cairo-sections.txt	8 Aug 2005 05:32:56 -0000
@@ -169,7 +169,6 @@ cairo_font_options_status
 cairo_font_options_merge
 cairo_font_options_hash
 cairo_font_options_equal
-cairo_antialias_t
 cairo_font_options_set_antialias
 cairo_font_options_get_antialias
 cairo_subpixel_order_t
@@ -203,6 +202,8 @@ cairo_set_source_rgba
 cairo_set_source
 cairo_set_source_surface
 cairo_set_tolerance
+cairo_antialias_t
+cairo_set_shape_antialias
 cairo_fill_rule_t
 cairo_set_fill_rule
 cairo_set_line_width
@@ -272,6 +273,7 @@ cairo_glyph_path
 cairo_get_operator
 cairo_get_source
 cairo_get_tolerance
+cairo_get_shape_antialias
 cairo_get_current_point
 cairo_get_fill_rule
 cairo_get_line_width
Index: doc/public/tmpl/cairo-font.sgml
===================================================================
RCS file: /cvs/cairo/cairo/doc/public/tmpl/cairo-font.sgml,v
retrieving revision 1.10
diff -p -u -r1.10 cairo-font.sgml
--- doc/public/tmpl/cairo-font.sgml	5 Aug 2005 17:30:31 -0000	1.10
+++ doc/public/tmpl/cairo-font.sgml	8 Aug 2005 05:32:56 -0000
@@ -228,16 +228,6 @@ Font Handling
 @Returns: 
 
 
-<!-- ##### ENUM cairo_antialias_t ##### -->
-<para>
-
-</para>
-
- at CAIRO_ANTIALIAS_DEFAULT: 
- at CAIRO_ANTIALIAS_NONE: 
- at CAIRO_ANTIALIAS_GRAY: 
- at CAIRO_ANTIALIAS_SUBPIXEL: 
-
 <!-- ##### FUNCTION cairo_font_options_set_antialias ##### -->
 <para>
 
Index: doc/public/tmpl/cairo.sgml
===================================================================
RCS file: /cvs/cairo/cairo/doc/public/tmpl/cairo.sgml,v
retrieving revision 1.28
diff -p -u -r1.28 cairo.sgml
--- doc/public/tmpl/cairo.sgml	5 Aug 2005 17:30:31 -0000	1.28
+++ doc/public/tmpl/cairo.sgml	8 Aug 2005 05:32:57 -0000
@@ -191,6 +191,25 @@ Drawing contexts.
 @tolerance: 
 
 
+<!-- ##### ENUM cairo_antialias_t ##### -->
+<para>
+
+</para>
+
+ at CAIRO_ANTIALIAS_DEFAULT: 
+ at CAIRO_ANTIALIAS_NONE: 
+ at CAIRO_ANTIALIAS_GRAY: 
+ at CAIRO_ANTIALIAS_SUBPIXEL: 
+
+<!-- ##### FUNCTION cairo_set_shape_antialias ##### -->
+<para>
+
+</para>
+
+ at cr: 
+ at antialias: 
+
+
 <!-- ##### ENUM cairo_fill_rule_t ##### -->
 <para>
 
@@ -846,6 +865,15 @@ Drawing contexts.
 @Returns: 
 
 
+<!-- ##### FUNCTION cairo_get_shape_antialias ##### -->
+<para>
+
+</para>
+
+ at cr: 
+ at Returns: 
+
+
 <!-- ##### FUNCTION cairo_get_current_point ##### -->
 <para>
 
Index: src/cairo-clip-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-clip-private.h,v
retrieving revision 1.1
diff -p -u -r1.1 cairo-clip-private.h
--- src/cairo-clip-private.h	5 Aug 2005 05:45:59 -0000	1.1
+++ src/cairo-clip-private.h	8 Aug 2005 05:32:57 -0000
@@ -49,6 +49,7 @@ struct _cairo_clip_path {
     cairo_path_fixed_t	path;
     cairo_fill_rule_t	fill_rule;
     double		tolerance;
+    cairo_antialias_t	shape_antialias;
     cairo_clip_path_t	*prev;
 };
 
@@ -100,6 +101,7 @@ _cairo_clip_clip (cairo_clip_t       *cl
 		  cairo_path_fixed_t *path,
 		  cairo_fill_rule_t   fill_rule,
 		  double              tolerance,
+		  cairo_antialias_t   shape_antialias,
 		  cairo_surface_t    *target);
 
 cairo_private cairo_status_t
Index: src/cairo-clip.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-clip.c,v
retrieving revision 1.1
diff -p -u -r1.1 cairo-clip.c
--- src/cairo-clip.c	5 Aug 2005 05:45:59 -0000	1.1
+++ src/cairo-clip.c	8 Aug 2005 05:32:57 -0000
@@ -242,6 +242,7 @@ _cairo_clip_intersect_path (cairo_clip_t
 			    cairo_path_fixed_t *path,
 			    cairo_fill_rule_t   fill_rule,
 			    double              tolerance,
+			    cairo_antialias_t   shape_antialias,
 			    cairo_surface_t    *target)
 {
     cairo_clip_path_t *clip_path;
@@ -261,6 +262,7 @@ _cairo_clip_intersect_path (cairo_clip_t
     clip_path->ref_count = 1;
     clip_path->fill_rule = fill_rule;
     clip_path->tolerance = tolerance;
+    clip_path->shape_antialias = shape_antialias;
     clip_path->prev = clip->path;
     clip->path = clip_path;
     clip->serial = _cairo_surface_allocate_clip_serial (target);
@@ -335,9 +337,10 @@ _cairo_clip_intersect_region (cairo_clip
 }
 
 static cairo_status_t
-_cairo_clip_intersect_mask (cairo_clip_t    *clip,
-			    cairo_traps_t   *traps,
-			    cairo_surface_t *target)
+_cairo_clip_intersect_mask (cairo_clip_t      *clip,
+			    cairo_traps_t     *traps,
+			    cairo_antialias_t shape_antialias,
+			    cairo_surface_t   *target)
 {
     cairo_pattern_union_t pattern;
     cairo_box_t extents;
@@ -371,6 +374,7 @@ _cairo_clip_intersect_mask (cairo_clip_t
     status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_IN,
 						  &pattern.base,
 						  surface,
+						  shape_antialias,
 						  0, 0,
 						  0, 0,
 						  surface_rect.width,
@@ -425,6 +429,7 @@ _cairo_clip_clip (cairo_clip_t       *cl
 		  cairo_path_fixed_t *path,
 		  cairo_fill_rule_t   fill_rule,
 		  double              tolerance,
+		  cairo_antialias_t   shape_antialias,
 		  cairo_surface_t    *target)
 {
     cairo_status_t status;
@@ -432,7 +437,7 @@ _cairo_clip_clip (cairo_clip_t       *cl
     
     status = _cairo_clip_intersect_path (clip,
 					 path, fill_rule, tolerance,
-					 target);
+					 shape_antialias, target);
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	return status;
 
@@ -448,7 +453,7 @@ _cairo_clip_clip (cairo_clip_t       *cl
     if (status != CAIRO_INT_STATUS_UNSUPPORTED)
 	goto bail;
 
-    status = _cairo_clip_intersect_mask (clip, &traps, target);
+    status = _cairo_clip_intersect_mask (clip, &traps, shape_antialias, target);
 	
  bail:
     _cairo_traps_fini (&traps);
Index: src/cairo-glitz-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-glitz-surface.c,v
retrieving revision 1.55
diff -p -u -r1.55 cairo-glitz-surface.c
--- src/cairo-glitz-surface.c	5 Aug 2005 01:44:29 -0000	1.55
+++ src/cairo-glitz-surface.c	8 Aug 2005 05:32:58 -0000
@@ -936,6 +936,7 @@ static cairo_int_status_t
 _cairo_glitz_surface_composite_trapezoids (cairo_operator_t  op,
 					   cairo_pattern_t   *pattern,
 					   void		     *abstract_dst,
+					   cairo_antialias_t shape_antialias,
 					   int		     src_x,
 					   int		     src_y,
 					   int		     dst_x,
Index: src/cairo-gstate-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate-private.h,v
retrieving revision 1.15
diff -p -u -r1.15 cairo-gstate-private.h
--- src/cairo-gstate-private.h	5 Aug 2005 05:45:59 -0000	1.15
+++ src/cairo-gstate-private.h	8 Aug 2005 05:32:58 -0000
@@ -42,6 +42,7 @@ struct _cairo_gstate {
     cairo_operator_t operator;
     
     double tolerance;
+    cairo_antialias_t shape_antialias;
 
     /* stroke style */
     double line_width;
Index: src/cairo-gstate.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-gstate.c,v
retrieving revision 1.159
diff -p -u -r1.159 cairo-gstate.c
--- src/cairo-gstate.c	6 Aug 2005 23:57:14 -0000	1.159
+++ src/cairo-gstate.c	8 Aug 2005 05:32:58 -0000
@@ -92,6 +92,7 @@ _cairo_gstate_init (cairo_gstate_t  *gst
     gstate->operator = CAIRO_GSTATE_OPERATOR_DEFAULT;
 
     gstate->tolerance = CAIRO_GSTATE_TOLERANCE_DEFAULT;
+    gstate->shape_antialias = CAIRO_GSTATE_SHAPE_ANTIALIAS_DEFAULT;
 
     gstate->line_width = CAIRO_GSTATE_LINE_WIDTH_DEFAULT;
     gstate->line_cap = CAIRO_GSTATE_LINE_CAP_DEFAULT;
@@ -982,6 +983,7 @@ _composite_traps_intermediate_surface (c
 				       cairo_operator_t   operator,
 				       cairo_surface_t   *dst,
 				       cairo_traps_t     *traps,
+				       cairo_antialias_t  shape_antialias,
 				       cairo_rectangle_t *extents)
 {
     cairo_pattern_union_t pattern;
@@ -1004,6 +1006,7 @@ _composite_traps_intermediate_surface (c
     status = _cairo_surface_composite_trapezoids (CAIRO_OPERATOR_ADD,
 						  &pattern.base,
 						  intermediate,
+						  shape_antialias,
 						  extents->x, extents->y,
 						  0, 0,
 						  extents->width,
@@ -1086,12 +1089,14 @@ _composite_traps (cairo_clip_t      *cli
 		  cairo_operator_t   operator,
 		  cairo_surface_t   *dst,
 		  cairo_traps_t     *traps,
+		  cairo_antialias_t  shape_antialias,
 		  cairo_rectangle_t *extents)
 {
     cairo_status_t status;
 
     status = _cairo_surface_composite_trapezoids (operator,
 						  src, dst,
+						  shape_antialias,
 						  extents->x, extents->y,
 						  extents->x, extents->y,
 						  extents->width,
@@ -1121,7 +1126,8 @@ _cairo_surface_clip_and_composite_trapez
 					      cairo_operator_t operator,
 					      cairo_surface_t *dst,
 					      cairo_traps_t *traps,
-					      cairo_clip_t *clip)
+					      cairo_clip_t *clip,
+					      cairo_antialias_t shape_antialias)
 {
     cairo_status_t status;
     pixman_region16_t *trap_region;
@@ -1166,7 +1172,9 @@ _cairo_surface_clip_and_composite_trapez
 	
 	/* Handle a clip surface by creating an intermediate surface. */
 	status = _composite_traps_intermediate_surface (clip, src, operator,
-							dst, traps, &extents);
+							dst, traps,
+							shape_antialias,
+							&extents);
     } else {
         /* No clip surface */
 	if (trap_region && src->type == CAIRO_PATTERN_SOLID) {
@@ -1189,7 +1197,7 @@ _cairo_surface_clip_and_composite_trapez
 	    }
 	  
 	  status = _composite_traps (clip, src, operator,
-				     dst, traps, &extents);
+				     dst, traps, shape_antialias, &extents);
 	}
     }
 
@@ -1214,7 +1222,8 @@ _cairo_gstate_clip_and_composite_trapezo
 							 gstate->operator,
 							 gstate->target,
 							 traps,
-							 &gstate->clip);
+							 &gstate->clip,
+							 gstate->shape_antialias);
 
   _cairo_pattern_fini (&pattern.base);
 
@@ -1383,7 +1392,7 @@ _cairo_gstate_clip (cairo_gstate_t *gsta
 {
     return _cairo_clip_clip (&gstate->clip,
 			     path, gstate->fill_rule, gstate->tolerance,
-			     gstate->target);
+			     gstate->shape_antialias, gstate->target);
 }
 
 static void
@@ -1861,3 +1870,19 @@ _cairo_gstate_glyph_path (cairo_gstate_t
     free (transformed_glyphs);
     return status;
 }
+
+cairo_private cairo_status_t
+_cairo_gstate_set_shape_antialias (cairo_gstate_t *gstate,
+				   cairo_antialias_t antialias)
+{
+    gstate->shape_antialias = antialias;
+
+    return CAIRO_STATUS_SUCCESS;
+}
+
+cairo_private cairo_antialias_t
+_cairo_gstate_get_shape_antialias (cairo_gstate_t *gstate)
+{
+    return gstate->shape_antialias;
+}
+
Index: src/cairo-image-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-image-surface.c,v
retrieving revision 1.55
diff -p -u -r1.55 cairo-image-surface.c
--- src/cairo-image-surface.c	5 Aug 2005 01:44:29 -0000	1.55
+++ src/cairo-image-surface.c	8 Aug 2005 05:32:59 -0000
@@ -648,6 +648,7 @@ static cairo_int_status_t
 _cairo_image_surface_composite_trapezoids (cairo_operator_t	operator,
 					   cairo_pattern_t	*pattern,
 					   void			*abstract_dst,
+					   cairo_antialias_t	shape_antialias,
 					   int			src_x,
 					   int			src_y,
 					   int			dst_x,
@@ -663,6 +664,18 @@ _cairo_image_surface_composite_trapezoid
     cairo_int_status_t		status;
     int				render_reference_x, render_reference_y;
     int				render_src_x, render_src_y;
+    pixman_format_t		*image_format;
+
+    switch (shape_antialias) {
+    case CAIRO_ANTIALIAS_NONE:
+	image_format = pixman_format_create (PIXMAN_FORMAT_NAME_A1);
+	break;
+    default:
+	image_format = pixman_format_create (PIXMAN_FORMAT_NAME_A8);
+	break;
+    }
+    if (!image_format)
+        return CAIRO_STATUS_NO_MEMORY;
 
     status = _cairo_pattern_acquire_surface (pattern, &dst->base,
 					     src_x, src_y, width, height,
@@ -689,12 +702,15 @@ _cairo_image_surface_composite_trapezoid
 	pixman_composite_trapezoids (_pixman_operator (operator),
 				     src->pixman_image,
 				     dst->pixman_image,
+				     image_format,
 				     render_src_x + attributes.x_offset,
 				     render_src_y + attributes.y_offset,
 				     (pixman_trapezoid_t *) traps, num_traps);
 
     _cairo_pattern_release_surface (pattern, &src->base, &attributes);
 
+    pixman_format_destroy (image_format);
+
     return status;
 }
 
Index: src/cairo-meta-surface-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface-private.h,v
retrieving revision 1.2
diff -p -u -r1.2 cairo-meta-surface-private.h
--- src/cairo-meta-surface-private.h	13 Jul 2005 19:32:51 -0000	1.2
+++ src/cairo-meta-surface-private.h	8 Aug 2005 05:32:59 -0000
@@ -77,6 +77,7 @@ typedef struct _cairo_command_composite_
     cairo_command_type_t	type;
     cairo_operator_t		operator;
     cairo_pattern_union_t	pattern;
+    cairo_antialias_t		shape_antialias;
     int				x_src;
     int				y_src;
     int				x_dst;
@@ -99,6 +100,7 @@ typedef struct _cairo_command_intersect_
     cairo_path_fixed_t		path;
     cairo_fill_rule_t		fill_rule;
     double			tolerance;
+    cairo_antialias_t		shape_antialias;
 } cairo_command_intersect_clip_path_t;
 
 typedef struct _cairo_command_show_glyphs {
@@ -123,6 +125,7 @@ typedef struct _cairo_command_fill_path 
     cairo_path_fixed_t		path;
     cairo_fill_rule_t		fill_rule;
     double			tolerance;
+    cairo_antialias_t		shape_antialias;
 } cairo_command_fill_path_t;
 
 typedef union _cairo_command {
Index: src/cairo-meta-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-meta-surface.c,v
retrieving revision 1.7
diff -p -u -r1.7 cairo-meta-surface.c
--- src/cairo-meta-surface.c	5 Aug 2005 05:45:59 -0000	1.7
+++ src/cairo-meta-surface.c	8 Aug 2005 05:32:59 -0000
@@ -217,6 +217,7 @@ static cairo_int_status_t
 _cairo_meta_surface_composite_trapezoids (cairo_operator_t	operator,
 					  cairo_pattern_t	*pattern,
 					  void			*abstract_surface,
+					  cairo_antialias_t	shape_antialias,
 					  int			x_src,
 					  int			y_src,
 					  int			x_dst,
@@ -236,6 +237,7 @@ _cairo_meta_surface_composite_trapezoids
     command->type = CAIRO_COMMAND_COMPOSITE_TRAPEZOIDS;
     command->operator = operator;
     _cairo_pattern_init_copy (&command->pattern.base, pattern);
+    command->shape_antialias = shape_antialias;
     command->x_src = x_src;
     command->y_src = y_src;
     command->x_dst = x_dst;
@@ -267,7 +269,8 @@ static cairo_int_status_t
 _cairo_meta_surface_intersect_clip_path (void		    *dst,
 					 cairo_path_fixed_t *path,
 					 cairo_fill_rule_t   fill_rule,
-					 double		     tolerance)
+					 double		     tolerance,
+					 cairo_antialias_t   shape_antialias)
 {
     cairo_meta_surface_t *meta = dst;
     cairo_command_intersect_clip_path_t *command;
@@ -291,6 +294,7 @@ _cairo_meta_surface_intersect_clip_path 
     }
     command->fill_rule = fill_rule;
     command->tolerance = tolerance;
+    command->shape_antialias = shape_antialias;
 
     if (_cairo_array_append (&meta->commands, &command, 1) == NULL) {
 	if (path)
@@ -494,6 +498,7 @@ _cairo_meta_surface_replay (cairo_surfac
 		(command->composite_trapezoids.operator,
 		 &command->composite_trapezoids.pattern.base,
 		 target,
+		 command->composite_trapezoids.shape_antialias,
 		 command->composite_trapezoids.x_src,
 		 command->composite_trapezoids.y_src,
 		 command->composite_trapezoids.x_dst,
@@ -514,6 +519,7 @@ _cairo_meta_surface_replay (cairo_surfac
 					   command->intersect_clip_path.path_pointer,
 					   command->intersect_clip_path.fill_rule,
 					   command->intersect_clip_path.tolerance,
+					   command->intersect_clip_path.shape_antialias,
 					   target);
 	    break;
 
@@ -566,7 +572,8 @@ _cairo_meta_surface_replay (cairo_surfac
 								   command->fill_path.operator,
 								   target,
 								   &traps,
-								   &clip);
+								   &clip,
+								   command->fill_path.shape_antialias);
 
 	    _cairo_traps_fini (&traps);
 	    break;
Index: src/cairo-path-data-private.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-path-data-private.h,v
retrieving revision 1.8
diff -p -u -r1.8 cairo-path-data-private.h
--- src/cairo-path-data-private.h	5 Aug 2005 17:30:31 -0000	1.8
+++ src/cairo-path-data-private.h	8 Aug 2005 05:32:59 -0000
@@ -38,7 +38,7 @@
 
 #include "cairoint.h"
 
-cairo_private const cairo_path_t _cairo_path_nil;
+extern cairo_private const cairo_path_t _cairo_path_nil;
 
 cairo_private cairo_path_t *
 _cairo_path_data_create (cairo_path_fixed_t *path,
Index: src/cairo-pdf-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-pdf-surface.c,v
retrieving revision 1.55
diff -p -u -r1.55 cairo-pdf-surface.c
--- src/cairo-pdf-surface.c	5 Aug 2005 01:44:29 -0000	1.55
+++ src/cairo-pdf-surface.c	8 Aug 2005 05:33:00 -0000
@@ -1151,6 +1151,7 @@ static cairo_int_status_t
 _cairo_pdf_surface_composite_trapezoids (cairo_operator_t	operator,
 					 cairo_pattern_t	*pattern,
 					 void			*abstract_dst,
+					 cairo_antialias_t	shape_antialias,
 					 int			x_src,
 					 int			y_src,
 					 int			x_dst,
@@ -1334,7 +1335,8 @@ static cairo_int_status_t
 _cairo_pdf_surface_intersect_clip_path (void			*dst,
 					cairo_path_fixed_t	*path,
 					cairo_fill_rule_t	fill_rule,
-					double			tolerance)
+					double			tolerance,
+					cairo_antialias_t	shape_antialias)
 {
     cairo_pdf_surface_t *surface = dst;
     cairo_pdf_document_t *document = surface->document;
Index: src/cairo-ps-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-ps-surface.c,v
retrieving revision 1.45
diff -p -u -r1.45 cairo-ps-surface.c
--- src/cairo-ps-surface.c	28 Jul 2005 16:46:38 -0000	1.45
+++ src/cairo-ps-surface.c	8 Aug 2005 05:33:00 -0000
@@ -272,6 +272,7 @@ static cairo_int_status_t
 _cairo_ps_surface_composite_trapezoids (cairo_operator_t	operator,
 					cairo_pattern_t		*pattern,
 					void			*abstract_dst,
+					cairo_antialias_t	shape_antialias,
 					int			x_src,
 					int			y_src,
 					int			x_dst,
@@ -286,6 +287,7 @@ _cairo_ps_surface_composite_trapezoids (
     return _cairo_surface_composite_trapezoids (operator,
 						pattern,
 						surface->current_page,
+						shape_antialias,
 						x_src,
 						y_src,
 						x_dst,
@@ -324,14 +326,16 @@ static cairo_int_status_t
 _cairo_ps_surface_intersect_clip_path (void		  *dst,
 				       cairo_path_fixed_t *path,
 				       cairo_fill_rule_t   fill_rule,
-				       double		   tolerance)
+				       double		   tolerance,
+				       cairo_antialias_t   shape_antialias)
 {
     cairo_ps_surface_t *surface = dst;
 
     return _cairo_surface_intersect_clip_path (surface->current_page,
 					       path,
 					       fill_rule,
-					       tolerance);
+					       tolerance,
+					       shape_antialias);
 }
 
 static cairo_int_status_t
@@ -929,6 +933,7 @@ static cairo_int_status_t
 _ps_output_composite_trapezoids (cairo_operator_t	operator,
 				 cairo_pattern_t	*pattern,
 				 void			*abstract_dst,
+				 cairo_antialias_t	shape_antialias,
 				 int			x_src,
 				 int			y_src,
 				 int			x_dst,
@@ -1054,7 +1059,8 @@ static cairo_int_status_t
 _ps_output_intersect_clip_path (void		   *abstract_surface,
 				cairo_path_fixed_t *path,
 				cairo_fill_rule_t   fill_rule,
-				double		    tolerance)
+				double		    tolerance,
+				cairo_antialias_t   shape_antialias)
 {
     ps_output_surface_t *surface = abstract_surface;
     cairo_output_stream_t *stream = surface->parent->stream;
Index: src/cairo-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-surface.c,v
retrieving revision 1.88
diff -p -u -r1.88 cairo-surface.c
--- src/cairo-surface.c	5 Aug 2005 05:45:59 -0000	1.88
+++ src/cairo-surface.c	8 Aug 2005 05:33:01 -0000
@@ -991,6 +991,7 @@ static cairo_status_t
 _fallback_composite_trapezoids (cairo_operator_t	operator,
 				cairo_pattern_t		*pattern,
 				cairo_surface_t		*dst,
+				cairo_antialias_t	shape_antialias,
 				int			src_x,
 				int			src_y,
 				int			dst_x,
@@ -1043,6 +1044,7 @@ _fallback_composite_trapezoids (cairo_op
 
     state.image->base.backend->composite_trapezoids (operator, pattern,
 						     &state.image->base,
+						     shape_antialias,
 						     src_x, src_y,
 						     dst_x - state.image_rect.x,
 						     dst_y - state.image_rect.y,
@@ -1060,6 +1062,7 @@ cairo_status_t
 _cairo_surface_composite_trapezoids (cairo_operator_t		operator,
 				     cairo_pattern_t		*pattern,
 				     cairo_surface_t		*dst,
+				     cairo_antialias_t		shape_antialias,
 				     int			src_x,
 				     int			src_y,
 				     int			dst_x,
@@ -1080,6 +1083,7 @@ _cairo_surface_composite_trapezoids (cai
     if (dst->backend->composite_trapezoids) {
 	status = dst->backend->composite_trapezoids (operator,
 						     pattern, dst,
+						     shape_antialias,
 						     src_x, src_y,
 						     dst_x, dst_y,
 						     width, height,
@@ -1089,6 +1093,7 @@ _cairo_surface_composite_trapezoids (cai
     }
 
     return  _fallback_composite_trapezoids (operator, pattern, dst,
+					    shape_antialias,
 					    src_x, src_y,
 					    dst_x, dst_y,
 					    width, height,
@@ -1191,7 +1196,8 @@ _cairo_surface_reset_clip (cairo_surface
 	status = surface->backend->intersect_clip_path (surface,
 							NULL,
 							CAIRO_FILL_RULE_WINDING,
-							0);
+							0,
+							CAIRO_ANTIALIAS_DEFAULT);
 	if (status)
 	    return status;
     }
@@ -1237,7 +1243,8 @@ cairo_int_status_t
 _cairo_surface_intersect_clip_path (cairo_surface_t    *surface,
 				    cairo_path_fixed_t *path,
 				    cairo_fill_rule_t   fill_rule,
-				    double		tolerance)
+				    double		tolerance,
+				    cairo_antialias_t	shape_antialias)
 {
     if (surface->status)
 	return surface->status;
@@ -1250,7 +1257,8 @@ _cairo_surface_intersect_clip_path (cair
     return surface->backend->intersect_clip_path (surface,
 						  path,
 						  fill_rule,
-						  tolerance);
+						  tolerance,
+						  shape_antialias);
 }
 
 static cairo_status_t
@@ -1269,7 +1277,8 @@ _cairo_surface_set_clip_path_recursive (
     return surface->backend->intersect_clip_path (surface,
 						  &clip_path->path,
 						  clip_path->fill_rule,
-						  clip_path->tolerance);
+						  clip_path->tolerance,
+						  clip_path->shape_antialias);
 }
 
 /**
@@ -1301,7 +1310,8 @@ _cairo_surface_set_clip_path (cairo_surf
     status = surface->backend->intersect_clip_path (surface,
 						    NULL,
 						    CAIRO_FILL_RULE_WINDING,
-						    0);
+						    0,
+						    CAIRO_ANTIALIAS_DEFAULT);
     if (status)
 	return status;
 
Index: src/cairo-xcb-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xcb-surface.c,v
retrieving revision 1.45
diff -p -u -r1.45 cairo-xcb-surface.c
--- src/cairo-xcb-surface.c	5 Aug 2005 01:44:29 -0000	1.45
+++ src/cairo-xcb-surface.c	8 Aug 2005 05:33:01 -0000
@@ -942,6 +942,7 @@ static cairo_int_status_t
 _cairo_xcb_surface_composite_trapezoids (cairo_operator_t	operator,
 					 cairo_pattern_t	*pattern,
 					 void			*abstract_dst,
+					 cairo_antialias_t	shape_antialias,
 					 int			src_x,
 					 int			src_y,
 					 int			dst_x,
@@ -980,9 +981,17 @@ _cairo_xcb_surface_composite_trapezoids 
     render_src_x = src_x + render_reference_x - dst_x;
     render_src_y = src_y + render_reference_y - dst_y;
 
+    switch (shape_antialias) {
+    case CAIRO_ANTIALIAS_NONE:
+	render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A1),
+	break;
+    default:
+	render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8),
+	break;
+    }
+
     /* XXX: The XTrapezoid cast is evil and needs to go away somehow. */
     /* XXX: _format_from_cairo is slow. should cache something. */
-    render_format = _format_from_cairo (dst->dpy, CAIRO_FORMAT_A8),
     status = _cairo_xcb_surface_set_attributes (src, &attributes);
     if (status == CAIRO_STATUS_SUCCESS)
 	XCBRenderTrapezoids (dst->dpy,
Index: src/cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.104
diff -p -u -r1.104 cairo-xlib-surface.c
--- src/cairo-xlib-surface.c	5 Aug 2005 01:44:29 -0000	1.104
+++ src/cairo-xlib-surface.c	8 Aug 2005 05:33:02 -0000
@@ -1218,6 +1218,7 @@ static cairo_int_status_t
 _cairo_xlib_surface_composite_trapezoids (cairo_operator_t	operator,
 					  cairo_pattern_t	*pattern,
 					  void			*abstract_dst,
+					  cairo_antialias_t	shape_antialias,
 					  int			src_x,
 					  int			src_y,
 					  int			dst_x,
@@ -1234,6 +1235,7 @@ _cairo_xlib_surface_composite_trapezoids
     composite_operation_t       operation;
     int				render_reference_x, render_reference_y;
     int				render_src_x, render_src_y;
+    XRenderPictFormat		*pict_format;
 
     if (!CAIRO_SURFACE_RENDER_HAS_TRAPEZOIDS (dst))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
@@ -1254,6 +1256,15 @@ _cairo_xlib_surface_composite_trapezoids
 	status = CAIRO_INT_STATUS_UNSUPPORTED;
 	goto FAIL;
     }
+
+    switch (shape_antialias) {
+    case CAIRO_ANTIALIAS_NONE:
+	pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA1);
+	break;
+    default:
+	pict_format = XRenderFindStandardFormat (dst->dpy, PictStandardA8);
+	break;
+    }
 	
     if (traps[0].left.p1.y < traps[0].left.p2.y) {
 	render_reference_x = _cairo_fixed_integer_floor (traps[0].left.p1.x);
@@ -1273,7 +1284,7 @@ _cairo_xlib_surface_composite_trapezoids
 	XRenderCompositeTrapezoids (dst->dpy,
 				    _render_operator (operator),
 				    src->src_picture, dst->dst_picture,
-				    XRenderFindStandardFormat (dst->dpy, PictStandardA8),
+				    pict_format,
 				    render_src_x + attributes.x_offset, 
 				    render_src_y + attributes.y_offset,
 				    (XTrapezoid *) traps, num_traps);
Index: src/cairo.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.c,v
retrieving revision 1.122
diff -p -u -r1.122 cairo.c
--- src/cairo.c	6 Aug 2005 23:38:34 -0000	1.122
+++ src/cairo.c	8 Aug 2005 05:33:03 -0000
@@ -536,6 +536,27 @@ cairo_set_tolerance (cairo_t *cr, double
 }
 
 /**
+ * cairo_set_shape_antialias:
+ * @cr: a #cairo_t
+ * @antialias: the new antialiasing mode
+ * 
+ * Set the antialiasing mode of the rasterizer used for drawing shapes.
+ * This value is a hint and may not be supported by all backends.
+ **/
+void
+cairo_set_shape_antialias (cairo_t *cr, cairo_antialias_t antialias)
+{
+    if (cr->status) {
+	_cairo_set_error (cr, cr->status);
+	return;
+    }
+
+    cr->status = _cairo_gstate_set_shape_antialias (cr->gstate, antialias);
+    if (cr->status)
+	_cairo_set_error (cr, cr->status);
+}
+
+/**
  * cairo_set_fill_rule:
  * @cr: a #cairo_t
  * @fill_rule: a fill rule, specified as a #cairo_fill_rule_t
@@ -2082,6 +2103,20 @@ cairo_get_tolerance (cairo_t *cr)
 }
 
 /**
+ * cairo_get_shape_antialias:
+ * @cr: a cairo context
+ * 
+ * Gets the antialising mode set, as set by cairo_set_shape_antialias().
+ * 
+ * Return value: the requested shape antialiasing mode.
+ **/
+cairo_antialias_t
+cairo_get_shape_antialias (cairo_t *cr)
+{
+    return _cairo_gstate_get_shape_antialias (cr->gstate);
+}
+
+/**
  * cairo_get_current_point:
  * @cr: a cairo context
  * @x: return value for X coordinate of the current point
Index: src/cairo.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo.h,v
retrieving revision 1.145
diff -p -u -r1.145 cairo.h
--- src/cairo.h	5 Aug 2005 01:44:29 -0000	1.145
+++ src/cairo.h	8 Aug 2005 05:33:03 -0000
@@ -288,6 +288,29 @@ void
 cairo_set_tolerance (cairo_t *cr, double tolerance);
 
 /**
+ * cairo_antialias_t:
+ * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for
+ *   the subsystem and target device
+ * @CAIRO_ANTIALIAS_NONE: Do no antialiasing; use a bilevel alpha channel
+ * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using
+ *  shades of gray for black text on a white background, for example).
+ * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking
+ *  advantage of the order of subpixel elements on devices
+ *  such as LCD panels
+ * 
+ * Specifies the type of antialiasing to do when rendering text or shapes.
+ **/
+typedef enum _cairo_antialias {
+    CAIRO_ANTIALIAS_DEFAULT,
+    CAIRO_ANTIALIAS_NONE,
+    CAIRO_ANTIALIAS_GRAY,
+    CAIRO_ANTIALIAS_SUBPIXEL
+} cairo_antialias_t;
+
+void
+cairo_set_shape_antialias (cairo_t *cr, cairo_antialias_t antialias);
+
+/**
  * cairo_fill_rule_t
  * @CAIRO_FILL_RULE_WINDING: If the path crosses the ray from
  * left-to-right, counts +1. If the path crosses the ray
@@ -660,26 +683,6 @@ typedef enum _cairo_font_weight {
 } cairo_font_weight_t;
 
 /**
- * cairo_antialias_t:
- * @CAIRO_ANTIALIAS_DEFAULT: Use the default antialiasing for
- *   the font subsystem and target device
- * @CAIRO_ANTIALIAS_NONE: Do no antialiasing of fonts; use bilevel text
- * @CAIRO_ANTIALIAS_GRAY: Perform single-color antialiasing (using
- *  shades of gray for black text on a white background, for example).
- * @CAIRO_ANTIALIAS_SUBPIXEL: Perform antialiasing by taking
- *  advantage of the order of subpixel elements on devices
- *  such as LCD panels
- * 
- * Specifies the type of antialiasing to do when rendering text.
- **/
-typedef enum _cairo_antialias {
-    CAIRO_ANTIALIAS_DEFAULT,
-    CAIRO_ANTIALIAS_NONE,
-    CAIRO_ANTIALIAS_GRAY,
-    CAIRO_ANTIALIAS_SUBPIXEL
-} cairo_antialias_t;
-
-/**
  * cairo_subpixel_order_t:
  * @CAIRO_SUBPIXEL_ORDER_DEFAULT: Use the default subpixel order for
  *   for the target device
@@ -920,6 +923,9 @@ cairo_get_source (cairo_t *cr);
 double
 cairo_get_tolerance (cairo_t *cr);
 
+cairo_antialias_t
+cairo_get_shape_antialias (cairo_t *cr);
+
 void
 cairo_get_current_point (cairo_t *cr, double *x, double *y);
 
Index: src/cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.186
diff -p -u -r1.186 cairoint.h
--- src/cairoint.h	6 Aug 2005 05:29:06 -0000	1.186
+++ src/cairoint.h	8 Aug 2005 05:33:04 -0000
@@ -728,6 +728,7 @@ typedef struct _cairo_surface_backend {
     (*composite_trapezoids)	(cairo_operator_t	 operator,
 				 cairo_pattern_t	*pattern,
 				 void			*dst,
+				 cairo_antialias_t	 shape_antialias,
 				 int			 src_x,
 				 int			 src_y,
 				 int			 dst_x,
@@ -778,7 +779,8 @@ typedef struct _cairo_surface_backend {
     (*intersect_clip_path)	(void			*dst,
 				 cairo_path_fixed_t	*path,
 				 cairo_fill_rule_t	fill_rule,
-				 double			tolerance);
+				 double			tolerance,
+				 cairo_antialias_t	shape_antialias);
 
     /* Get the extents of the current surface. For many surface types
      * this will be as simple as { x=0, y=0, width=surface->width,
@@ -1033,6 +1035,7 @@ typedef struct _cairo_traps {
 
 #define CAIRO_GSTATE_OPERATOR_DEFAULT	CAIRO_OPERATOR_OVER
 #define CAIRO_GSTATE_TOLERANCE_DEFAULT	0.1
+#define CAIRO_GSTATE_SHAPE_ANTIALIAS_DEFAULT	CAIRO_ANTIALIAS_DEFAULT
 #define CAIRO_GSTATE_FILL_RULE_DEFAULT	CAIRO_FILL_RULE_WINDING
 #define CAIRO_GSTATE_LINE_WIDTH_DEFAULT	2.0
 #define CAIRO_GSTATE_LINE_CAP_DEFAULT	CAIRO_LINE_CAP_BUTT
@@ -1312,6 +1315,13 @@ _cairo_gstate_glyph_path (cairo_gstate_t
 			  int		      num_glyphs,
 			  cairo_path_fixed_t *path);
 
+cairo_private cairo_status_t
+_cairo_gstate_set_shape_antialias (cairo_gstate_t *gstate,
+				   cairo_antialias_t antialias);
+
+cairo_private cairo_antialias_t
+_cairo_gstate_get_shape_antialias (cairo_gstate_t *gstate);
+
 
 /* cairo_color.c */
 cairo_private const cairo_color_t *
@@ -1603,6 +1613,7 @@ cairo_private cairo_status_t
 _cairo_surface_composite_trapezoids (cairo_operator_t	operator,
 				     cairo_pattern_t	*pattern,
 				     cairo_surface_t	*dst,
+				     cairo_antialias_t	shape_antialias,
 				     int		src_x,
 				     int		src_y,
 				     int		dst_x,
@@ -1617,7 +1628,8 @@ _cairo_surface_clip_and_composite_trapez
 					      cairo_operator_t operator,
 					      cairo_surface_t *dst,
 					      cairo_traps_t *traps,
-					      cairo_clip_t *clip);
+					      cairo_clip_t *clip,
+					      cairo_antialias_t shape_antialias);
 
 cairo_private cairo_status_t
 _cairo_surface_copy_page (cairo_surface_t *surface);
@@ -1672,7 +1684,8 @@ cairo_private cairo_int_status_t
 _cairo_surface_intersect_clip_path (cairo_surface_t    *surface,
 				    cairo_path_fixed_t *path,
 				    cairo_fill_rule_t   fill_rule,
-				    double		tolerance);
+				    double		tolerance,
+				    cairo_antialias_t	shape_antialias);
 
 cairo_private cairo_status_t
 _cairo_surface_set_clip (cairo_surface_t *surface, cairo_clip_t *clip);
Index: test/Makefile.am
===================================================================
RCS file: /cvs/cairo/cairo/test/Makefile.am,v
retrieving revision 1.72
diff -p -u -r1.72 Makefile.am
--- test/Makefile.am	5 Aug 2005 22:07:46 -0000	1.72
+++ test/Makefile.am	8 Aug 2005 05:33:04 -0000
@@ -41,6 +41,7 @@ text-rotate			\
 transforms			\
 translate-show-surface		\
 trap-clip			\
+unantialiased-shapes		\
 user-data			\
 rel-path
 
@@ -96,7 +97,8 @@ text-antialias-none-ref.png		\
 transforms-ref.png			\
 translate-show-surface-ref.png		\
 trap-clip-ref.png			\
-rel-path-ref.png
+rel-path-ref.png			\
+unantialiased-shapes-ref.png
 
 # Any test for which the code committed to CVS is expected to fail
 # should be listed here.
@@ -195,6 +197,7 @@ text_rotate_LDADD = $(LDADDS)
 transforms_LDADD = $(LDADDS)
 translate_show_surface_LDADD = $(LDADDS)
 trap_clip_LDADD = $(LDADDS)
+unantialiased_shapes_LDADD = $(LDADDS)
 user_data_LDADD = $(LDADDS)
 rel_path_LDADD = $(LDADDS)
 xlib_surface_LDADD = $(LDADDS)
Index: test/unantialiased-shapes.c
===================================================================
RCS file: test/unantialiased-shapes.c
diff -N test/unantialiased-shapes.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test/unantialiased-shapes.c	8 Aug 2005 05:33:04 -0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright ?? 2005 Billy Biggs
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Billy Biggs not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Billy Biggs makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * BILLY BIGGS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL BILLY BIGGS BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Billy Biggs <vektor at dumbterm.net>
+ */
+
+#include "cairo-test.h"
+
+cairo_test_t test = {
+    "unantialiased-shapes",
+    "Test shape drawing without antialiasing",
+    320, 240
+};
+
+/* The star shape from the SVG test suite, from the fill rule test */
+static void
+big_star_path (cairo_t *cr)
+{
+    cairo_move_to (cr, 40, 0);
+    cairo_rel_line_to (cr, 25, 80);
+    cairo_rel_line_to (cr, -65, -50);
+    cairo_rel_line_to (cr, 80, 0);
+    cairo_rel_line_to (cr, -65, 50);
+    cairo_close_path (cr);
+}
+
+static cairo_test_status_t
+draw (cairo_t *cr, int width, int height)
+{
+    int i;
+
+    cairo_set_source_rgb (cr, 0, 0, 0);
+    cairo_paint (cr);
+
+    cairo_set_shape_antialias hp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB18.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenB24.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI08.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI12.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI18.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenBI24.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI08-ISO8859-2.pcf.gz
/home/compromised/knts/75dpi/ncenI24-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenI24.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR08.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12-ISO8859-9.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR12.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-1.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-10.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-13.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-14.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-15.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-2.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-3.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO8859-4.pcf.gz
/home/compromised/keithp/6.7/root/usr/X11R6/lib/X11/fonts/75dpi/ncenR14-ISO88e
manipulations in the create and fini functions for
cairo_toy_font_face, two functions that are not intended to have
matching implementations. So the right answer is to also push the hash
table manipulation down from cairo_toy_font_face_create to
cairo_toy_font_face_init.

I think that new approach will look just fine. I haven't changed that
now since the previous cairo_ft_unscaled_font_map patch will also need
the same shuffling. Plus, it's not an important change as it doesn't
change any functionality, but just makes the naming clear. The unclear
naming is something I will want to fix eventually as it led to
double-free errors as I implemented cairo_toy_font_face_destroy.
Fortunately, valgrind noticed that and the current patch should be
functionally clean.

===File
~/src/cairo/cairo-hash-rework-toy-font-face/cairo-toy-font-face-hash-table.patch===
Index: ChangeLog
===================================================================
RCS file: /mirrors/freedesktop/cairo/cairo/ChangeLog,v
retrieving revision 1.844
diff -u -p -r1.844 ChangeLog
--- ChangeLog	6 Aug 2005 23:57:14 -0000	1.844
+++ ChangeLog	8 Aug 2005 14:12:30 -0000
@@ -1,3 +1,19 @@
+2005-08-08  Carl Worth  <cworth at cworth.org>
+
+	* src/cairoint.h: Add hash_entry field to cairo_font_face_t so
+	that it can (optionally) be hashed.
+
+	* src/cairo-font.c: (_cairo_toy_font_face_hash_table_lock),
+	(_cairo_toy_font_face_hash_table_unlock),
+	(_cairo_toy_font_face_init_key), (_cairo_toy_font_face_init),
+	(_cairo_toy_font_face_fini), (_cairo_toy_font_face_keys_equal),
+	(_cairo_toy_font_face_create), (_cairo_toy_font_face_destroy),
+	(_cairo_toy_font_face_scaled_font_create),
+	(_cairo_font_reset_static_data): Complete the remainder of the
+	simple -> toy renaming. Convert the family/slant/weight ->
+	cairo_toy_font_face_t mapping to use cairo-hash-table.c rather
+	than cairo-cache.c.
+
 2005-08-06  Carl Worth  <cworth at cworth.org>
 
 	* BUGS: Remove several bugs that have been fixed.
Index: src/cairo-font.c
===================================================================
RCS file: /mirrors/freedesktop/cairo/cairo/src/cairo-font.c,v
retrieving revision 1.65
diff -u -p -r1.65 cairo-font.c
--- src/cairo-font.c	6 Aug 2005 03:53:09 -0000	1.65
+++ src/cairo-font.c	8 Aug 2005 14:12:58 -0000
@@ -47,6 +47,7 @@ static const cairo_font_face_backend_t _
 /* cairo_font_face_t */
 
 const cairo_font_face_t _cairo_font_face_nil = {
+    { 0 },			/* hash_entry */
     CAIRO_STATUS_NO_MEMORY,	/* status */
     -1,		                /* ref_count */
     { 0, 0, 0, NULL },		/* user_data */
@@ -188,219 +189,124 @@ cairo_font_face_set_user_data (cairo_fon
 					    key, user_data, destroy);
 }
 
-/* We maintain a global cache from family/weight/slant => cairo_font_face_t
- * for cairo_simple_font_t. The primary purpose of this cache is to provide
- * unique cairo_font_face_t values so that our cache from
- * cairo_font_face_t => cairo_scaled_font_t works. For this reason, we don't need
- * this cache to keep font faces alive; we just add them to the cache and
- * remove them again when freed.
- */
-
-typedef struct {
-    cairo_cache_entry_base_t base;
-    const char *family;
-    cairo_font_slant_t slant;
-    cairo_font_weight_t weight;
-} cairo_simple_cache_key_t;
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend;
 
-typedef struct {
-    cairo_simple_cache_key_t key;
-    cairo_toy_font_face_t *font_face;
-} cairo_simple_cache_entry_t;
+static int
+_cairo_toy_font_face_keys_equal (void *key_a,
+				 void *key_b);
 
-static const cairo_cache_backend_t _cairo_simple_font_cache_backend;
+/* We maintain a hash table from family/weight/slant =>
+ * cairo_font_face_t for cairo_toy_font_t. The primary purpose of
+ * this mapping is to provide unique cairo_font_face_t values so that
+ * our cache and mapping from cairo_font_face_t => cairo_scaled_font_t
+ * works. Once the corresponding cairo_font_face_t objects fall out of
+ * downstream caches, we don't need them in this hash table anymore.
+ */
 
-CAIRO_MUTEX_DECLARE(_global_simple_cache_mutex);
+static cairo_hash_table_t *cairo_toy_font_face_hash_table = NULL;
 
-static void
-_lock_global_simple_cache (void)
-{
-    CAIRO_MUTEX_LOCK (_global_simple_cache_mutex);
-}
+CAIRO_MUTEX_DECLARE (cairo_toy_font_face_hash_table_mutex);
 
-static void
-_unlock_global_simple_cache (void)
+static cairo_hash_table_t *
+_cairo_toy_font_face_hash_table_lock (void)
 {
-    CAIRO_MUTEX_UNLOCK (_global_simple_cache_mutex);
-}
+    CAIRO_MUTEX_LOCK (cairo_toy_font_face_hash_table_mutex);
 
-static cairo_cache_t *global_simple_cache = NULL;
-
-static cairo_cache_t *
-_get_global_simple_cache (void)
-{
-    if (global_simple_cache == NULL)
+    if (cairo_toy_font_face_hash_table == NULL)
     {
-	global_simple_cache = malloc (sizeof (cairo_cache_t));	
-	if (!global_simple_cache)
-	    goto FAIL;
+	cairo_toy_font_face_hash_table =
+	    _cairo_hash_table_create (_cairo_toy_font_face_keys_equal);
 
-	if (_cairo_cache_init (global_simple_cache,
-			       &_cairo_simple_font_cache_backend,
-			       0)) /* No memory limit */
-	    goto FAIL;
+	if (cairo_toy_font_face_hash_table == NULL) {
+	    CAIRO_MUTEX_UNLOCK (cairo_toy_font_face_hash_table_mutex);
+	    return NULL;
+	}
     }
-    return global_simple_cache;
-
- FAIL:
-    if (global_simple_cache)
-	free (global_simple_cache);
-    global_simple_cache = NULL;
-    return NULL;
-}
-
-static unsigned long
-_cairo_simple_font_cache_hash (void *cache, void *key)
-{
-    cairo_simple_cache_key_t *k = (cairo_simple_cache_key_t *) key;
-    unsigned long hash;
 
-    /* 1607 and 1451 are just a couple random primes. */
-    hash = _cairo_hash_string (k->family);
-    hash += ((unsigned long) k->slant) * 1607;
-    hash += ((unsigned long) k->weight) * 1451;
-    
-    return hash;
+    return cairo_toy_font_face_hash_table;
 }
 
-static int
-_cairo_simple_font_cache_keys_equal (void *cache,
-				     void *k1,
-				     void *k2)
+static void
+_cairo_toy_font_face_hash_table_unlock (void)
 {
-    cairo_simple_cache_key_t *a;
-    cairo_simple_cache_key_t *b;
-    a = (cairo_simple_cache_key_t *) k1;
-    b = (cairo_simple_cache_key_t *) k2;
-
-    return strcmp (a->family, b->family) == 0 &&
-	a->slant == b->slant &&
-	a->weight == b->weight;
+    CAIRO_MUTEX_UNLOCK (cairo_toy_font_face_hash_table_mutex);
 }
 
-static cairo_toy_font_face_t *
-_cairo_toy_font_face_create_from_cache_key (cairo_simple_cache_key_t *key)
+/**
+ * _cairo_toy_font_face_init_key:
+ * 
+ * Initialize those portions of cairo_toy_font_face_t needed to use
+ * it as a hash table key, including the hash code buried away in
+ * font_face->base.hash_entry. No memory allocation is performed here
+ * so that no fini call is needed. We do this to make it easier to use
+ * an automatic cairo_toy_font_face_t variable as a key.
+ **/
+static void
+_cairo_toy_font_face_init_key (cairo_toy_font_face_t *key,
+			       const char	     *family,
+			       cairo_font_slant_t     slant,
+			       cairo_font_weight_t    weight)
 {
-    cairo_toy_font_face_t *simple_face;
+    unsigned long hash;
 
-    simple_face = malloc (sizeof (cairo_toy_font_face_t));
-    if (!simple_face)
-	return NULL;
+    /* It's rather rude of us to cast away a const qualifier like
+     * this. So we note it here, and assert that the only modification
+     * we ever do, (which is to free it), only occurs when
+     * key->family_is_const is FALSE. */
+    key->family = (char *) family;
+    key->family_is_const = TRUE;
+
+    key->slant = slant;
+    key->weight = weight;
+
+    /* 1607 and 1451 are just a couple of arbitrary primes. */
+    hash = _cairo_hash_string (family);
+    hash += ((unsigned long) slant) * 1607;
+    hash += ((unsigned long) weight) * 1451;
     
-    simple_face->family = strdup (key->family);
-    if (!simple_face->family) {
-	free (simple_face);
-	return NULL;
-    }
-
-    simple_face->slant = key->slant;
-    simple_face->weight = key->weight;
-
-    _cairo_font_face_init (&simple_face->base, &_cairo_toy_font_face_backend);
-
-    return simple_face;
+    key->base.hash_entry.hash = hash;
 }
 
 static cairo_status_t
-_cairo_simple_font_cache_create_entry (void  *cache,
-				       void  *key,
-				       void **return_entry)
+_cairo_toy_font_face_init (cairo_toy_font_face_t *font_face,
+			   const char	         *family,
+			   cairo_font_slant_t	  slant,
+			   cairo_font_weight_t	  weight)
 {
-    cairo_simple_cache_key_t *k = (cairo_simple_cache_key_t *) key;
-    cairo_simple_cache_entry_t *entry;
+    char *family_copy;
 
-    entry = malloc (sizeof (cairo_simple_cache_entry_t));
-    if (entry == NULL)
+    family_copy = strdup (family);
+    if (family_copy == NULL)
 	return CAIRO_STATUS_NO_MEMORY;
 
-    entry->font_face = _cairo_toy_font_face_create_from_cache_key (k);
-    if (!entry->font_face) {
-	free (entry);
-	return CAIRO_STATUS_NO_MEMORY;
-    }
-    
-    entry->key.base.memory = 0;
-    entry->key.family = entry->font_face->family;
-    entry->key.slant = entry->font_face->slant;
-    entry->key.weight = entry->font_face->weight;
-    
-    *return_entry = entry;
+    _cairo_toy_font_face_init_key (font_face, family_copy,
+				      slant, weight);
+    font_face->family_is_const = FALSE;
 
-    return CAIRO_STATUS_SUCCESS;
-}
-
-/* Entries are never spontaneously destroyed; but only when
- * we remove them from the cache specifically. We free entry->font_face
- * in the code that removes the entry from the cache
- */
-static void
-_cairo_simple_font_cache_destroy_entry (void *cache,
-					void *entry)
-{    
-    cairo_simple_cache_entry_t *e = (cairo_simple_cache_entry_t *) entry;
-
-    free (e);
-}
+    _cairo_font_face_init (&font_face->base, &_cairo_toy_font_face_backend);
 
-static void 
-_cairo_simple_font_cache_destroy_cache (void *cache)
-{
-    free (cache);
+    return CAIRO_STATUS_SUCCESS;
 }
 
-static const cairo_cache_backend_t _cairo_simple_font_cache_backend = {
-    _cairo_simple_font_cache_hash,
-    _cairo_simple_font_cache_keys_equal,
-    _cairo_simple_font_cache_create_entry,
-    _cairo_simple_font_cache_destroy_entry,
-    _cairo_simple_font_cache_destroy_cache
-};
-
 static void
-_cairo_toy_font_face_destroy (void *abstract_face)
+_cairo_toy_font_face_fini (cairo_toy_font_face_t *font_face)
 {
-    cairo_toy_font_face_t *simple_face = abstract_face;
-    cairo_cache_t *cache;
-    cairo_simple_cache_key_t key;
-
-    if (simple_face == NULL)
-	return;
-
-    _lock_global_simple_cache ();
-    cache = _get_global_simple_cache ();
-    assert (cache);
-    
-    key.family = simple_face->family;
-    key.slant = simple_face->slant;
-    key.weight = simple_face->weight;
-	
-    _cairo_cache_remove (cache, &key);
-    
-    _unlock_global_simple_cache ();
-    
-    free (simple_face->family);
+    assert (! font_face->family_is_const);
+    free (font_face->family);
 }
 
-static cairo_status_t
-_cairo_toy_font_face_scaled_font_create (void			  *abstract_face,
-					 const cairo_matrix_t       *font_matrix,
-					 const cairo_matrix_t       *ctm,
-					 const cairo_font_options_t *options,
-					 cairo_scaled_font_t    **scaled_font)
+static int
+_cairo_toy_font_face_keys_equal (void *key_a,
+				 void *key_b)
 {
-    const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
+    cairo_toy_font_face_t *face_a = key_a;
+    cairo_toy_font_face_t *face_b = key_b;
 
-    cairo_toy_font_face_t *simple_face = abstract_face;
-
-    return backend->create_toy (simple_face,
-				font_matrix, ctm, options, scaled_font);
+    return (strcmp (face_a->family, face_b->family) == 0 &&
+	    face_a->slant == face_b->slant &&
+	    face_a->weight == face_b->weight);
 }
 
-static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
-    _cairo_toy_font_face_destroy,
-    _cairo_toy_font_face_scaled_font_create
-};
-
 /**
  * _cairo_toy_font_face_create:
  * @family: a font family name, encoded in UTF-8
@@ -419,36 +325,90 @@ _cairo_toy_font_face_create (const char 
 			     cairo_font_slant_t   slant, 
 			     cairo_font_weight_t  weight)
 {
-    cairo_simple_cache_entry_t *entry;
-    cairo_simple_cache_key_t key;
-    cairo_cache_t *cache;
     cairo_status_t status;
-    cairo_bool_t created_entry;
+    cairo_toy_font_face_t key, *font_face;
+    cairo_hash_table_t *hash_table;
 
-    key.family = family;
-    key.slant = slant;
-    key.weight = weight;
-    
-    _lock_global_simple_cache ();
-    cache = _get_global_simple_cache ();
-    if (cache == NULL) {
-	_unlock_global_simple_cache ();
-	_cairo_error (CAIRO_STATUS_NO_MEMORY);
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
+    hash_table = _cairo_toy_font_face_hash_table_lock ();
+    if (hash_table == NULL)
+	goto UNWIND;
+
+    _cairo_toy_font_face_init_key (&key, family, slant, weight);
+    
+    /* Return existing font_face if it exists in the hash table. */
+    if (_cairo_hash_table_lookup (hash_table,
+				  &key.base.hash_entry,
+				  (cairo_hash_entry_t **) &font_face))
+    {
+	_cairo_toy_font_face_hash_table_unlock ();
+	return cairo_font_face_reference (&font_face->base);
     }
-    status = _cairo_cache_lookup (cache, &key, (void **) &entry, &created_entry);
-    if (status == CAIRO_STATUS_SUCCESS && !created_entry)
-	cairo_font_face_reference (&entry->font_face->base);
+
+    /* Otherwise create it and insert into hash table. */
+    font_face = malloc (sizeof (cairo_toy_font_face_t));
+    if (font_face == NULL)
+	goto UNWIND_HASH_TABLE_LOCK;
+
+    status = _cairo_toy_font_face_init (font_face, family, slant, weight);
+    if (status)
+	goto UNWIND_FONT_FACE_MALLOC;
+
+    status = _cairo_hash_table_insert (hash_table, &font_face->base.hash_entry);
+    if (status)
+	goto UNWIND_FONT_FACE_INIT;
+
+    _cairo_toy_font_face_hash_table_unlock ();
+
+    return &font_face->base;
+
+ UNWIND_FONT_FACE_INIT:
+ UNWIND_FONT_FACE_MALLOC:
+    free (font_face);
+ UNWIND_HASH_TABLE_LOCK:
+    _cairo_toy_font_face_hash_table_unlock ();
+ UNWIND:
+    return (cairo_font_face_t*) &_cairo_font_face_nil;
+}
+
+static void
+_cairo_toy_font_face_destroy (void *abstract_face)
+{
+    cairo_toy_font_face_t *font_face = abstract_face;
+    cairo_hash_table_t *hash_table;
+
+    if (font_face == NULL)
+	return;
+
+    hash_table = _cairo_toy_font_face_hash_table_lock ();
+    /* All created objects must have been mapped in the hash table. */
+    assert (hash_table != NULL);
+
+    _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
     
-    _unlock_global_simple_cache ();
-    if (status) {
-	_cairo_error (status);
-	return (cairo_font_face_t *)&_cairo_font_face_nil;
-    }
+    _cairo_toy_font_face_hash_table_unlock ();
+    
+    _cairo_toy_font_face_fini (font_face);
+}
 
-    return &entry->font_face->base;
+static cairo_status_t
+_cairo_toy_font_face_scaled_font_create (void                *abstract_font_face,
+					 const cairo_matrix_t       *font_matrix,
+					 const cairo_matrix_t       *ctm,
+					 const cairo_font_options_t *options,
+					 cairo_scaled_font_t	   **scaled_font)
+{
+    cairo_toy_font_face_t *font_face = abstract_font_face;
+    const cairo_scaled_font_backend_t * backend = CAIRO_SCALED_FONT_BACKEND_DEFAULT;
+
+    return backend->create_toy (font_face,
+				font_matrix, ctm, options, scaled_font);
 }
 
+static const cairo_font_face_backend_t _cairo_toy_font_face_backend = {
+    _cairo_toy_font_face_destroy,
+    _cairo_toy_font_face_scaled_font_create
+};
+
 /* cairo_scaled_font_t */
 
 static const cairo_scaled_font_t _cairo_scaled_font_nil = {
@@ -1392,8 +1352,8 @@ _cairo_font_reset_static_data (void)
     _global_image_glyph_cache = NULL;
     _cairo_unlock_global_image_glyph_cache();
 
-    _lock_global_simple_cache ();
-    _cairo_cache_destroy (global_simple_cache);
-    global_simple_cache = NULL;
-    _unlock_global_simple_cache ();
+    CAIRO_MUTEX_LOCK (cairo_toy_font_face_hash_table_mutex);
+    _cairo_hash_table_destroy (cairo_toy_font_face_hash_table);
+    cairo_toy_font_face_hash_table = NULL;
+    CAIRO_MUTEX_UNLOCK (cairo_toy_font_face_hash_table_mutex);
 }
Index: src/cairoint.h
===================================================================
RCS file: /mirrors/freedesktop/cairo/cairo/src/cairoint.h,v
retrieving revision 1.186
diff -u -p -r1.186 cairoint.h
--- src/cairoint.h	6 Aug 2005 05:29:06 -0000	1.186
+++ src/cairoint.h	8 Aug 2005 13:11:45 -0000
@@ -489,6 +489,7 @@ struct _cairo_scaled_font {
 };
 
 struct _cairo_font_face {
+    cairo_hash_entry_t hash_entry;
     cairo_status_t status;
     int ref_count;
     cairo_user_data_array_t user_data;
@@ -567,6 +568,7 @@ typedef struct _cairo_toy_font_face {
     cairo_font_face_t base;
     char *family;
     cairo_font_slant_t slant;
+    cairo_bool_t family_is_const;
     cairo_font_weight_t weight;
 } cairo_toy_font_face_t;
 
============================================================

--pgp-sign-Multipart_Mon_Aug__8_07:33:42_2005-1
Content-Type: application/pgp-signature
Content-Transfer-Encoding: 7bit

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBC921O6JDdNq8qSWgRAuL6AKCQQUCHPPcqgExO4mr4efdXoKo+5gCgqAbZ
mG6CvGweufhIEnORmpYdtfI=
=tBHw
-----END PGP SIGNATURE-----

--pgp-sign-Multipart_Mon_Aug__8_07:33:42_2005-1--



More information about the cairo mailing list