--- gtkhsv-old.c	2004-01-09 15:53:58.000000000 +0100
+++ gtkhsv.c	2004-01-11 23:27:43.000000000 +0100
@@ -916,11 +916,11 @@
 /* Paints the hue ring */
 static void
 paint_ring (GtkHSV      *hsv,
-	    GdkDrawable *drawable,
-	    gint         x,
-	    gint         y,
-	    gint         width,
-	    gint         height)
+            GdkDrawable *drawable,
+            gint         x,
+            gint         y,
+            gint         width,
+            gint         height)
 {
   HSVPrivate *priv;
   int xx, yy;
@@ -930,104 +930,178 @@
   guchar *buf, *p;
   gdouble angle;
   gdouble hue;
-  gdouble r, g, b;
-  GdkBitmap *mask;
+  gdouble r, g, b, alpha;
   GdkGC *gc;
   GdkColor color;
-  
+
   priv = hsv->priv;
-  
+
   center = priv->size / 2.0;
-  
+
   outer = priv->size / 2.0;
   inner = outer - priv->ring_width;
-  
-  /* Paint the ring */
-  
-  buf = g_new (guchar, width * height * 3);
-  
-  for (yy = 0; yy < height; yy++)
-    {
-      p = buf + yy * width * 3;
-      
-      dy = -(yy + y - center);
-      
-      for (xx = 0; xx < width; xx++)
-	{
-	  dx = xx + x - center;
-	  
-	  dist = dx * dx + dy * dy;
-	  if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1)))
-	    {
-	      *p++ = 0;
-	      *p++ = 0;
-	      *p++ = 0;
-	      continue;
-	    }
-	  
-	  angle = atan2 (dy, dx);
-	  if (angle < 0.0)
-	    angle += 2.0 * G_PI;
-	  
-	  hue = angle / (2.0 * G_PI);
-	  
-	  r = hue;
-	  g = 1.0;
-	  b = 1.0;
-	  hsv_to_rgb (&r, &g, &b);
-	  
-	  *p++ = floor (r * 255 + 0.5);
-	  *p++ = floor (g * 255 + 0.5);
-	  *p++ = floor (b * 255 + 0.5);
-	}
-    }
-  
-  /* Create clipping mask */
-  
-  mask = gdk_pixmap_new (GTK_WIDGET (hsv)->window, width, height, 1);
 
-  gc = gdk_gc_new (mask);
-  
-  color.pixel = 0;
-  gdk_gc_set_foreground (gc, &color);
-  gdk_draw_rectangle (mask, gc, TRUE,
-		      0, 0, width, height);
-  
-  
-  color.pixel = 1;
-  gdk_gc_set_foreground (gc, &color);
-  gdk_draw_arc (mask, gc, TRUE,
-		-x, -y,
-		priv->size - 1, priv->size - 1,
-		0, 360 * 64);
-  
-  color.pixel = 0;
-  gdk_gc_set_foreground (gc, &color);
-  gdk_draw_arc (mask, gc, TRUE,
-		-x + priv->ring_width - 1, -y + priv->ring_width - 1,
-		priv->size - 2 * priv->ring_width + 1, priv->size - 2 * priv->ring_width + 1,
-		0, 360 * 64);
-  
-  g_object_unref (gc);
-  
-  gdk_gc_set_clip_mask (priv->gc, mask);
-  gdk_gc_set_clip_origin (priv->gc, 0, 0);
-  
-  /* Draw ring */
-  
-  gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height,
-				GDK_RGB_DITHER_MAX,
-				buf,
-				width * 3,
-				x, y);
-  
+
+
+  {
+    int u,v,xx,yy,alphames;
+    gdouble r;
+    int inrad,outrad;
+    const gdouble out = 0.15;
+    guchar *py,*p;
+    GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 1,
+                                       8,
+                                       width, height);
+    py = (guchar*)gdk_pixbuf_get_pixels(pixbuf);
+    memset(py, 0, width*height*4);
+    yy = y - center;
+    inrad = inner*inner;
+    outrad = outer*outer;
+    alphames = 0;
+    for(; yy < y-center+height; yy++,
+        py += gdk_pixbuf_get_rowstride(pixbuf))
+      {
+        xx = x - center;
+        p = py;
+        for(; xx < x-center+width; xx++, p+=4)
+          {
+            r = (xx+.5)*(xx+.5)+(yy+.5)*(yy+.5);
+            if (r > outrad || r < inrad)
+              continue;
+
+            angle = atan2 (-yy, xx);
+            if (angle < 0.0)
+              angle += 2.0 * G_PI;
+
+            hue = angle / (2.0 * G_PI);
+
+            r = hue;
+            g = 1.0;
+            b = 1.0;
+            hsv_to_rgb (&r, &g, &b);
+            alpha = 0.0;
+
+            if ( fabs(((double)(r - inrad))/(outrad-inrad)-0.5) < 0.5-out)
+              alpha = 1.0;
+            else
+              { // Supersample
+                const int sampling = 5;
+                const gdouble sample = 1.0 / (2*(sampling + 1));
+                gdouble rad,ru,rv,stepru,scale;
+                rv=yy+sample;
+                u = 0;
+                v = 0;
+                stepru = 2*sample;
+                while(v < sampling)
+                  {
+                    ru=xx+sample;
+                    while(u < sampling)
+                      {
+                        rad = ru*ru+rv*rv;
+                        scale = (rad - inrad)/(outrad - inrad);
+                        if (scale > out && scale < 1.0 - out)
+                          alpha += 1.0/(sampling);
+                        else if (scale >= 0.0 && scale <= out)
+                          alpha += scale/out * 1.0/(sampling);
+                        else if (scale >= 1.0-out && scale <= 1.0)
+                          alpha += (1.0-scale)/out * 1.0/(sampling);
+                        ru += stepru;
+                        u++;
+                      }
+                    rv += 2*sample;
+                    v++;
+                  }
+
+              }
+#if 0
+            // Gamma correction, i don't know
+	    // a lot about it and it consume too much CPU
+            alpha = pow(alpha, 1.0/1.2);
+#endif
+
+            p[0] = floor (r * 255 + 0.5);
+            p[1] = floor (g * 255 + 0.5);
+            p[2] = floor (b * 255 + 0.5);
+            p[3] = floor (alpha * 255 + 0.5);
+          }
+      }
+    if (GTK_WIDGET_HAS_FOCUS (hsv) /*&&
+        priv->focus_on_ring*/)
+      {
+
+        inrad = (outer-2)*(outer-2);
+        outrad = (outer)*(outer);
+        py = (guchar*)gdk_pixbuf_get_pixels(pixbuf);
+        yy = y - center;
+        for(; yy < y-center+height; yy++,
+            py += gdk_pixbuf_get_rowstride(pixbuf))
+          {
+            gdouble oldalpha;
+            xx = x - center;
+            p = py;
+            for(; xx < x-center+width; xx++, p+=4 )
+              {
+                r = (xx+.5)*(xx+.5)+(yy+0.5)*(yy+0.5);
+                if (r > outrad+4*(outer+4)+4 || r < inrad-4*(outer+2)+4)
+                  continue;
+                angle = atan2(yy,xx);
+                angle *= 50;
+
+                r = g = b = sin(angle)*sin(angle);
+                alpha = 0.0;
+
+                { // Supersample
+                  const int sampling = 5;
+                  const gdouble out = 0.1;
+                  const gdouble sample = 1.0 / (2*(sampling + 1));
+                  gdouble rad,ru,rv,stepru,scale;
+                  rv=yy+sample;
+                  u = 0;
+                  v = 0;
+                  stepru = 2*sample;
+                  while(v < sampling)
+                    {
+                      ru=xx+sample;
+                      while(u < sampling)
+                        {
+                          rad = ru*ru+rv*rv;
+                          scale = (rad - inrad)/(outrad - inrad);
+                          if (scale > out && scale < 1.0 - out)
+                            alpha += 1.0/(sampling);
+                          else if (scale > 0 && scale < out)
+                            alpha += scale/out * 1.0/(sampling);
+                          else if (scale > 1.0-out && scale < 1.0)
+                            alpha += (1.0-scale)/out * 1.0/(sampling);
+                          ru += stepru;
+                          u++;
+                        }
+                      rv += 2*sample;
+                      v++;
+                    }
+                }
+                oldalpha = ((double)p[3])/255.0;
+
+                p[0] = floor ((r * 255 - p[0]) * alpha + p[0] + 0.5);
+                p[1] = floor ((g * 255 - p[1]) * alpha + p[1] + 0.5);
+                p[2] = floor ((b * 255 - p[2]) * alpha + p[2] + 0.5);
+                alpha = (alpha - oldalpha)*alpha+oldalpha;
+                alpha = pow(alpha, 1.0/1.2);
+                p[3] = floor (alpha * 255 + 0.5);
+              }
+          }
+      }
+    gdk_draw_pixbuf(drawable, priv->gc, pixbuf, 0, 0, 0, 0,
+                    width, height, GDK_RGB_DITHER_MAX, x, y);
+    g_object_unref (pixbuf);
+  }
+
   /* Draw value marker */
-  
+
   r = priv->h;
   g = 1.0;
   b = 1.0;
   hsv_to_rgb (&r, &g, &b);
-  
+
   if (INTENSITY (r, g, b) > 0.5)
     {
       color.red = 0x0000;
@@ -1042,39 +1116,11 @@
     }
 
   gdk_gc_set_rgb_fg_color (priv->gc, &color);
-  
-  gdk_draw_line (drawable, priv->gc,
-		 -x + center, -y + center,
-		 -x + center + cos (priv->h * 2.0 * G_PI) * center,
-		 -y + center - sin (priv->h * 2.0 * G_PI) * center);
-  
-  gdk_gc_set_clip_mask (priv->gc, NULL);
-  g_object_unref (mask);
-  
-  g_free (buf);
-  
-  /* Draw ring outline */
 
-  if (GTK_WIDGET_HAS_FOCUS (hsv) &&
-      priv->focus_on_ring)
-    {
-      gint focus_width;
-      gint focus_halfwidth;
-      GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width);
-      focus_halfwidth = (focus_width + 1) / 2;
-      
-      gdk_draw_arc (drawable, gc, FALSE,
-                    -x + focus_width/2, -y + focus_width/2,
-                    priv->size - focus_width, priv->size - focus_width,
-                    0, 360 * 64);
-      gdk_draw_arc (drawable, gc, FALSE,
-                    -x + priv->ring_width - focus_halfwidth, -y + priv->ring_width - focus_halfwidth,
-                    priv->size - 2 * priv->ring_width + focus_width,
-		    priv->size - 2 * priv->ring_width + focus_width,
-                    0, 360 * 64);
-      
-      g_object_unref (gc);
-    }
+  gdk_draw_line (drawable, priv->gc,
+                 -x + center, -y + center,
+                 -x + center + cos (priv->h * 2.0 * G_PI) * center,
+                 -y + center - sin (priv->h * 2.0 * G_PI) * center);
 }
 
 /* Converts an HSV triplet to an integer RGB triplet */
@@ -1096,51 +1142,58 @@
 #define SWAP(a, b, t) ((t) = (a), (a) = (b), (b) = (t))
 
 #define LERP(a, b, v1, v2, i) (((v2) - (v1) != 0)					\
-			       ? ((a) + ((b) - (a)) * ((i) - (v1)) / ((v2) - (v1)))	\
+			       ? (((double)a) + ((double)(b) - (a)) * ((double)(i) - (v1)) / ((double)(v2) - (v1)))	\
 			       : (a))
-
+// #define CLAMP(a,b,c) (MIN(MAX(a,b),c))
 /* Paints the HSV triangle */
 static void
 paint_triangle (GtkHSV      *hsv,
-		GdkDrawable *drawable,
-		gint         x,
-		gint         y,
-		gint         width,
-		gint         height)
+                GdkDrawable *drawable,
+                gint         x,
+                gint         y,
+                gint         width,
+                gint         height)
 {
   HSVPrivate *priv;
   gint hx, hy, sx, sy, vx, vy; /* HSV vertices */
-  gint x1, y1, r1, g1, b1; /* First vertex in scanline order */
-  gint x2, y2, r2, g2, b2; /* Second vertex */
-  gint x3, y3, r3, g3, b3; /* Third vertex */
+  gint x1, y1, r1, g1, b1; /* Vertex on the right of 3 in clockwise order */
+  gint x2, y2, r2, g2, b2; /* Vertex on the left of 3 in clockwise order */
+  gint x3, y3, r3, g3, b3; /* Last vertex in scanline order  */
+  gint x4, y4, r4, g4, b4; /* Middle vertex in scanline order */
+  gint x5, y5, r5, g5, b5; /* First vertex in scanline order */
   gint t;
+  gdouble u;
   guchar *buf, *p;
-  gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */
-  gint xx, yy;
+  gdouble xl1, xr1, rl, rr, gl, gr, bl, br; /* Scanline data */
+  gdouble xl2, xr2; /* Scanline data on the line after */
+  gdouble yy;
+  int xx;
   GdkBitmap *mask;
   GdkGC *gc;
   GdkColor color;
   GdkPoint points[3];
   gdouble r, g, b;
-  
+  GdkPixbuf *pixbuf;
+  guchar *py;
+
   priv = hsv->priv;
-  
+
   /* Compute triangle's vertices */
-  
+
   compute_triangle (hsv, &hx, &hy, &sx, &sy, &vx, &vy);
-  
+
   x1 = hx;
   y1 = hy;
   get_color (priv->h, 1.0, 1.0, &r1, &g1, &b1);
-  
+
   x2 = sx;
   y2 = sy;
   get_color (priv->h, 1.0, 0.0, &r2, &g2, &b2);
-  
+
   x3 = vx;
   y3 = vy;
   get_color (priv->h, 0.0, 1.0, &r3, &g3, &b3);
-  
+
   if (y2 > y3)
     {
       SWAP (x2, x3, t);
@@ -1149,7 +1202,7 @@
       SWAP (g2, g3, t);
       SWAP (b2, b3, t);
     }
-  
+
   if (y1 > y3)
     {
       SWAP (x1, x3, t);
@@ -1158,8 +1211,8 @@
       SWAP (g1, g3, t);
       SWAP (b1, b3, t);
     }
-  
-  if (y1 > y2)
+
+  if ((x1 > x2) || ((x1 == x2) && ( x2 >= x3) && (y2 > y1)))
     {
       SWAP (x1, x2, t);
       SWAP (y1, y2, t);
@@ -1167,160 +1220,191 @@
       SWAP (g1, g2, t);
       SWAP (b1, b2, t);
     }
-  
-  /* Shade the triangle */
-  
-  buf = g_new (guchar, width * height * 3);
-  
-  for (yy = 0; yy < height; yy++)
-    {
-      p = buf + yy * width * 3;
-      
-      if (yy + y < y1 || yy + y > y3)
-	for (xx = 0; xx < width; xx++)
-	  {
-	    *p++ = 0;
-	    *p++ = 0;
-	    *p++ = 0;
-	  }
-      else {
-	if (yy + y < y2)
-	  {
-	    xl = LERP (x1, x2, y1, y2, yy + y);
-	    
-	    rl = LERP (r1, r2, y1, y2, yy + y);
-	    gl = LERP (g1, g2, y1, y2, yy + y);
-	    bl = LERP (b1, b2, y1, y2, yy + y);
-	  }
-	else
-	  {
-	    xl = LERP (x2, x3, y2, y3, yy + y);
-	    
-	    rl = LERP (r2, r3, y2, y3, yy + y);
-	    gl = LERP (g2, g3, y2, y3, yy + y);
-	    bl = LERP (b2, b3, y2, y3, yy + y);
-	  }
-	
-	xr = LERP (x1, x3, y1, y3, yy + y);
-	
-	rr = LERP (r1, r3, y1, y3, yy + y);
-	gr = LERP (g1, g3, y1, y3, yy + y);
-	br = LERP (b1, b3, y1, y3, yy + y);
-	
-	if (xl > xr)
-	  {
-	    SWAP (xl, xr, t);
-	    SWAP (rl, rr, t);
-	    SWAP (gl, gr, t);
-	    SWAP (bl, br, t);
-	  }
-	
-	for (xx = 0; xx < width; xx++)
-	  {
-	    if (xx + x < xl || xx + x > xr)
-	      {
-		*p++ = 0;
-		*p++ = 0;
-		*p++ = 0;
-	      }
-	    else
-	      {
-		*p++ = LERP (rl, rr, xl, xr, xx + x);
-		*p++ = LERP (gl, gr, xl, xr, xx + x);
-		*p++ = LERP (bl, br, xl, xr, xx + x);
-	      }
-	  }
-      }
+  x4 = x1;
+  x5 = x2;
+  y4 = y1;
+  y5 = y2;
+  r4 = r1;
+  r5 = r2;
+  g4 = g1;
+  g5 = g2;
+  b4 = b1;
+  b5 = b2;
+  if (y4 > y5)
+    {
+      SWAP(y4,y5,t);
+      SWAP(x4,x5,t);
+      SWAP(r4,r5,t);
+      SWAP(g4,g5,t);
+      SWAP(b4,b5,t);
     }
-  
-  /* Create clipping mask */
-  
-  mask = gdk_pixmap_new (GTK_WIDGET (hsv)->window, width, height, 1);
 
-  gc = gdk_gc_new (mask);
-  
-  color.pixel = 0;
-  gdk_gc_set_foreground (gc, &color);
-  gdk_draw_rectangle (mask, gc, TRUE,
-		      0, 0, width, height);
-  
-  color.pixel = 1;
-  gdk_gc_set_foreground (gc, &color);
-  
-  points[0].x = x1 - x;
-  points[0].y = y1 - y;
-  points[1].x = x2 - x;
-  points[1].y = y2 - y;
-  points[2].x = x3 - x;
-  points[2].y = y3 - y;
-  gdk_draw_polygon (mask, gc, TRUE, points, 3);
-  
-  g_object_unref (gc);
-  
-  gdk_gc_set_clip_mask (priv->gc, mask);
-  gdk_gc_set_clip_origin (priv->gc, 0, 0);
-  
-  /* Draw triangle */
-  
-  gdk_draw_rgb_image_dithalign (drawable, priv->gc, 0, 0, width, height,
-				GDK_RGB_DITHER_MAX,
-				buf,
-				width * 3,
-				x, y);
-  
-  gdk_gc_set_clip_mask (priv->gc, NULL);
-  g_object_unref (mask);
-  
-  g_free (buf);
-  
-  /* Draw triangle focus outline */
 
-  if (GTK_WIDGET_HAS_FOCUS (hsv) &&
-      !priv->focus_on_ring)
-    {
-      gint focus_width = 1;	    
-      GdkGC *gc = gtk_hsv_get_focus_gc (hsv, &focus_width);
-  
-      gdk_draw_polygon (drawable, gc, FALSE, points, 3);
-      g_object_unref (gc);
-    }
-  
-  /* Draw value marker */
-  
-  xx = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5) - x;
-  yy = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5) - y;
-  
-  r = priv->h;
-  g = priv->s;
-  b = priv->v;
-  hsv_to_rgb (&r, &g, &b);
+  /* Shade the triangle */
 
-  if (INTENSITY (r, g, b) > 0.5)
-    {
-      color.red = 0x0000;
-      color.green = 0x0000;
-      color.blue = 0x0000;
-    }
-  else
-    {
-      color.red = 0xffff;
-      color.green = 0xffff;
-      color.blue = 0xffff;
-    }
+  pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 1, 8, width, height);
+  buf =  gdk_pixbuf_get_pixels(pixbuf);
+  memset(buf, 0, width*height*4);
+  // MIN(..) -> Work until end of the buffer or end of the triangle
+  // in scanline order
+  py = buf;
+  yy = MAX(y4,y);
+  py += (int)( yy - y ) * width * 4;
+  for(; yy < MIN( y + height, y3);
+      yy += 1.0, py += width * 4)
+    {
+      gdouble prel,postl,prer,postr,alpha2, alpha3;
+      int xa1,xa2,xb1,xb2,debut,fin;
+      gdouble alpha, stepl, stepr;
 
-  gdk_gc_set_rgb_fg_color (priv->gc, &color);
 
-#define OUTER_RADIUS 4
-#define INNER_RADIUS 3 
-  
-  gdk_draw_arc (drawable, priv->gc, FALSE,
-		xx - OUTER_RADIUS, yy - OUTER_RADIUS,
-		OUTER_RADIUS * 2, OUTER_RADIUS * 2,
-		0, 360 * 64);
-  gdk_draw_arc (drawable, priv->gc, FALSE,
-		xx - INNER_RADIUS, yy - INNER_RADIUS,
-		INNER_RADIUS * 2, INNER_RADIUS * 2,
-		0, 360 * 64);
+      if (yy < y1) // Calculate left and right x position on the scanline
+        {
+          xl1 = LERP(x1,x4,y1,y4,yy);
+          rl = LERP(r1,r4,y1,y4,yy);
+          gl = LERP(g1,g4,y1,y4,yy);
+          bl = LERP(b1,b4,y1,y4,yy);
+        }
+      else
+        {
+          xl1 = LERP(x1,x3,y1,y3,yy);
+          rl = LERP(r1,r3,y1,y3,yy);
+          gl = LERP(g1,g3,y1,y3,yy);
+          bl = LERP(b1,b3,y1,y3,yy);
+        }
+      if (yy < y2)
+        {
+          xr1 = LERP(x2,x4,y2,y4,yy);
+          rr = LERP(r2,r4,y2,y4,yy);
+          gr = LERP(g2,g4,y2,y4,yy);
+          br = LERP(b2,b4,y2,y4,yy);
+        }
+      else
+        {
+          xr1 = LERP(x2,x3,y2,y3,yy);
+          rr = LERP(r2,r3,y2,y3,yy);
+          gr = LERP(g2,g3,y2,y3,yy);
+          br = LERP(b2,b3,y2,y3,yy);
+        }
+      yy++;
+      if (yy < y1) // Calculate left and right x position on the next scanline
+        xl2 = LERP(x1,x4,y1,y4,yy);
+      else
+        xl2 = LERP(x1,x3,y1,y3,yy);
+      if (yy < y2)
+        xr2 = LERP(x2,x4,y2,y4,yy);
+      else
+        xr2 = LERP(x2,x3,y2,y3,yy);
+      yy--;
+
+      if (xl2 < xl1)
+        SWAP(xl2,xl1,u);
+      if (xr2 < xr1)
+        SWAP(xr2,xr1,u);
+      // Integer coordinates of the trapezoid
+      //   xa1  xa2         xb1   xb2
+      //    .,;:/|||||||||||||\:;,.         ,    ,
+      // ===|====|=={.....}==|=====|====
+      xa1 = floor(xl1);
+      xb1 = floor(xr1);
+      xa2 = ceil(xl2);
+      xb2 = ceil(xr2);
+      debut = MAX(xa1,x);
+      fin = MIN(xb2,x+width);
+
+      xx = debut;
+      p = py + ( xx - x ) * 4;
+      if (xl2 != xl1)
+        {
+          stepl = 1.0 / ( xl2 - xl1 );
+          alpha2 = ( ceil(xl1) - xl1 + 0.5 ) * stepl;
+        }
+      if (xr2 != xr1)
+        {
+          stepr = 1.0 / ( xr2 - xr1 );
+          alpha3 = 1.0 - ( ceil(xr1) - xr1 + 0.5 ) * stepr;
+        }
+      for(; xx < fin;
+          p += 4, xx += 1.0)
+        {
+          // The point we are on is partially or completely
+          // on the triangle
+          r = LERP(rl,rr,xa1,xb2,xx);
+          g = LERP(gl,gr,xa1,xb2,xx);
+          b = LERP(bl,br,xa1,xb2,xx);
+
+          if (xx >= xa2 && xx < xb1) // The point is integrally on the triangle
+            alpha = 1.0;
+          else if (xx < xa2)
+            {
+              if (xx == xa1 && xa2-xa1 != 1)
+                alpha = ( ( ceil(xl1) - xl1 ) * ( ceil(xl1) - xl1 ) ) * stepl * 0.5;
+              else if (xx == xa1)
+                alpha = ( xl2 - xl1 ) * 0.5 + xa2 - xl2;
+              else if (xx == xa2 - 1)
+                alpha = 1.0 - ( ( xl2 - floor(xl2) ) * ( xl2 - floor(xl2) ) ) * stepl * 0.5;
+              else
+                {
+                  alpha = alpha2;
+                  alpha2 += stepl;
+                }
+            }
+          else if (xx >= xb1)
+            {
+              if (xx == xb1 && xb2-xb1 != 1)
+                alpha = 1.0 - ( ( ceil(xr1) - xr1 )
+                                * ( ceil(xr1) - xr1 ) ) * stepr * 0.5;
+              else if (xx == xb1)
+                alpha = ( xr2 - xr1 ) * 0.5 + xr1 - xb1;
+              else if (xx == xb2 - 1)
+                alpha = ( ( xr2 - floor(xr2) ) *
+                          ( xr2 - floor(xr2) ) ) * stepr * 0.5;
+              else
+                {
+                  alpha = alpha3;
+                  alpha3 -= stepr;
+                }
+            }
+          //	  alpha = pow(alpha,1.2);
+
+          p[0] = floor(r + 0.5);
+          p[1] = floor(g + 0.5);
+          p[2] = floor(b + 0.5);
+          p[3] = floor(alpha * 255 + .5);
+        }
+    }
+  /* Draw value marker */
+
+  x2 = floor (sx + (vx - sx) * priv->v + (hx - vx) * priv->s * priv->v + 0.5) - x;
+  y2 = floor (sy + (vy - sy) * priv->v + (hy - vy) * priv->s * priv->v + 0.5) - y;
+  for(yy = MAX(y,y2-5), py = buf+(int)(yy-y)*width*4; yy <MIN(y2+5,y+width); yy++,py+=width*4)
+    for(xx = MAX(x,x2-5), p = py + (xx-x)*4; xx < MIN(x2+5,x+width); xx++, p+=4)
+      {
+        gdouble hits = 0;
+        int cx = xx - x2;
+        int cy = yy - y2;
+        int r = cx*cx+cy*cy;
+        gdouble u,v;
+#define INNER_RADIUS 4
+#define OUTER_RADIUS 13
+
+        for(u = cx; u < cx+0.99; u+=0.1)
+          for(v = cy; v < cy+.99; v+=0.1)
+            {
+              r = u*u+v*v;
+              if (r >= INNER_RADIUS && r <= OUTER_RADIUS)
+                hits+=1.0;
+            }
+        hits = 1.0 - hits / 100.0;
+        p[0] = hits * p[0];
+        p[1] = hits * p[1];
+        p[2] = hits * p[2];
+        p[3] = floor(hits * p[3] + (1-hits) * (1-hits)*255);
+      }
+  /* Draw triangle */
+  gdk_draw_pixbuf(drawable, priv->gc, pixbuf, 0, 0, 0, 0,
+                  width, height, GDK_RGB_DITHER_MAX, x, y);
+  g_object_unref(pixbuf);
 }
 
 /* Paints the contents of the HSV color selector */
