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

gEDA-cvs: gaf.git: branch: master updated (1.5.1-20081221-34-g6e8513e)



The branch, master has been updated
       via  6e8513e78fb37bfdeba7254a7670cb86e3608924 (commit)
       via  88118f5d62e1655d30c4680ac0f68a89fbc1a213 (commit)
       via  c122c32cdd82419159786720b9c2cdd82b382a68 (commit)
       via  95abdb28b1ededc4a57f13627bea544c8a7fe41b (commit)
      from  46fdb00b19d300dfcc5f9009f9c7dbbf0940834f (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


=========
 Summary
=========

 gschem/include/gschem_struct.h |    1 +
 gschem/include/prototype.h     |   36 +--
 gschem/po/POTFILES.in          |    1 +
 gschem/src/Makefile.am         |    3 +-
 gschem/src/gschem_cairo.c      |  194 ++++++++++++
 gschem/src/gschem_toplevel.c   |    1 +
 gschem/src/o_arc.c             |  680 ++--------------------------------------
 gschem/src/o_box.c             |  350 ++-------------------
 gschem/src/o_bus.c             |   29 +-
 gschem/src/o_circle.c          |  123 ++------
 gschem/src/o_cue.c             |  100 +++----
 gschem/src/o_line.c            |  580 +---------------------------------
 gschem/src/o_net.c             |   60 +---
 gschem/src/o_path.c            |  269 +++++-----------
 gschem/src/o_pin.c             |   41 ++--
 gschem/src/o_text.c            |    4 +-
 gschem/src/x_event.c           |    3 +
 gschem/src/x_image.c           |    3 +
 gschem/src/x_preview.c         |    3 +
 19 files changed, 473 insertions(+), 2008 deletions(-)
 create mode 100644 gschem/src/gschem_cairo.c


=================
 Commit Messages
=================

commit 88118f5d62e1655d30c4680ac0f68a89fbc1a213
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 20:21:03 2008 +0000

    gschem: Use new COLOR system

:100644 100644 317a5ee... 624e392... M	gschem/include/prototype.h
:100644 100644 0355d82... 7ba3605... M	gschem/src/gschem_cairo.c
:100644 100644 2fbfd05... 006543f... M	gschem/src/o_arc.c
:100644 100644 bbf4515... 1902fb2... M	gschem/src/o_box.c
:100644 100644 39f1d78... 032cb32... M	gschem/src/o_bus.c
:100644 100644 c50fbba... d04ce01... M	gschem/src/o_circle.c
:100644 100644 5cea49d... 47dbde3... M	gschem/src/o_cue.c
:100644 100644 803ff15... bbc1f48... M	gschem/src/o_line.c
:100644 100644 64c6131... af03da9... M	gschem/src/o_net.c
:100644 100644 fa50a44... 3864620... M	gschem/src/o_path.c
:100644 100644 0163773... 951fb51... M	gschem/src/o_pin.c
:100644 100644 195460a... 0700a6e... M	gschem/src/o_text.c

commit c122c32cdd82419159786720b9c2cdd82b382a68
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 13:21:07 2008 +0000

    Replace portions of the GDK drawing code with cairo routines.

:100644 100644 4fd5128... 317a5ee... M	gschem/include/prototype.h
:100644 100644 e3f4350... be5c7ac... M	gschem/po/POTFILES.in
:100644 100644 c47bf73... 2a4e7cf... M	gschem/src/Makefile.am
:000000 100644 0000000... 0355d82... A	gschem/src/gschem_cairo.c
:100644 100644 cd4acde... 2fbfd05... M	gschem/src/o_arc.c
:100644 100644 070491a... bbf4515... M	gschem/src/o_box.c
:100644 100644 a34b031... 39f1d78... M	gschem/src/o_bus.c
:100644 100644 db9fd96... c50fbba... M	gschem/src/o_circle.c
:100644 100644 13cd5dc... 5cea49d... M	gschem/src/o_cue.c
:100644 100644 2478807... 803ff15... M	gschem/src/o_line.c
:100644 100644 479b880... 64c6131... M	gschem/src/o_net.c
:100644 100644 0b6951e... fa50a44... M	gschem/src/o_path.c
:100644 100644 def222c... 0163773... M	gschem/src/o_pin.c
:100644 100644 80a5e9f... f0ebf63... M	gschem/src/x_event.c
:100644 100644 696247f... 857075e... M	gschem/src/x_image.c
:100644 100644 63098d5... 9047abe... M	gschem/src/x_preview.c

commit 95abdb28b1ededc4a57f13627bea544c8a7fe41b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 13:21:00 2008 +0000

    Add a cairo context member, cairo_t *cr to GSCHEM_TOPLEVEL

:100644 100644 324693e... df4386d... M	gschem/include/gschem_struct.h
:100644 100644 1b66a00... d5ab97d... M	gschem/src/gschem_toplevel.c

=========
 Changes
=========

commit 88118f5d62e1655d30c4680ac0f68a89fbc1a213
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 20:21:03 2008 +0000

    gschem: Use new COLOR system

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 317a5ee..624e392 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -282,6 +282,7 @@ int main(int argc, char *argv[]);
 void gschem_cairo_line(cairo_t *cr, int line_end, int width, int x1, int y1, int x2, int y2);
 void gschem_cairo_box(cairo_t *cr, int width, int x1, int y1, int x2, int y2);
 void gschem_cairo_stroke(cairo_t *cr, int line_type, int line_end, int width, int length, int space);
+void gschem_cairo_set_source_color(cairo_t *cr, COLOR *color);
 /* i_basic.c */
 void i_show_state(GSCHEM_TOPLEVEL *w_current, const char *message);
 void i_set_state(GSCHEM_TOPLEVEL *w_current, enum x_states newstate);
@@ -472,10 +473,10 @@ void o_invalidate(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_invalidate_glist(GSCHEM_TOPLEVEL *w_current, GList *list);
 /* o_box.c */
 void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_box_fill_hollow(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_box_fill_fill(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_box_fill_hatch(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_box_fill_mesh(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_box_fill_hollow(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_box_fill_fill(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_box_fill_hatch(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_box_fill_mesh(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_box_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_box_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_box_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -500,10 +501,10 @@ void o_bus_rubberbus_xor(GSCHEM_TOPLEVEL *w_current);
 void o_bus_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 /* o_circle.c */
 void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_circle_fill_hollow(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_circle_fill_fill(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_circle_fill_hatch(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
-void o_circle_fill_mesh(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_circle_fill_hollow(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_circle_fill_fill(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_circle_fill_hatch(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
+void o_circle_fill_mesh(GdkDrawable *w, GdkGC *gc, COLOR *color, GSCHEM_TOPLEVEL *w_current, CIRCLE *circle, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_circle_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_circle_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_circle_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
diff --git a/gschem/src/gschem_cairo.c b/gschem/src/gschem_cairo.c
index 0355d82..7ba3605 100644
--- a/gschem/src/gschem_cairo.c
+++ b/gschem/src/gschem_cairo.c
@@ -183,3 +183,12 @@ void gschem_cairo_stroke (cairo_t *cr, int line_type, int line_end,
 
   cairo_set_dash (cr, NULL, 0, 0.);
 }
+
+
+void gschem_cairo_set_source_color (cairo_t *cr, COLOR *color)
+{
+  cairo_set_source_rgba (cr, (double)color->r / 256.0,
+                             (double)color->g / 256.0,
+                             (double)color->b / 256.0,
+                             (double)color->a / 256.0);
+}
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index 2fbfd05..006543f 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -47,7 +47,7 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int wleft, wright, wtop, wbottom;
   int x, y, radius, start_angle, end_angle;
   int line_width;
-  GdkColor *color;
+  COLOR *color;
   int length, space;
 
   if (o_current->arc == NULL) {
@@ -97,9 +97,9 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 #endif
 
   if (toplevel->override_color != -1 )
-    color = x_get_color(toplevel->override_color);
+    color = x_color_lookup (toplevel->override_color);
   else
-    color = x_get_color(o_current->color);
+    color = x_color_lookup (o_current->color);
 
   line_width = SCREENabs( toplevel, o_current->line_width );
   if(line_width <= 0) {
@@ -109,7 +109,7 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
   cairo_new_sub_path (w_current->cr);
   if (start_angle > start_angle + end_angle) {
     cairo_arc (w_current->cr, x + 0.5, y + 0.5, radius,
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index bbf4515..1902fb2 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -36,7 +36,7 @@
 #define GET_BOX_TOP(w)				\
         max((w)->first_wy, (w)->second_wy)
 
-typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
+typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, COLOR *color,
                            GSCHEM_TOPLEVEL *w_current, BOX *box,
                            gint fill_width, gint angle1, gint pitch1,
                            gint angle2, gint pitch2 );
@@ -61,7 +61,7 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int s_upper_x, s_upper_y, s_lower_x, s_lower_y;
   int line_width, length, space;
   int fill_width, angle1, pitch1, angle2, pitch2;
-  GdkColor *color;
+  COLOR *color;
   FILL_FUNC fill_func;
 
   if (o_current->box == NULL) {
@@ -96,9 +96,9 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
    * (if any). Finally the function takes care of the grips.
    */
   if (toplevel->override_color != -1 ) {  /* Override */
-    color = x_get_color(toplevel->override_color);
+    color = x_color_lookup (toplevel->override_color);
   } else {
-    color = x_get_color(o_current->color);
+    color = x_color_lookup (o_current->color);
   }
 
   /*
@@ -206,7 +206,7 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                 w_current, o_current->box,
                 fill_width, angle1, pitch1, angle2, pitch2);
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
   gschem_cairo_box (w_current->cr, line_width,
                     s_lower_x, s_lower_y, s_upper_x, s_upper_y);
 
@@ -240,7 +240,7 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-void o_box_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_box_fill_hollow (GdkDrawable *w, GdkGC *gc, COLOR *color,
                         GSCHEM_TOPLEVEL *w_current, BOX *box,
                         gint fill_width,
                         gint angle1, gint pitch1,
@@ -277,7 +277,7 @@ void o_box_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-void o_box_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_box_fill_fill (GdkDrawable *w, GdkGC *gc, COLOR *color,
                       GSCHEM_TOPLEVEL *w_current, BOX *box,
                       gint fill_width,
                       gint angle1, gint pitch1,
@@ -316,7 +316,7 @@ void o_box_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, COLOR *color,
                        GSCHEM_TOPLEVEL *w_current, BOX *box,
                        gint fill_width,
                        gint angle1, gint pitch1,
@@ -325,7 +325,7 @@ void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
 
   lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_box (box, angle1, pitch1, lines);
@@ -371,7 +371,7 @@ void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-void o_box_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_box_fill_mesh (GdkDrawable *w, GdkGC *gc, COLOR *color,
                       GSCHEM_TOPLEVEL *w_current, BOX *box,
                       gint fill_width,
                       gint angle1, gint pitch1,
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index 39f1d78..032cb32 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -69,9 +69,9 @@ void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_SQUARE);
 
   if (toplevel->override_color != -1 ) {
-    gdk_cairo_set_source_color (w_current->cr, x_get_color(toplevel->override_color));
+    gschem_cairo_set_source_color (w_current->cr, x_color_lookup (toplevel->override_color));
   } else {
-    gdk_cairo_set_source_color (w_current->cr, x_get_color(o_current->color));
+    gschem_cairo_set_source_color (w_current->cr, x_color_lookup (o_current->color));
   }
 
   gschem_cairo_line (w_current->cr, END_SQUARE, size, x1, y1, x2, y2);
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index c50fbba..d04ce01 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -28,7 +28,7 @@
 #endif
 
 
-typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
+typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, COLOR *color,
                            GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                            gint fill_width, gint angle1, gint pitch1,
                            gint angle2, gint pitch2 );
@@ -54,7 +54,7 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int radius;
   int line_width, length, space;
   int fill_width, angle1, pitch1, angle2, pitch2;
-  GdkColor *color;
+  COLOR *color;
   FILL_FUNC fill_func;
 
   if (o_current->circle == NULL) {
@@ -82,9 +82,9 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
    * Finally the function takes care of the grips.
    */
   if (toplevel->override_color != -1 ) {
-    color = x_get_color(toplevel->override_color);
+    color = x_color_lookup (toplevel->override_color);
   } else {
-    color = x_get_color(o_current->color);
+    color = x_color_lookup (o_current->color);
   }
 
   radius = SCREENabs( toplevel, o_current->circle->radius );
@@ -191,7 +191,7 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                 color, w_current, o_current->circle,
                 fill_width, angle1, pitch1, angle2, pitch2);
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
   cairo_new_sub_path (w_current->cr);
   cairo_arc (w_current->cr, s_x + 0.5, s_y + 0.5, radius, 0., 2 * M_PI);
 
@@ -231,7 +231,7 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-void o_circle_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_circle_fill_hollow (GdkDrawable *w, GdkGC *gc, COLOR *color,
                            GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                            gint fill_width,
                            gint angle1, gint pitch1,
@@ -269,7 +269,7 @@ void o_circle_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-void o_circle_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_circle_fill_fill (GdkDrawable *w, GdkGC *gc, COLOR *color,
                          GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                          gint fill_width,
                          gint angle1, gint pitch1,
@@ -311,7 +311,7 @@ void o_circle_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, COLOR *color,
                           GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                           gint fill_width,
                           gint angle1, gint pitch1,
@@ -320,7 +320,7 @@ void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
 
   lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_circle (circle, angle1, pitch1, lines);
@@ -370,7 +370,7 @@ void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-void o_circle_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+void o_circle_fill_mesh (GdkDrawable *w, GdkGC *gc, COLOR *color,
                          GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                          gint fill_width,
                          gint angle1, gint pitch1,
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 5cea49d..47dbde3 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -85,9 +85,9 @@ void o_cue_redraw_all (GSCHEM_TOPLEVEL *w_current, GList *list, gboolean draw_se
 static void o_cue_set_color(GSCHEM_TOPLEVEL *w_current, int color)
 {
   if (w_current->toplevel->override_color != -1 ) {
-    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->override_color));
+    gschem_cairo_set_source_color(w_current->cr, x_color_lookup (w_current->toplevel->override_color));
   } else {
-    gdk_cairo_set_source_color(w_current->cr, x_get_color(color));
+    gschem_cairo_set_source_color(w_current->cr, x_color_lookup (color));
   }
 }
 
@@ -278,9 +278,9 @@ void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   int size, x2size;
 
   if (toplevel->override_color != -1 ) {
-    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->override_color));
+    gschem_cairo_set_source_color(w_current->cr, x_color_lookup (w_current->toplevel->override_color));
   } else {
-    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->junction_color));
+    gschem_cairo_set_source_color(w_current->cr, x_color_lookup (w_current->toplevel->junction_color));
   }
   
   cl_current = object->conn_list;
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 803ff15..bbc1f48 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -46,7 +46,7 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int x1, y1, x2, y2;
   int line_width, length, space;
-  GdkColor *color;
+  COLOR *color;
 
   if (o_current->line == NULL) {
     return;
@@ -88,9 +88,9 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
    * Finally the function takes care of the grips.
    */
   if (toplevel->override_color != -1 )
-  color = x_get_color(toplevel->override_color);
+  color = x_color_lookup (toplevel->override_color);
   else
-  color = x_get_color(o_current->color);
+  color = x_color_lookup (o_current->color);
 	
   line_width = SCREENabs( toplevel, o_current->line_width );
   if( line_width <= 0) {
@@ -103,7 +103,7 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   gschem_cairo_line (w_current->cr, o_current->line_end,
                      line_width, x1, y1, x2, y2);
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
   gschem_cairo_stroke (w_current->cr, o_current->line_type,
                        o_current->line_end, line_width, length, space);
 
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 64c6131..af03da9 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -112,9 +112,9 @@ void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_SQUARE);
 
   if (toplevel->override_color != -1 ) {
-    gdk_cairo_set_source_color (w_current->cr, x_get_color(toplevel->override_color));
+    gschem_cairo_set_source_color (w_current->cr, x_color_lookup (toplevel->override_color));
   } else {
-    gdk_cairo_set_source_color (w_current->cr, x_get_color(o_current->color));
+    gschem_cairo_set_source_color (w_current->cr, x_color_lookup (o_current->color));
   }
 
   gschem_cairo_line (w_current->cr, END_SQUARE, size, x1, y1, x2, y2);
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index fa50a44..3864620 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -32,7 +32,7 @@
 #define NUM_BEZIER_SEGMENTS 100
 
 
-typedef void (*FILL_FUNC) (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+typedef void (*FILL_FUNC) (GdkDrawable *w, GdkGC *gc, COLOR *color,
                            GSCHEM_TOPLEVEL *w_currentm, PATH *path,
                            gint fill_width,
                            gint angle1, gint pitch1, gint angle2, gint pitch2);
@@ -208,7 +208,7 @@ void o_path_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-static void o_path_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+static void o_path_fill_hollow (GdkDrawable *w, GdkGC *gc, COLOR *color,
                                 GSCHEM_TOPLEVEL *w_current, PATH *path,
                                 gint fill_width,
                                 gint angle1, gint pitch1,
@@ -234,7 +234,7 @@ static void o_path_fill_hollow (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-static void o_path_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+static void o_path_fill_fill (GdkDrawable *w, GdkGC *gc, COLOR *color,
                               GSCHEM_TOPLEVEL *w_current, PATH *path,
                               gint fill_width,
                               gint angle1, gint pitch1,
@@ -262,7 +262,7 @@ static void o_path_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      (unused)
  *  \param [in] pitch2      (unused)
  */
-static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, COLOR *color,
                                GSCHEM_TOPLEVEL *w_current, PATH *path,
                                gint fill_width,
                                gint angle1, gint pitch1,
@@ -271,7 +271,7 @@ static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
 
   lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_path (path, angle1, pitch1, lines);
@@ -311,7 +311,7 @@ static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
  *  \param [in] angle2      2nd angle for pattern.
  *  \param [in] pitch2      2nd pitch for pattern.
  */
-static void o_path_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
+static void o_path_fill_mesh (GdkDrawable *w, GdkGC *gc, COLOR *color,
                               GSCHEM_TOPLEVEL *w_current, PATH *path,
                               gint fill_width,
                               gint angle1, gint pitch1,
@@ -349,7 +349,7 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   double fx2 = 0.0, fy2 = 0.0;
   double fx3 = 0.0, fy3 = 0.0;
 
-  GdkColor *color;
+  COLOR *color;
 
   if (path == NULL) {
     return;
@@ -363,10 +363,11 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   if (toplevel->DONT_REDRAW == 1)
     return;
 
-  if (toplevel->override_color != -1 )
-    color = x_get_color(toplevel->override_color);
-  else
-    color = x_get_color(o_current->color);
+  if (toplevel->override_color != -1 ) {
+    color = x_color_lookup (toplevel->override_color);
+  } else {
+    color = x_color_lookup (o_current->color);
+  }
 
   line_width = SCREENabs( toplevel, o_current->line_width );
   if( line_width <= 0) {
@@ -485,7 +486,7 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     }
   }
 
-  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_set_source_color (w_current->cr, color);
 
   if (o_current->fill_type == FILLING_FILL)
     cairo_fill_preserve (w_current->cr);
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index 0163773..951fb51 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -38,7 +38,7 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int size;
   int x1, y1, x2, y2; /* screen coords */
-  GdkColor *color;
+  COLOR *color;
 
   if (o_current->line == NULL) {
     return;
@@ -55,9 +55,9 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 #endif
 
   if (toplevel->override_color != -1 ) {
-    color = x_get_color(toplevel->override_color);
+    color = x_color_lookup (toplevel->override_color);
   } else {
-    color = x_get_color(o_current->color);
+    color = x_color_lookup (o_current->color);
   }
 
   if (toplevel->DONT_REDRAW == 0) {
@@ -71,7 +71,7 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     cairo_set_line_width (w_current->cr, size);
     cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT);
 
-    gdk_cairo_set_source_color (w_current->cr, color);
+    gschem_cairo_set_source_color (w_current->cr, color);
 
     gschem_cairo_line (w_current->cr, END_NONE, size, x1, y1, x2, y2);
     cairo_stroke (w_current->cr);
diff --git a/gschem/src/o_text.c b/gschem/src/o_text.c
index 195460a..0700a6e 100644
--- a/gschem/src/o_text.c
+++ b/gschem/src/o_text.c
@@ -89,9 +89,9 @@ void o_text_draw_rectangle(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   WORLDtoSCREEN( toplevel, o_current->w_right, o_current->w_top, &right, &bottom );
 
   if (toplevel->override_color != -1 ) {  /* Override */
-    color = x_get_color(toplevel->override_color);
+    color = x_get_color (toplevel->override_color);
   } else {
-    color = x_get_color(o_current->color);
+    color = x_get_color (o_current->color);
   }
   gdk_gc_set_foreground(w_current->gc, color);
 

commit c122c32cdd82419159786720b9c2cdd82b382a68
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 13:21:07 2008 +0000

    Replace portions of the GDK drawing code with cairo routines.

diff --git a/gschem/include/prototype.h b/gschem/include/prototype.h
index 4fd5128..317a5ee 100644
--- a/gschem/include/prototype.h
+++ b/gschem/include/prototype.h
@@ -278,6 +278,10 @@ void gschem_atexit(gschem_atexit_func func, gpointer data);
 void gschem_quit(void);
 void main_prog(void *closure, int argc, char *argv[]);
 int main(int argc, char *argv[]);
+/* gschem_cairo.c */
+void gschem_cairo_line(cairo_t *cr, int line_end, int width, int x1, int y1, int x2, int y2);
+void gschem_cairo_box(cairo_t *cr, int width, int x1, int y1, int x2, int y2);
+void gschem_cairo_stroke(cairo_t *cr, int line_type, int line_end, int width, int length, int space);
 /* i_basic.c */
 void i_show_state(GSCHEM_TOPLEVEL *w_current, const char *message);
 void i_set_state(GSCHEM_TOPLEVEL *w_current, enum x_states newstate);
@@ -441,11 +445,6 @@ void i_vars_set(GSCHEM_TOPLEVEL *w_current);
 void i_vars_freenames();
 /* o_arc.c */
 void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_arc_draw_solid(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
-void o_arc_draw_dotted(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
-void o_arc_draw_dashed(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
-void o_arc_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
-void o_arc_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x, gint y, gint radius, gint angle1, gint angle2, gint arc_width, gint length, gint space);
 void o_arc_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_arc_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_arc_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
@@ -473,11 +472,6 @@ void o_invalidate(GSCHEM_TOPLEVEL *w_current, OBJECT *object);
 void o_invalidate_glist(GSCHEM_TOPLEVEL *w_current, GList *list);
 /* o_box.c */
 void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_box_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
-void o_box_draw_dotted(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
-void o_box_draw_dashed(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
-void o_box_draw_center(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
-void o_box_draw_phantom(GdkDrawable *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint filled, gint x, gint y, gint width, gint height, gint line_width, gint length, gint space);
 void o_box_fill_hollow(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_box_fill_fill(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
 void o_box_fill_hatch(GdkDrawable *w, GdkGC *gc, GdkColor *color, GSCHEM_TOPLEVEL *w_current, BOX *box, gint fill_width, gint angle1, gint pitch1, gint angle2, gint pitch2);
@@ -572,11 +566,6 @@ void o_grips_draw(GSCHEM_TOPLEVEL *w_current, int x, int y);
 void o_grips_rubbergrip_xor(GSCHEM_TOPLEVEL *w_current);
 /* o_line.c */
 void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current);
-void o_line_draw_solid(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
-void o_line_draw_dotted(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
-void o_line_draw_dashed(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
-void o_line_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
-void o_line_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color, GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2, gint line_width, gint length, gint space);
 void o_line_invalidate_rubber(GSCHEM_TOPLEVEL *w_current);
 void o_line_draw_xor(GSCHEM_TOPLEVEL *w_current, int dx, int dy, OBJECT *o_current);
 void o_line_start(GSCHEM_TOPLEVEL *w_current, int x, int y);
diff --git a/gschem/po/POTFILES.in b/gschem/po/POTFILES.in
index e3f4350..be5c7ac 100644
--- a/gschem/po/POTFILES.in
+++ b/gschem/po/POTFILES.in
@@ -8,6 +8,7 @@ src/g_rc.c
 src/g_register.c
 src/globals.c
 src/gschem.c
+src/gschem_cairo.c
 src/i_basic.c
 src/i_callbacks.c
 src/i_vars.c
diff --git a/gschem/src/Makefile.am b/gschem/src/Makefile.am
index c47bf73..2a4e7cf 100644
--- a/gschem/src/Makefile.am
+++ b/gschem/src/Makefile.am
@@ -67,7 +67,8 @@ gschem_SOURCES = \
 	x_stroke.c \
 	x_window.c
 
-CAIRO_SRCS =
+CAIRO_SRCS = \
+	gschem_cairo.c
 
 EXTRA_gschem_SOURCES = \
 	${CAIRO_SRCS}
diff --git a/gschem/src/gschem_cairo.c b/gschem/src/gschem_cairo.c
new file mode 100644
index 0000000..0355d82
--- /dev/null
+++ b/gschem/src/gschem_cairo.c
@@ -0,0 +1,185 @@
+/* gEDA - GPL Electronic Design Automation
+ * gschem - gEDA Schematic Capture
+ * Copyright (C) 1998-2007 Ales Hvezda
+ * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
+ */
+
+
+#include <config.h>
+
+#include <cairo.h>
+
+#include "gschem.h"
+
+#ifdef HAVE_LIBDMALLOC
+#include <dmalloc.h>
+#endif
+
+
+void gschem_cairo_line (cairo_t *cr, int line_end, int width,
+                        int x1, int y1, int x2, int y2)
+{
+  double offset = ((width % 2) == 0) ? 0 : 0.5;
+  double xoffset = 0;
+  double yoffset = 0;
+  int horizontal = 0;
+  int vertical = 0;
+
+  if (width == 0)
+    return;
+
+  if (y1 == y2) horizontal = 1;
+  if (x1 == x2) vertical = 1;
+
+  /* Hint so the length of the line runs along a pixel boundary */
+
+  if (horizontal)
+    yoffset = offset;
+  else if (vertical)
+    xoffset = offset;
+
+  /* Now hint the ends of the lines */
+
+  switch (line_end) {
+    case END_NONE:
+      /* Line terminates at the passed coordinate */
+      /* Do nothing */
+      break;
+    case END_SQUARE:
+      /* Line terminates half a width away from the passed coordinate */
+      if (horizontal) {
+        xoffset = offset;
+      } else if (vertical) {
+        yoffset = offset;
+      }
+    case END_ROUND:
+      /* Do nothing */
+      break;
+  }
+
+  cairo_move_to (cr, x1 + xoffset, y1 + yoffset);
+  cairo_line_to (cr, x2 + xoffset, y2 + yoffset);
+}
+
+
+void gschem_cairo_box (cairo_t *cr, int width,
+                       int x1, int y1, int x2, int y2)
+{
+  double offset = ((width % 2) == 0) ? 0 : 0.5;
+  cairo_move_to (cr, x2 + offset, y2 + offset);
+  cairo_line_to (cr, x1 + offset, y2 + offset);
+  cairo_line_to (cr, x1 + offset, y1 + offset);
+  cairo_line_to (cr, x2 + offset, y1 + offset);
+  cairo_close_path (cr);
+}
+
+
+void gschem_cairo_stroke (cairo_t *cr, int line_type, int line_end,
+                          int width, int length, int space)
+{
+  double dashes[4];
+  cairo_line_cap_t cap;
+  int num_dashes;
+
+  cairo_set_line_width (cr, width);
+  cairo_set_line_join (cr, CAIRO_LINE_JOIN_MITER);
+
+  switch (line_end) {
+    case END_NONE:   cap = CAIRO_LINE_CAP_BUTT;   break;
+    case END_SQUARE: cap = CAIRO_LINE_CAP_SQUARE; break;
+    case END_ROUND:  cap = CAIRO_LINE_CAP_ROUND;  break;
+    default:
+      fprintf(stderr, _("Unknown end for line (%d)\n"), line_end);
+      cap = CAIRO_LINE_CAP_BUTT;
+    break;
+  }
+
+  switch (line_type) {
+
+    default:
+      fprintf(stderr, _("Unknown type for stroke (%d) !\n"), line_type);
+      /* Fall through */
+
+    case TYPE_SOLID:
+      num_dashes = 0;
+
+      cairo_set_dash (cr, dashes, num_dashes, 0.);
+      cairo_set_line_cap (cr, cap);
+      cairo_stroke (cr);
+      break;
+
+    case TYPE_DOTTED:
+      dashes[0] = 0;                    /* DOT */
+      dashes[1] = space;
+      num_dashes = 2;
+
+      cairo_set_dash (cr, dashes, num_dashes, 0.);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+      cairo_stroke (cr);
+      break;
+
+    case TYPE_DASHED:
+      dashes[0] = length;               /* DASH */
+      dashes[1] = space;
+      num_dashes = 2;
+
+      cairo_set_dash (cr, dashes, num_dashes, 0.);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+      cairo_stroke (cr);
+      break;
+
+    case TYPE_CENTER:
+      dashes[0] = length;               /* DASH */
+      dashes[1] = 2 * space;
+      num_dashes = 2;
+
+      cairo_set_dash (cr, dashes, num_dashes, 0.);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+      cairo_stroke_preserve (cr);
+
+      dashes[0] = 0;                    /* DOT */
+      dashes[1] = 2 * space + length;
+      num_dashes = 2;
+
+      cairo_set_dash (cr, dashes, num_dashes, -length - space);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+      cairo_stroke (cr);
+      break;
+
+    case TYPE_PHANTOM:
+      dashes[0] = length;               /* DASH */
+      dashes[1] = 3 * space;
+      num_dashes = 2;
+
+      cairo_set_dash (cr, dashes, num_dashes, 0.);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_BUTT);
+      cairo_stroke_preserve (cr);
+
+      dashes[0] = 0;                    /* DOT */
+      dashes[1] = space;
+      dashes[2] = 0;                    /* DOT */
+      dashes[3] = 2 * space + length;
+      num_dashes = 4;
+
+      cairo_set_dash (cr, dashes, num_dashes, -length - space);
+      cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
+      cairo_stroke (cr);
+      break;
+  }
+
+  cairo_set_dash (cr, NULL, 0, 0.);
+}
diff --git a/gschem/src/o_arc.c b/gschem/src/o_arc.c
index cd4acde..2fbfd05 100644
--- a/gschem/src/o_arc.c
+++ b/gschem/src/o_arc.c
@@ -28,11 +28,6 @@
 #endif
 
 
-typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                           GdkCapStyle cap, gint x, gint y, gint radius,
-                           gint angle1, gint angle2,
-                           gint arc_width, gint length, gint space );
-
 /*! \brief Draw an arc on the screen.
  *  \par Function Description
  *  This function is used to draw an arc on screen. The arc is described
@@ -51,10 +46,8 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int wleft, wright, wtop, wbottom;
   int x, y, radius, start_angle, end_angle;
-  int arc_width;
-  GdkCapStyle arc_end;
+  int line_width;
   GdkColor *color;
-  DRAW_FUNC draw_func = NULL;
   int length, space;
 
   if (o_current->arc == NULL) {
@@ -108,67 +101,27 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   else
     color = x_get_color(o_current->color);
 
-  arc_width = SCREENabs( toplevel, o_current->line_width );
-  if(arc_width <= 0) {
-    arc_width = 1;
-  }
-	
-  switch(o_current->line_end) {
-  case END_NONE:   arc_end = GDK_CAP_BUTT;       break;
-  case END_SQUARE: arc_end = GDK_CAP_PROJECTING; break;
-  case END_ROUND:  arc_end = GDK_CAP_ROUND;      break;
-  default: fprintf(stderr, _("Unknown end for arc (%d)\n"), o_current->line_end); 
-    arc_end = GDK_CAP_BUTT; 
-    break;
+  line_width = SCREENabs( toplevel, o_current->line_width );
+  if(line_width <= 0) {
+    line_width = 1;
   }
 
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
-	
-  switch(o_current->line_type) {
-  case TYPE_SOLID:
-    length = -1;
-    space = -1;
-    draw_func = o_arc_draw_solid;
-    break;
-			
-  case TYPE_DOTTED:
-    length = -1; /* o_arc_draw_dotted uses space parameter only */
-    draw_func = o_arc_draw_dotted;
-    break;
-			
-  case TYPE_DASHED:
-    draw_func = o_arc_draw_dashed;
-    break;
-			
-  case TYPE_CENTER:
-    draw_func = o_arc_draw_center;
-    break;
-			
-  case TYPE_PHANTOM:
-    draw_func = o_arc_draw_phantom;
-    break;
-			
-  case TYPE_ERASE:
-    break;
-			
-  default:
-    length = -1;
-    space = -1;
-    arc_width = 0; /* just to be careful */
-    draw_func = o_arc_draw_solid;
-    fprintf(stderr, _("Unknown type for arc !\n"));
-    break;
-  }
-
-  if((length == 0) || (space == 0))
-    draw_func =  o_arc_draw_solid;
-
-  (*draw_func) (w_current->drawable, w_current->gc, color,
-                arc_end,
-                x, y, radius, start_angle, end_angle,
-                arc_width, length, space);
 
+  gdk_cairo_set_source_color (w_current->cr, color);
+  cairo_new_sub_path (w_current->cr);
+  if (start_angle > start_angle + end_angle) {
+    cairo_arc (w_current->cr, x + 0.5, y + 0.5, radius,
+               -start_angle * (M_PI / 180.),
+               (-start_angle - end_angle) * (M_PI / 180.));
+  } else {
+    cairo_arc_negative (w_current->cr, x + 0.5, y + 0.5, radius,
+                        -start_angle * (M_PI / 180.),
+                        (-start_angle - end_angle) * (M_PI / 180.));
+  }
+  gschem_cairo_stroke (w_current->cr, o_current->line_type,
+                       o_current->line_end, line_width, length, space);
 
   if (o_current->selected && w_current->draw_grips == TRUE) {
     o_arc_draw_grips (w_current, o_current);
@@ -179,599 +132,6 @@ void o_arc_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 #endif
 }
 
-/*! \brief Draw an arc with a solid line type.
- *  \par Function Description
- *  This function draw an arc with a solid line type. The arc is defined
- *  by two angle (start and end of arc) and the definition of a box by
- *  which the arc is restricted by. The parameters <B>length</B> and
- *  <B>space</B> are unused here.
- *
- *  The unit of <B>x</B>, <B>y</B> and <B>width</B>, <B>height</B> and <B>arc_width</B>,
- *  <B>space</B>, <B>length</B> is pixel.
- *
- *  <B>angle1</B> and <B>angle2</B> are in degrees.
- *
- *  The lines attributes are settled. Then it simply make a call to
- *  the gdk original function.
- *
- *  \param [in] w          GdkWindow to draw in.
- *  \param [in] gc         GdkGC graphics context to draw on.
- *  \param [in] color      Arc line color.
- *  \param [in] cap        Arc line end cap type (unused).
- *  \param [in] x          Arc center x.
- *  \param [in] y          Arc center y.
- *  \param [in] radius     Arc radius.
- *  \param [in] angle1     Start angle in degrees.
- *  \param [in] angle2     End angle in degrees.
- *  \param [in] arc_width  Width of arc line.
- *  \param [in] length     (unused)
- *  \param [in] space      (unused)
- */
-void o_arc_draw_solid(GdkWindow *w, GdkGC *gc,
-		      GdkColor *color, GdkCapStyle cap,
-		      gint x, gint y, gint radius,
-		      gint angle1, gint angle2,
-		      gint arc_width, gint length, gint space)
-{
-  gdk_gc_set_foreground(gc, color);
-  /* Set the width, end type and join style of the line */
-  gdk_gc_set_line_attributes(gc, arc_width, 
-                             GDK_LINE_SOLID, cap, GDK_JOIN_MITER);
-
-  /* Draw the arc */
-  gdk_draw_arc(w, gc, FALSE,
-               x - radius, y - radius, 2 * radius, 2 * radius,
-               angle1 * 64, angle2 * 64);
-
-}
-
-/*! \brief Draw an arch with a dotted line type.
- *  \par Function Description
- *  This functions draws an arc with a dotted line type. The parameter
- *  <B>space</B> represents the distance between two of the dots. The
- *  parameter <B>length</B> is unused. The diameter of the dots is given
- *  by the width of the line given by <B>arc_width</B>.
- *
- *  The unit of <B>x</B>, <B>y</B> and <B>width</B>, <B>height</B> and
- *  <B>arc_width</B>, <B>space</B>, <B>length</B> is pixel.
- *
- *  <B>angle1</B> and <B>angle2</B> are in degrees.
- *  A negative or null value for length leads to an endless loop.
- *  length parameter is not used here.
- *
- *  \param [in] w          GdkWindow to draw in.
- *  \param [in] gc         GdkGC graphics context to draw on.
- *  \param [in] color      Arc line color.
- *  \param [in] cap        Arc line end cap type (unused).
- *  \param [in] x          Arc center x.
- *  \param [in] y          Arc center y.
- *  \param [in] radius     Arc radius.
- *  \param [in] angle1     Start angle in degrees.
- *  \param [in] angle2     End angle in degrees.
- *  \param [in] arc_width  Width of arc line.
- *  \param [in] length     (unused).
- *  \param [in] space      Spacing between dots in pixels.
- */
-void o_arc_draw_dotted(GdkWindow *w, GdkGC *gc,
-		       GdkColor *color, GdkCapStyle cap,
-		       gint x, gint y, gint radius,
-		       gint angle1, gint angle2,
-		       gint arc_width, gint length, gint space)
-{
-  double xa, ya;
-  int da, d;
-
-  gdk_gc_set_foreground(gc, color);
-
-  /*
-   * It calculates the angle that match the length <B>space</B> as <B>da</B>.
-   * If <B>da</B> is negative or null, the way the function uses it after
-   * leads to an andless loop. In fact such a case occur when it is not
-   * possible to distinguish a solid line from a dotted line because of
-   * zoom factor. The arc is therefore drawn solid.
-   */
-  /* inverting angle2 if < 0 and changing angle1 accordingly */
-  /* the loop test assume that da > 0 */
-  if(angle2 < 0) {
-    angle1 = angle1 + angle2;
-    angle2 = -angle2;
-  }
-
-  da = space * 180 / (M_PI * radius);
-
-  /* If da is too small for arc to be displayed as dotted,
-     draw a solid arc */
-  if(da <= 0) {
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 angle1 * 64, angle2 * 64);
-    return;
-  }
-  /*
-   * It starts from <B>angle1</B> and increments <B>angle1</B> by <B>da</B> as
-   * a loop until all the arc has been browsed. For each angle value a
-   * dot is drawing after calculating back its coordinates from the angle.
-   */
-  d = angle1;
-  while(d < (angle2 + angle1)) {
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real worl width is equal to 0, then the
-     * width is translated to 1 in screen coordinates to be visible.
-     * Drawing a circle with a 1-diameter and the GDK function
-     * #gdk_draw_arc() is not possible. So we needs to test
-     * whether the width is 1 or not.
-     */
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - arc_width/2, 
-		   ((int) ya) - arc_width/2,
-		   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-
-    d = d + da;
-  }
-
-}
-
-/*! \brief Draw an arc with a dashed line type.
- *  This functions draws an arc with a dashed line type. The parameter
- *  <B>space</B> represents the distance between two of the dash. The
- *  parameter <B>length</B> represents the length of the dash.
- *
- *  The unit of <B>x</B>, <B>y</B> and <B>width</B>, <B>height</B> and
- *  <B>arc_width</B>, <B>space</B>, <B>length</B> is pixel.
- *
- *  <B>angle1</B> and <B>angle2</B> are in degrees.
- *
- *  A negative or null value for <B>length</B> and <B>space</B> leads to an
- *  endless loop.
- *
- *  \param [in] w          GdkWindow to draw in.
- *  \param [in] gc         GdkGC graphics context to draw on.
- *  \param [in] color      Arc line color.
- *  \param [in] cap        Arc line end cap type (unused).
- *  \param [in] x          Arc center x.
- *  \param [in] y          Arc center y.
- *  \param [in] radius     Arc radius.
- *  \param [in] angle1     Start angle in degrees.
- *  \param [in] angle2     End angle in degrees.
- *  \param [in] arc_width  Width of arc line.
- *  \param [in] length     Length of dash in pixels..
- *  \param [in] space      Spacing between dashes in pixels.
- */
-void o_arc_draw_dashed(GdkWindow *w, GdkGC *gc,
-		       GdkColor *color, GdkCapStyle cap,
-		       gint x, gint y,
-		       gint radius,
-		       gint angle1, gint angle2,
-		       gint arc_width, gint length, gint space)
-{
-  int da, db, a1, a2, d;
-
-  gdk_gc_set_foreground(gc, color);	
-  gdk_gc_set_line_attributes(gc, arc_width, GDK_LINE_SOLID, cap, 
-                             GDK_JOIN_MITER);
-
-  /*
-   * The function first determines the radius and the center of the arc.
-   *
-   * The function determines the angular increments that match the
-   * <B>length</B> and <B>space</B> parameter. These are <B>db</B> and <B>da</B>.
-   * Whenever one or both of these variables are null or negative, the
-   * line is drawn solid. It means that it is not possible to distinguish
-   * a dashed line from a solid line because of current value of zoom.
-   */
-
-  /* inverting angle2 if < 0 and changing angle1 accordingly */
-  /* the loop test assume that da > 0 */
-  if(angle2 < 0) {
-    angle1 = angle1 + angle2;
-    angle2 = -angle2;
-  }
-  da = length * 180 / (M_PI * radius);
-  db = space  * 180 / (M_PI * radius);
-
-  /* If da or db too small for arc to be displayed as dotted,
-     draw a solid arc */
-  if((da <= 0) || (db <= 0)) {
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 angle1 * 64, angle2 * 64);
-    return;
-  }
-
-  /*
-   * It starts from <B>angle1</B> and increments <B>angle1</B> by <B>da</B> as a
-   * loop until the whole arc has been browsed. At each position a dash
-   * of length <B>length</B> - represented by the <B>da</B> increment - is drawn.
-   *
-   * It draws as many dashes of length <B>length</B> as possible.
-   */
-
-  d = angle1;
-  while((d + da + db) < (angle1 + angle2)) {
-    a1 = d;
-    d = d + da;
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 a1 * 64, da * 64);
-
-    d = d + db;
-		
-  }
-
-  /*
-   * When the above condition is no more satisfied, the it is possible
-   * to draw a dash of length <B>length</B>. However it may be possible to
-   * draw a shorter dash.
-   */
-
-  if((d + da) < (angle1 + angle2)) {
-    a1 = d;
-    a2 = da;
-  } else {
-    a1 = d;
-    a2 = (angle1 + angle2) - d;
-  }
-  gdk_draw_arc(w, gc, FALSE,
-               x - radius, y - radius, 2 * radius, 2 * radius,
-               a1 * 64, a2 * 64);
-	
-}
-
-
-/*! \brief Draw arc with a centered line type.
- *  \par Function Description
- *  This functions draws an arc with a centered line type. The parameter
- *  <B>space</B> represents the distance between a dot and the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The unit of <B>x</B>, <B>y</B> and <B>width</B>, <B>height</B> and
- *  <B>arc_width</B>, <B>space</B>, <B>length</B> is pixel.
- *
- *  <B>angle1</B> and <B>angle2</B> are in units of degrees.
- *
- *  A negative or null value for <B>length</B> and <B>space</B> leads to an
- *  endless loop.
- *
- *  \param [in] w          GdkWindow to draw in.
- *  \param [in] gc         GdkGC graphics context to draw on.
- *  \param [in] color      Arc line color.
- *  \param [in] cap        Arc line end cap type (unused).
- *  \param [in] x          Arc center x.
- *  \param [in] y          Arc center y.
- *  \param [in] radius     Arc radius.
- *  \param [in] angle1     Start angle in degrees.
- *  \param [in] angle2     End angle in degrees.
- *  \param [in] arc_width  Width of arc line.
- *  \param [in] length     Length of dash in pixels..
- *  \param [in] space      Spacing between dashes in pixels.
- */
-void o_arc_draw_center(GdkWindow *w, GdkGC *gc,
-		       GdkColor *color, GdkCapStyle cap,
-		       gint x, gint y,
-		       gint radius,
-		       gint angle1, gint angle2,
-		       gint arc_width, gint length, gint space)
-{
-  double xa, ya; /* coordinate of center */
-  int da, db, a1, a2, d;
-
-  gdk_gc_set_foreground(gc, color);	
-  gdk_gc_set_line_attributes(gc, arc_width, 
-                             GDK_LINE_SOLID, cap, GDK_JOIN_MITER);
-
-  /*
-   * The function determines the angular increments that match the
-   * <B>length</B> and <B>space</B> parameter. These are <B>db</B> and <B>da</B>.
-   * Whenever one or both of these variables are null or negative, the
-   * line is drawn solid. It means that it is not possible to distinguish
-   * a dashed line from a solid line because of current value of zoom.
-   */
-
-  /* inverting angle2 if < 0 and changing angle1 accordingly */
-  /* the loop test assume that da > 0 */
-  if(angle2 < 0) {
-    angle1 = angle1 + angle2;
-    angle2 = -angle2;
-  }
-  da = length * 180 / (M_PI * radius);
-  db = space  * 180 / (M_PI * radius);
-
-  /* If da or db too small to be displayed, draw an arc */
-  if((da <= 0) || (db <= 0)) {
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2* radius, 2 * radius,
-                 angle1 * 64, angle2 * 64);
-    return;
-  }
-
-  /*
-   * Starting from <B>angle1</B> and incrementing the position gives the
-   * coordinates of every dots and dashes on the arc providing that the
-   * second extremity is not exceeded. 
-   *
-   * It draws as many sets of 'dash of length <B>length</B> and dot' as possible.
-   */
-
-  d = angle1;
-  while((d + da + 2 * db) < (angle1 + angle2)) {
-    a1 = d;
-    d = d + da;
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 a1 * 64, da * 64);
-
-    d = d + db;
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-
-
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - arc_width/2, 
-		   ((int) ya) - arc_width/2,
-		   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-
-    /*
-     * If the above condition is no more satisfied, it may still be possible
-     * to continue drawing a part of the initial pattern. Here two cases are
-     * possible :
-     * <DL>
-     *   <DT>*</DT><DD>it is possible to draw a dash and a dot.
-     *   <DT>*</DT><DD>it is possible to draw a dash or at least
-     *                 a part of the original dash.
-     * </DL>
-     */
-
-    d = d + db;
-  }
-
-
-  if((d + da) < (angle1 + angle2)) {
-    a1 = d;
-    a2 = da;
-		
-    d = d + da;
-  } else {
-    a1 = d;
-    a2 = (angle1 + angle2) - d;
-
-    d = d + da;
-  }
-  gdk_draw_arc(w, gc, FALSE,
-               x - radius, y - radius, 2 * radius, 2 * radius,
-               a1 * 64, da * 64);
-
-  if((d + db) < (angle1 + angle2)) {
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real worl width is equal to 0, then the
-     * width is translated to 1 in screen coordinates to be visible.
-     * Drawing a circle with a 1-diameter and the GDK function
-     * #gdk_draw_arc() is not possible. So we needs to test whether the
-     * width is 1 or not.
-     */
-
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - arc_width/2, 
-		   ((int) ya) - arc_width/2,
-		   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-
-
-  }
-	
-}
-
-
-/*! \brief Draw an arc with a phantom line type.
- *  \par Function Description
- *  This function draws an arc with a phantom line type. The parameter
- *  <B>space</B> represents the distance between a dot and a dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The unit of <B>x</B>, <B>y</B> and <B>width</B>, <B>height</B> and
- *  <B>arc_width</B>, <B>space</B>, <B>length</B> is pixel.
- *
- *  <B>angle1</B> and <B>angle2</B> are in units of degrees.
- *
- *  A negative or null value for <B>length</B> and <B>space</B> leads to an
- *  endless loop.
- *
- *  \param [in] w          GdkWindow to draw in.
- *  \param [in] gc         GdkGC graphics context to draw on.
- *  \param [in] color      Arc line color.
- *  \param [in] cap        Arc line end cap type (unused).
- *  \param [in] x          Arc center x.
- *  \param [in] y          Arc center y.
- *  \param [in] radius     Arc radius.
- *  \param [in] angle1     Start angle in degrees.
- *  \param [in] angle2     End angle in degrees.
- *  \param [in] arc_width  Width of arc line.
- *  \param [in] length     Length of dash in pixels.
- *  \param [in] space      Spacing between dashes in pixels.
- */
-void o_arc_draw_phantom(GdkWindow *w, GdkGC *gc,
-			GdkColor *color, GdkCapStyle cap,
-			gint x, gint y,
-			gint radius,
-			gint angle1, gint angle2,
-			gint arc_width, gint length, gint space)
-{
-  double xa, ya;
-  int da, db, a1, a2, d;
-
-  gdk_gc_set_foreground(gc, color);	
-  gdk_gc_set_line_attributes(gc, arc_width, 
-                             GDK_LINE_SOLID, cap, GDK_JOIN_MITER);
-
-  /* The function determines the angular increments that match the
-   * <B>length</B> and <B>space</B> parameters. These are <B>db</B> and <B>da</B>.
-   * Whenever one or both of these variables are null or negative, the
-   * line is drawn solid. It means that it is not possible to distinguish
-   * a dashed line from a solid line because of current value of zoom.
-   */
-
-  /* inverting angle2 if < 0 and changing angle1 accordingly */
-  /* the loop test assume that da > 0 */
-  if(angle2 < 0) {
-    angle1 = angle1 + angle2;
-    angle2 = -angle2;
-  }
-  da = length * 180 / (M_PI * radius);
-  db = space  * 180 / (M_PI * radius);
-
-  /* If da or db too small for arc to be displayed as dotted,
-     draw a solid arc */
-  if((da <= 0) || (db <= 0)) {
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 angle1 * 64, angle2 * 64);
-    return;
-  }
-
-  /*
-   * Starting from <B>angle1</B> and incrementing the position gives the
-   * coordinates of every dots and dashes on the arc providing that the
-   * second extremity is not exceeded. 
-   *
-   * It draws as many sets of 'dash of length <B>length</B> and two dots'
-   * as possible.
-   */
-
-  d = angle1;
-  while((d + da + 3 * db) < (angle1 + angle2)) {
-    a1 = d;
-    d = d + da;
-    gdk_draw_arc(w, gc, FALSE,
-                 x - radius, y - radius, 2 * radius, 2 * radius,
-                 a1 * 64, da * 64);
-
-    d = d + db;
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real worl width is equal to 0, then the
-     * width is translated to 1 in screen coordinates to be visible.
-     * Drawing a circle with a 1-diameter and the GDK function
-     * #gdk_draw_arc() is not possible. So we needs to test whether the
-     * width is 1 or not.
-     */
-
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - arc_width/2, 
-		   ((int) ya) - arc_width/2,
-		   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-
-
-    d = d + db;
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-
-    
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real world width is equal to 0, then the
-     * width is translated to 1 in screen coordinates to be visible. Drawing
-     * a circle with a 1-diameter and the GDK function #gdk_draw_arc() is
-     * not possible. So we needs to test whether the width is 1 or not.
-     */
-
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - arc_width/2, 
-		   ((int) ya) - arc_width/2,
-		   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-
-
-
-    d = d + db;
-  }
-
-  /*
-   * If the above condition is no more satisfied, it may still be possible
-   * to continue drawing a part of the original pattern. Here three cases
-   * are possible :
-   * <DL>
-   *   <DT>*</DT><DD>it is possible to draw a dash and the two dots.
-   *   <DT>*</DT><DD>it is possible to draw a dash and one of the two dots.
-   *   <DT>*</DT><DD>it is possible to draw at least a part of the initial
-   *                 dash.
-   */
-
-  if((d + da) < (angle1 + angle2)) {
-    a1 = d;
-    a2 = da;
-    d = d + da;
-  } else {
-    a1 = d;
-    a2 = (angle1 + angle2) - d;
-    d = d + da;
-  }
-  gdk_draw_arc(w, gc, FALSE,
-               x - radius, y - radius, 2 * radius, 2 * radius,
-               a1 * 64, a2 * 64);
-
-  if((d + db) < (angle1 + angle2)) {
-    d = d + db;
-
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-		
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-                   ((int) xa) - arc_width/2, 
-                   ((int) ya) - arc_width/2,
-                   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-  }
-
-  if((d + db) < (angle1 + angle2)) {
-    d = d + db;
-
-    xa = ((double) x) + ((double) radius) * cos(d * M_PI / 180);
-    ya = ((double) y) - ((double) radius) * sin(d * M_PI / 180);
-		
-    if(arc_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-                   ((int) xa) - arc_width/2, 
-                   ((int) ya) - arc_width/2,
-                   arc_width, arc_width, 0, FULL_CIRCLE);
-    }
-  }
-	
-}
-
-
 /*! \todo Finish function documentation!!!
  *  \brief
  *  \par Function Description
diff --git a/gschem/src/o_box.c b/gschem/src/o_box.c
index 070491a..bbf4515 100644
--- a/gschem/src/o_box.c
+++ b/gschem/src/o_box.c
@@ -36,11 +36,6 @@
 #define GET_BOX_TOP(w)				\
         max((w)->first_wy, (w)->second_wy)
 
-typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                           GdkCapStyle cap, gint filled,
-                           gint x, gint y, gint width, gint height,
-                           gint line_width, gint length, gint space );
-
 typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GSCHEM_TOPLEVEL *w_current, BOX *box,
                            gint fill_width, gint angle1, gint pitch1,
@@ -66,9 +61,7 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int s_upper_x, s_upper_y, s_lower_x, s_lower_y;
   int line_width, length, space;
   int fill_width, angle1, pitch1, angle2, pitch2;
-  GdkCapStyle box_end;
   GdkColor *color;
-  DRAW_FUNC draw_func = NULL;
   FILL_FUNC fill_func;
 
   if (o_current->box == NULL) {
@@ -129,68 +122,13 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     line_width = 1;
   }
 
-  switch(o_current->line_end) {
-    case END_NONE:   box_end = GDK_CAP_BUTT;       break;
-    case END_SQUARE: box_end = GDK_CAP_PROJECTING; break;
-    case END_ROUND:  box_end = GDK_CAP_ROUND;      break;
-    default: fprintf(stderr, _("Unknown end for box (%d)\n"), o_current->line_end);
-    box_end = GDK_CAP_BUTT;
-    break;
-  }
-	
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
-	
-  switch(o_current->line_type) {
-    case TYPE_SOLID:
-      length = -1;
-      space = -1;
-      draw_func = o_box_draw_solid;
-      break;
-
-    case TYPE_DOTTED:
-      length = -1; /* ..._draw_dotted only space is used */
-      draw_func = o_box_draw_dotted;
-      break;
-
-    case TYPE_DASHED:
-      draw_func = o_box_draw_dashed;
-      break;
-
-    case TYPE_CENTER:
-      draw_func = o_box_draw_center;
-      break;
-
-    case TYPE_PHANTOM:
-      draw_func = o_box_draw_phantom;
-      break;
-
-    case TYPE_ERASE:
-      break;
-			
-    default:
-      length = -1;
-      space = -1;
-      line_width = 0; /* just to be careful */
-      draw_func = o_box_draw_solid;
-      fprintf(stderr, _("Unknown type for box !\n"));
-      break;
-  }
-
-  if((length == 0) || (space == 0))
-  draw_func = o_box_draw_solid;
 
   WORLDtoSCREEN( toplevel, o_current->box->upper_x, o_current->box->upper_y,
                  &s_upper_x, &s_upper_y );
   WORLDtoSCREEN( toplevel, o_current->box->lower_x, o_current->box->lower_y,
                  &s_lower_x, &s_lower_y );
-	
-  (*draw_func) (w_current->drawable, w_current->gc, color, box_end,
-                FALSE,
-                s_upper_x, s_upper_y,
-                abs(s_lower_x - s_upper_x),
-                abs(s_lower_y - s_upper_y),
-                line_width, length, space);
 
   /*
    * The values needed for the fill operation are taken from the
@@ -268,249 +206,19 @@ void o_box_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
                 w_current, o_current->box,
                 fill_width, angle1, pitch1, angle2, pitch2);
 
-  if (o_current->selected && w_current->draw_grips) {
-    o_box_draw_grips (w_current, o_current);
-  }
-}
+  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_box (w_current->cr, line_width,
+                    s_lower_x, s_lower_y, s_upper_x, s_upper_y);
 
-/*! \brief Draw a box with a solid line type.
- *  \par Function Description
- *  This function draws a box with a solid line type. The length and space
- *  parameters are not used by this function.
- *
- *  The function uses the functions previously defined in #o_line.c. It is
- *  called four times for each of the side of the box. Therefore note that
- *  the cap parameter is significant here even if it is a box (i.e. a closed
- *  shape).
- *
- *  The box is defined in the same way as it is in GDK : one point and
- *  the width and height of the box.
- *
- *  The unit of <B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>,
- *  <B>line_width</B>, <B>length</B> and <B>space</B> is pixel.
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] filled      (unused)
- *  \param [in] x           Box upper x.
- *  \param [in] y           Box upper y.
- *  \param [in] width       Box width.
- *  \param [in] height      Box height
- *  \param [in] line_width  Width of line to draw box.
- *  \param [in] length      (unused)
- *  \param [in] space       (unused)
- */
-void o_box_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color,
-		      GdkCapStyle cap, gint filled, gint x, gint y, gint width,
-		      gint height, gint line_width, gint length, gint space)
-{
-  o_line_draw_solid(w, gc, color, cap,
-                    x, y, x + width, y, line_width, length, space);
-  o_line_draw_solid(w, gc, color, cap,
-                    x + width, y, x + width, y + height, line_width, 
-                    length, space);
-  o_line_draw_solid(w, gc, color, cap,
-                    x + width, y + height, x, y + height, line_width, 
-                    length, space);
-  o_line_draw_solid(w, gc, color, cap,
-                    x, y + height, x, y, line_width, length, space);
-}
+  if (o_current->fill_type == FILLING_FILL)
+    cairo_fill_preserve (w_current->cr);
 
-/*! \brief Draw a box with a dotted line type.
- *  \par Function Description
- *  This function draws a box with a dotted line type. The parameter
- *  <B>space</B> represents the distance between two of the dots. The
- *  parameter <B>length</B> is unused. The diameter of the dots is given by
- *  the width of the line given by <B>width</B>.
- *
- *  The function uses the functions previously defined in #o_line.c. It is
- *  called four times for each of the side of the box.
- *
- *  The box is defined in the same way as it is in GDK : one point and
- *  the width and height of the box.
- *
- *  The unit of <B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>,
- *  <B>line_width</B>, <B>length</B> and <B>space</B> is pixel.
- *
- *  A negative or null value for <B>space</B> leads to an endless loop
- *  in #o_line_draw_dotted().
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] filled      (unused)
- *  \param [in] x           Box upper x.
- *  \param [in] y           Box upper y.
- *  \param [in] width       Box width.
- *  \param [in] height      Box height
- *  \param [in] line_width  Width of line to draw box.
- *  \param [in] length      (unused)
- *  \param [in] space       Space in pixels between dots.
- */
+  gschem_cairo_stroke (w_current->cr, o_current->line_type,
+                       o_current->line_end, line_width, length, space);
 
-void o_box_draw_dotted(GdkDrawable *w, GdkGC *gc, GdkColor *color,
-		       GdkCapStyle cap, gint filled, gint x, gint y,
-		       gint width, gint height, gint line_width,
-		       gint length, gint space)
-{
-  o_line_draw_dotted(w, gc, color, cap,
-                     x, y, x + width, y, line_width, length, space);
-  o_line_draw_dotted(w, gc, color, cap,
-                     x + width, y, x + width, y + height, 
-                     line_width, length, space);
-  o_line_draw_dotted(w, gc, color, cap,
-                     x + width, y + height, x, y+height, 
-                     line_width, length, space);
-  o_line_draw_dotted(w, gc, color, cap,
-                     x, y + height, x, y, line_width, length, space);
-	
-}
-
-/*! \brief Draw a box with a dashed line type.
- *  \par Function Description
- *  This function draws a box with a dashed line type. The parameter
- *  <B>space</B> represents the distance between two of the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The function uses the functions previously defined in #o_line.c. It is
- *  called four times for each of the side of the box.
- *
- *  The box is defined in the same way as it is in GDK : one point and
- *  the width and height of the box.
- *
- *  The unit of <B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>,
- *  <B>line_width</B>, <B>length</B> and <B>space</B> is pixel.
- *
- *  A negative or null value for length or space leads to an endless
- *  loop in #o_line_draw_dashed().
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] filled      (unused)
- *  \param [in] x           Box upper x.
- *  \param [in] y           Box upper y.
- *  \param [in] width       Box width.
- *  \param [in] height      Box height
- *  \param [in] line_width  Width of line to draw box.
- *  \param [in] length      Length of dash in pixels.
- *  \param [in] space       Space between dashes in pixels.
- */
-void o_box_draw_dashed(GdkDrawable *w, GdkGC *gc, GdkColor *color,
-		       GdkCapStyle cap, gint filled, gint x, gint y,
-		       gint width, gint height, gint line_width,
-		       gint length, gint space)
-{
-  o_line_draw_dashed(w, gc, color, cap,
-                     x, y, x + width, y, line_width, length, space);
-  o_line_draw_dashed(w, gc, color, cap,
-                     x + width, y, x + width, y + height, 
-                     line_width, length, space);
-  o_line_draw_dashed(w, gc, color, cap,
-                     x + width, y + height, x, y+height, 
-                     line_width, length, space);
-  o_line_draw_dashed(w, gc, color, cap,
-                     x, y + height, x, y, line_width, length, space);
-}
-
-/*! \brief Draw a box with a centered line type.
- *  \par Function Description
- *  This function draws a box with a centered line type. The parameter
- *  <B>space</B> represents the distance between a dot and the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The function uses the functions previously defined in #o_line.c. It is
- *  called four times for each of the side of the box.
- *
- *  The box is defined in the same way as it is in GDK : one point and the
- *  width and height of the box.
- *
- *  The unit of <B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>,
- *  <B>line_width</B>, <B>length</B> and <B>space</B> is pixel.
- *
- *  A negative or null value for length or space leads to an endless
- *  loop in #o_line_draw_center().
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] filled      (unused)
- *  \param [in] x           Box upper x.
- *  \param [in] y           Box upper y.
- *  \param [in] width       Box width.
- *  \param [in] height      Box height
- *  \param [in] line_width  Width of line to draw box.
- *  \param [in] length      (unused)?
- *  \param [in] space       (unused)?
- */
-void o_box_draw_center(GdkDrawable *w, GdkGC *gc, GdkColor *color,
-		       GdkCapStyle cap, gint filled, gint x, gint y,
-		       gint width, gint height, gint line_width,
-		       gint length, gint space)
-{
-  o_line_draw_center(w, gc, color, cap,
-                     x, y, x + width, y, line_width, length, space);
-  o_line_draw_center(w, gc, color, cap,
-                     x + width, y, x + width, y + height, 
-                     line_width, length, space);
-  o_line_draw_center(w, gc, color, cap,
-                     x + width, y + height, x, y+height, 
-                     line_width, length, space);
-  o_line_draw_center(w, gc, color, cap,
-                     x, y + height, x, y, line_width, length, space);
-}
-
-/*! \brief Draw a box with a phantom line type.
- *  \par Function Description
- *  This function draws a box with a phantom line type. The parameter
- *  <B>space</B> represents the distance between a dot and a dash.
- *  The parameter <B>length</B> represents the length of a dash.
- *
- *  The function uses the functions previously defined in #o_line.c.
- *  It is called four times for each of the side of the box.
- *
- *  The box is defined in the same way as it is in GDK : one point and the
- *  width and height of the box.
- *
- *  The unit of <B>x</B>, <B>y</B>, <B>width</B>, <B>height</B>,
- *  <B>line_width</B>, <B>length</B> and <B>space</B> is pixel.
- *
- *  A negative or null value for length or space leads to an endless loop
- *  in #o_line_draw_phantom().
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] filled      (unused)
- *  \param [in] x           Box upper x.
- *  \param [in] y           Box upper y.
- *  \param [in] width       Box width.
- *  \param [in] height      Box height
- *  \param [in] line_width  Width of line to draw box.
- *  \param [in] length      (unused)?
- *  \param [in] space       (unused)?
- */
-void o_box_draw_phantom(GdkDrawable *w, GdkGC *gc, GdkColor *color,
-			GdkCapStyle cap, gint filled, gint x, gint y,
-			gint width, gint height, gint line_width,
-			gint length, gint space)
-{
-  o_line_draw_phantom(w, gc, color, cap,
-                      x, y, x + width, y, line_width, length, space);
-  o_line_draw_phantom(w, gc, color, cap,
-                      x + width, y, x + width, y+height, 
-                      line_width, length, space);
-  o_line_draw_phantom(w, gc, color, cap,
-                      x + width, y + height, x, y+height, 
-                      line_width, length, space);
-  o_line_draw_phantom(w, gc, color, cap,
-                      x, y + height, x, y, line_width, length, space);
+  if (o_current->selected && w_current->draw_grips) {
+    o_box_draw_grips (w_current, o_current);
+  }
 }
 
 /*! \brief Placeholder filling function.
@@ -575,19 +283,7 @@ void o_box_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                       gint angle1, gint pitch1,
                       gint angle2, gint pitch2)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int s_lower_x, s_lower_y;
-  int s_upper_x, s_upper_y;
-
-  WORLDtoSCREEN (toplevel, box->lower_x, box->lower_y, &s_lower_x, &s_lower_y);
-  WORLDtoSCREEN (toplevel, box->upper_x, box->upper_y, &s_upper_x, &s_upper_y);
-
-  gdk_gc_set_foreground (gc, color);
-  gdk_gc_set_line_attributes (gc, 1, GDK_LINE_SOLID,
-                              GDK_CAP_BUTT, GDK_JOIN_MITER);
-
-  gdk_draw_rectangle (w, gc, TRUE, s_upper_x, s_upper_y,
-                      s_lower_x - s_upper_x, s_lower_y - s_upper_y);
+  /* NOP: We'll fill it when we do the stroking */
 }
 
 /*! \brief Fill inside of box with single line pattern.
@@ -629,8 +325,9 @@ void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
+  gdk_cairo_set_source_color (w_current->cr, color);
 
+  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_box (box, angle1, pitch1, lines);
 
   for (i=0; i < lines->len; i++) {
@@ -639,8 +336,9 @@ void o_box_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
 
     WORLDtoSCREEN (w_current->toplevel, line->x[0], line->y[0], &x1, &y1);
     WORLDtoSCREEN (w_current->toplevel, line->x[1], line->y[1], &x2, &y2);
-    o_line_draw_solid (w, gc, color, GDK_CAP_BUTT,
-                       x1, y1, x2, y2, fill_width, -1, -1);
+    gschem_cairo_line (w_current->cr, END_NONE, fill_width, x1, y1, x2, y2);
+    gschem_cairo_stroke (w_current->cr, TYPE_SOLID, END_NONE,
+                                        fill_width, -1, -1);
   }
 
   g_array_free (lines, TRUE);
diff --git a/gschem/src/o_bus.c b/gschem/src/o_bus.c
index a34b031..39f1d78 100644
--- a/gschem/src/o_bus.c
+++ b/gschem/src/o_bus.c
@@ -56,33 +56,26 @@ void o_bus_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing bus\n\n");
 #endif
 
+  size = 1;
+
   if (toplevel->bus_style == THICK ) {
     size = SCREENabs(toplevel, BUS_WIDTH);
 
-    if (size < 0)
-      size=0;
-
-    gdk_gc_set_line_attributes(w_current->gc, size, GDK_LINE_SOLID,
-                               GDK_CAP_BUTT,
-                               GDK_JOIN_MITER);
+    if (size < 1)
+      size=1;
   }
 
+  cairo_set_line_width (w_current->cr, size);
+  cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_SQUARE);
+
   if (toplevel->override_color != -1 ) {
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(toplevel->override_color));
-    gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
+    gdk_cairo_set_source_color (w_current->cr, x_get_color(toplevel->override_color));
   } else {
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(o_current->color));
-    gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
+    gdk_cairo_set_source_color (w_current->cr, x_get_color(o_current->color));
   }
 
-  /* yes zero is right for the width -> use hardware lines */
-  if (toplevel->bus_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->gc, 0, GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
+  gschem_cairo_line (w_current->cr, END_SQUARE, size, x1, y1, x2, y2);
+  cairo_stroke (w_current->cr);
 
 #if DEBUG
   printf("drawing bus\n");
diff --git a/gschem/src/o_circle.c b/gschem/src/o_circle.c
index db9fd96..c50fbba 100644
--- a/gschem/src/o_circle.c
+++ b/gschem/src/o_circle.c
@@ -28,11 +28,6 @@
 #endif
 
 
-typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                           GdkCapStyle cap, gint x, gint y, gint radius,
-                           gint angle1, gint angle2,
-                           gint arc_width, gint length, gint space );
-
 typedef void (*FILL_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GSCHEM_TOPLEVEL *w_current, CIRCLE *circle,
                            gint fill_width, gint angle1, gint pitch1,
@@ -57,11 +52,9 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int wleft, wright, wtop, wbottom; /* world bounds */
   int s_x, s_y;
   int radius;
-  int circle_width, length, space;
+  int line_width, length, space;
   int fill_width, angle1, pitch1, angle2, pitch2;
-  GdkCapStyle circle_end;
   GdkColor *color;
-  DRAW_FUNC draw_func = NULL;
   FILL_FUNC fill_func;
 
   if (o_current->circle == NULL) {
@@ -112,71 +105,16 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
    * to an endless loop in function called after. If such a case is encountered
    * the circle is drawn as a solid circle independently of its initial type.
    */
-  circle_width = SCREENabs( toplevel, o_current->line_width );
-  if(circle_width <= 0) {
-    circle_width = 1;
+  line_width = SCREENabs( toplevel, o_current->line_width );
+  if (line_width <= 0) {
+    line_width = 1;
   }
 
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
 
-  switch(o_current->line_end) {
-    case END_NONE:   circle_end = GDK_CAP_BUTT;       break;
-    case END_SQUARE: circle_end = GDK_CAP_PROJECTING; break;
-    case END_ROUND:  circle_end = GDK_CAP_ROUND;      break;
-    default: fprintf(stderr, _("Unknown end for circle\n"));
-      circle_end = GDK_CAP_BUTT;
-      break;
-  }
-
-  switch(o_current->line_type) {
-    case TYPE_SOLID:
-    length = -1;
-    space = -1;
-    draw_func = o_arc_draw_solid;
-    break;
-			
-    case TYPE_DOTTED:
-    length = -1; /* ..._draw_dotted only space used */
-    draw_func = o_arc_draw_dotted;
-    break;
-			
-    case TYPE_DASHED:
-    draw_func = o_arc_draw_dashed;
-    break;
-			
-    case TYPE_CENTER:
-    draw_func = o_arc_draw_center;
-    break;
-			
-    case TYPE_PHANTOM:
-    draw_func = o_arc_draw_phantom;
-    break;
-			
-    case TYPE_ERASE:
-    break;
-			
-    default:
-    length = -1;
-    space = -1;
-    circle_width = 0; /* just to be careful */
-    fprintf(stderr, _("Unknown type for circle!\n"));
-    draw_func = o_arc_draw_solid;			
-    break;
-  }
-
-  if((length == 0) || (space == 0))
-  draw_func = o_arc_draw_solid;
-
   WORLDtoSCREEN( toplevel, o_current->circle->center_x, o_current->circle->center_y,
                  &s_x, &s_y );
-	
-  (*draw_func) (w_current->drawable, w_current->gc, color,
-                circle_end,
-                s_x, s_y,
-                radius,
-                0, FULL_CIRCLE / 64,
-                circle_width, length, space);
 
   /*
    * The values needed for the fill operation are taken from the
@@ -249,10 +187,20 @@ void o_circle_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     fill_func = o_circle_fill_fill;
   }
 
-  (*fill_func) (w_current->drawable, w_current->gc, color,
-                w_current, o_current->circle,
+  (*fill_func) (w_current->drawable, w_current->gc,
+                color, w_current, o_current->circle,
                 fill_width, angle1, pitch1, angle2, pitch2);
 
+  gdk_cairo_set_source_color (w_current->cr, color);
+  cairo_new_sub_path (w_current->cr);
+  cairo_arc (w_current->cr, s_x + 0.5, s_y + 0.5, radius, 0., 2 * M_PI);
+
+  if (o_current->fill_type == FILLING_FILL)
+    cairo_fill_preserve (w_current->cr);
+
+  gschem_cairo_stroke (w_current->cr, o_current->line_type,
+                       o_current->line_end, line_width, length, space);
+
 #if DEBUG
   printf("drawing circle\n");
 #endif
@@ -327,19 +275,7 @@ void o_circle_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                          gint angle1, gint pitch1,
                          gint angle2, gint pitch2)
 {
-  TOPLEVEL *toplevel = w_current->toplevel;
-  int s_x, s_y;
-  int radius;
-
-  gdk_gc_set_foreground(gc, color);
-  gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID,
-                             GDK_CAP_BUTT, GDK_JOIN_MITER);
-
-  WORLDtoSCREEN (toplevel, circle->center_x, circle->center_y, &s_x, &s_y);
-  radius = SCREENabs (toplevel, circle->radius);
-
-  gdk_draw_arc (w, gc, TRUE, s_x - radius, s_y - radius,
-                2 * radius, 2 * radius, 0, FULL_CIRCLE);
+  /* NOP: We'll fill it when we do the stroking */
 }
 
 /*! \brief Fill inside of circle with single line pattern.
@@ -384,8 +320,9 @@ void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
+  gdk_cairo_set_source_color (w_current->cr, color);
 
+  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_circle (circle, angle1, pitch1, lines);
 
   for (i=0; i < lines->len; i++) {
@@ -394,8 +331,10 @@ void o_circle_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
 
     WORLDtoSCREEN (w_current->toplevel, line->x[0], line->y[0], &x1, &y1);
     WORLDtoSCREEN (w_current->toplevel, line->x[1], line->y[1], &x2, &y2);
-    o_line_draw_solid (w, gc, color, GDK_CAP_BUTT,
-                       x1, y1, x2, y2, fill_width, -1, -1);
+    gschem_cairo_line (w_current->cr, END_NONE, fill_width, x1, y1, x2, y2);
+    gschem_cairo_stroke (w_current->cr, TYPE_SOLID, END_NONE,
+                                        fill_width, -1, -1);
+
   }
 
   g_array_free (lines, TRUE);
diff --git a/gschem/src/o_cue.c b/gschem/src/o_cue.c
index 13cd5dc..5cea49d 100644
--- a/gschem/src/o_cue.c
+++ b/gschem/src/o_cue.c
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 #include <string.h>
+#include <math.h> /* For M_PI */
 
 #include "gschem.h"
 
@@ -84,10 +85,9 @@ void o_cue_redraw_all (GSCHEM_TOPLEVEL *w_current, GList *list, gboolean draw_se
 static void o_cue_set_color(GSCHEM_TOPLEVEL *w_current, int color)
 {
   if (w_current->toplevel->override_color != -1 ) {
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(w_current->toplevel->override_color));
+    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->override_color));
   } else {
-    gdk_gc_set_foreground(w_current->gc, x_get_color(color));
+    gdk_cairo_set_source_color(w_current->cr, x_get_color(color));
   }
 }
 
@@ -162,20 +162,20 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
   WORLDtoSCREEN(toplevel, x, y, &screen_x, &screen_y);
   
   switch(type) {
-    
+
     case(CONN_ENDPOINT):
       if (object->type == OBJ_NET) { /* only nets have these cues */
         if (count < 1) { /* Didn't find anything connected there */
-	  if (toplevel->DONT_REDRAW == 0) {
-	    o_cue_set_color(w_current, toplevel->net_endpoint_color);
-	    gdk_draw_rectangle (w_current->drawable,
-                                w_current->gc, TRUE,
-                                screen_x - size,
-                                screen_y - size,
-                                x2size,
-                                x2size);
-	  }
-        
+          if (toplevel->DONT_REDRAW == 0) {
+            o_cue_set_color (w_current, toplevel->net_endpoint_color);
+            cairo_move_to (w_current->cr, screen_x - size, screen_y - size);
+            cairo_rel_line_to (w_current->cr, x2size + 1, 0);
+            cairo_rel_line_to (w_current->cr, 0, x2size + 1);
+            cairo_rel_line_to (w_current->cr, -x2size - 1, 0);
+            cairo_close_path (w_current->cr);
+            cairo_fill (w_current->cr);
+          }
+
         } else if (count >= 2) {
           /* draw circle */
 
@@ -185,63 +185,57 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
             size = SCREENabs(toplevel, CUE_CIRCLE_LARGE_SIZE) / 2;
           }
           x2size = 2 * size;
-	  if (toplevel->DONT_REDRAW == 0) {
-	    o_cue_set_color(w_current, toplevel->junction_color);
-            gdk_draw_arc (w_current->drawable,
-                          w_current->gc, TRUE,
-                          screen_x - size,
-                          screen_y - size,
-                          x2size, x2size, 0, FULL_CIRCLE);
-	  }
+          if (toplevel->DONT_REDRAW == 0) {
+            o_cue_set_color(w_current, toplevel->junction_color);
+            cairo_arc (w_current->cr, screen_x + 0.5, screen_y + 0.5, size, 0, 2. * M_PI);
+            cairo_fill (w_current->cr);
+
+          }
         }
       } else if (object->type == OBJ_PIN) {
         /* Didn't find anything connected there */
         if (count < 1 && object->whichend == whichone) {
-                  
+
           otherone = !whichone;
 
           pinsize = SCREENabs(toplevel, 10);
           if (toplevel->pin_style == THICK ) {
-            gdk_gc_set_line_attributes(w_current->gc, pinsize,
-                                       GDK_LINE_SOLID,
-                                       GDK_CAP_NOT_LAST,
-                                       GDK_JOIN_MITER);
+            cairo_set_line_width (w_current->cr, pinsize);
+            cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT);
           }
 
-    /* No need to invalidate the PIN end CUE, as the
-     * whole pin region is already invalidated. */
           if (toplevel->DONT_REDRAW == 0) {
             o_cue_set_color(w_current, toplevel->net_endpoint_color);
             if (object->line->y[whichone] == object->line->y[otherone]) {
               /* horizontal line */
               if (object->line->x[whichone] <= object->line->x[otherone]) {
-                gdk_draw_line (w_current->drawable, w_current->gc,
-                               screen_x, screen_y, screen_x + size, screen_y);
+                gschem_cairo_line (w_current->cr, END_NONE, pinsize,
+                                   screen_x,        screen_y,
+                                   screen_x + size, screen_y);
               } else {
-                gdk_draw_line (w_current->drawable, w_current->gc,
-                               screen_x, screen_y, screen_x - size, screen_y);
+                gschem_cairo_line (w_current->cr, END_NONE, pinsize,
+                                   screen_x,         screen_y,
+                                   screen_x - size, screen_y);
               }
+              cairo_stroke (w_current->cr);
             } else if (object->line->x[0] == object->line->x[1]) {
               /* vertical line */
               if (object->line->y[whichone] <= object->line->y[otherone]) {
-                gdk_draw_line (w_current->drawable, w_current->gc,
-                               screen_x, screen_y, screen_x, screen_y - size);
+                gschem_cairo_line (w_current->cr, END_NONE, pinsize,
+                                   screen_x, screen_y,
+                                   screen_x, screen_y - size);
               } else {
-                gdk_draw_line (w_current->drawable, w_current->gc,
-                               screen_x, screen_y, screen_x, screen_y + size);
+                gschem_cairo_line (w_current->cr, END_NONE, pinsize,
+                                   screen_x, screen_y,
+                                   screen_x, screen_y + size);
               }
+              cairo_stroke (w_current->cr);
             } else {
               /* angled line */
               /* not supporting rendering of que for angled pin for now. hack */
             }
           }
 
-          if (toplevel->pin_style == THICK ) {
-            gdk_gc_set_line_attributes(w_current->gc, 0,
-                                       GDK_LINE_SOLID,
-                                       GDK_CAP_NOT_LAST,
-                                       GDK_JOIN_MITER);
-          }
         }
       }
       break;
@@ -258,11 +252,8 @@ void o_cue_draw_lowlevel(GSCHEM_TOPLEVEL *w_current, OBJECT *object, int whichon
 
       if (toplevel->DONT_REDRAW == 0) {
 	o_cue_set_color(w_current, toplevel->junction_color);
-        gdk_draw_arc (w_current->drawable,
-                      w_current->gc, TRUE,
-                      screen_x - size,
-                      screen_y - size,
-                      x2size, x2size, 0, FULL_CIRCLE);
+        cairo_arc (w_current->cr, screen_x + 0.5, screen_y + 0.5, size, 0, 2. * M_PI);
+        cairo_fill (w_current->cr);
       }
       break;
 
@@ -287,11 +278,9 @@ void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
   int size, x2size;
 
   if (toplevel->override_color != -1 ) {
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(toplevel->override_color));
+    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->override_color));
   } else {
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(toplevel->junction_color));
+    gdk_cairo_set_source_color(w_current->cr, x_get_color(w_current->toplevel->junction_color));
   }
   
   cl_current = object->conn_list;
@@ -319,11 +308,8 @@ void o_cue_draw_lowlevel_midpoints(GSCHEM_TOPLEVEL *w_current, OBJECT *object)
         x2size = size * 2;
 
         if (toplevel->DONT_REDRAW == 0) {
-          gdk_draw_arc (w_current->drawable,
-                        w_current->gc, TRUE,
-                        screen_x - size,
-                        screen_y - size,
-                        x2size, x2size, 0, FULL_CIRCLE);
+          cairo_arc (w_current->cr, screen_x + 0.5, screen_y + 0.5, size, 0, 2. * M_PI);
+          cairo_fill (w_current->cr);
         }
         break;
     }
diff --git a/gschem/src/o_line.c b/gschem/src/o_line.c
index 2478807..803ff15 100644
--- a/gschem/src/o_line.c
+++ b/gschem/src/o_line.c
@@ -28,11 +28,6 @@
 #include <dmalloc.h>
 #endif
 
-typedef void (*DRAW_FUNC)( GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                           GdkCapStyle cap,
-                           gint x1, gint y1, gint x2, gint y2,
-                           gint line_width, gint length, gint space );
-
 /*! \brief Draw a line on screen.
  *  \par Function Description
  *  This function is used to draw a line on screen. The line is described
@@ -52,9 +47,7 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int x1, y1, x2, y2;
   int line_width, length, space;
   GdkColor *color;
-  GdkCapStyle line_end;
-  DRAW_FUNC draw_func = NULL;
-	
+
   if (o_current->line == NULL) {
     return;
   }
@@ -103,67 +96,16 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   if( line_width <= 0) {
     line_width = 1;
   }
-	
-  switch(o_current->line_end) {
-    case END_NONE:   line_end = GDK_CAP_BUTT;       break;
-    case END_SQUARE: line_end = GDK_CAP_PROJECTING; break;
-    case END_ROUND:  line_end = GDK_CAP_ROUND;      break;
-    default: fprintf(stderr, _("Unknown end for line (%d)\n"),
-                     o_current->line_end);
-    line_end = GDK_CAP_BUTT; 
-    break;
-  }
 
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
-	
-  switch(o_current->line_type) {
-    case TYPE_SOLID:
-      length = -1;
-      space = -1;
-      draw_func = o_line_draw_solid;
-      break;
-			
-    case TYPE_DOTTED:
-      length = -1; /* in ..._draw_dotted, length is unused */
-      draw_func = o_line_draw_dotted;
-      break;
-			
-    case TYPE_DASHED:
-      draw_func = o_line_draw_dashed;
-      break;
-			
-    case TYPE_CENTER:
-      draw_func = o_line_draw_center;
-      break;
-			
-    case TYPE_PHANTOM:
-      draw_func = o_line_draw_phantom;
-      break;
-			
-    case TYPE_ERASE:
-      break;
-			
-    default:
-      length = -1;
-      space = -1;
-      line_width = 0; /* just to be careful */
-      fprintf(stderr, _("Unknown type for line (%d) !\n"),
-              o_current->line_type);
-      draw_func = o_line_draw_solid;
-      break;
-  }
-
-  if((length == 0) || (space == 0))
-  draw_func = o_line_draw_solid;
 
-  (*draw_func) (w_current->drawable, w_current->gc, color, line_end,
-                x1, y1, x2, y2, line_width, length, space);
+  gschem_cairo_line (w_current->cr, o_current->line_end,
+                     line_width, x1, y1, x2, y2);
 
-  /* reset line width and reset back to default */
-  gdk_gc_set_line_attributes(w_current->gc, 0, GDK_LINE_SOLID,
-                             GDK_CAP_NOT_LAST,
-                             GDK_JOIN_MITER);
+  gdk_cairo_set_source_color (w_current->cr, color);
+  gschem_cairo_stroke (w_current->cr, o_current->line_type,
+                       o_current->line_end, line_width, length, space);
 
   if (o_current->selected && w_current->draw_grips) {
     o_line_draw_grips (w_current, o_current);
@@ -174,510 +116,6 @@ void o_line_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
 #endif
 }
 
-/*! \brief Draw a line with a solid line type.
- *  \par Function Description
- *  This function draws a line with a solid line type. The line is defined
- *  by the coordinates of its two extremities. The parameters <B>length</B>
- *  and <B>space</B> are unused here.
- *
- *  The line attributes are settled. Then it simply make a call to the
- *  gdk original function.
- *
- *  \param [in] w           GdkWindow to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Circle fill color. 
- *  \param [in] cap         GdkCapStype line end cap style.
- *  \param [in] x1          Upper x coordinate of Line.
- *  \param [in] y1          Upper y coordinate of Line.
- *  \param [in] x2          Lower x coordinate of Line.
- *  \param [in] y2          Lower y coordinate of Line.
- *  \param [in] line_width  Line width.
- *  \param [in] length      (unused).
- *  \param [in] space       (unused).
- */
-void o_line_draw_solid(GdkWindow *w, GdkGC *gc, GdkColor *color,
-		       GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2,
-		       gint line_width, gint length, gint space)
-{
-  gdk_gc_set_foreground(gc, color);
-
-  /* Set the width, end type and join style of the line */
-  gdk_gc_set_line_attributes(gc, line_width, GDK_LINE_SOLID,
-                             cap, GDK_JOIN_MITER);
-
-  /* Draw the line */
-  gdk_draw_line(w, gc, x1, y1, x2, y2);
-
-}
-
-/*! \brief Draw a line with a dotted line type.
- *  \par Function Description
- *  This function draw a line with a dotted line type. The parameter
- *  <B>space</B> represents the distance between two of the dots. The parameter
- *  <B>length</B> is unused. The diameter of the dots is given by the width
- *  of the line given by <B>line_width</B>.
- *
- *  The unit of <B>x1</B>, <B>y1</B> and <B>x2</B>, <B>y2</B> and
- *  <B>line_width</B>, <B>length</B>, <B>space</B> is pixel.
- *
- *  A negative of null value for length or space leads to an endless loop.
- *
- *  \param [in] w           GdkWindow to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Circle fill color. 
- *  \param [in] cap         GdkCapStype line end cap style.
- *  \param [in] x1          Upper x coordinate of Line.
- *  \param [in] y1          Upper y coordinate of Line.
- *  \param [in] x2          Lower x coordinate of Line.
- *  \param [in] y2          Lower y coordinate of Line.
- *  \param [in] line_width  Line width.
- *  \param [in] length      (unused).
- *  \param [in] space       Space between dots in pixels.
- */
-void o_line_draw_dotted(GdkWindow *w, GdkGC *gc, GdkColor *color,
-			GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2,
-			gint line_width, gint length, gint space)
-{
-  double dx, dy, l, d;
-  double dx1, dy1;
-  double xa, ya;
-
-  gdk_gc_set_foreground(gc, color);
-
-  /*
-   * It first finds the increments on x and y axis that match the space
-   * on the line between two dots.
-   *
-   * Starting from one of the end of the line and incrementing the position
-   * gives the coordinates of every dots on the line providing that the
-   * second extremities is not exceeded.
-   */
-  dx = (double) (x2 - x1);
-  dy = (double) (y2 - y1);
-  l = sqrt((dx * dx) + (dy * dy));
-
-  dx1 = (dx * space) / l;
-  dy1 = (dy * space) / l;
-
-  d = 0;
-  xa = x1; ya = y1;
-  while(d < l) {
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real world width is equal to 0, then the
-     * width is translated to 1 in screen coordinates. Drawing a circle with
-     * a 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */
-    if(line_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - line_width/2, 
-		   ((int) ya) - line_width/2,
-		   line_width, line_width, 0, FULL_CIRCLE);
-    }
-    
-    d = d + space;
-    xa = xa + dx1;
-    ya = ya + dy1;
-  }
-	
-}
-
-/*! \brief Draw a line with a dotted line type.
- *  \par Function Description
- *  This function draws a line with a dashed line type. The parameter
- *  <B>space</B> respresents the distance between two of the dashes. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The unit of <B>x1</B>, <B>y1</B> and <B>x2</B>, <B>y2</B> and
- *  <B>line_width</B>, <B>length</B>, <B>space</B> is pixel.
- *
- *  A negative of null value for length or space leads to an endless loop.
- *
- *  \param [in] w           GdkWindow to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Circle fill color. 
- *  \param [in] cap         GdkCapStype line end cap style.
- *  \param [in] x1          Upper x coordinate of Line.
- *  \param [in] y1          Upper y coordinate of Line.
- *  \param [in] x2          Lower x coordinate of Line.
- *  \param [in] y2          Lower y coordinate of Line.
- *  \param [in] line_width  Line width.
- *  \param [in] length      Length of dashes in pixels.
- *  \param [in] space       Space between dashes in pixels.
- */
-void o_line_draw_dashed(GdkWindow *w, GdkGC *gc, GdkColor *color,
-			GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2,
-			gint line_width, gint length, gint space)
-{
-  double dx, dy, l, d;
-  double dx1, dy1, dx2, dy2;
-  double xa, ya, xb, yb;
-
-  gdk_gc_set_foreground(gc, color);
-  gdk_gc_set_line_attributes(gc, line_width, GDK_LINE_SOLID,
-                             cap, GDK_JOIN_MITER);
-
-  /*
-   * The function determines the increments on x and y axis that match
-   * the space on the line between two dots. The same thing is done for length.
-   *
-   * Starting from one of the end of the line and incrementing the position
-   * gives the coordinates of every dots on the line providing that the
-   * second extremities is not exceeded. This is checked by first computing
-   * the distance between the two extremities and then checking whether this
-   * limit is exceeded by a new dash or not.
-   *
-   * It draws as many dashes of length <B>length</B> as possible.
-   */
-  dx = (double) (x2 - x1);
-  dy = (double) (y2 - y1);
-  l = sqrt((dx * dx) + (dy * dy));
-
-  dx1 = (dx * length) / l;
-  dy1 = (dy * length) / l;
-
-  dx2 = (dx * space) / l;
-  dy2 = (dy * space) / l;
-  
-  d = 0;
-  xa = x1; ya = y1;
-  while((d + length + space) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-		
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-
-  }
-
-  /*
-   * When the above condition is not satisfied, then it is not possible
-   * to draw a dash of length <B>length</B>. However it may be possible to
-   * draw a shorter dash.
-   */
-  if((d + length) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-  } else {
-    xb = x2;
-    yb = y2;
-  }
-
-  gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-
-}
-
-/*! \brief Draw line with a centered line type.
- *  \par Function Description.
- *  This function draws a line with a centered line type. The parameter
- *  <B>space</B> represents the distance between a dot and the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  The unit of <B>x1</B>, <B>y1</B> and <B>x2</B>, <B>y2</B> and
- *  <B>line_width</B>, <B>length</B>, <B>space</B> is pixel.
- *
- *  A negative of null value for length or space leads to an endless loop.
- *
- *  \param [in] w           GdkWindow to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Circle fill color. 
- *  \param [in] cap         GdkCapStype line end cap style.
- *  \param [in] x1          Upper x coordinate of Line.
- *  \param [in] y1          Upper y coordinate of Line.
- *  \param [in] x2          Lower x coordinate of Line.
- *  \param [in] y2          Lower y coordinate of Line.
- *  \param [in] line_width  Line width.
- *  \param [in] length      Length of dashes in pixels.
- *  \param [in] space       Space between dashes in pixels.
- */
-void o_line_draw_center(GdkWindow *w, GdkGC *gc, GdkColor *color,
-			GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2,
-			gint line_width, gint length, gint space)
-{
-  double dx, dy, l, d;
-  double dx1, dy1, dx2, dy2;
-  double xa, ya, xb, yb;
-
-  gdk_gc_set_foreground(gc, color);
-  gdk_gc_set_line_attributes(gc, line_width, GDK_LINE_SOLID,
-                             cap, GDK_JOIN_MITER);
-
-  /*
-   * The function determines the increments on x and y axis that match
-   * the space on the line between two dots. The same thing is done for length.
-   *
-   * Starting from one of the end of the line and incrementing the position
-   * gives the coordinates of every dots and dashes on the line providing
-   * that the second extremity is not exceeded. This is checked by first
-   * computing the distance between the two extremities and then checking
-   * whether this limit is exceeded by a new dash or not.
-   *
-   * It draws as many sets of 'dash of length <B>length</B> and dot' as possible.
-   */
-  dx = (double) (x2 - x1);
-  dy = (double) (y2 - y1);
-  l = sqrt((dx * dx) + (dy * dy));
-
-  dx1 = (dx * length) / l;
-  dy1 = (dy * length) / l;
-
-  dx2 = (dx * space) / l;
-  dy2 = (dy * space) / l;
-	
-  d = 0;
-  xa = x1; ya = y1;
-  while((d + length + 2 * space) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-		
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a different
-     * manner : if the real world width is equal to 0, then the width is
-     * translated to 1 in screen coordinates. Drawing a circle with a
-     * 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */
-  if(line_width == 1) {
-	gdk_draw_point(w, gc, (int) xa, (int) ya);
-  } else {
-	gdk_draw_arc(w, gc, TRUE,
-	     ((int) xa) - line_width/2, 
-	     ((int) ya) - line_width/2,
-	     line_width, line_width, 0, FULL_CIRCLE);
-  }
-
-		
-        d = d + space;
-    xa = xa + dx2;
-    ya = ya + dy2;
-  }
-}
-
-
-/*! \brief Draw a line with a phantom line type.
- *  \par Function Description
- *  This function draws a line with a phantom line type. The parameter
- *  <B>space</B> represents the distance between a dot and a dash. The parameter
- *  <B>length</B> represents the length of a dash.
- *
- *  The unit of <B>x1</B>, <B>y1</B> and <B>x2</B>, <B>y2</B> and
- *  <B>line_width</B>, <B>length</B>, <B>space</B> is pixel.
- *
- *  A negative of null value for length or space leads to an endless loop.
- *
- *  \param [in] w           GdkWindow to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Circle fill color. 
- *  \param [in] cap         GdkCapStype line end cap style.
- *  \param [in] x1          Upper x coordinate of Line.
- *  \param [in] y1          Upper y coordinate of Line.
- *  \param [in] x2          Lower x coordinate of Line.
- *  \param [in] y2          Lower y coordinate of Line.
- *  \param [in] line_width  Line width.
- *  \param [in] length      Length of dashes in pixels.
- *  \param [in] space       Space between dashes in pixels.
- */
-void o_line_draw_phantom(GdkWindow *w, GdkGC *gc, GdkColor *color,
-			 GdkCapStyle cap, gint x1, gint y1, gint x2, gint y2,
-			 gint line_width, gint length, gint space)
-{
-  double dx, dy, l, d; 
-  double dx1, dy1, dx2, dy2;
-  double xa, ya, xb, yb;
-
-  gdk_gc_set_foreground(gc, color);
-  gdk_gc_set_line_attributes(gc, line_width, GDK_LINE_SOLID,
-			     cap, GDK_JOIN_MITER);
-
-  /*
-   * The function determines the increments on x and y axis that match
-   * the space on the line between two dots. The same thing is done for length.
-   *
-   * Starting from one of the end of the line and incrementing the position
-   * gives the coordinates of every dots and dashes on the line providing
-   * that the second extremity is not exceeded. This is checked by first
-   * computing the distance between the two extremities and then checking
-   * whether this limit is exceeded by a new dash or not.
-   *
-   * It draws as many sets of 'dash of length <B>length</B> and two dots'
-   * as possible.
-   */
-  dx = (double) (x2 - x1);
-  dy = (double) (y2 - y1);
-  l = sqrt((dx * dx) + (dy * dy));
-
-  dx1 = (dx * length) / l;
-  dy1 = (dy * length) / l;
-
-  dx2 = (dx * space) / l;
-  dy2 = (dy * space) / l;
-	
-  d = 0;
-  xa = x1; ya = y1;
-  while((d + length + 3 * space) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-		
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-
-    
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real world width is equal to 0, then the
-     * width is translated to 1 in screen coordinates. Drawing a circle with
-     * a 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */
-    if(line_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - line_width/2, 
-		   ((int) ya) - line_width/2,
-		   line_width, line_width, 0, FULL_CIRCLE);
-    }
-    
-    d = d + space;
-    xa = xa + dx2;
-    ya = ya + dy2;
-
-    /*
-     * Depending on the width of the line, dots has to be drawn in a different
-     * manner : if the real world width is equal to 0, then the width is
-     * translated to 1 in screen coordinates. Drawing a circle with a
-     * 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */
-    
-    if(line_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - line_width/2, 
-		   ((int) ya) - line_width/2,
-		   line_width, line_width, 0, FULL_CIRCLE);
-    }
-    
-    d = d + space;
-    xa = xa + dx2;
-    ya = ya + dy2;
-  }
-  
-  /*
-   * If the above condition is not satisfied, it may still be possible to
-   * continue drawing a part of the original pattern.
-   * Here three cases are possible :
-   * <DL>
-   *   <DT>*</DT><DD>it is possible to draw a dash and the two dots.
-   *   <DT>*</DT><DD>it is possible to draw a dash and one of the two dots.
-   *   <DT>*</DT><DD>it is possible to draw at least a part of the initial
-   *                 dash.
-   * </DL>
-   */
-
-  if((d + length + 2 * space) < l) {
-    d = d + length;
-    xb = xa + dx1;
-    yb = ya + dy1;
-    gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-    
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-    
-    /*
-     * Depending on the width of the line, dots has to be drawn in a
-     * different manner : if the real world width is equal to 0, then the
-     * width is translated to 1 in screen coordinates. Drawing a circle with
-     * a 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */  
-    if(line_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - line_width/2, 
-		   ((int) ya) - line_width/2,
-		   line_width, line_width, 0, FULL_CIRCLE);
-    }
-
-    d = d + space;
-    xa = xb + dx2;
-    ya = yb + dy2;
-
-    
-    /*
-     * Depending on the width of the line, dots has to be drawn in a different
-     * manner : if the real world width is equal to 0, then the width is
-     * translated to 1 in screen coordinates. Drawing a circle with a
-     * 1-diameter and the GDK function #gdk_draw_arc() is not possible.
-     * So we needs to test whether the width is 1 or not.
-     */  
-    if(line_width == 1) {
-      gdk_draw_point(w, gc, (int) xa, (int) ya);
-    } else {
-      gdk_draw_arc(w, gc, TRUE,
-		   ((int) xa) - line_width/2, 
-		   ((int) ya) - line_width/2,
-		   line_width, line_width, 0, FULL_CIRCLE);
-    }
-  } else {
-    if(d + length + space < l) {
-      d = d + length;
-      xb = xa + dx1;
-      yb = ya + dy1;
-      gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-      
-      d = d + space;
-      xa = xb + dx2;
-      ya = yb + dy2;
-      
-      /*
-       * Depending on the width of the line, dots has to be drawn in a
-       * different manner : if the real world width is equal to 0, then the
-       * width is translated to 1 in screen coordinates. Drawing a circle
-       * with a 1-diameter and the GDK function #gdk_draw_arc() is not
-       * possible. So we needs to test whether the width is 1 or not.
-       */
-      if(line_width == 1) {
-	gdk_draw_point(w, gc, (int) xa, (int) ya);
-      } else {
-	gdk_draw_arc(w, gc, TRUE,
-		     ((int) xa) - line_width/2, 
-		     ((int) ya) - line_width/2,
-		     line_width, line_width, 0, FULL_CIRCLE);
-      }
-    } else {
-      if(d + length < l) {
-	xb = xa + dx1;
-	yb = ya + dy1;
-      } else {
-	xb = x2;
-	yb = y2;
-      }	
-      gdk_draw_line(w, gc, (int) xa, (int) ya, (int) xb, (int) yb);
-    }
-  }
-}
-
 
 /*! \todo Finish function documentation
  *  \brief
diff --git a/gschem/src/o_net.c b/gschem/src/o_net.c
index 479b880..64c6131 100644
--- a/gschem/src/o_net.c
+++ b/gschem/src/o_net.c
@@ -99,67 +99,31 @@ void o_net_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing net\n\n");
 #endif
 
+  size = 1;
+
   if (toplevel->net_style == THICK ) {
     size = SCREENabs(toplevel, NET_WIDTH);
 
-    if (size < 0)
-      size=0;
-
-    gdk_gc_set_line_attributes(w_current->gc, size, 
-                               GDK_LINE_SOLID,
-                               GDK_CAP_BUTT,
-                               GDK_JOIN_MITER);
-
-    gdk_gc_set_line_attributes(w_current->bus_gc, size, 
-                               GDK_LINE_SOLID,
-                               GDK_CAP_BUTT,
-                               GDK_JOIN_MITER);
+    if (size < 1)
+      size=1;
   }
 
-  if (toplevel->override_color != -1 ) {
-
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(toplevel->override_color));
+  cairo_set_line_width (w_current->cr, size);
+  cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_SQUARE);
 
-    gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
+  if (toplevel->override_color != -1 ) {
+    gdk_cairo_set_source_color (w_current->cr, x_get_color(toplevel->override_color));
   } else {
-
-    gdk_gc_set_foreground(w_current->gc,
-                          x_get_color(o_current->color));
-    gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
-
-#if NET_DEBUG
-    /* temp debug only */
-    font = gdk_fontset_load ("10x20");
-    tempstring = g_strdup_printf("%s", o_current->name);
-    gdk_draw_text (w_current->drawable,
-                   font,
-                   w_current->gc,
-                   x1+20, y1+20,
-                   tempstring,
-                   strlen(tempstring));
-    gdk_font_unref(font);
-    g_free(tempstring);
-#endif
+    gdk_cairo_set_source_color (w_current->cr, x_get_color(o_current->color));
   }
 
+  gschem_cairo_line (w_current->cr, END_SQUARE, size, x1, y1, x2, y2);
+  cairo_stroke (w_current->cr);
+
 #if DEBUG 
   printf("drew net\n\n");
 #endif
 
-  /* yes zero is right for the width -> use hardware lines */
-  if (toplevel->net_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->gc, 0, 
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-
-    gdk_gc_set_line_attributes(w_current->bus_gc, 0, 
-                               GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
   if (o_current->selected && w_current->draw_grips) {
     o_line_draw_grips (w_current, o_current);
   }
diff --git a/gschem/src/o_path.c b/gschem/src/o_path.c
index 0b6951e..fa50a44 100644
--- a/gschem/src/o_path.c
+++ b/gschem/src/o_path.c
@@ -21,6 +21,7 @@
 
 #include <stdio.h>
 #include <math.h>
+#include <cairo.h>
 
 #include "gschem.h"
 
@@ -31,17 +32,20 @@
 #define NUM_BEZIER_SEGMENTS 100
 
 
-typedef void (*DRAW_FUNC) (GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                           GSCHEM_TOPLEVEL *w_current, PATH *path,
-                           GdkCapStyle cap,
-                           gint line_width, gint length, gint space);
-
 typedef void (*FILL_FUNC) (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                            GSCHEM_TOPLEVEL *w_currentm, PATH *path,
                            gint fill_width,
                            gint angle1, gint pitch1, gint angle2, gint pitch2);
 
 
+static void hint_coordinates (int x, int y, double *fx, double *fy, int width)
+{
+  double offset = ((width % 2) == 0) ? 0 : 0.5;
+  *fx = (double)x + offset;
+  *fy = (double)y + offset;
+}
+
+
 static void path_to_points_modify (GSCHEM_TOPLEVEL *w_current, PATH *path,
                                    int dx, int dy, int new_x, int new_y, int whichone,
                                    GdkPoint **points, int *num_points)
@@ -187,103 +191,6 @@ void o_path_draw_solid(GdkDrawable *w, GdkGC *gc, GdkColor *color,
   g_free (points);
 }
 
-/*! \brief Draw a path with a dotted line type.
- *  \par Function Description
- *  This function draws a path with a dotted line type. The parameter
- *  <B>space</B> represents the distance between two of the dots. The
- *  parameter <B>length</B> is unused. The diameter of the dots is given by
- *  the width of the line given by <B>width</B>.
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] path        The PATH object to draw
- *  \param [in] line_width  Width of line to draw path.
- *  \param [in] length      (unused)
- *  \param [in] space       Space in pixels between dots.
- */
-
-static void o_path_draw_dotted (GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                                GSCHEM_TOPLEVEL *w_current, PATH *path,
-                                GdkCapStyle cap, gint line_width,
-                                gint length, gint space)
-{
-  o_path_draw_solid (w, gc, color, w_current, path, cap,
-                     line_width, length, space);
-}
-
-/*! \brief Draw a path with a dashed line type.
- *  \par Function Description
- *  This function draws a path with a dashed line type. The parameter
- *  <B>space</B> represents the distance between two of the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] path        The PATH object to draw
- *  \param [in] line_width  Width of line to draw path.
- *  \param [in] length      Length of dash in pixels.
- *  \param [in] space       Space between dashes in pixels.
- */
-static void o_path_draw_dashed (GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                                GSCHEM_TOPLEVEL *w_current, PATH *path,
-                                GdkCapStyle cap, gint line_width,
-                                gint length, gint space)
-{
-  o_path_draw_solid (w, gc, color, w_current, path, cap,
-                     line_width, length, space);
-}
-
-/*! \brief Draw a path with a centered line type.
- *  \par Function Description
- *  This function draws a path with a centered line type. The parameter
- *  <B>space</B> represents the distance between a dot and the dash. The
- *  parameter <B>length</B> represents the length of a dash.
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] path        The PATH object to draw
- *  \param [in] line_width  Width of line to draw path.
- *  \param [in] length      (unused)?
- *  \param [in] space       (unused)?
- */
-static void o_path_draw_center (GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                                GSCHEM_TOPLEVEL *w_current, PATH *path,
-                                GdkCapStyle cap, gint line_width,
-                                gint length, gint space)
-{
-  o_path_draw_solid (w, gc, color, w_current, path, cap,
-                     line_width, length, space);
-}
-
-/*! \brief Draw a path with a phantom line type.
- *  \par Function Description
- *  This function draws a path with a phantom line type. The parameter
- *  <B>space</B> represents the distance between a dot and a dash.
- *  The parameter <B>length</B> represents the length of a dash.
- *
- *  \param [in] w           GdkDrawable to draw in.
- *  \param [in] gc          GdkGC graphics context to draw on.
- *  \param [in] color       Box line color.
- *  \param [in] cap         Box line end cap type (unused).
- *  \param [in] path        The PATH object to draw
- *  \param [in] line_width  Width of line to draw path.
- *  \param [in] length      (unused)?
- *  \param [in] space       (unused)?
- */
-static void o_path_draw_phantom (GdkDrawable *w, GdkGC *gc, GdkColor *color,
-                                 GSCHEM_TOPLEVEL *w_current, PATH *path,
-                                 GdkCapStyle cap, gint line_width,
-                                 gint length, gint space)
-{
-  o_path_draw_solid (w, gc, color, w_current, path, cap,
-                     line_width, length, space);
-}
 
 /*! \brief Placeholder filling function.
  *  \par Function Description
@@ -333,23 +240,7 @@ static void o_path_fill_fill (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                               gint angle1, gint pitch1,
                               gint angle2, gint pitch2)
 {
-  GdkPoint *points;
-  int num_points;
-
-  gdk_gc_set_foreground(gc, color);
-  gdk_gc_set_line_attributes(gc, 1, GDK_LINE_SOLID,
-                             GDK_CAP_BUTT, GDK_JOIN_MITER);
-  path_to_points (w_current, path, 0, 0, &points, &num_points);
-
-  if (num_points == 0) {
-    g_free (points);
-    return;
-  }
-
-  gdk_draw_polygon (w_current->drawable, w_current->gc,
-                    TRUE, points, num_points);
-
-  g_free (points);
+  /* NOP: We'll fill it when we do the stroking */
 }
 
 /*! \brief Fill inside of path with single line pattern.
@@ -380,8 +271,9 @@ static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
   int i;
   GArray *lines;
 
-  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
+  gdk_cairo_set_source_color (w_current->cr, color);
 
+  lines = g_array_new (FALSE, FALSE, sizeof (LINE));
   m_hatch_path (path, angle1, pitch1, lines);
 
   for (i=0; i < lines->len; i++) {
@@ -390,8 +282,9 @@ static void o_path_fill_hatch (GdkDrawable *w, GdkGC *gc, GdkColor *color,
 
     WORLDtoSCREEN (w_current->toplevel, line->x[0], line->y[0], &x1, &y1);
     WORLDtoSCREEN (w_current->toplevel, line->x[1], line->y[1], &x2, &y2);
-    o_line_draw_solid (w, gc, color, GDK_CAP_BUTT,
-                       x1, y1, x2, y2, fill_width, -1, -1);
+    gschem_cairo_line (w_current->cr, END_NONE, fill_width, x1, y1, x2, y2);
+    gschem_cairo_stroke (w_current->cr, TYPE_SOLID, END_NONE,
+                                        fill_width, -1, -1);
   }
 
   g_array_free (lines, TRUE);
@@ -430,6 +323,7 @@ static void o_path_fill_mesh (GdkDrawable *w, GdkGC *gc, GdkColor *color,
                      fill_width, angle2, pitch2, -1, -1);
 }
 
+
 /*! \brief Draw a path on screen.
  *  \par Function Description
  *  This function is used to draw a path on screen. The path is described
@@ -447,11 +341,15 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   int wleft, wtop, wright, wbottom;
   int line_width, length, space;
   int fill_width, angle1, pitch1, angle2, pitch2;
-  DRAW_FUNC draw_func = NULL;
   FILL_FUNC fill_func;
+  PATH_SECTION *section;
+  int i;
+  int x1, y1, x2, y2, x3, y3;
+  double fx1 = 0.0, fy1 = 0.0;
+  double fx2 = 0.0, fy2 = 0.0;
+  double fx3 = 0.0, fy3 = 0.0;
 
   GdkColor *color;
-  GdkCapStyle path_end;
 
   if (path == NULL) {
     return;
@@ -475,63 +373,9 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
     line_width = 1;
   }
 
-  switch(o_current->line_end) {
-    case END_NONE:   path_end = GDK_CAP_BUTT;       break;
-    case END_SQUARE: path_end = GDK_CAP_PROJECTING; break;
-    case END_ROUND:  path_end = GDK_CAP_ROUND;      break;
-    default:
-      fprintf(stderr, _("Unknown end for path (%d)\n"),
-                      o_current->line_end);
-      path_end = GDK_CAP_BUTT;
-    break;
-  }
-
   length = SCREENabs( toplevel, o_current->line_length );
   space = SCREENabs( toplevel, o_current->line_space );
 
-  switch(o_current->line_type) {
-    case TYPE_SOLID:
-      length = -1;
-      space = -1;
-      draw_func = o_path_draw_solid;
-      break;
-
-    case TYPE_DOTTED:
-      length = -1; /* ..._draw_dotted only space is used */
-      draw_func = o_path_draw_dotted;
-      break;
-
-    case TYPE_DASHED:
-      draw_func = o_path_draw_dashed;
-      break;
-
-    case TYPE_CENTER:
-      draw_func = o_path_draw_center;
-      break;
-
-    case TYPE_PHANTOM:
-      draw_func = o_path_draw_phantom;
-      break;
-
-    case TYPE_ERASE:
-      break;
-
-    default:
-      length = -1;
-      space = -1;
-      line_width = 0; /* just to be careful */
-      draw_func = o_path_draw_solid;
-      fprintf(stderr, _("Unknown type for path !\n"));
-      break;
-  }
-
-  if((length == 0) || (space == 0))
-  draw_func = o_path_draw_solid;
-
-  (*draw_func) (w_current->drawable, w_current->gc, color, w_current,
-                o_current->path, path_end, line_width, length, space);
-
-
   /*
    * The values needed for the fill operation are taken from the
    * <B>o_current</B> pointed OBJECT. It include the type of fill required,
@@ -601,6 +445,54 @@ void o_path_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   (*fill_func) (w_current->drawable, w_current->gc, color,
                 w_current, path, fill_width, angle1, pitch1, angle2, pitch2);
 
+  for (i = 0; i <  path->num_sections; i++) {
+    section = &path->sections[i];
+
+    switch (section->code) {
+      case PATH_CURVETO:
+        /* Two control point grips */
+        WORLDtoSCREEN (toplevel, section->x1, section->y1, &x1, &y1);
+        WORLDtoSCREEN (toplevel, section->x2, section->y2, &x2, &y2);
+        hint_coordinates (x1, y1, &fx1, &fy1, line_width);
+        hint_coordinates (x2, y2, &fx2, &fy2, line_width);
+        /* Fall through */
+      case PATH_MOVETO:
+      case PATH_MOVETO_OPEN:
+      case PATH_LINETO:
+        /* Destination point grip */
+        WORLDtoSCREEN (toplevel, section->x3, section->y3, &x3, &y3);
+        hint_coordinates (x3, y3, &fx3, &fy3, line_width);
+      case PATH_END:
+        break;
+    }
+
+    switch (section->code) {
+      case PATH_MOVETO:
+        cairo_close_path (w_current->cr);
+        /* fall-through */
+      case PATH_MOVETO_OPEN:
+        cairo_move_to (w_current->cr, fx3, fy3);
+        break;
+      case PATH_CURVETO:
+        cairo_curve_to (w_current->cr, fx1, fy1, fx2, fy2, fx3, fy3);
+        break;
+      case PATH_LINETO:
+        cairo_line_to (w_current->cr, fx3, fy3);
+        break;
+      case PATH_END:
+        cairo_close_path (w_current->cr);
+        break;
+    }
+  }
+
+  gdk_cairo_set_source_color (w_current->cr, color);
+
+  if (o_current->fill_type == FILLING_FILL)
+    cairo_fill_preserve (w_current->cr);
+
+  gschem_cairo_stroke (w_current->cr, o_current->line_type,
+                       o_current->line_end, line_width, length, space);
+
   if (o_current->selected && w_current->draw_grips) {
     o_path_draw_grips (w_current, o_current);
   }
diff --git a/gschem/src/o_pin.c b/gschem/src/o_pin.c
index def222c..0163773 100644
--- a/gschem/src/o_pin.c
+++ b/gschem/src/o_pin.c
@@ -38,6 +38,7 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   TOPLEVEL *toplevel = w_current->toplevel;
   int size;
   int x1, y1, x2, y2; /* screen coords */
+  GdkColor *color;
 
   if (o_current->line == NULL) {
     return;
@@ -53,35 +54,31 @@ void o_pin_draw(GSCHEM_TOPLEVEL *w_current, OBJECT *o_current)
   printf("drawing pin\n\n");
 #endif
 
-  if (toplevel->pin_style == THICK ) {
-    size = SCREENabs(toplevel, PIN_WIDTH);
-    gdk_gc_set_line_attributes(w_current->gc, size, GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
-
   if (toplevel->override_color != -1 ) {
-    gdk_gc_set_foreground(w_current->gc,
-			  x_get_color(toplevel->override_color));
-    if (toplevel->DONT_REDRAW == 0) {
-      gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
-    }
+    color = x_get_color(toplevel->override_color);
   } else {
-    if (toplevel->DONT_REDRAW == 0) {
-      gdk_gc_set_foreground(w_current->gc, x_get_color(o_current->color));
-      gdk_draw_line (w_current->drawable, w_current->gc, x1, y1, x2, y2);
+    color = x_get_color(o_current->color);
+  }
+
+  if (toplevel->DONT_REDRAW == 0) {
+    size = 1;
+    if (toplevel->pin_style == THICK) {
+      size = SCREENabs(toplevel, PIN_WIDTH);
+      if (size < 1)
+        size=1;
     }
+
+    cairo_set_line_width (w_current->cr, size);
+    cairo_set_line_cap (w_current->cr, CAIRO_LINE_CAP_BUTT);
+
+    gdk_cairo_set_source_color (w_current->cr, color);
+
+    gschem_cairo_line (w_current->cr, END_NONE, size, x1, y1, x2, y2);
+    cairo_stroke (w_current->cr);
   }
 
   /* draw the cue directly */
   o_cue_draw_lowlevel(w_current, o_current, o_current->whichend);
-  
-  /* yes zero is right for the width -> use hardware lines */
-  if (toplevel->pin_style == THICK ) {
-    gdk_gc_set_line_attributes(w_current->gc, 0, GDK_LINE_SOLID,
-                               GDK_CAP_NOT_LAST,
-                               GDK_JOIN_MITER);
-  }
 
 #if DEBUG
   printf("drawing pin\n");
diff --git a/gschem/src/x_event.c b/gschem/src/x_event.c
index 80a5e9f..f0ebf63 100644
--- a/gschem/src/x_event.c
+++ b/gschem/src/x_event.c
@@ -61,6 +61,9 @@ gint x_event_expose(GtkWidget *widget, GdkEventExpose *event,
   /* nasty global variable */
   global_window_current = w_current;
 
+  if (w_current->cr != NULL) cairo_destroy( w_current->cr );
+  w_current->cr = gdk_cairo_create( widget->window );
+
   gdk_region_get_rectangles (event->region, &rectangles, &n_rectangles);
   o_redraw_rects (w_current, rectangles, n_rectangles);
   g_free (rectangles);
diff --git a/gschem/src/x_image.c b/gschem/src/x_image.c
index 696247f..857075e 100644
--- a/gschem/src/x_image.c
+++ b/gschem/src/x_image.c
@@ -657,6 +657,8 @@ GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current)
 
   new_w_current.window = gdk_pixmap_new (w_current->window, size_x, size_y, -1);
   new_w_current.drawable = new_w_current.window;
+  new_w_current.cr = gdk_cairo_create (new_w_current.window);
+
   new_w_current.grid = 0;
   new_w_current.text_origin_marker = FALSE;
 
@@ -735,6 +737,7 @@ GdkPixbuf *x_image_get_pixbuf (GSCHEM_TOPLEVEL *w_current)
     x_image_convert_to_greyscale(pixbuf); 
   }
 
+  if (new_w_current.cr != NULL) cairo_destroy (new_w_current.cr);
   if (new_w_current.window != NULL) {
     g_object_unref(new_w_current.window);
   }
diff --git a/gschem/src/x_preview.c b/gschem/src/x_preview.c
index 63098d5..9047abe 100644
--- a/gschem/src/x_preview.c
+++ b/gschem/src/x_preview.c
@@ -124,6 +124,9 @@ preview_callback_expose (GtkWidget *widget,
   GdkRectangle *rectangles;
   int n_rectangles;
 
+  if (preview_w_current->cr != NULL) cairo_destroy (preview_w_current->cr);
+  preview_w_current->cr = gdk_cairo_create (widget->window);
+
   gdk_region_get_rectangles (event->region, &rectangles, &n_rectangles);
   o_redraw_rects (preview_w_current, rectangles, n_rectangles);
   g_free (rectangles);

commit 95abdb28b1ededc4a57f13627bea544c8a7fe41b
Author: Peter Clifton <pcjc2@xxxxxxxxx>
Date:   Wed Dec 24 13:21:00 2008 +0000

    Add a cairo context member, cairo_t *cr to GSCHEM_TOPLEVEL

diff --git a/gschem/include/gschem_struct.h b/gschem/include/gschem_struct.h
index 324693e..df4386d 100644
--- a/gschem/include/gschem_struct.h
+++ b/gschem/include/gschem_struct.h
@@ -82,6 +82,7 @@ struct st_gschem_toplevel {
   /* ---------------- */
   GdkWindow *window;                    /* drawing_area's X drawable */
   GdkPixmap *drawable;                  /* drawable to paint onto */
+  cairo_t *cr;                          /* Cairo surface */
   int win_width, win_height;            /* Actual size of window (?) */
 
   /* ------------- */
diff --git a/gschem/src/gschem_toplevel.c b/gschem/src/gschem_toplevel.c
index 1b66a00..d5ab97d 100644
--- a/gschem/src/gschem_toplevel.c
+++ b/gschem/src/gschem_toplevel.c
@@ -100,6 +100,7 @@ GSCHEM_TOPLEVEL *gschem_toplevel_new ()
   /* ---------------- */
   w_current->window = NULL;
   w_current->drawable = NULL;
+  w_current->cr = NULL;
   w_current->win_width = 0;
   w_current->win_height = 0;
 




_______________________________________________
geda-cvs mailing list
geda-cvs@xxxxxxxxxxxxxx
http://www.seul.org/cgi-bin/mailman/listinfo/geda-cvs