[mutter] gradient: Support alpha values in colors



commit c068c2122df3015c23dace66b58d8b841234716e
Author: Florian Müllner <fmuellner gnome org>
Date:   Thu Jul 3 19:44:24 2014 +0200

    gradient: Support alpha values in colors
    
    Designers got used to RGBA support in GTK+, so the colors we pick
    up from there might well have an alpha channel; update our gradient
    rendering to support this - eventually we should probably port that
    code to cairo ...

 src/ui/gradient.c |   76 +++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 54 insertions(+), 22 deletions(-)
---
diff --git a/src/ui/gradient.c b/src/ui/gradient.c
index b62d548..eb73808 100644
--- a/src/ui/gradient.c
+++ b/src/ui/gradient.c
@@ -74,14 +74,14 @@ blank_pixbuf (int width, int height)
   g_return_val_if_fail (height > 0, NULL);
 
   /* Always align rows to 32-bit boundaries */
-  rowstride = 4 * ((3 * width + 3) / 4);
+  rowstride = 4 * ((4 * width + 4) / 4);
 
   buf = g_try_malloc (height * rowstride);
   if (!buf)
     return NULL;
 
   return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB,
-                                   FALSE, 8,
+                                   TRUE, 8,
                                    width, height, rowstride,
                                    free_buffer, NULL);
 }
@@ -193,8 +193,8 @@ meta_gradient_create_interwoven (int            width,
 {
 
   int i, j, k, l, ll;
-  long r1, g1, b1, dr1, dg1, db1;
-  long r2, g2, b2, dr2, dg2, db2;
+  long r1, g1, b1, a1, dr1, dg1, db1, da1;
+  long r2, g2, b2, a2, dr2, dg2, db2, da2;
   GdkPixbuf *pixbuf;
   unsigned char *ptr;
   unsigned char *pixels;
@@ -210,18 +210,22 @@ meta_gradient_create_interwoven (int            width,
   r1 = (long)(colors1[0].red*0xffffff);
   g1 = (long)(colors1[0].green*0xffffff);
   b1 = (long)(colors1[0].blue*0xffffff);
+  a1 = (long)(colors1[0].alpha*0xffffff);
 
   r2 = (long)(colors2[0].red*0xffffff);
   g2 = (long)(colors2[0].green*0xffffff);
   b2 = (long)(colors2[0].blue*0xffffff);
+  a2 = (long)(colors2[0].alpha*0xffffff);
 
   dr1 = ((colors1[1].red-colors1[0].red)*0xffffff)/(int)height;
   dg1 = ((colors1[1].green-colors1[0].green)*0xffffff)/(int)height;
   db1 = ((colors1[1].blue-colors1[0].blue)*0xffffff)/(int)height;
+  da1 = ((colors1[1].alpha-colors1[0].alpha)*0xffffff)/(int)height;
 
   dr2 = ((colors2[1].red-colors2[0].red)*0xffffff)/(int)height;
   dg2 = ((colors2[1].green-colors2[0].green)*0xffffff)/(int)height;
   db2 = ((colors2[1].blue-colors2[0].blue)*0xffffff)/(int)height;
+  db2 = ((colors2[1].alpha-colors2[0].alpha)*0xffffff)/(int)height;
 
   for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
     {
@@ -232,17 +236,19 @@ meta_gradient_create_interwoven (int            width,
           ptr[0] = (unsigned char) (r1>>16);
           ptr[1] = (unsigned char) (g1>>16);
           ptr[2] = (unsigned char) (b1>>16);
+          ptr[3] = (unsigned char) (a1>>16);
         }
       else
         {
           ptr[0] = (unsigned char) (r2>>16);
           ptr[1] = (unsigned char) (g2>>16);
           ptr[2] = (unsigned char) (b2>>16);
+          ptr[3] = (unsigned char) (a2>>16);
         }
 
       for (j=1; j <= width/2; j *= 2)
-        memcpy (&(ptr[j*3]), ptr, j*3);
-      memcpy (&(ptr[j*3]), ptr, (width - j)*3);
+        memcpy (&(ptr[j*4]), ptr, j*4);
+      memcpy (&(ptr[j*4]), ptr, (width - j)*4);
 
       if (++l == ll)
         {
@@ -261,10 +267,12 @@ meta_gradient_create_interwoven (int            width,
       r1+=dr1;
       g1+=dg1;
       b1+=db1;
+      a1+=da1;
 
       r2+=dr2;
       g2+=dg2;
       b2+=db2;
+      a2+=da2;
     }
 
   return pixbuf;
@@ -289,12 +297,12 @@ meta_gradient_create_horizontal (int width, int height,
                                  const GdkRGBA *to)
 {
   int i;
-  long r, g, b, dr, dg, db;
+  long r, g, b, a, dr, dg, db, da;
   GdkPixbuf *pixbuf;
   unsigned char *ptr;
   unsigned char *pixels;
-  int r0, g0, b0;
-  int rf, gf, bf;
+  int r0, g0, b0, a0;
+  int rf, gf, bf, af;
   int rowstride;
 
   pixbuf = blank_pixbuf (width, height);
@@ -308,26 +316,32 @@ meta_gradient_create_horizontal (int width, int height,
   r0 = (guchar) (from->red * 0xff);
   g0 = (guchar) (from->green * 0xff);
   b0 = (guchar) (from->blue * 0xff);
+  a0 = (guchar) (from->alpha * 0xff);
   rf = (guchar) (to->red * 0xff);
   gf = (guchar) (to->green * 0xff);
   bf = (guchar) (to->blue * 0xff);
+  af = (guchar) (to->alpha * 0xff);
 
   r = r0 << 16;
   g = g0 << 16;
   b = b0 << 16;
+  a = a0 << 16;
 
   dr = ((rf-r0)<<16)/(int)width;
   dg = ((gf-g0)<<16)/(int)width;
   db = ((bf-b0)<<16)/(int)width;
+  da = ((af-a0)<<16)/(int)width;
   /* render the first line */
   for (i=0; i<width; i++)
     {
       *(ptr++) = (unsigned char)(r>>16);
       *(ptr++) = (unsigned char)(g>>16);
       *(ptr++) = (unsigned char)(b>>16);
+      *(ptr++) = (unsigned char)(a>>16);
       r += dr;
       g += dg;
       b += db;
+      a += da;
     }
 
   /* copy the first line to the other lines */
@@ -357,11 +371,11 @@ meta_gradient_create_vertical (int width, int height,
                                const GdkRGBA *to)
 {
   int i, j;
-  long r, g, b, dr, dg, db;
+  long r, g, b, a, dr, dg, db, da;
   GdkPixbuf *pixbuf;
   unsigned char *ptr;
-  int r0, g0, b0;
-  int rf, gf, bf;
+  int r0, g0, b0, a0;
+  int rf, gf, bf, af;
   int rowstride;
   unsigned char *pixels;
 
@@ -375,17 +389,21 @@ meta_gradient_create_vertical (int width, int height,
   r0 = (guchar) (from->red * 0xff);
   g0 = (guchar) (from->green * 0xff);
   b0 = (guchar) (from->blue * 0xff);
+  a0 = (guchar) (from->alpha * 0xff);
   rf = (guchar) (to->red * 0xff);
   gf = (guchar) (to->green * 0xff);
   bf = (guchar) (to->blue * 0xff);
+  af = (guchar) (to->alpha * 0xff);
 
   r = r0<<16;
   g = g0<<16;
   b = b0<<16;
+  a = a0<<16;
 
   dr = ((rf-r0)<<16)/(int)height;
   dg = ((gf-g0)<<16)/(int)height;
   db = ((bf-b0)<<16)/(int)height;
+  da = ((af-a0)<<16)/(int)height;
 
   for (i=0; i<height; i++)
     {
@@ -394,14 +412,16 @@ meta_gradient_create_vertical (int width, int height,
       ptr[0] = (unsigned char)(r>>16);
       ptr[1] = (unsigned char)(g>>16);
       ptr[2] = (unsigned char)(b>>16);
+      ptr[3] = (unsigned char)(a>>16);
 
       for (j=1; j <= width/2; j *= 2)
-        memcpy (&(ptr[j*3]), ptr, j*3);
-      memcpy (&(ptr[j*3]), ptr, (width - j)*3);
+        memcpy (&(ptr[j*4]), ptr, j*4);
+      memcpy (&(ptr[j*4]), ptr, (width - j)*4);
 
       r+=dr;
       g+=dg;
       b+=db;
+      a+=da;
     }
   return pixbuf;
 }
@@ -456,12 +476,12 @@ meta_gradient_create_diagonal (int width, int height,
   ptr = gdk_pixbuf_get_pixels (tmp);
 
   a = ((float)(width - 1))/((float)(height - 1));
-  width = width * 3;
+  width = width * 4;
 
   /* copy the first line to the other lines with corresponding offset */
   for (j=0, offset=0.0; j<rowstride*height; j += rowstride)
     {
-      memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
+      memcpy (&(pixels[j]), &ptr[4*(int)offset], width);
       offset += a;
     }
 
@@ -476,7 +496,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
                                        int count)
 {
   int i, j, k;
-  long r, g, b, dr, dg, db;
+  long r, g, b, a, dr, dg, db, da;
   GdkPixbuf *pixbuf;
   unsigned char *ptr;
   unsigned char *pixels;
@@ -506,6 +526,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
   r = (long)(colors[0].red * 0xffffff);
   g = (long)(colors[0].green * 0xffffff);
   b = (long)(colors[0].blue * 0xffffff);
+  a = (long)(colors[0].alpha * 0xffffff);
 
   /* render the first line */
   for (i=1; i<count; i++)
@@ -513,25 +534,30 @@ meta_gradient_create_multi_horizontal (int width, int height,
       dr = (int)((colors[i].red   - colors[i-1].red)  *0xffffff)/(int)width2;
       dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)width2;
       db = (int)((colors[i].blue  - colors[i-1].blue) *0xffffff)/(int)width2;
+      da = (int)((colors[i].alpha  - colors[i-1].alpha) *0xffffff)/(int)width2;
       for (j=0; j<width2; j++)
         {
           *ptr++ = (unsigned char)(r>>16);
           *ptr++ = (unsigned char)(g>>16);
           *ptr++ = (unsigned char)(b>>16);
+          *ptr++ = (unsigned char)(a>>16);
           r += dr;
           g += dg;
           b += db;
+          a += da;
           k++;
        }
       r = (long)(colors[i].red   * 0xffffff);
       g = (long)(colors[i].green * 0xffffff);
       b = (long)(colors[i].blue  * 0xffffff);
+      a = (long)(colors[i].alpha  * 0xffffff);
     }
   for (j=k; j<width; j++)
     {
       *ptr++ = (unsigned char)(r>>16);
       *ptr++ = (unsigned char)(g>>16);
       *ptr++ = (unsigned char)(b>>16);
+      *ptr++ = (unsigned char)(a>>16);
     }
 
   /* copy the first line to the other lines */
@@ -548,7 +574,7 @@ meta_gradient_create_multi_vertical (int width, int height,
                                      int count)
 {
   int i, j, k;
-  long r, g, b, dr, dg, db;
+  long r, g, b, a, dr, dg, db, da;
   GdkPixbuf *pixbuf;
   unsigned char *ptr, *tmp, *pixels;
   int height2;
@@ -578,33 +604,38 @@ meta_gradient_create_multi_vertical (int width, int height,
   r = (long)(colors[0].red * 0xffffff);
   g = (long)(colors[0].green * 0xffffff);
   b = (long)(colors[0].blue * 0xffffff);
+  a = (long)(colors[0].alpha * 0xffffff);
 
   for (i=1; i<count; i++)
     {
       dr = (int)((colors[i].red   - colors[i-1].red)  *0xffffff)/(int)height2;
       dg = (int)((colors[i].green - colors[i-1].green)*0xffffff)/(int)height2;
       db = (int)((colors[i].blue  - colors[i-1].blue) *0xffffff)/(int)height2;
+      da = (int)((colors[i].alpha  - colors[i-1].alpha) *0xffffff)/(int)height2;
 
       for (j=0; j<height2; j++)
         {
           ptr[0] = (unsigned char)(r>>16);
           ptr[1] = (unsigned char)(g>>16);
           ptr[2] = (unsigned char)(b>>16);
+          ptr[3] = (unsigned char)(a>>16);
 
           for (x=1; x <= width/2; x *= 2)
-            memcpy (&(ptr[x*3]), ptr, x*3);
-          memcpy (&(ptr[x*3]), ptr, (width - x)*3);
+            memcpy (&(ptr[x*4]), ptr, x*4);
+          memcpy (&(ptr[x*4]), ptr, (width - x)*4);
 
           ptr += rowstride;
 
           r += dr;
           g += dg;
           b += db;
+          a += da;
           k++;
        }
       r = (long)(colors[i].red   * 0xffffff);
       g = (long)(colors[i].green * 0xffffff);
       b = (long)(colors[i].blue  * 0xffffff);
+      a = (long)(colors[i].alpha  * 0xffffff);
     }
 
   if (k<height)
@@ -614,10 +645,11 @@ meta_gradient_create_multi_vertical (int width, int height,
       ptr[0] = (unsigned char) (r>>16);
       ptr[1] = (unsigned char) (g>>16);
       ptr[2] = (unsigned char) (b>>16);
+      ptr[3] = (unsigned char) (a>>16);
 
       for (x=1; x <= width/2; x *= 2)
-        memcpy (&(ptr[x*3]), ptr, x*3);
-      memcpy (&(ptr[x*3]), ptr, (width - x)*3);
+        memcpy (&(ptr[x*4]), ptr, x*4);
+      memcpy (&(ptr[x*4]), ptr, (width - x)*4);
 
       ptr += rowstride;
 


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