Index: gdk/win32/gdkdrawable-win32.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkdrawable-win32.c,v
retrieving revision 1.71.2.3
diff -p -u -2 -r1.71.2.3 gdkdrawable-win32.c
--- gdk/win32/gdkdrawable-win32.c	26 May 2005 07:54:32 -0000	1.71.2.3
+++ gdk/win32/gdkdrawable-win32.c	21 Jun 2005 19:52:18 -0000
@@ -309,5 +309,5 @@ render_line_horizontal (GdkGCWin32 *gcwi
     }
 
-  if (gcwin32->pen_double_dash)
+  if (gcwin32->line_style == GDK_LINE_DOUBLE_DASH)
     {
       HBRUSH hbr;
@@ -379,5 +379,5 @@ render_line_vertical (GdkGCWin32 *gcwin3
     }
 
-  if (gcwin32->pen_double_dash)
+  if (gcwin32->line_style == GDK_LINE_DOUBLE_DASH)
     {
       HBRUSH hbr;
@@ -844,5 +844,5 @@ draw_rectangle (GdkGCWin32 *gcwin32,
   y -= y_offset;
 
-  if (!filled && (gcwin32->pen_double_dash ||
+  if (!filled && (gcwin32->line_style == GDK_LINE_DOUBLE_DASH ||
                   (gcwin32->pen_dashes && (gcwin32->pen_dash_offset ||
 					   !G_WIN32_IS_NT_BASED ()))))
@@ -1295,5 +1295,5 @@ draw_segments (GdkGCWin32 *gcwin32,
     }
 
-  if (gcwin32->pen_double_dash ||
+  if (gcwin32->line_style == GDK_LINE_DOUBLE_DASH ||
       (gcwin32->pen_dashes && (gcwin32->pen_dash_offset ||
 			       !G_WIN32_IS_NT_BASED ())))
@@ -1326,5 +1326,4 @@ draw_segments (GdkGCWin32 *gcwin32,
 	    GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
 	      GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2));
-
 	}
     }
@@ -1332,34 +1331,15 @@ draw_segments (GdkGCWin32 *gcwin32,
     {
       for (i = 0; i < nsegs; i++)
-	GDI_CALL (MoveToEx, (hdc, segs[i].x1, segs[i].y1, NULL)) &&
-	  GDI_CALL (LineTo, (hdc, segs[i].x2, segs[i].y2));
-
-      /* not drawing the end pixel does produce a crippled mask, look 
-       * e.g. at xpm icons produced with gdk_pixbuf_new_from_xpm_data trough
-       * gdk_pixbuf_render_threshold_alpha (testgtk folder icon or
-       * Dia's toolbox icons) but only on win9x ... --hb
-       *
-       * Update : see bug #81895 and bug #126710 why this is finally
-       *          needed on any win32 platform ;-)
-       */
-      if (gcwin32->pen_width <= 1)
-        {
-          GdkSegment *ps = &segs[nsegs-1];
-          int xc = 0, yc = 0;
-
-          if (ps->y2 == ps->y1 && ps->x2 == ps->x1)
-            xc = 1; /* just a point */
-          else if (ps->y2 == ps->y1)
-            xc = (ps->x1 < ps->x2) ? 1 : -1; /* advance x only */
-          else if (ps->x2 == ps->x1)
-            yc = (ps->y1 < ps->y2) ? 1 : -1; /* advance y only */
-          else
-            {
-              xc = (ps->x1 < ps->x2) ? 1 : -1;
-              yc = (ps->y1 < ps->y2) ? 1 : -1;
-            }
+	{
+	  const GdkSegment *ps = &segs[i];
+	  const int x1 = ps->x1, y1 = ps->y1;
+	  int x2 = ps->x2, y2 = ps->y2;
+
+	  GDK_NOTE (MISC, g_print (" +%d+%d..+%d+%d", x1, y1, x2, y2));
+	  GDI_CALL (MoveToEx, (hdc, x1, y1, NULL)) &&
+	    GDI_CALL (LineTo, (hdc, x2, y2));
+	}
 
-          GDI_CALL (LineTo, (hdc, ps->x2 + xc, ps->y2 + yc));
-        }
+      GDK_NOTE (MISC, g_print ("\n"));
     }
   if (x_offset != 0 || y_offset != 0)
@@ -1404,6 +1384,5 @@ gdk_win32_draw_segments (GdkDrawable *dr
   region = widen_bounds (&bounds, GDK_GC_WIN32 (gc)->pen_width);
 
-  generic_draw (drawable, gc, GDK_GC_FOREGROUND | GDK_GC_FOREGROUND |
-			      LINE_ATTRIBUTES,
+  generic_draw (drawable, gc, GDK_GC_FOREGROUND | LINE_ATTRIBUTES,
 		draw_segments, region, segs, nsegs);
 
@@ -1432,5 +1411,5 @@ draw_lines (GdkGCWin32 *gcwin32,
       }
   
-  if (gcwin32->pen_double_dash ||
+  if (gcwin32->line_style == GDK_LINE_DOUBLE_DASH ||
       (gcwin32->pen_dashes && (gcwin32->pen_dash_offset ||
 			       !G_WIN32_IS_NT_BASED ())))
Index: gdk/win32/gdkgc-win32.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkgc-win32.c,v
retrieving revision 1.64.2.2
diff -p -u -2 -r1.64.2.2 gdkgc-win32.c
--- gdk/win32/gdkgc-win32.c	11 Mar 2005 23:45:53 -0000	1.64.2.2
+++ gdk/win32/gdkgc-win32.c	21 Jun 2005 19:52:20 -0000
@@ -121,4 +121,70 @@ gdk_gc_win32_finalize (GObject *object)
 
 static void
+fix_pen (GdkGCWin32 *win32_gc)
+{
+  win32_gc->pen_style = 0;
+
+  if (win32_gc->pen_width == 0 &&
+      win32_gc->cap_style == GDK_CAP_NOT_LAST)
+    {
+      /* Use a cosmetic pen, always width 1 */
+      win32_gc->pen_style |= PS_COSMETIC;
+    }
+  else if (win32_gc->pen_width <= 1 &&
+	   win32_gc->cap_style == GDK_CAP_BUTT)
+    {
+      /* For 1 pixel wide lines PS_ENDCAP_ROUND means draw both ends,
+       * even for one pixel length lines. But if we are drawing dashed
+       * lines we can't use PS_ENDCAP_ROUND.
+       */
+      if (win32_gc->line_style == GDK_LINE_SOLID)
+	win32_gc->pen_style |= PS_GEOMETRIC | PS_ENDCAP_ROUND;
+      else
+	win32_gc->pen_style |= PS_GEOMETRIC | PS_ENDCAP_FLAT;
+    }
+  else
+    {
+      win32_gc->pen_style |= PS_GEOMETRIC;
+      switch (win32_gc->cap_style)
+	{
+	/* For non-zero-width lines X11's CapNotLast works like CapButt */
+	case GDK_CAP_NOT_LAST:
+	case GDK_CAP_BUTT:
+	  win32_gc->pen_style |= PS_ENDCAP_FLAT;
+	  break;
+	case GDK_CAP_ROUND:
+	  win32_gc->pen_style |= PS_ENDCAP_ROUND;
+	  break;
+	case GDK_CAP_PROJECTING:
+	  win32_gc->pen_style |= PS_ENDCAP_SQUARE;
+	  break;
+	}
+    }
+
+  switch (win32_gc->line_style)
+    {
+    case GDK_LINE_SOLID:
+      g_free (win32_gc->pen_dashes);
+      win32_gc->pen_dashes = NULL;
+      win32_gc->pen_num_dashes = 0;
+      win32_gc->pen_style |= PS_SOLID;
+      break;
+    case GDK_LINE_ON_OFF_DASH:
+    case GDK_LINE_DOUBLE_DASH:
+      if (G_WIN32_IS_NT_BASED ())
+	win32_gc->pen_style |= PS_USERSTYLE;
+      else
+	win32_gc->pen_style |= PS_SOLID;
+      if (win32_gc->pen_dashes == NULL)
+	{
+	  win32_gc->pen_dashes = g_new (DWORD, 1);
+	  win32_gc->pen_dashes[0] = 4;
+	  win32_gc->pen_num_dashes = 1;
+	}
+     break;
+    }
+}
+
+static void
 gdk_win32_gc_values_to_win32values (GdkGCValues    *values,
 				    GdkGCValuesMask mask,
@@ -356,33 +422,5 @@ gdk_win32_gc_values_to_win32values (GdkG
   if (mask & GDK_GC_LINE_STYLE)
     {
-      switch (values->line_style)
-	{
-	case GDK_LINE_SOLID:
-	  if (win32_gc->pen_dashes)
-	    {
-	      g_free (win32_gc->pen_dashes);
-	      win32_gc->pen_dashes = NULL;
-	      win32_gc->pen_num_dashes = 0;
-	    }
-          win32_gc->pen_style &= ~(PS_STYLE_MASK);
-	  win32_gc->pen_style |= PS_SOLID;
-	  win32_gc->pen_double_dash = FALSE;
-	  break;
-	case GDK_LINE_ON_OFF_DASH:
-	case GDK_LINE_DOUBLE_DASH: 
-	  if (!win32_gc->pen_dashes)
-	    {
-            /* setting to PS_DASH probably isn't correct. If I understand the
-             * xlib docs correctly it should influence the handling of
-             * line endings ? --hb
-             */
-            win32_gc->pen_style &= ~(PS_STYLE_MASK);
-	    win32_gc->pen_style |= PS_DASH;
-          }
-	  win32_gc->pen_double_dash = values->line_style == GDK_LINE_DOUBLE_DASH;
-	  break;
-	}
-      GDK_NOTE (GC, (g_print ("%sps|=PS_STYLE_%s", s, _gdk_win32_psstyle_to_string (win32_gc->pen_style)),
-		     s = ","));
+      win32_gc->line_style = values->line_style;
       win32_gc->values_mask |= GDK_GC_LINE_STYLE;
     }
@@ -390,21 +428,15 @@ gdk_win32_gc_values_to_win32values (GdkG
   if (mask & GDK_GC_CAP_STYLE)
     {
-      win32_gc->pen_style &= ~(PS_ENDCAP_MASK);
-      switch (values->cap_style)
-	{
-	case GDK_CAP_NOT_LAST:	/* ??? */
-	case GDK_CAP_BUTT:
-	  win32_gc->pen_style |= PS_ENDCAP_FLAT;
-	  break;
-	case GDK_CAP_ROUND:
-	  win32_gc->pen_style |= PS_ENDCAP_ROUND;
-	  break;
-	case GDK_CAP_PROJECTING:
-	  win32_gc->pen_style |= PS_ENDCAP_SQUARE;
-	  break;
-	}
+      win32_gc->cap_style = values->cap_style;
+      win32_gc->values_mask |= GDK_GC_CAP_STYLE;
+    }
+
+  if (mask & (GDK_GC_LINE_WIDTH | GDK_GC_LINE_STYLE | GDK_GC_CAP_STYLE))
+    {
+      fix_pen (win32_gc);
+      GDK_NOTE (GC, (g_print ("%sps|=PS_STYLE_%s", s, _gdk_win32_psstyle_to_string (win32_gc->pen_style)),
+		     s = ","));
       GDK_NOTE (GC, (g_print ("%sps|=PS_ENDCAP_%s", s, _gdk_win32_psendcap_to_string (win32_gc->pen_style)),
 		     s = ","));
-      win32_gc->values_mask |= GDK_GC_CAP_STYLE;
     }
 
@@ -462,9 +494,14 @@ _gdk_win32_gc_new (GdkDrawable	  *drawab
   win32_gc->graphics_exposures = TRUE;
   win32_gc->pen_width = 0;
-  win32_gc->pen_style = PS_GEOMETRIC|PS_ENDCAP_FLAT|PS_JOIN_MITER;
+  /* Don't get confused by the PS_ENDCAP_ROUND. For narrow GDI pens
+   * (width == 1), PS_GEOMETRIC|PS_ENDCAP_ROUND works like X11's
+   * CapButt.
+   */
+  win32_gc->pen_style = PS_GEOMETRIC|PS_ENDCAP_ROUND|PS_JOIN_MITER;
+  win32_gc->cap_style = GDK_CAP_BUTT;
+  win32_gc->line_style = GDK_LINE_SOLID;
   win32_gc->pen_dashes = NULL;
   win32_gc->pen_num_dashes = 0;
   win32_gc->pen_dash_offset = 0;
-  win32_gc->pen_double_dash = FALSE;
   win32_gc->pen_hbrbg = NULL;
 
@@ -543,19 +580,6 @@ gdk_win32_gc_get_values (GdkGC       *gc
   values->line_width = win32_gc->pen_width;
   
-  if (win32_gc->pen_style & PS_SOLID)
-    values->line_style = GDK_LINE_SOLID;
-  else if (win32_gc->pen_style & PS_DASH)
-    values->line_style = win32_gc->pen_double_dash ? GDK_LINE_DOUBLE_DASH :
-						     GDK_LINE_ON_OFF_DASH;
-  else
-    values->line_style = GDK_LINE_SOLID;
-
-  /* PS_ENDCAP_ROUND is zero */
-  if (win32_gc->pen_style & PS_ENDCAP_FLAT)
-    values->cap_style = GDK_CAP_BUTT;
-  else if (win32_gc->pen_style & PS_ENDCAP_SQUARE)
-    values->cap_style = GDK_CAP_PROJECTING;
-  else
-    values->cap_style = GDK_CAP_ROUND;
+  values->line_style = win32_gc->line_style;
+  values->cap_style = win32_gc->cap_style;
     
   /* PS_JOIN_ROUND is zero */
@@ -594,17 +618,11 @@ gdk_win32_gc_set_dashes (GdkGC *gc,
   win32_gc = GDK_GC_WIN32 (gc);
 
-  /* mark as set, see gdk_win32_gc_values_to_win32values () for the reason */
-  win32_gc->values_mask |= GDK_GC_LINE_STYLE;
-
-  win32_gc->pen_style &= ~(PS_STYLE_MASK);
-
-  win32_gc->pen_style |= (PS_GEOMETRIC | PS_USERSTYLE);
   win32_gc->pen_num_dashes = n;
-  if (win32_gc->pen_dashes != NULL)
-    g_free (win32_gc->pen_dashes);
+  g_free (win32_gc->pen_dashes);
   win32_gc->pen_dashes = g_new (DWORD, n);
   for (i = 0; i < n; i++)
     win32_gc->pen_dashes[i] = dash_list[i];
   win32_gc->pen_dash_offset = dash_offset;
+  fix_pen (win32_gc);
 }
 
@@ -754,4 +772,6 @@ gdk_gc_copy (GdkGC *dst_gc,
   dst_win32_gc->pen_width = src_win32_gc->pen_width;
   dst_win32_gc->pen_style = src_win32_gc->pen_style;
+  dst_win32_gc->line_style = src_win32_gc->line_style;
+  dst_win32_gc->cap_style = src_win32_gc->cap_style;
   dst_win32_gc->pen_dashes = src_win32_gc->pen_dashes;
   if (dst_win32_gc->pen_dashes)
@@ -760,5 +780,4 @@ gdk_gc_copy (GdkGC *dst_gc,
   dst_win32_gc->pen_num_dashes = src_win32_gc->pen_num_dashes;
   dst_win32_gc->pen_dash_offset = src_win32_gc->pen_dash_offset;
-  dst_win32_gc->pen_double_dash = src_win32_gc->pen_double_dash;
 
 
@@ -962,5 +981,5 @@ gdk_win32_hdc_get (GdkDrawable    *drawa
     {
       /* For drawing GDK_LINE_DOUBLE_DASH */
-      if ((usage & GDK_GC_BACKGROUND) && win32_gc->pen_double_dash)
+      if ((usage & GDK_GC_BACKGROUND) && win32_gc->line_style == GDK_LINE_DOUBLE_DASH)
         {
           bg = _gdk_win32_colormap_color (impl->colormap, win32_gc->background);
@@ -982,6 +1001,5 @@ gdk_win32_hdc_get (GdkDrawable    *drawa
 	       * drawn solid to avoid implementing a whole line renderer.
 	       */
-	      if ((hpen = ExtCreatePen (
-					(win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
+	      if ((hpen = ExtCreatePen ((win32_gc->pen_style & ~(PS_STYLE_MASK)) | PS_SOLID,
 					MAX (win32_gc->pen_width, 1),
 					&logbrush, 
Index: gdk/win32/gdkprivate-win32.h
===================================================================
RCS file: /cvs/gnome/gtk+/gdk/win32/gdkprivate-win32.h,v
retrieving revision 1.64.2.5
diff -p -u -2 -r1.64.2.5 gdkprivate-win32.h
--- gdk/win32/gdkprivate-win32.h	4 Jun 2005 21:54:48 -0000	1.64.2.5
+++ gdk/win32/gdkprivate-win32.h	21 Jun 2005 19:52:20 -0000
@@ -281,8 +281,9 @@ struct _GdkGCWin32
   gint pen_width;
   DWORD pen_style;
+  GdkLineStyle line_style;
+  GdkCapStyle cap_style;
   DWORD *pen_dashes;		/* use for PS_USERSTYLE or step-by-step rendering */
   gint pen_num_dashes;
   gint pen_dash_offset;
-  gboolean pen_double_dash;
   HBRUSH pen_hbrbg;
 
