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 11:44:54 -0000
@@ -1278,4 +1278,7 @@ draw_segments (GdkGCWin32 *gcwin32,
   gint nsegs;
   gint i;
+  gboolean do_cap_butt = (gcwin32->pen_width <= 1 &&
+			  (gcwin32->pen_style & PS_ENDCAP_FLAT) &&
+			  gcwin32->cap_style == GDK_CAP_BUTT);
 
   segs = va_arg (args, GdkSegment *);
@@ -1332,34 +1335,71 @@ 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));
+	{
+	  const GdkSegment *ps = &segs[i];
+	  const int x1 = ps->x1, y1 = ps->y1;
+	  int x2 = ps->x2, y2 = ps->y2;
+	  int xc = 0, yc = 0;
+
+	  /* If drawing a narrow segment with GDK_CAP_BUTT endcap
+	   * style, we must draw the end point explicitly, as GDI's
+	   * endcap style is the equivalent of GDK_CAP_NOT_LAST. If
+	   * the segment is vertical, norizontal or diagonal, we can
+	   * simply extend it one pixel at the end. Otherwise we draw
+	   * an extra one-pixel final segment.
+	   */
+	  if (do_cap_butt)
+	    {
+	      if (y2 == y1 && x2 == x1)
+		xc = 1; /* just a point */
+	      else if (y2 == y1)
+		xc = (x1 < x2) ? 1 : -1; /* advance x only */
+	      else if (x2 == x1)
+		yc = (y1 < y2) ? 1 : -1; /* advance y only */
+	      else if (ABS (y2 - y1) == ABS (x2 - x1))
+		{
+		  xc = (x1 < x2) ? 1 : -1;
+		  yc = (y1 < y2) ? 1 : -1;
+		}
+	      x2 += xc;
+	      y2 += yc;
+	    }
 
-      /* 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;
+	  /* There seems to b a bug at least in my XP in that drawing
+	   * horizontal segments to the left or vertical segments up
+	   * actually draws the last point (but not the first).
+	   */
+	  if (!do_cap_butt && G_WIN32_IS_NT_BASED () && y1 == y2 && x1 > x2)
+	    {
+	      g_print (" +%d!+%d..+%d!+%d", x2+1, y2, x1+1, y1);
+	      GDI_CALL (MoveToEx, (hdc, x2+1, y2, NULL)) &&
+		GDI_CALL (LineTo, (hdc, x1+1, y1));
+	    }
+	  else if (!do_cap_butt && G_WIN32_IS_NT_BASED () && x1 == x2 && y1 > y2)
+	    {
+	      g_print (" +%d+%d!..+%d+%d!", x2, y2+1, x1, y1+1);
+	      GDI_CALL (MoveToEx, (hdc, x2, y2+1, NULL)) &&
+		GDI_CALL (LineTo, (hdc, x1, y1+1));
+	    }
+	  else
+	    {
+	      if (!do_cap_butt) g_print (" +%d+%d..+%d+%d\n", x1, y1, x2, 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));
+	    }
 
-          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;
-            }
+	  if (do_cap_butt && xc == 0 && yc == 0)
+	    {
+	      /* Oblique segment not handled above */
+	      xc = (x1 < x2) ? 1 : -1;
+	      yc = (y1 < y2) ? 1 : -1;
+	      x2 += xc;
+	      y2 += yc;
+	      GDK_NOTE (MISC, g_print ("..+%d+%d", x2, y2));
+	      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 +1444,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);
 
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 11:44:56 -0000
@@ -393,5 +393,5 @@ gdk_win32_gc_values_to_win32values (GdkG
       switch (values->cap_style)
 	{
-	case GDK_CAP_NOT_LAST:	/* ??? */
+	case GDK_CAP_NOT_LAST:
 	case GDK_CAP_BUTT:
 	  win32_gc->pen_style |= PS_ENDCAP_FLAT;
@@ -404,4 +404,5 @@ gdk_win32_gc_values_to_win32values (GdkG
 	  break;
 	}
+      win32_gc->cap_style = values->cap_style;
       GDK_NOTE (GC, (g_print ("%sps|=PS_ENDCAP_%s", s, _gdk_win32_psendcap_to_string (win32_gc->pen_style)),
 		     s = ","));
@@ -463,4 +464,5 @@ _gdk_win32_gc_new (GdkDrawable	  *drawab
   win32_gc->pen_width = 0;
   win32_gc->pen_style = PS_GEOMETRIC|PS_ENDCAP_FLAT|PS_JOIN_MITER;
+  win32_gc->cap_style = GDK_CAP_BUTT;
   win32_gc->pen_dashes = NULL;
   win32_gc->pen_num_dashes = 0;
@@ -553,5 +555,5 @@ gdk_win32_gc_get_values (GdkGC       *gc
   /* PS_ENDCAP_ROUND is zero */
   if (win32_gc->pen_style & PS_ENDCAP_FLAT)
-    values->cap_style = GDK_CAP_BUTT;
+    values->cap_style = win32_gc->cap_style;
   else if (win32_gc->pen_style & PS_ENDCAP_SQUARE)
     values->cap_style = GDK_CAP_PROJECTING;
@@ -754,4 +756,5 @@ 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->cap_style = src_win32_gc->cap_style;
   dst_win32_gc->pen_dashes = src_win32_gc->pen_dashes;
   if (dst_win32_gc->pen_dashes)
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 11:44:57 -0000
@@ -281,4 +281,5 @@ struct _GdkGCWin32
   gint pen_width;
   DWORD pen_style;
+  GdkCapStyle cap_style;	/* to distinguish between BUTT and NOT_LAST */
   DWORD *pen_dashes;		/* use for PS_USERSTYLE or step-by-step rendering */
   gint pen_num_dashes;
