Index: back/Source/cairo/CairoGState.m
===================================================================
--- back/Source/cairo/CairoGState.m	(revision 25529)
+++ back/Source/cairo/CairoGState.m	(working copy)
@@ -87,107 +87,31 @@
   [super dealloc];
 }
 
+
+/* This is a complete re-write. Mark Tracy 23-Oct-07
+   Cairo, by design, does not have a cairo_copy(ct) operation;
+   instead the authors want us to use cairo_save/cairo_restore.
+   DPSgsave uses this implementation with cairo_save(ct).
+   DPSgrestore is overridden to use cairo_restore(ct).
+*/
 - (id) copyWithZone: (NSZone *)zone
 {
   CairoGState *copy = (CairoGState *)[super copyWithZone: zone];
 
   RETAIN(_surface);
+  if (_surface)
+    {
+      // FIXME: do we need a deep copy for this?
+      copy->_surface = _surface;
+    }
 
   if (_ct)
     {
-      cairo_status_t status;
- 
-      // FIXME: Need some way to do a copy
-      // but there isnt anything like copy->_ct = cairo_copy(_ct);
-      copy->_ct = cairo_create(cairo_get_target(_ct));
-      status = cairo_status(copy->_ct);
-      if (status != CAIRO_STATUS_SUCCESS)
-        {
-          NSLog(@"Cairo status '%s' in copy", cairo_status_to_string(status));
-          _ct = NULL;
-        }
-      else
-        {
-          cairo_path_t *cpath;
-          cairo_matrix_t local_matrix;
-          cairo_rectangle_list_t *clip_rects;
-          int	num_dashes;
-
-          cairo_get_matrix(_ct, &local_matrix);
-          cairo_set_matrix(copy->_ct, &local_matrix);
-          status = cairo_status(copy->_ct);
-          if (status != CAIRO_STATUS_SUCCESS)
-            {
-              NSLog(@"Cairo status '%s' in set matrix", cairo_status_to_string(status));
-            }
-
-          cpath = cairo_copy_path(_ct);
-          status = cpath->status;
-          if (status != CAIRO_STATUS_SUCCESS)
-            {
-              /*
-                Due to an interesting programming concept in cairo this does not
-                mean that an error has occured. It may as well just be that the 
-                old path had no elements. 
-                At least in cairo 1.4.10 (See file cairo-path.c, line 379).
-              */
-              // NSLog(@"Cairo status '%s' in copy path", cairo_status_to_string(status));
-            }
-          else
-            {
-              cairo_append_path(copy->_ct, cpath);
-            }
-          cairo_path_destroy(cpath);
-          
-          cairo_set_operator(copy->_ct, cairo_get_operator(_ct));
-          cairo_set_source(copy->_ct, cairo_get_source(_ct));
-          cairo_set_tolerance(copy->_ct, cairo_get_tolerance(_ct));
-          cairo_set_antialias(copy->_ct, cairo_get_antialias(_ct));
-          cairo_set_line_width(copy->_ct, cairo_get_line_width(_ct));
-          cairo_set_line_cap(copy->_ct, cairo_get_line_cap(_ct));
-          cairo_set_line_join(copy->_ct, cairo_get_line_join(_ct));
-          cairo_set_miter_limit(copy->_ct, cairo_get_miter_limit(_ct));
-
-#if CAIRO_VERSION > CAIRO_VERSION_ENCODE(1, 4, 0)
-          // In cairo 1.4 there is a way get the dash.
-          num_dashes = cairo_get_dash_count(_ct);
-          if (num_dashes != 0)
-            {
-              double dash_offset;
-              GS_BEGINITEMBUF(dashes, num_dashes, double);
-
-              dashes = (double *)malloc(sizeof(double) * num_dashes);
-              cairo_get_dash(_ct, dashes, &dash_offset);
-              cairo_set_dash (copy->_ct, dashes, num_dashes, dash_offset);
-              GS_ENDITEMBUF();
-            }
-
-          // In cairo 1.4 there also is a way to get the current clipping path
-          clip_rects = cairo_copy_clip_rectangle_list(_ct);
-          status = clip_rects->status;
-          if (status != CAIRO_STATUS_SUCCESS)
-            {
-              NSLog(@"Cairo status '%s' in copy clip", cairo_status_to_string(status));
-            }
-          else
-            {
-              int i;
-
-              for (i = 0; i < clip_rects->num_rectangles; i++)
-                {
-                  cairo_rectangle_t rect = clip_rects->rectangles[i];
-                  NSSize size = [_surface size];
-
-                  // This strange computation is due to the device offset. 
-                  cairo_rectangle(copy->_ct, rect.x, 
-                                  rect.y + 2*(offset.y - size.height), 
-                                  rect.width, rect.height);
-                  cairo_clip(copy->_ct);
-                }
-            }
-          cairo_rectangle_list_destroy(clip_rects);
-        }
-#endif
+      // TODO: check for memory leaks here
+      // TODO: find out why the order of these two lines
+      //       seems to make no difference
+      copy->_ct = cairo_reference(_ct);
+      cairo_save(copy->_ct);
     }
 
   return copy;
@@ -412,7 +336,14 @@
   cairo_set_operator(_ct, CAIRO_OPERATOR_OVER);
   cairo_new_path(_ct);
 
-  _strokeadjust = 1;
+
+  // As currently defined the _adjustpath limits resolution of
+  // linear segments to half-integral values; not nice at all.
+  // Temporarily eliminate the adjustment until a better fix.
+  // Before fixing the save/restore, setting this to 0 would
+  // produce clipping errors.
+  // Mark Tracy 23-Oct-07
+  _strokeadjust = 0;
 }
 
 - (void) DPScurrentflat: (float *)flatness
Index: back/Source/cairo/CairoContext.m
===================================================================
--- back/Source/cairo/CairoContext.m	(revision 25529)
+++ back/Source/cairo/CairoContext.m	(working copy)
@@ -72,6 +72,26 @@
   XFlush([(XGServer *)server xDisplay]);
 }
 
+/* By design, Cairo does not have a cairo_copy(context) function. They want us
+   to use cairo_save/cairo_restore. This is messy for GNUstep.
+   We will override DPSgrestore (currently defined in GSContext.m)
+   because it does the actual work for NSGraphicsContext -restoreGraphicContext.
+   The change is simply to restore the cairo gstate.
+
+   We fix DPSgsave by rewriting CairoGState -copyWithZone:
+*/
+
+- (void) DPSgrestore
+{
+  CairoGState * cgstate = (CairoGState *)gstate;
+  cairo_t * ct = cgstate->_ct;
+  [super DPSgrestore];
+  if (ct)
+    {
+      cairo_restore(ct);
+    }
+}
+
 /* Private backend methods */
 + (void) handleExposeRect: (NSRect)rect forDriver: (void *)driver
 {
Index: back/Source/x11/XGDragView.m
===================================================================
--- back/Source/x11/XGDragView.m	(revision 25529)
+++ back/Source/x11/XGDragView.m	(working copy)
@@ -33,6 +33,7 @@
 #include <AppKit/NSPasteboard.h>
 #include <AppKit/NSView.h>
 #include <AppKit/NSWindow.h>
+#include <AppKit/NSGraphics.h>
 
 #include <Foundation/NSDebug.h>
 #include <Foundation/NSThread.h>
