more de-cairoification patches



These patches are clearly not suitable for inclusion, but may be interesting for
benchmarking. The gtkstyle.c patch was done by taking the 2.6 version of the
file and quickly backporting the relevant changes of the 2.9 version.

Matthias
Index: gtkstyle.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkstyle.c,v
retrieving revision 1.193
diff -u -r1.193 gtkstyle.c
--- gtkstyle.c	28 May 2006 12:56:26 -0000	1.193
+++ gtkstyle.c	2 Jul 2006 14:15:15 -0000
@@ -37,7 +37,6 @@
 #include "gtkthemes.h"
 #include "gtkiconfactory.h"
 #include "gtksettings.h"	/* _gtk_settings_parse_convert() */
-#include "gtkintl.h"
 #include "gtkalias.h"
 
 #define LIGHTNESS_MULT  1.3
@@ -59,6 +58,8 @@
 };
 
 /* --- prototypes --- */
+static void	 gtk_style_init			(GtkStyle	*style);
+static void	 gtk_style_class_init		(GtkStyleClass	*klass);
 static void	 gtk_style_finalize		(GObject	*object);
 static void	 gtk_style_realize		(GtkStyle	*style,
 						 GdkColormap	*colormap);
@@ -311,6 +312,9 @@
                                           gint            width,
                                           gint            height);
 
+void _gtk_style_shade			(GdkColor	 *a,
+					 GdkColor	 *b,
+					 gdouble	  k);
 static void rgb_to_hls			(gdouble	 *r,
 					 gdouble	 *g,
 					 gdouble	 *b);
@@ -329,6 +333,128 @@
 static const GtkRequisition default_option_indicator_size = { 7, 13 };
 static const GtkBorder default_option_indicator_spacing = { 7, 5, 2, 2 };
 
+#define INDICATOR_PART_SIZE 13
+
+typedef enum {
+  CHECK_AA,
+  CHECK_BASE,
+  CHECK_BLACK,
+  CHECK_DARK,
+  CHECK_LIGHT,
+  CHECK_MID,
+  CHECK_TEXT,
+  CHECK_INCONSISTENT_TEXT,
+  RADIO_BASE,
+  RADIO_BLACK,
+  RADIO_DARK,
+  RADIO_LIGHT,
+  RADIO_MID,
+  RADIO_TEXT,
+  RADIO_INCONSISTENT_AA,
+  RADIO_INCONSISTENT_TEXT
+} IndicatorPart;
+
+/*
+ * Extracted from check-13.png, width=13, height=13
+ */
+static const guchar check_black_bits[] = {
+  0x00,0x00,0xfe,0x0f,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
+  0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00};
+static const guchar check_dark_bits[] = {
+  0xff,0x1f,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,
+  0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00};
+static const guchar check_mid_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,
+  0x08,0x00,0x08,0x00,0x08,0x00,0x08,0xfc,0x0f,0x00,0x00,0x00,0x00};
+static const guchar check_light_bits[] = {
+  0x00,0x00,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,
+  0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0xfe,0x1f,0x00,0x00};
+static const guchar check_text_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x03,0x80,0x01,0x80,0x00,0x58,
+  0x00,0x60,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+static const guchar check_aa_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x58,0x00,0xa0,
+  0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+static const guchar check_base_bits[] = {
+  0x00,0x00,0x00,0x00,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
+  0x07,0xfc,0x07,0xfc,0x07,0xfc,0x07,0x00,0x00,0x00,0x00,0x00,0x00};
+
+/*
+ * Extracted from check-13-inconsistent.png, width=13, height=13
+ */
+static const guchar check_inconsistent_text_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0xf8,
+  0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#if 0
+/*
+ * check_inconsistent_aa_bits is currently not used, since it is all zeros.
+ */
+static const guchar check_inconsistent_aa_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#endif
+
+/*
+ * Extracted from radio-13.png, width=13, height=13
+ */
+static const guchar radio_black_bits[] = {
+  0x00,0x00,0xf0,0x01,0x0c,0x02,0x04,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,
+  0x00,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0d,0x08};
+static const guchar radio_dark_bits[] = {
+  0xf0,0x00,0x0c,0x02,0x02,0x04,0x02,0x04,0x01,0x08,0x01,0x08,0x01,0x08,0x01,
+  0x08,0x00,0x08,0x02,0x04,0x0c,0x06,0xf0,0x01,0x00,0x00,0x00,0x00};
+static const guchar radio_mid_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+static const guchar radio_light_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x10,0x00,
+  0x10,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x06,0xe0,0x01,0x00,0x00};
+static const guchar radio_text_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x00,0xf0,0x01,0xf0,0x01,0xf0,
+  0x01,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#if 0
+/*
+ * radio_aa_bits is currently not used, since it is all zeros.
+ */
+static const guchar radio_aa_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+#endif
+static const guchar radio_base_bits[] = {
+  0x00,0x00,0x00,0x00,0xf0,0x01,0xf8,0x03,0xfc,0x07,0xfc,0x07,0xfc,0x07,0xfc,
+  0x07,0xfc,0x07,0xf8,0x03,0xf0,0x01,0x00,0x00,0x00,0x00,0x00,0x00};
+
+/*
+ * Extracted from radio-13.png, width=13, height=13
+ */
+static const guchar radio_inconsistent_text_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+static const guchar radio_inconsistent_aa_bits[] = {
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x03,0x00,0x00,0xf8,
+  0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+static struct {
+  const guchar      *bits;
+  GList	    *bmap_list; /* list of GdkBitmap */
+} indicator_parts[] = {
+  { check_aa_bits, NULL },
+  { check_base_bits, NULL },
+  { check_black_bits, NULL },
+  { check_dark_bits, NULL },
+  { check_light_bits, NULL },
+  { check_mid_bits, NULL },
+  { check_text_bits, NULL },
+  { check_inconsistent_text_bits, NULL },
+  { radio_base_bits, NULL },
+  { radio_black_bits, NULL },
+  { radio_dark_bits, NULL },
+  { radio_light_bits, NULL },
+  { radio_mid_bits, NULL },
+  { radio_text_bits, NULL },
+  { radio_inconsistent_aa_bits, NULL },
+  { radio_inconsistent_text_bits, NULL },
+};
 #define GTK_GRAY		0xdcdc, 0xdada, 0xd5d5
 #define GTK_DARK_GRAY		0xc4c4, 0xc2c2, 0xbdbd
 #define GTK_LIGHT_GRAY		0xeeee, 0xebeb, 0xe7e7
@@ -353,13 +479,39 @@
 static const GdkColor gtk_default_selected_base =  { 0, GTK_BLUE };
 static const GdkColor gtk_default_active_base =    { 0, GTK_VERY_DARK_GRAY };
 
+static gpointer parent_class = NULL;
+
 /* --- signals --- */
 static guint realize_signal = 0;
 static guint unrealize_signal = 0;
 
-G_DEFINE_TYPE (GtkStyle, gtk_style, G_TYPE_OBJECT)
-
 /* --- functions --- */
+GType
+gtk_style_get_type (void)
+{
+  static GType style_type = 0;
+  
+  if (!style_type)
+    {
+      static const GTypeInfo style_info =
+      {
+        sizeof (GtkStyleClass),
+        (GBaseInitFunc) NULL,
+        (GBaseFinalizeFunc) NULL,
+        (GClassInitFunc) gtk_style_class_init,
+        NULL,           /* class_finalize */
+        NULL,           /* class_data */
+        sizeof (GtkStyle),
+        0,              /* n_preallocs */
+        (GInstanceInitFunc) gtk_style_init,
+      };
+      
+      style_type = g_type_register_static (G_TYPE_OBJECT, "GtkStyle",
+					   &style_info, 0);
+    }
+  
+  return style_type;
+}
 
 /**
  * _gtk_style_init_for_settings:
@@ -477,6 +629,8 @@
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   
+  parent_class = g_type_class_peek_parent (klass);
+
   object_class->finalize = gtk_style_finalize;
 
   klass->clone = gtk_style_real_clone;
@@ -511,6 +665,7 @@
 
   g_type_class_add_private (object_class, sizeof (GtkStylePrivate));
 
+  
   /**
    * GtkStyle::realize:
    * @style: the object which received the signal
@@ -522,7 +677,7 @@
    *
    * Since: 2.4
    */
-  realize_signal = g_signal_new (I_("realize"),
+  realize_signal = g_signal_new ("realize",
 				 G_TYPE_FROM_CLASS (object_class),
 				 G_SIGNAL_RUN_FIRST,
 				 G_STRUCT_OFFSET (GtkStyleClass, realize),
@@ -540,7 +695,7 @@
    *
    * Since: 2.4
    */
-  unrealize_signal = g_signal_new (I_("unrealize"),
+  unrealize_signal = g_signal_new ("unrealize",
 				   G_TYPE_FROM_CLASS (object_class),
 				   G_SIGNAL_RUN_FIRST,
 				   G_STRUCT_OFFSET (GtkStyleClass, unrealize),
@@ -602,8 +757,18 @@
         }
     }
 
-  g_slist_foreach (style->icon_factories, (GFunc) g_object_unref, NULL);
-  g_slist_free (style->icon_factories);
+  if (style->icon_factories)
+    {
+      GSList *tmp_list = style->icon_factories;
+
+      while (tmp_list)
+	{
+	  g_object_unref (tmp_list->data);
+	  tmp_list = tmp_list->next;
+	}
+
+      g_slist_free (style->icon_factories);
+    }
 
   g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_unref, NULL);
   g_slist_free (priv->color_hashes);
@@ -619,7 +784,7 @@
   if (style->rc_style)
     gtk_rc_style_unref (style->rc_style);
   
-  G_OBJECT_CLASS (gtk_style_parent_class)->finalize (object);
+  G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 
@@ -686,10 +851,6 @@
  * it to a particular visual and colormap. The process may 
  * involve the creation of a new style if the style has already 
  * been attached to a window with a different style and colormap.
- *
- * Since this function may return a new object, you have to use it 
- * in the following way: 
- * <literal>style = gtk_style_attach (style, window)</literal>
  **/
 GtkStyle*
 gtk_style_attach (GtkStyle  *style,
@@ -766,19 +927,10 @@
   return new_style;
 }
 
-/**
- * gtk_style_detach:
- * @style: a #GtkStyle
- *
- * Detaches a style from a window. If the style is not attached
- * to any windows anymore, it is unrealized. See gtk_style_attach().
- * 
- */
 void
 gtk_style_detach (GtkStyle *style)
 {
   g_return_if_fail (GTK_IS_STYLE (style));
-  g_return_if_fail (style->attach_count > 0);
   
   style->attach_count -= 1;
   if (style->attach_count == 0)
@@ -833,6 +985,9 @@
 gtk_style_realize (GtkStyle    *style,
                    GdkColormap *colormap)
 {
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (GDK_IS_COLORMAP (colormap));
+  
   style->colormap = g_object_ref (colormap);
   style->depth = gdk_colormap_get_visual (colormap)->depth;
 
@@ -862,22 +1017,6 @@
   return gtk_icon_factory_lookup_default (stock_id);
 }
 
-/**
- * gtk_style_lookup_color:
- * @style: a #GtkStyle
- * @color_name: the name of the logical color to look up
- * @color: the #GdkColor to fill in
- *
- * Looks up @color_name in the style's logical color mappings,
- * filling in @color and returning %TRUE if found, otherwise
- * returning %FALSE. Do not cache the found mapping, because
- * it depends on the #GtkStyle and might change when a theme
- * switch occurs.
- *
- * Return value: %TRUE if the mapping was found.
- *
- * Since: 2.10
- **/
 gboolean
 gtk_style_lookup_color (GtkStyle   *style,
                         const char *color_name,
@@ -909,6 +1048,7 @@
   return FALSE;
 }
 
+
 /**
  * gtk_draw_hline:
  * @style: a #GtkStyle
@@ -1653,8 +1793,19 @@
   if (rc_style->ythickness >= 0)
     style->ythickness = rc_style->ythickness;
 
-  style->icon_factories = g_slist_copy (rc_style->icon_factories);
-  g_slist_foreach (style->icon_factories, (GFunc) g_object_ref, NULL);
+  if (rc_style->icon_factories)
+    {
+      GSList *iter;
+
+      style->icon_factories = g_slist_copy (rc_style->icon_factories);
+      
+      iter = style->icon_factories;
+      while (iter != NULL)
+        {
+          g_object_ref (iter->data);
+          iter = g_slist_next (iter);
+        }
+    }
 
   priv->color_hashes = g_slist_copy (_gtk_rc_style_get_color_hashes (rc_style));
   g_slist_foreach (priv->color_hashes, (GFunc) g_hash_table_ref, NULL);
@@ -1782,7 +1933,7 @@
     {
       _gtk_style_shade (&style->bg[i], &style->light[i], LIGHTNESS_MULT);
       _gtk_style_shade (&style->bg[i], &style->dark[i], DARKNESS_MULT);
-
+      
       style->mid[i].red = (style->light[i].red + style->dark[i].red) / 2;
       style->mid[i].green = (style->light[i].green + style->dark[i].green) / 2;
       style->mid[i].blue = (style->light[i].blue + style->dark[i].blue) / 2;
@@ -2162,6 +2313,57 @@
     gdk_drawable_get_size (window, NULL, height);
 }
 
+static GdkBitmap * 
+get_indicator_for_screen (GdkDrawable   *drawable,
+			  IndicatorPart  part)
+			  
+{
+  GdkScreen *screen = gdk_drawable_get_screen (drawable);
+  GdkBitmap *bitmap;
+  GList *tmp_list;
+  
+  tmp_list = indicator_parts[part].bmap_list;
+  while (tmp_list)
+    {
+      bitmap = tmp_list->data;
+      
+      if (gdk_drawable_get_screen (bitmap) == screen)
+	return bitmap;
+      
+      tmp_list = tmp_list->next;
+    }
+  
+  bitmap = gdk_bitmap_create_from_data (drawable,
+					(gchar *)indicator_parts[part].bits,
+					INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
+  indicator_parts[part].bmap_list = g_list_prepend (indicator_parts[part].bmap_list, bitmap);
+
+  return bitmap;
+}
+
+static void
+draw_part (GdkDrawable  *drawable,
+	   GdkGC        *gc,
+	   GdkRectangle *area,
+	   gint          x,
+	   gint          y,
+	   IndicatorPart part)
+{
+  if (area)
+    gdk_gc_set_clip_rectangle (gc, area);
+  
+  gdk_gc_set_ts_origin (gc, x, y);
+  gdk_gc_set_stipple (gc, get_indicator_for_screen (drawable, part));
+  gdk_gc_set_fill (gc, GDK_STIPPLED);
+
+  gdk_draw_rectangle (drawable, gc, TRUE, x, y, INDICATOR_PART_SIZE, INDICATOR_PART_SIZE);
+
+  gdk_gc_set_fill (gc, GDK_SOLID);
+
+  if (area)
+    gdk_gc_set_clip_rectangle (gc, NULL);
+}
+
 static void
 gtk_default_draw_hline (GtkStyle     *style,
                         GdkWindow    *window,
@@ -2177,6 +2379,9 @@
   gint thickness_dark;
   gint i;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   thickness_light = style->ythickness / 2;
   thickness_dark = style->ythickness - thickness_light;
   
@@ -2231,6 +2436,9 @@
   gint thickness_dark;
   gint i;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   thickness_light = style->xthickness / 2;
   thickness_dark = style->xthickness - thickness_light;
   
@@ -2456,6 +2664,9 @@
   gint thickness_dark;
   gint i;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+
   if (shadow_type == GTK_SHADOW_IN)
     {
       if (detail && (strcmp (detail, "buttondefault") == 0))
@@ -2791,6 +3002,10 @@
   gint yadjust;
   gint i;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (points != NULL);
+  
   switch (shadow_type)
     {
     case GTK_SHADOW_IN:
@@ -2900,7 +3115,7 @@
 
 static void
 draw_arrow (GdkWindow     *window,
-	    GdkColor      *color,
+	    GdkGC         *gc,
 	    GdkRectangle  *area,
 	    GtkArrowType   arrow_type,
 	    gint           x,
@@ -2908,44 +3123,34 @@
 	    gint           width,
 	    gint           height)
 {
-  cairo_t *cr = gdk_cairo_create (window);
-  gdk_cairo_set_source_color (cr, color);
-  
+  gint i, j;
+
   if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
-    }
-    
+    gdk_gc_set_clip_rectangle (gc, area);
+
   if (arrow_type == GTK_ARROW_DOWN)
     {
-      cairo_move_to (cr, x,              y);
-      cairo_line_to (cr, x + width,      y);
-      cairo_line_to (cr, x + width / 2., y + height);
+      for (i = 0, j = 0; i < height; i++, j++)
+	gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
     }
   else if (arrow_type == GTK_ARROW_UP)
     {
-      cairo_move_to (cr, x,              y + height);
-      cairo_line_to (cr, x + width / 2., y);
-      cairo_line_to (cr, x + width,      y + height);
+      for (i = height - 1, j = 0; i >= 0; i--, j++)
+	gdk_draw_line (window, gc, x + j, y + i, x + width - j - 1, y + i);
     }
   else if (arrow_type == GTK_ARROW_LEFT)
     {
-      cairo_move_to (cr, x + width,      y);
-      cairo_line_to (cr, x + width,      y + height);
-      cairo_line_to (cr, x,              y + height / 2.);
+      for (i = width - 1, j = 0; i >= 0; i--, j++)
+	gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
     }
   else if (arrow_type == GTK_ARROW_RIGHT)
     {
-      cairo_move_to (cr, x,              y);
-      cairo_line_to (cr, x + width,      y + height / 2.);
-      cairo_line_to (cr, x,              y + height);
+      for (i = 0, j = 0; i < width; i++, j++)
+	gdk_draw_line (window, gc, x + i, y + j, x + i, y + height - j - 1);
     }
 
-  cairo_close_path (cr);
-  cairo_fill (cr);
-
-  cairo_destroy (cr);
+  if (area)
+    gdk_gc_set_clip_rectangle (gc, NULL);
 }
 
 static void
@@ -3032,17 +3237,22 @@
 			gint           width,
 			gint           height)
 {
+  gint original_width, original_x;
+  
   sanitize_size (window, &width, &height);
 
+  original_width = width;
+  original_x = x;
+
   calculate_arrow_geometry (arrow_type, &x, &y, &width, &height);
 
   if (detail && strcmp (detail, "menu_scroll_arrow_up") == 0)
     y++;
 
   if (state == GTK_STATE_INSENSITIVE)
-    draw_arrow (window, &style->white, area, arrow_type,
+    draw_arrow (window, style->white_gc, area, arrow_type,
 		x + 1, y + 1, width, height);
-  draw_arrow (window, &style->fg[state], area, arrow_type,
+  draw_arrow (window, style->fg_gc[state], area, arrow_type,
 	      x, y, width, height);
 }
 
@@ -3074,6 +3284,9 @@
   GdkGC *inner_sw = NULL;
   GdkGC *inner_se = NULL;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
   
   half_width = width / 2;
@@ -3191,6 +3404,13 @@
                          gint           y,
                          const gchar   *string)
 {
+  GdkDisplay *display;
+  
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
+  display = gdk_drawable_get_display (window);
+  
   if (area)
     {
       gdk_gc_set_clip_rectangle (style->white_gc, area);
@@ -3223,8 +3443,8 @@
   
   if (widget)
     gtk_widget_style_get (widget, 
-			  "indicator-size", &tmp_size,
-			  "indicator-spacing", &tmp_spacing,
+			  "indicator_size", &tmp_size,
+			  "indicator_spacing", &tmp_spacing,
 			  NULL);
 
   if (tmp_size)
@@ -3259,6 +3479,9 @@
 {
   gboolean is_spinbutton_box = FALSE;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
 
   if (widget && GTK_IS_SPIN_BUTTON (widget) && detail)
@@ -3407,6 +3630,9 @@
   GdkGC *gc1;
   GdkGC *freeme = NULL;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
   
   if (detail)
@@ -3415,26 +3641,15 @@
         {
           if (!strcmp ("text", detail))
             gc1 = style->bg_gc[GTK_STATE_SELECTED];
-          else if (!strcmp ("cell_even", detail) ||
-                   !strcmp ("cell_odd", detail) ||
-                   !strcmp ("cell_even_ruled", detail) ||
-		   !strcmp ("cell_even_ruled_sorted", detail))
+          else if (!strncmp ("cell_even", detail, strlen ("cell_even")) ||
+		   !strncmp ("cell_odd", detail, strlen ("cell_odd")))
             {
 	      /* This has to be really broken; alex made me do it. -jrb */
 	      if (GTK_WIDGET_HAS_FOCUS (widget))
 		gc1 = style->base_gc[state_type];
-	      else
-	        gc1 = style->base_gc[GTK_STATE_ACTIVE];
+	      else 
+		gc1 = style->base_gc[GTK_STATE_ACTIVE];
             }
-	  else if (!strcmp ("cell_odd_ruled", detail) ||
-		   !strcmp ("cell_odd_ruled_sorted", detail))
-	    {
-	      if (GTK_WIDGET_HAS_FOCUS (widget))
-	        freeme = get_darkened_gc (window, &style->base[state_type], 1);
-	      else
-	        freeme = get_darkened_gc (window, &style->base[GTK_STATE_ACTIVE], 1);
-	      gc1 = freeme;
-	    }
           else
             {
               gc1 = style->bg_gc[state_type];
@@ -3459,7 +3674,7 @@
 	      GdkColor *color = NULL;
 
 	      gtk_widget_style_get (widget,
-		                    "even-row-color", &color,
+		                    "even_row_color", &color,
 				    NULL);
 
 	      if (color)
@@ -3477,7 +3692,7 @@
 	      GdkColor *color;
 
 	      gtk_widget_style_get (widget,
-		                    "odd-row-color", &color,
+		                    "odd_row_color", &color,
 				    NULL);
 
 	      if (color)
@@ -3490,7 +3705,7 @@
 	      else
 	        {
 		  gtk_widget_style_get (widget,
-		                        "even-row-color", &color,
+		                        "even_row_color", &color,
 					NULL);
 
 		  if (color)
@@ -3511,11 +3726,11 @@
 
 	      if (!strcmp ("cell_odd_sorted", detail))
 	        gtk_widget_style_get (widget,
-		                      "odd-row-color", &color,
+		                      "odd_row_color", &color,
 				      NULL);
 	      else
 	        gtk_widget_style_get (widget,
-		                      "even-row-color", &color,
+		                      "even_row_color", &color,
 				      NULL);
 
 	      if (color)
@@ -3536,7 +3751,7 @@
 	      GdkColor *color = NULL;
 
 	      gtk_widget_style_get (widget,
-		                    "odd-row-color", &color,
+		                    "odd_row_color", &color,
 				    NULL);
 
 	      if (color)
@@ -3549,7 +3764,7 @@
 	      else
 	        {
 		  gtk_widget_style_get (widget,
-		                        "even-row-color", &color,
+		                        "even_row_color", &color,
 					NULL);
 
 		  if (color)
@@ -3595,6 +3810,21 @@
     g_object_unref (freeme);
 }
 
+static GdkGC *
+create_aa_gc (GdkWindow *window, GtkStyle *style, GtkStateType state_type)
+{
+  GdkColor aa_color;
+  GdkGC *gc = gdk_gc_new (window);
+   
+  aa_color.red = (style->fg[state_type].red + style->bg[state_type].red) / 2;
+  aa_color.green = (style->fg[state_type].green + style->bg[state_type].green) / 2;
+  aa_color.blue = (style->fg[state_type].blue + style->bg[state_type].blue) / 2;
+  
+  gdk_gc_set_rgb_fg_color (gc, &aa_color);
+
+  return gc;
+}
+
 static void 
 gtk_default_draw_check (GtkStyle      *style,
 			GdkWindow     *window,
@@ -3608,116 +3838,92 @@
 			gint           width,
 			gint           height)
 {
-  cairo_t *cr = gdk_cairo_create (window);
-  enum { BUTTON, MENU, CELL } type = BUTTON;
-  int exterior_size;
-  int interior_size;
-  int pad;
-  
-  if (detail)
-    {
-      if (strcmp (detail, "cellcheck") == 0)
-	type = CELL;
-      else if (strcmp (detail, "check") == 0)
-	type = MENU;
-    }
-      
-  if (area)
+  if (detail && strcmp (detail, "cellcheck") == 0)
     {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
+      if (area)               
+      	gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], area);
+      gdk_draw_rectangle (window,
+			  widget->style->base_gc[state_type],
+			  TRUE,
+                          x, y,
+			  width, height);
+      if (area)
+	{
+	  gdk_gc_set_clip_rectangle (widget->style->base_gc[state_type], NULL);
+	  gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], area);
+	}
+      gdk_draw_rectangle (window,
+			  widget->style->text_gc[state_type],
+			  FALSE,
+                          x, y,
+			  width, height);
+      if (area)               
+      	gdk_gc_set_clip_rectangle (widget->style->text_gc[state_type], NULL);
+
+      x -= (1 + INDICATOR_PART_SIZE - width) / 2;
+      y -= (((1 + INDICATOR_PART_SIZE - height) / 2) - 1);
+      if (shadow_type == GTK_SHADOW_IN)
+	{
+	  draw_part (window, style->text_gc[state_type], area, x, y, CHECK_TEXT);
+	  draw_part (window, style->text_aa_gc[state_type], area, x, y, CHECK_AA);
+	}
+      else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
+	{
+	  draw_part (window, style->text_gc[state_type], area, x, y, CHECK_INCONSISTENT_TEXT);
+	}
     }
-  
-  exterior_size = MIN (width, height);
-  if (exterior_size % 2 == 0) /* Ensure odd */
-    exterior_size -= -1;
-
-  pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
-  interior_size = MAX (1, exterior_size - 2 * pad);
-
-  if (interior_size < 7)
+  else
     {
-      interior_size = 7;
-      pad = MAX (0, (exterior_size - interior_size) / 2);
-    }
+      GdkGC *free_me = NULL;
+      
+      GdkGC *base_gc;
+      GdkGC *text_gc;
+      GdkGC *aa_gc;
 
-  x -= (1 + exterior_size - width) / 2;
-  y -= (1 + exterior_size - height) / 2;
+      x -= (1 + INDICATOR_PART_SIZE - width) / 2;
+      y -= (1 + INDICATOR_PART_SIZE - height) / 2;
 
-  switch (type)
-    {
-    case BUTTON:
-    case CELL:
-      if (type == BUTTON)
-	gdk_cairo_set_source_color (cr, &style->fg[state_type]);
+      if (detail && strcmp (detail, "check") == 0)	/* Menu item */
+	{
+	  text_gc = style->fg_gc[state_type];
+	  base_gc = style->bg_gc[state_type];
+	  aa_gc = free_me = create_aa_gc (window, style, state_type);
+	}
       else
-	gdk_cairo_set_source_color (cr, &style->text[state_type]);
-	
-      cairo_set_line_width (cr, 1.0);
-      cairo_rectangle (cr, x + 0.5, y + 0.5, exterior_size - 1, exterior_size - 1);
-      cairo_stroke (cr);
+	{
+	  if (state_type == GTK_STATE_ACTIVE)
+	    {
+	      text_gc = style->fg_gc[state_type];
+	      base_gc = style->bg_gc[state_type];
+	      aa_gc = free_me = create_aa_gc (window, style, state_type);
+	    }
+	  else
+	    {
+	      text_gc = style->text_gc[state_type];
+	      base_gc = style->base_gc[state_type];
+	      aa_gc = style->text_aa_gc[state_type];
+	    }
 
-      gdk_cairo_set_source_color (cr, &style->base[state_type]);
-      cairo_rectangle (cr, x + 1, y + 1, exterior_size - 2, exterior_size - 2);
-      cairo_fill (cr);
-      break;
+	  draw_part (window, base_gc, area, x, y, CHECK_BASE);
+	  draw_part (window, style->black_gc, area, x, y, CHECK_BLACK);
+	  draw_part (window, style->dark_gc[state_type], area, x, y, CHECK_DARK);
+	  draw_part (window, style->mid_gc[state_type], area, x, y, CHECK_MID);
+	  draw_part (window, style->light_gc[state_type], area, x, y, CHECK_LIGHT);
+	}
 
-    case MENU:
-      break;
-    }
-      
-  switch (type)
-    {
-    case BUTTON:
-    case CELL:
-      gdk_cairo_set_source_color (cr, &style->text[state_type]);
-      break;
-    case MENU:
-      gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-      break;
-    }
+      if (shadow_type == GTK_SHADOW_IN)
+	{
+	  draw_part (window, text_gc, area, x, y, CHECK_TEXT);
+	  draw_part (window, aa_gc, area, x, y, CHECK_AA);
+	}
+      else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
+	{
+	  draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
+	}
 
-  if (shadow_type == GTK_SHADOW_IN)
-    {
-      cairo_translate (cr,
-		       x + pad, y + pad);
-      
-      cairo_scale (cr, interior_size / 7., interior_size / 7.);
-      
-      cairo_move_to  (cr, 7.0, 0.0);
-      cairo_line_to  (cr, 7.5, 1.0);
-      cairo_curve_to (cr, 5.3, 2.0,
-		      4.3, 4.0,
-		      3.5, 7.0);
-      cairo_curve_to (cr, 3.0, 5.7,
-		      1.3, 4.7,
-		      0.0, 4.7);
-      cairo_line_to  (cr, 0.2, 3.5);
-      cairo_curve_to (cr, 1.1, 3.5,
-		      2.3, 4.3,
-		      3.0, 5.0);
-      cairo_curve_to (cr, 1.0, 3.9,
-		      2.4, 4.1,
-		      3.2, 4.9);
-      cairo_curve_to (cr, 3.5, 3.1,
-		      5.2, 2.0,
-		      7.0, 0.0);
-      
-      cairo_fill (cr);
-    }
-  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
-    {
-      int line_thickness = MAX (1, (3 + interior_size * 2) / 7);
-
-      cairo_rectangle (cr,
-		       x + pad,
-		       y + pad + (1 + interior_size - line_thickness) / 2,
-		       interior_size,
-		       line_thickness);
-      cairo_fill (cr);
+      if (free_me)
+	g_object_unref (free_me);
     }
-  
-  cairo_destroy (cr);
 }
 
 static void 
@@ -3733,111 +3939,96 @@
 			 gint           width,
 			 gint           height)
 {
-  cairo_t *cr = gdk_cairo_create (window);
-  enum { BUTTON, MENU, CELL } type = BUTTON;
-  int exterior_size;
-  
-  if (detail)
+  if (detail && strcmp (detail, "cellradio") == 0)
     {
-      if (strcmp (detail, "radio") == 0)
-	type = CELL;
-      else if (strcmp (detail, "option") == 0)
-	type = MENU;
-    }
-      
-  if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
+      if (area)               
+	gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], area);
+      gdk_draw_arc (window,
+		    widget->style->fg_gc[state_type],
+		    FALSE,
+                    x, y,
+		    width,
+		    height,
+		    0, 360*64);
+
+      if (shadow_type == GTK_SHADOW_IN)
+	{
+	  gdk_draw_arc (window,
+			widget->style->fg_gc[state_type],
+			TRUE,
+                        x + 2,
+                        y + 2,
+			width - 4,
+			height - 4,
+			0, 360*64);
+	}
+      else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
+        {
+          draw_part (window, widget->style->fg_gc[state_type],
+	             area, x, y, CHECK_INCONSISTENT_TEXT);
+	}
+      if (area)               
+	gdk_gc_set_clip_rectangle (widget->style->fg_gc[state_type], NULL);
     }
-  
-  exterior_size = MIN (width, height);
-  if (exterior_size % 2 == 0) /* Ensure odd */
-    exterior_size -= -1;
-  
-  x -= (1 + exterior_size - width) / 2;
-  y -= (1 + exterior_size - height) / 2;
-
-  switch (type)
+  else
     {
-    case BUTTON:
-    case CELL:
-      gdk_cairo_set_source_color (cr, &style->base[state_type]);
+      GdkGC *free_me = NULL;
       
-      cairo_arc (cr,
-		 x + exterior_size / 2.,
-		 y + exterior_size / 2.,
-		 (exterior_size - 1) / 2.,
-		 0, 2 * G_PI);
+      GdkGC *base_gc;
+      GdkGC *text_gc;
+      GdkGC *aa_gc;
 
-      cairo_fill_preserve (cr);
+      x -= (1 + INDICATOR_PART_SIZE - width) / 2;
+      y -= (1 + INDICATOR_PART_SIZE - height) / 2;
 
-      if (type == BUTTON)
-	gdk_cairo_set_source_color (cr, &style->fg[state_type]);
+      if (detail && strcmp (detail, "option") == 0)	/* Menu item */
+	{
+	  text_gc = style->fg_gc[state_type];
+	  base_gc = style->bg_gc[state_type];
+	  aa_gc = free_me = create_aa_gc (window, style, state_type);
+	}
       else
-	gdk_cairo_set_source_color (cr, &style->text[state_type]);
-	
-      cairo_set_line_width (cr, 1.);
-      cairo_stroke (cr);
-      break;
-
-    case MENU:
-      break;
-    }
-      
-  switch (type)
-    {
-    case BUTTON:
-      gdk_cairo_set_source_color (cr, &style->text[state_type]);
-      break;
-    case CELL:
-      break;
-    case MENU:
-      gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-      break;
-    }
+	{
+	  if (state_type == GTK_STATE_ACTIVE)
+	    {
+	      text_gc = style->fg_gc[state_type];
+	      base_gc = style->bg_gc[state_type];
+	      aa_gc = free_me = create_aa_gc (window, style, state_type);
+	    }
+	  else
+	    {
+	      text_gc = style->text_gc[state_type];
+	      base_gc = style->base_gc[state_type];
+	      aa_gc = style->text_aa_gc[state_type];
+	    }
 
-  if (shadow_type == GTK_SHADOW_IN)
-    {
-      int pad = style->xthickness + MAX (1, 2 * (exterior_size - 2 * style->xthickness) / 9);
-      int interior_size = MAX (1, exterior_size - 2 * pad);
+	  draw_part (window, base_gc, area, x, y, RADIO_BASE);
+	  draw_part (window, style->black_gc, area, x, y, RADIO_BLACK);
+	  draw_part (window, style->dark_gc[state_type], area, x, y, RADIO_DARK);
+	  draw_part (window, style->mid_gc[state_type], area, x, y, RADIO_MID);
+	  draw_part (window, style->light_gc[state_type], area, x, y, RADIO_LIGHT);
+	}
 
-      if (interior_size < 5)
+      if (shadow_type == GTK_SHADOW_IN)
 	{
-	  interior_size = 7;
-	  pad = MAX (0, (exterior_size - interior_size) / 2);
+	  draw_part (window, text_gc, area, x, y, RADIO_TEXT);
 	}
-
-      cairo_arc (cr,
-		 x + pad + interior_size / 2.,
-		 y + pad + interior_size / 2.,
-		 interior_size / 2.,
-		 0, 2 * G_PI);
-      cairo_fill (cr);
-    }
-  else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
-    {
-      int pad = style->xthickness + MAX (1, (exterior_size - 2 * style->xthickness) / 9);
-      int interior_size = MAX (1, exterior_size - 2 * pad);
-      int line_thickness;
-
-      if (interior_size < 7)
+      else if (shadow_type == GTK_SHADOW_ETCHED_IN) /* inconsistent */
 	{
-	  interior_size = 7;
-	  pad = MAX (0, (exterior_size - interior_size) / 2);
+	  if (detail && strcmp (detail, "option") == 0)  /* Menu item */
+	    {
+	      draw_part (window, text_gc, area, x, y, CHECK_INCONSISTENT_TEXT);
+	    }
+	  else
+	    {
+	      draw_part (window, text_gc, area, x, y, RADIO_INCONSISTENT_TEXT);
+	      draw_part (window, aa_gc, area, x, y, RADIO_INCONSISTENT_AA);
+	    }
 	}
 
-      line_thickness = MAX (1, (3 + interior_size * 2) / 7);
-
-      cairo_rectangle (cr,
-		       x + pad,
-		       y + pad + (interior_size - line_thickness) / 2.,
-		       interior_size,
-		       line_thickness);
-      cairo_fill (cr);
+      if (free_me)
+	g_object_unref (free_me);
     }
-  
-  cairo_destroy (cr);
 }
 
 static void
@@ -3869,21 +4060,21 @@
 
   if (state_type == GTK_STATE_INSENSITIVE)
     {
-      draw_arrow (window, &style->white, area,
+      draw_arrow (window, style->white_gc, area,
 		  GTK_ARROW_UP, x + 1, y + 1,
 		  indicator_size.width, arrow_height);
       
-      draw_arrow (window, &style->white, area,
+      draw_arrow (window, style->white_gc, area,
 		  GTK_ARROW_DOWN, x + 1, y + arrow_height + ARROW_SPACE + 1,
 		  indicator_size.width, arrow_height);
     }
   
-  draw_arrow (window, &style->fg[state_type], area,
+  draw_arrow (window, style->fg_gc[state_type], area,
 	      GTK_ARROW_UP, x, y,
 	      indicator_size.width, arrow_height);
   
   
-  draw_arrow (window, &style->fg[state_type], area,
+  draw_arrow (window, style->fg_gc[state_type], area,
 	      GTK_ARROW_DOWN, x, y + arrow_height + ARROW_SPACE,
 	      indicator_size.width, arrow_height);
 }
@@ -3909,6 +4100,9 @@
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
   
   switch (shadow_type)
@@ -4122,6 +4316,9 @@
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   gtk_style_apply_default_background (style, window,
                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
                                       state_type, area, x, y, width, height);
@@ -4338,6 +4535,9 @@
   GdkGC *gc3 = NULL;
   GdkGC *gc4 = NULL;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   gtk_style_apply_default_background (style, window,
                                       widget && !GTK_WIDGET_NO_WINDOW (widget),
                                       GTK_STATE_NORMAL, area, x, y, width, height);
@@ -4503,10 +4703,12 @@
 			gint           width,
 			gint           height)
 {
-  cairo_t *cr;
+  GdkPoint points[5];
+  GdkGC    *gc;
   gboolean free_dash_list = FALSE;
   gint line_width = 1;
   gint8 *dash_list = "\1\1";
+  gint dash_len;
 
   if (widget)
     {
@@ -4518,6 +4720,22 @@
       free_dash_list = TRUE;
   }
 
+  sanitize_size (window, &width, &height);
+  
+  if (detail && !strcmp (detail, "colorwheel_light"))
+    gc = style->black_gc;
+  else if (detail && !strcmp (detail, "colorwheel_dark"))
+    gc = style->white_gc;
+  else 
+    gc = style->fg_gc[state_type];
+
+  gdk_gc_set_line_attributes (gc, line_width,
+			      dash_list[0] ? GDK_LINE_ON_OFF_DASH : GDK_LINE_SOLID,
+			      GDK_CAP_BUTT, GDK_JOIN_MITER);
+  
+  if (area)
+    gdk_gc_set_clip_rectangle (gc, area);
+
   if (detail && !strcmp (detail, "add-mode"))
     {
       if (free_dash_list)
@@ -4527,59 +4745,88 @@
       free_dash_list = FALSE;
     }
 
-  sanitize_size (window, &width, &height);
+  points[0].x = x + line_width / 2;
+  points[0].y = y + line_width / 2;
+  points[1].x = x + width - line_width + line_width / 2;
+  points[1].y = y + line_width / 2;
+  points[2].x = x + width - line_width + line_width / 2;
+  points[2].y = y + height - line_width + line_width / 2;
+  points[3].x = x + line_width / 2;
+  points[3].y = y + height - line_width + line_width / 2;
+  points[4] = points[0];
 
-  cr = gdk_cairo_create (window);
-  
-  if (detail && !strcmp (detail, "colorwheel_light"))
-    cairo_set_source_rgb (cr, 0., 0., 0.);
-  else if (detail && !strcmp (detail, "colorwheel_dark"))
-    cairo_set_source_rgb (cr, 1., 1., 1.);
+  if (!dash_list[0])
+    {
+      gdk_draw_lines (window, gc, points, 5);
+    }
   else
-    gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-
-  cairo_set_line_width (cr, line_width);
-
-  if (dash_list[0])
     {
-      gint n_dashes = strlen (dash_list);
-      gdouble *dashes = g_new (gdouble, n_dashes);
-      gdouble total_length = 0;
-      gdouble dash_offset;
-      gint i;
-
-      for (i = 0; i < n_dashes; i++)
+      /* We go through all the pain below because the X rasterization
+       * rules don't really work right for dashed lines if you
+       * want continuity in segments that go between top/right
+       * and left/bottom. For instance, a top left corner
+       * with a 1-1 dash is drawn as:
+       *
+       *  X X X 
+       *  X
+       *
+       *  X
+       *
+       * This is because pixels on the top and left boundaries
+       * of polygons are drawn, but not on the bottom and right.
+       * So, if you have a line going up that turns the corner
+       * and goes right, there is a one pixel shift in the pattern.
+       *
+       * So, to fix this, we drawn the top and right in one call,
+       * then the left and bottom in another call, fixing up
+       * the dash offset for the second call ourselves to get
+       * continuity at the upper left.
+       *
+       * It's not perfect since we really should have a join at
+       * the upper left and lower right instead of two intersecting
+       * lines but that's only really apparent for no-dashes,
+       * which (for this reason) are done as one polygon and
+       * don't to through this code path.
+       */
+      
+      dash_len = strlen (dash_list);
+      
+      if (dash_list[0])
+	gdk_gc_set_dashes (gc, 0, dash_list, dash_len);
+      
+      gdk_draw_lines (window, gc, points, 3);
+      
+      /* We draw this line one farther over than it is "supposed" to
+       * because of another rasterization problem ... if two 1 pixel
+       * unjoined lines meet at the lower right, there will be a missing
+       * pixel.
+       */
+      points[2].x += 1;
+      
+      if (dash_list[0])
 	{
-	  dashes[i] = dash_list[i];
-	  total_length += dash_list[i];
+	  gint dash_pixels = 0;
+	  gint i;
+	  
+	  /* Adjust the dash offset for the bottom and left so we
+	   * match up at the upper left.
+	   */
+	  for (i = 0; i < dash_len; i++)
+	    dash_pixels += dash_list[i];
+      
+	  if (dash_len % 2 == 1)
+	    dash_pixels *= 2;
+	  
+	  gdk_gc_set_dashes (gc, dash_pixels - (width + height - 2 * line_width) % dash_pixels, dash_list, dash_len);
 	}
-
-      /* The dash offset here aligns the pattern to integer pixels
-       * by starting the dash at the right side of the left border
-       * Negative dash offsets in cairo don't work
-       * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
-       */
-      dash_offset = - line_width / 2.;
-      while (dash_offset < 0)
-	dash_offset += total_length;
       
-      cairo_set_dash (cr, dashes, n_dashes, dash_offset);
-      g_free (dashes);
+      gdk_draw_lines (window, gc, points + 2, 3);
     }
 
-  if (area)
-    {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
-    }
+  gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
 
-  cairo_rectangle (cr,
-		   x + line_width / 2.,
-		   y + line_width / 2.,
-		   width - line_width,
-		   height - line_width);
-  cairo_stroke (cr);
-  cairo_destroy (cr);
+  if (area)
+    gdk_gc_set_clip_rectangle (gc, NULL);
 
   if (free_dash_list)
     g_free (dash_list);
@@ -4599,6 +4846,9 @@
                          gint           height,
                          GtkOrientation orientation)
 {
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
   
   gtk_paint_box (style, window, state_type, shadow_type,
@@ -4627,6 +4877,7 @@
 	  gint          y,
 	  gushort       size)
 {
+  
   size = CLAMP (size, 2, 3);
 
   if (size == 2)
@@ -4667,6 +4918,9 @@
   GdkRectangle dest;
   gint intersect;
   
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   sanitize_size (window, &width, &height);
   
   gtk_paint_box (style, window, state_type, shadow_type, area, widget, 
@@ -4682,9 +4936,9 @@
       if (state_type == GTK_STATE_SELECTED && widget && !GTK_WIDGET_HAS_FOCUS (widget))
 	{
 	  GdkColor unfocused_light;
-
+      
 	  _gtk_style_shade (&style->base[GTK_STATE_ACTIVE], &unfocused_light,
-                            LIGHTNESS_MULT);
+			   LIGHTNESS_MULT);
 
 	  light_gc = free_me = gdk_gc_new (window);
 	  gdk_gc_set_rgb_fg_color (light_gc, &unfocused_light);
@@ -4750,6 +5004,72 @@
 }
 
 static void
+create_expander_affine (gdouble affine[6],
+			gint    degrees,
+			gint    expander_size,
+			gint    x,
+			gint    y)
+{
+  gdouble s, c;
+  gdouble width;
+  gdouble height;
+
+  width = expander_size / 4.0;
+  height = expander_size / 2.0;
+
+  switch (degrees)
+    {
+    case 0:
+      s = 0.0;
+      c = 1.0;
+      break;
+    case 90:
+      s = 1.0;
+      c = 0.0;
+      break;
+    case 180:
+      s = 0.0;
+      c = -1.0;
+      break;
+    default:
+      s = sin (degrees * G_PI / 180.0);
+      c = cos (degrees * G_PI / 180.0);
+      break;
+    }
+  
+  affine[0] = c;
+  affine[1] = s;
+  affine[2] = -s;
+  affine[3] = c;
+  affine[4] = -width * c - height * -s + x;
+  affine[5] = -width * s - height * c + y;
+}
+
+static void
+apply_affine_on_point (double affine[6], GdkPoint *point)
+{
+  gdouble x, y;
+
+  x = point->x * affine[0] + point->y * affine[2] + affine[4];
+  y = point->x * affine[1] + point->y * affine[3] + affine[5];
+
+  point->x = floor (x);
+  point->y = floor (y);
+}
+
+static void
+gtk_style_draw_polygon_with_gc (GdkWindow *window, GdkGC *gc, gint line_width,
+				gboolean do_fill, GdkPoint *points, gint n_points)
+{
+  gdk_gc_set_line_attributes (gc, line_width,
+			      GDK_LINE_SOLID,
+			      GDK_CAP_BUTT, GDK_JOIN_MITER);
+
+  gdk_draw_polygon (window, gc, do_fill, points, n_points);
+  gdk_gc_set_line_attributes (gc, 0, GDK_LINE_SOLID, GDK_CAP_BUTT, GDK_JOIN_MITER);
+}
+
+static void
 gtk_default_draw_expander (GtkStyle        *style,
                            GdkWindow       *window,
                            GtkStateType     state_type,
@@ -4760,127 +5080,82 @@
                            gint             y,
 			   GtkExpanderStyle expander_style)
 {
-#define DEFAULT_EXPANDER_SIZE 12
-
   gint expander_size;
-  gint line_width;
-  double vertical_overshoot;
-  int diameter;
-  double radius;
-  double interp;		/* interpolation factor for center position */
-  double x_double_horz, y_double_horz;
-  double x_double_vert, y_double_vert;
-  double x_double, y_double;
+  GdkPoint points[3];
+  gint i;
+  gint line_width, o;
+  gdouble affine[6];
   gint degrees = 0;
 
-  cairo_t *cr = gdk_cairo_create (window);
-  
+  gtk_widget_style_get (widget,
+			"expander-size", &expander_size,
+			NULL);
+  line_width = MAX (1, expander_size/9);
+
   if (area)
     {
-      gdk_cairo_rectangle (cr, area);
-      cairo_clip (cr);
+      gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], area);
+      gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], area);
     }
 
-  if (widget &&
-      gtk_widget_class_find_style_property (GTK_WIDGET_GET_CLASS (widget),
-					    "expander-size"))
-    {
-      gtk_widget_style_get (widget,
-			    "expander-size", &expander_size,
-			    NULL);
-    }
-  else
-    expander_size = DEFAULT_EXPANDER_SIZE;
-    
-  line_width = MAX (1, expander_size/9);
+  /* a rough estimate of how much the joins of the triangle will overshoot. 
+   * 2.4 ~ 1 / tan (45 / 2)
+   */
+  o = ceil (2.4 * line_width / 2.0);
+  points[0].x = line_width / 2;
+  points[0].y = o;
+  points[1].x = expander_size / 2 + line_width / 2 - o;
+  points[1].y = expander_size / 2;
+  points[2].x = line_width / 2;
+  points[2].y = expander_size - o;
 
   switch (expander_style)
     {
     case GTK_EXPANDER_COLLAPSED:
       degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 180 : 0;
-      interp = 0.0;
       break;
     case GTK_EXPANDER_SEMI_COLLAPSED:
       degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 150 : 30;
-      interp = 0.25;
       break;
     case GTK_EXPANDER_SEMI_EXPANDED:
       degrees = (get_direction (widget) == GTK_TEXT_DIR_RTL) ? 120 : 60;
-      interp = 0.75;
       break;
     case GTK_EXPANDER_EXPANDED:
       degrees = 90;
-      interp = 1.0;
       break;
     default:
       g_assert_not_reached ();
     }
 
-  /* Compute distance that the stroke extends beyonds the end
-   * of the triangle we draw.
-   */
-  vertical_overshoot = line_width / 2.0 * (1. / tan (G_PI / 8));
-
-  /* For odd line widths, we end the vertical line of the triangle
-   * at a half pixel, so we round differently.
-   */
-  if (line_width % 2 == 1)
-    vertical_overshoot = ceil (0.5 + vertical_overshoot) - 0.5;
-  else
-    vertical_overshoot = ceil (vertical_overshoot);
-
-  /* Adjust the size of the triangle we draw so that the entire stroke fits
-   */
-  diameter = MAX (3, expander_size - 2 * vertical_overshoot);
-
-  /* If the line width is odd, we want the diameter to be even,
-   * and vice versa, so force the sum to be odd. This relationship
-   * makes the point of the triangle look right.
-   */
-  diameter -= (1 - (diameter + line_width) % 2);
-  
-  radius = diameter / 2.;
-
-  /* Adjust the center so that the stroke is properly aligned with
-   * the pixel grid. The center adjustment is different for the
-   * horizontal and vertical orientations. For intermediate positions
-   * we interpolate between the two.
-   */
-  x_double_vert = floor (x - (radius + line_width) / 2.) + (radius + line_width) / 2.;
-  y_double_vert = y - 0.5;
-
-  x_double_horz = x - 0.5;
-  y_double_horz = floor (y - (radius + line_width) / 2.) + (radius + line_width) / 2.;
-
-  x_double = x_double_vert * (1 - interp) + x_double_horz * interp;
-  y_double = y_double_vert * (1 - interp) + y_double_horz * interp;
-  
-  cairo_translate (cr, x_double, y_double);
-  cairo_rotate (cr, degrees * G_PI / 180);
+  create_expander_affine (affine, degrees, expander_size, x, y);
 
-  cairo_move_to (cr, - radius / 2., - radius);
-  cairo_line_to (cr,   radius / 2.,   0);
-  cairo_line_to (cr, - radius / 2.,   radius);
-  cairo_close_path (cr);
-  
-  cairo_set_line_width (cr, line_width);
+  for (i = 0; i < 3; i++)
+    apply_affine_on_point (affine, &points[i]);
 
   if (state_type == GTK_STATE_PRELIGHT)
-    gdk_cairo_set_source_color (cr,
-				&style->fg[GTK_STATE_PRELIGHT]);
+    {
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_PRELIGHT],
+				      1, TRUE, points, 3);
+    }
   else if (state_type == GTK_STATE_ACTIVE)
-    gdk_cairo_set_source_color (cr,
-				&style->light[GTK_STATE_ACTIVE]);
+    {
+      gtk_style_draw_polygon_with_gc (window, style->light_gc[GTK_STATE_ACTIVE],
+				      1, TRUE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
+				      line_width, FALSE, points, 3);
+    }
   else
-    gdk_cairo_set_source_color (cr,
-				&style->base[GTK_STATE_NORMAL]);
-  
-  cairo_fill_preserve (cr);
-  
-  gdk_cairo_set_source_color (cr, &style->fg[state_type]);
-  cairo_stroke (cr);
-  
-  cairo_destroy (cr);
+    {
+      gtk_style_draw_polygon_with_gc (window, style->base_gc[GTK_STATE_NORMAL],
+				      1, TRUE, points, 3);
+      gtk_style_draw_polygon_with_gc (window, style->fg_gc[GTK_STATE_NORMAL],
+				      line_width, FALSE, points, 3);
+    }
+  if (area)
+    {
+      gdk_gc_set_clip_rectangle (style->fg_gc[GTK_STATE_NORMAL], NULL);
+      gdk_gc_set_clip_rectangle (style->base_gc[GTK_STATE_NORMAL], NULL);
+    }
 }
 
 typedef struct _ByteRange ByteRange;
@@ -5046,6 +5321,9 @@
                          PangoLayout     *layout)
 {
   GdkGC *gc;
+  
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
 
   gc = use_text ? style->text_gc[state_type] : style->fg_gc[state_type];
   
@@ -5087,6 +5365,9 @@
   GdkPoint points[4];
   gint i, j, skip;
 
+  g_return_if_fail (GTK_IS_STYLE (style));
+  g_return_if_fail (window != NULL);
+  
   if (area)
     {
       gdk_gc_set_clip_rectangle (style->light_gc[state_type], area);
@@ -5390,8 +5671,8 @@
 
 void
 _gtk_style_shade (GdkColor *a,
-                  GdkColor *b,
-                  gdouble   k)
+                 GdkColor *b,
+                 gdouble   k)
 {
   gdouble red;
   gdouble green;
@@ -5578,10 +5859,9 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: rectangle to which the output is clipped, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: rectangle to which the output is clipped
+ * @widget: the widget
+ * @detail: a style detail
  * @x1: the starting x coordinate
  * @x2: the ending x coordinate
  * @y: the y coordinate
@@ -5602,7 +5882,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_hline != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_hline (style, window, state_type, area, widget, detail, x1, x2, y);
 }
@@ -5612,10 +5891,9 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: rectangle to which the output is clipped, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: rectangle to which the output is clipped
+ * @widget: the widget
+ * @detail: a style detail
  * @y1_: the starting y coordinate
  * @y2_: the ending y coordinate
  * @x: the x coordinate
@@ -5636,7 +5914,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_vline != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_vline (style, window, state_type, area, widget, detail, y1_, y2_, x);
 }
@@ -5647,10 +5924,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle
  * @y: y origin of the rectangle
  * @width: width of the rectangle 
@@ -5674,7 +5950,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_shadow (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5685,10 +5960,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @points: an array of #GdkPoint<!-- -->s
  * @npoints: length of @points
  * @fill: %TRUE if the polygon should be filled
@@ -5709,7 +5983,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_polygon != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_polygon (style, window, state_type, shadow_type, area, widget, detail, points, npoints, fill);
 }
@@ -5720,10 +5993,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @arrow_type: the type of arrow to draw
  * @fill: %TRUE if the arrow tip should be filled
  * @x: x origin of the rectangle to draw the arrow in
@@ -5751,7 +6023,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_arrow != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_arrow (style, window, state_type, shadow_type, area, widget, detail, arrow_type, fill, x, y, width, height);
 }
@@ -5762,10 +6033,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle to draw the diamond in
  * @y: y origin of the rectangle to draw the diamond in
  * @width: width of the rectangle to draw the diamond in
@@ -5789,7 +6059,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_diamond != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_diamond (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5799,10 +6068,9 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin
  * @y: y origin
  * @string: the string to draw
@@ -5824,7 +6092,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_string != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_string (style, window, state_type, area, widget, detail, x, y, string);
 }
@@ -5835,10 +6102,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the box
  * @y: y origin of the box
  * @width: the width of the box
@@ -5861,7 +6127,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5872,10 +6137,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the box
  * @y: y origin of the box
  * @width: the width of the box
@@ -5898,7 +6162,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_flat_box != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_flat_box (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5909,10 +6172,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle to draw the check in
  * @y: y origin of the rectangle to draw the check in
  * @width: the width of the rectangle to draw the check in
@@ -5936,7 +6198,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_check != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_check (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5947,10 +6208,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle to draw the option in
  * @y: y origin of the rectangle to draw the option in
  * @width: the width of the rectangle to draw the option in
@@ -5974,7 +6234,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_option != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_option (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -5985,10 +6244,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: the type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle to draw the tab in
  * @y: y origin of the rectangle to draw the tab in
  * @width: the width of the rectangle to draw the tab in
@@ -6012,7 +6270,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_tab != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_tab (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height);
 }
@@ -6023,10 +6280,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle
  * @y: y origin of the rectangle
  * @width: width of the rectangle 
@@ -6057,7 +6313,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_shadow_gap != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_shadow_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
 }
@@ -6069,10 +6324,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the rectangle
  * @y: y origin of the rectangle
  * @width: width of the rectangle 
@@ -6102,7 +6356,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_box_gap != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_box_gap (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side, gap_x, gap_width);
 }
@@ -6113,10 +6366,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the extension
  * @y: y origin of the extension
  * @width: width of the extension 
@@ -6141,7 +6393,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_extension != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_extension (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, gap_side);
 }
@@ -6151,10 +6402,9 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: the x origin of the rectangle around which to draw a focus indicator
  * @y: the y origin of the rectangle around which to draw a focus indicator
  * @width: the width of the rectangle around which to draw a focus indicator
@@ -6177,30 +6427,10 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_focus != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_focus (style, window, state_type, area, widget, detail, x, y, width, height);
 }
 
-/**
- * gtk_paint_slider:
- * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @shadow_type: a shadow
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
- * @x: the x origin of the rectangle in which to draw a slider
- * @y: the y origin of the rectangle in which to draw a slider
- * @width: the width of the rectangle in which to draw a slider
- * @height: the height of the rectangle in which to draw a slider
- * @orientation: the orientation to be used
- *
- * Draws a slider in the given rectangle on @window using the
- * given style and orientation.
- **/
 void
 gtk_paint_slider (GtkStyle      *style,
                   GdkWindow     *window,
@@ -6217,7 +6447,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_slider != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_slider (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
 }
@@ -6228,10 +6457,9 @@
  * @window: a #GdkWindow
  * @state_type: a state
  * @shadow_type: type of shadow to draw
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: x origin of the handle
  * @y: y origin of the handle
  * @width: with of the handle
@@ -6256,7 +6484,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_handle != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_handle (style, window, state_type, shadow_type, area, widget, detail, x, y, width, height, orientation);
 }
@@ -6266,25 +6493,14 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @x: the x position to draw the expander at
  * @y: the y position to draw the expander at
- * @expander_style: the style to draw the expander in; determines
- *   whether the expander is collapsed, expanded, or in an
- *   intermediate state.
+ * @expander_style: the style to draw the expander in
  * 
- * Draws an expander as used in #GtkTreeView. @x and @y specify the
- * center the expander. The size of the expander is determined by the
- * "expander-size" style property of @widget.  (If widget is not
- * specified or doesn't have an "expander-size" property, an
- * unspecified default size will be used, since the caller doesn't
- * have sufficient information to position the expander, this is
- * likely not useful.) The expander is expander_size pixels tall
- * in the collapsed position and expander_size pixels wide in the
- * expanded position.
+ * Draws an expander as used in #GtkTreeView.
  **/
 void
 gtk_paint_expander (GtkStyle        *style,
@@ -6299,34 +6515,16 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_expander != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_expander (style, window, state_type, area,
                                               widget, detail, x, y, expander_style);
 }
 
-/**
- * gtk_paint_layout:
- * @style: a #GtkStyle
- * @window: a #GdkWindow
- * @state_type: a state
- * @use_text: whether to use the text or foreground
- *            graphics context of @style
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
- * @x: x origin
- * @y: y origin
- * @layout: the layout to draw
- * 
- * Draws a layout on @window using the given parameters.
- **/
 void
 gtk_paint_layout (GtkStyle        *style,
                   GdkWindow       *window,
                   GtkStateType     state_type,
-                  gboolean         use_text,
+		  gboolean         use_text,
                   GdkRectangle    *area,
                   GtkWidget       *widget,
                   const gchar     *detail,
@@ -6336,7 +6534,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_layout != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
   
   GTK_STYLE_GET_CLASS (style)->draw_layout (style, window, state_type, use_text, area,
                                             widget, detail, x, y, layout);
@@ -6347,10 +6544,9 @@
  * @style: a #GtkStyle
  * @window: a #GdkWindow
  * @state_type: a state
- * @area: clip rectangle, or %NULL if the
- *        output should not be clipped
- * @widget: the widget (may be %NULL)
- * @detail: a style detail (may be %NULL)
+ * @area: clip rectangle
+ * @widget: the widget
+ * @detail: a style detail
  * @edge: the edge in which to draw the resize grip
  * @x: the x origin of the rectangle in which to draw the resize grip
  * @y: the y origin of the rectangle in which to draw the resize grip
@@ -6376,7 +6572,6 @@
 {
   g_return_if_fail (GTK_IS_STYLE (style));
   g_return_if_fail (GTK_STYLE_GET_CLASS (style)->draw_resize_grip != NULL);
-  g_return_if_fail (style->depth == gdk_drawable_get_depth (window));
 
   GTK_STYLE_GET_CLASS (style)->draw_resize_grip (style, window, state_type,
                                                  area, widget, detail,
@@ -6414,7 +6609,7 @@
   static GType our_type = 0;
   
   if (our_type == 0)
-    our_type = g_boxed_type_register_static (I_("GtkBorder"),
+    our_type = g_boxed_type_register_static ("GtkBorder",
 					     (GBoxedCopyFunc) gtk_border_copy,
 					     (GBoxedFreeFunc) gtk_border_free);
 
@@ -6553,7 +6748,7 @@
 	gtk_gc_release (cursor_info->secondary_gc);
       
       g_free (cursor_info);
-      g_object_set_data (G_OBJECT (style), I_("gtk-style-cursor-info"), NULL);
+      g_object_set_data (G_OBJECT (style), "gtk-style-cursor-info", NULL);
     }
 }
 
@@ -6591,7 +6786,7 @@
   if (!cursor_info)
     {
       cursor_info = g_new (CursorInfo, 1);
-      g_object_set_data (G_OBJECT (widget->style), I_("gtk-style-cursor-info"), cursor_info);
+      g_object_set_data (G_OBJECT (widget->style), "gtk-style-cursor-info", cursor_info);
       cursor_info->primary_gc = NULL;
       cursor_info->secondary_gc = NULL;
       cursor_info->for_type = G_TYPE_INVALID;
@@ -6655,6 +6850,8 @@
   gfloat cursor_aspect_ratio;
   gint offset;
   
+  g_return_if_fail (direction != GTK_TEXT_DIR_NONE);
+
   /* When changing the shape or size of the cursor here,
    * propagate the changes to gtktextview.c:text_window_invalidate_cursors().
    */
Index: gtkentry.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkentry.c,v
retrieving revision 1.317
diff -u -r1.317 gtkentry.c
--- gtkentry.c	29 Jun 2006 09:18:05 -0000	1.317
+++ gtkentry.c	2 Jul 2006 14:14:24 -0000
@@ -3337,7 +3337,9 @@
   if (GTK_WIDGET_DRAWABLE (entry))
     {
       PangoLayout *layout = gtk_entry_ensure_layout (entry, TRUE);
+#ifdef USE_CAIRO_INTERNALLY
       cairo_t *cr;
+#endif
       gint x, y;
       gint start_pos, end_pos;
       
@@ -3345,23 +3347,37 @@
       
       get_layout_position (entry, &x, &y);
 
+#ifdef USE_CAIRO_INTERNALLY
       cr = gdk_cairo_create (entry->text_area);
 
       cairo_move_to (cr, x, y);
       gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
       pango_cairo_show_layout (cr, layout);
+#else
+      gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
+                       x, y,
+                       layout);
+#endif
 
       if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
 	{
 	  gint *ranges;
 	  gint n_ranges, i;
           PangoRectangle logical_rect;
-	  GdkColor *selection_color, *text_color;
           GtkBorder inner_border;
+#ifdef USE_CAIRO_INTERNALLY
+	  GdkColor *selection_color, *text_color;
+#else
+	  GdkGC *selection_gc, *text_gc;
+          GdkRegion *clip_region;
+#endif
 
 	  pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
 	  gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
 
+          get_inner_border (entry, &inner_border);
+
+#ifdef USE_CAIRO_INTERNALLY
 	  if (GTK_WIDGET_HAS_FOCUS (entry))
 	    {
 	      selection_color = &widget->style->base [GTK_STATE_SELECTED];
@@ -3373,8 +3389,6 @@
 	      text_color = &widget->style->text [GTK_STATE_ACTIVE];
 	    }
 
-          get_inner_border (entry, &inner_border);
-
 	  for (i = 0; i < n_ranges; ++i)
 	    cairo_rectangle (cr,
 			     inner_border.left - entry->scroll_offset + ranges[2 * i],
@@ -3390,11 +3404,46 @@
 	  cairo_move_to (cr, x, y);
 	  gdk_cairo_set_source_color (cr, text_color);
 	  pango_cairo_show_layout (cr, layout);
-	  
+#else
+          if (GTK_WIDGET_HAS_FOCUS (entry))
+            {
+              selection_gc = widget->style->base_gc [GTK_STATE_SELECTED];
+              text_gc = widget->style->text_gc [GTK_STATE_SELECTED];
+            }
+          else
+            {
+              selection_gc = widget->style->base_gc [GTK_STATE_ACTIVE];
+              text_gc = widget->style->text_gc [GTK_STATE_ACTIVE];
+            }
+
+          clip_region = gdk_region_new ();
+          for (i = 0; i < n_ranges; ++i)
+            {
+              GdkRectangle rect;
+
+              rect.x = inner_border.left - entry->scroll_offset + ranges[2 * i];
+              rect.y = y;
+              rect.width = ranges[2 * i + 1];
+              rect.height = logical_rect.height;
+
+              gdk_draw_rectangle (entry->text_area, selection_gc, TRUE,
+                                  rect.x, rect.y, rect.width, rect.height);
+
+              gdk_region_union_with_rect (clip_region, &rect);
+            }
+
+          gdk_gc_set_clip_region (text_gc, clip_region);
+          gdk_draw_layout (entry->text_area, text_gc,
+                           x, y,
+                           layout);
+          gdk_gc_set_clip_region (text_gc, NULL);
+          gdk_region_destroy (clip_region);
+#endif	  
 	  g_free (ranges);
 	}
-
+#ifdef USE_CAIRO_INTERNALLY
       cairo_destroy (cr);
+#endif
     }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]