summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Kareh <[email protected]>2019-05-30 16:27:59 -0400
committerVictor Kareh <[email protected]>2019-06-05 12:34:34 -0400
commita1797ff49005fe18a3ae55f763f5a58ade66b480 (patch)
treea65dc5158e529c37801d4ecbc9b4aedf1c889684
parentfc5c86d9da24c795e42b0a00c6414365ea8949df (diff)
downloadmarco-a1797ff49005fe18a3ae55f763f5a58ade66b480.tar.bz2
marco-a1797ff49005fe18a3ae55f763f5a58ade66b480.tar.xz
gradient: sync code with mutter before it was removed
upstream commits: https://gitlab.gnome.org/GNOME/metacity/commit/3932dca0 https://gitlab.gnome.org/GNOME/metacity/commit/10240013 https://gitlab.gnome.org/GNOME/metacity/commit/3fa97193
-rw-r--r--src/ui/gradient.c496
-rw-r--r--src/ui/gradient.h9
2 files changed, 280 insertions, 225 deletions
diff --git a/src/ui/gradient.c b/src/ui/gradient.c
index 550017e1..d9bbb3f5 100644
--- a/src/ui/gradient.c
+++ b/src/ui/gradient.c
@@ -22,40 +22,17 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301, USA. */
-#include "gradient.h"
-#include "util.h"
-#include <string.h>
+/**
+ * SECTION: gradient
+ * @title: Gradients
+ * @short_description: Metacity gradient rendering
+ */
-#include <gdk/gdk.h>
+#include "config.h"
-/* This is all Alfredo's and Dan's usual very nice WindowMaker code,
- * slightly GTK-ized
- */
-static GdkPixbuf* meta_gradient_create_horizontal (int width,
- int height,
- const GdkRGBA *from,
- const GdkRGBA *to);
-static GdkPixbuf* meta_gradient_create_vertical (int width,
- int height,
- const GdkRGBA *from,
- const GdkRGBA *to);
-static GdkPixbuf* meta_gradient_create_diagonal (int width,
- int height,
- const GdkRGBA *from,
- const GdkRGBA *to);
-static GdkPixbuf* meta_gradient_create_multi_horizontal (int width,
- int height,
- const GdkRGBA *colors,
- int count);
-static GdkPixbuf* meta_gradient_create_multi_vertical (int width,
- int height,
- const GdkRGBA *colors,
- int count);
-static GdkPixbuf* meta_gradient_create_multi_diagonal (int width,
- int height,
- const GdkRGBA *colors,
- int count);
+#include <string.h>
+#include "gradient.h"
/* Used as the destroy notification function for gdk_pixbuf_new() */
static void
@@ -65,7 +42,7 @@ free_buffer (guchar *pixels, gpointer data)
}
static GdkPixbuf*
-blank_pixbuf (int width, int height, gboolean no_padding)
+blank_pixbuf (int width, int height)
{
guchar *buf;
int rowstride;
@@ -73,175 +50,19 @@ blank_pixbuf (int width, int height, gboolean no_padding)
g_return_val_if_fail (width > 0, NULL);
g_return_val_if_fail (height > 0, NULL);
- if (no_padding)
- rowstride = width * 3;
- else
- /* Always align rows to 32-bit boundaries */
- rowstride = 4 * ((3 * width + 3) / 4);
+ /* Always align rows to 32-bit boundaries */
+ 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);
}
-GdkPixbuf*
-meta_gradient_create_simple (int width,
- int height,
- const GdkRGBA *from,
- const GdkRGBA *to,
- MetaGradientType style)
-{
- switch (style)
- {
- case META_GRADIENT_HORIZONTAL:
- return meta_gradient_create_horizontal (width, height,
- from, to);
- case META_GRADIENT_VERTICAL:
- return meta_gradient_create_vertical (width, height,
- from, to);
-
- case META_GRADIENT_DIAGONAL:
- return meta_gradient_create_diagonal (width, height,
- from, to);
- case META_GRADIENT_LAST:
- break;
- }
- g_assert_not_reached ();
- return NULL;
-}
-
-GdkPixbuf*
-meta_gradient_create_multi (int width,
- int height,
- const GdkRGBA *colors,
- int n_colors,
- MetaGradientType style)
-{
- if (n_colors > 2)
- {
- switch (style)
- {
- case META_GRADIENT_HORIZONTAL:
- return meta_gradient_create_multi_horizontal (width, height, colors, n_colors);
- case META_GRADIENT_VERTICAL:
- return meta_gradient_create_multi_vertical (width, height, colors, n_colors);
- case META_GRADIENT_DIAGONAL:
- return meta_gradient_create_multi_diagonal (width, height, colors, n_colors);
- case META_GRADIENT_LAST:
- g_assert_not_reached ();
- break;
- }
- }
- else if (n_colors > 1)
- {
- return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
- style);
- }
- else if (n_colors > 0)
- {
- return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
- style);
- }
- g_assert_not_reached ();
- return NULL;
-}
-
-/* Interwoven essentially means we have two vertical gradients,
- * cut into horizontal strips of the given thickness, and then the strips
- * are alternated. I'm not sure what it's good for, just copied since
- * WindowMaker had it.
- */
-GdkPixbuf*
-meta_gradient_create_interwoven (int width,
- int height,
- const GdkRGBA colors1[2],
- int thickness1,
- const GdkRGBA colors2[2],
- int thickness2)
-{
- int i, j, k, l, ll;
- long r1, g1, b1, dr1, dg1, db1;
- long r2, g2, b2, dr2, dg2, db2;
- GdkPixbuf *pixbuf;
- unsigned char *ptr;
- unsigned char *pixels;
- int rowstride;
-
- pixbuf = blank_pixbuf (width, height, FALSE);
- if (pixbuf == NULL)
- return NULL;
-
- pixels = gdk_pixbuf_get_pixels (pixbuf);
- rowstride = gdk_pixbuf_get_rowstride (pixbuf);
-
- r1 = (long)(colors1[0].red*0xffffff);
- g1 = (long)(colors1[0].green*0xffffff);
- b1 = (long)(colors1[0].blue*0xffffff);
-
- r2 = (long)(colors2[0].red*0xffffff);
- g2 = (long)(colors2[0].green*0xffffff);
- b2 = (long)(colors2[0].blue*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;
-
- 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;
-
- for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
- {
- ptr = pixels + i * rowstride;
-
- if (k == 0)
- {
- ptr[0] = (unsigned char) (r1>>16);
- ptr[1] = (unsigned char) (g1>>16);
- ptr[2] = (unsigned char) (b1>>16);
- }
- else
- {
- ptr[0] = (unsigned char) (r2>>16);
- ptr[1] = (unsigned char) (g2>>16);
- ptr[2] = (unsigned char) (b2>>16);
- }
-
- for (j=1; j <= width/2; j *= 2)
- memcpy (&(ptr[j*3]), ptr, j*3);
- memcpy (&(ptr[j*3]), ptr, (width - j)*3);
-
- if (++l == ll)
- {
- if (k == 0)
- {
- k = 1;
- ll = thickness2;
- }
- else
- {
- k = 0;
- ll = thickness1;
- }
- l = 0;
- }
- r1+=dr1;
- g1+=dg1;
- b1+=db1;
-
- r2+=dr2;
- g2+=dg2;
- b2+=db2;
- }
-
- return pixbuf;
-}
-
/*
*----------------------------------------------------------------------
* meta_gradient_create_horizontal--
@@ -257,19 +78,19 @@ meta_gradient_create_interwoven (int width,
*/
static GdkPixbuf*
meta_gradient_create_horizontal (int width, int height,
- const GdkRGBA *from,
- const GdkRGBA *to)
+ const GdkRGBA *from,
+ 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, FALSE);
+ pixbuf = blank_pixbuf (width, height);
if (pixbuf == NULL)
return NULL;
@@ -280,26 +101,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 */
@@ -325,19 +152,19 @@ meta_gradient_create_horizontal (int width, int height,
*/
static GdkPixbuf*
meta_gradient_create_vertical (int width, int height,
- const GdkRGBA *from,
- const GdkRGBA *to)
+ const GdkRGBA *from,
+ 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;
- pixbuf = blank_pixbuf (width, height, FALSE);
+ pixbuf = blank_pixbuf (width, height);
if (pixbuf == NULL)
return NULL;
@@ -347,17 +174,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++)
{
@@ -366,14 +197,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;
}
@@ -393,10 +226,11 @@ meta_gradient_create_vertical (int width, int height,
*----------------------------------------------------------------------
*/
+
static GdkPixbuf*
meta_gradient_create_diagonal (int width, int height,
- const GdkRGBA *from,
- const GdkRGBA *to)
+ const GdkRGBA *from,
+ const GdkRGBA *to)
{
GdkPixbuf *pixbuf, *tmp;
int j;
@@ -410,7 +244,7 @@ meta_gradient_create_diagonal (int width, int height,
else if (height == 1)
return meta_gradient_create_horizontal (width, height, from, to);
- pixbuf = blank_pixbuf (width, height, FALSE);
+ pixbuf = blank_pixbuf (width, height);
if (pixbuf == NULL)
return NULL;
@@ -427,12 +261,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;
}
@@ -440,13 +274,14 @@ meta_gradient_create_diagonal (int width, int height,
return pixbuf;
}
+
static GdkPixbuf*
meta_gradient_create_multi_horizontal (int width, int height,
- const GdkRGBA *colors,
+ const GdkRGBA *colors,
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;
@@ -455,7 +290,7 @@ meta_gradient_create_multi_horizontal (int width, int height,
g_return_val_if_fail (count > 2, NULL);
- pixbuf = blank_pixbuf (width, height, FALSE);
+ pixbuf = blank_pixbuf (width, height);
if (pixbuf == NULL)
return NULL;
@@ -476,6 +311,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++)
@@ -483,28 +319,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 */
@@ -517,11 +355,11 @@ meta_gradient_create_multi_horizontal (int width, int height,
static GdkPixbuf*
meta_gradient_create_multi_vertical (int width, int height,
- const GdkRGBA *colors,
+ const GdkRGBA *colors,
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;
@@ -530,7 +368,7 @@ meta_gradient_create_multi_vertical (int width, int height,
g_return_val_if_fail (count > 2, NULL);
- pixbuf = blank_pixbuf (width, height, FALSE);
+ pixbuf = blank_pixbuf (width, height);
if (pixbuf == NULL)
return NULL;
@@ -551,34 +389,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)
@@ -588,10 +430,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;
@@ -605,9 +448,10 @@ meta_gradient_create_multi_vertical (int width, int height,
return pixbuf;
}
+
static GdkPixbuf*
meta_gradient_create_multi_diagonal (int width, int height,
- const GdkRGBA *colors,
+ const GdkRGBA *colors,
int count)
{
GdkPixbuf *pixbuf, *tmp;
@@ -812,6 +656,204 @@ meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
g_free (gradient);
}
+/**
+ * meta_gradient_create_simple:
+ * @width: Width in pixels
+ * @height: Height in pixels
+ * @from: Starting color
+ * @to: Ending color
+ * @style: Gradient style
+ *
+ * Returns: (transfer full): A new linear gradient
+ */
+GdkPixbuf*
+meta_gradient_create_simple (int width,
+ int height,
+ const GdkRGBA *from,
+ const GdkRGBA *to,
+ MetaGradientType style)
+{
+ switch (style)
+ {
+ case META_GRADIENT_HORIZONTAL:
+ return meta_gradient_create_horizontal (width, height,
+ from, to);
+ case META_GRADIENT_VERTICAL:
+ return meta_gradient_create_vertical (width, height,
+ from, to);
+
+ case META_GRADIENT_DIAGONAL:
+ return meta_gradient_create_diagonal (width, height,
+ from, to);
+ case META_GRADIENT_LAST:
+ break;
+
+ default:
+ break;
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
+/**
+ * meta_gradient_create_multi:
+ * @width: Width in pixels
+ * @height: Height in pixels
+ * @colors: (array length=n_colors): Array of colors
+ * @n_colors: Number of colors
+ * @style: Gradient style
+ *
+ * Returns: (transfer full): A new multi-step linear gradient
+ */
+GdkPixbuf*
+meta_gradient_create_multi (int width,
+ int height,
+ const GdkRGBA *colors,
+ int n_colors,
+ MetaGradientType style)
+{
+
+ if (n_colors > 2)
+ {
+ switch (style)
+ {
+ case META_GRADIENT_HORIZONTAL:
+ return meta_gradient_create_multi_horizontal (width, height, colors, n_colors);
+ case META_GRADIENT_VERTICAL:
+ return meta_gradient_create_multi_vertical (width, height, colors, n_colors);
+ case META_GRADIENT_DIAGONAL:
+ return meta_gradient_create_multi_diagonal (width, height, colors, n_colors);
+ case META_GRADIENT_LAST:
+ g_assert_not_reached ();
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+ else if (n_colors > 1)
+ {
+ return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
+ style);
+ }
+ else if (n_colors > 0)
+ {
+ return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
+ style);
+ }
+ g_assert_not_reached ();
+ return NULL;
+}
+
+/**
+ * meta_gradient_create_interwoven: (skip)
+ * @width: Width in pixels
+ * @height: Height in pixels
+ * @colors1: Array of colors
+ * @thickness1: Thickness
+ * @colors2: Array of colors
+ * @thickness2: Thickness
+ *
+ * Interwoven essentially means we have two vertical gradients,
+ * cut into horizontal strips of the given thickness, and then the strips
+ * are alternated. I'm not sure what it's good for, just copied since
+ * WindowMaker had it.
+ */
+GdkPixbuf*
+meta_gradient_create_interwoven (int width,
+ int height,
+ const GdkRGBA colors1[2],
+ int thickness1,
+ const GdkRGBA colors2[2],
+ int thickness2)
+{
+
+ int i, j, k, l, ll;
+ 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;
+ int rowstride;
+
+ pixbuf = blank_pixbuf (width, height);
+ if (pixbuf == NULL)
+ return NULL;
+
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ 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;
+ da2 = ((colors2[1].alpha-colors2[0].alpha)*0xffffff)/(int)height;
+
+ for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
+ {
+ ptr = pixels + i * rowstride;
+
+ if (k == 0)
+ {
+ 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*4]), ptr, j*4);
+ memcpy (&(ptr[j*4]), ptr, (width - j)*4);
+
+ if (++l == ll)
+ {
+ if (k == 0)
+ {
+ k = 1;
+ ll = thickness2;
+ }
+ else
+ {
+ k = 0;
+ ll = thickness1;
+ }
+ l = 0;
+ }
+ r1+=dr1;
+ g1+=dg1;
+ b1+=db1;
+ a1+=da1;
+
+ r2+=dr2;
+ g2+=dg2;
+ b2+=db2;
+ a2+=da2;
+ }
+
+ return pixbuf;
+}
+
void
meta_gradient_add_alpha (GdkPixbuf *pixbuf,
const guchar *alphas,
@@ -839,5 +881,9 @@ meta_gradient_add_alpha (GdkPixbuf *pixbuf,
case META_GRADIENT_LAST:
g_assert_not_reached ();
break;
+
+ default:
+ g_assert_not_reached ();
+ break;
}
}
diff --git a/src/ui/gradient.h b/src/ui/gradient.h
index e40ba8eb..8da20485 100644
--- a/src/ui/gradient.h
+++ b/src/ui/gradient.h
@@ -27,6 +27,14 @@
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
+/**
+ * MetaGradientType:
+ * @META_GRADIENT_VERTICAL: Vertical gradient
+ * @META_GRADIENT_HORIZONTAL: Horizontal gradient
+ * @META_GRADIENT_DIAGONAL: Diagonal gradient
+ * @META_GRADIENT_LAST: Marks the end of the #MetaGradientType enumeration
+ *
+ */
typedef enum
{
META_GRADIENT_VERTICAL,
@@ -52,6 +60,7 @@ GdkPixbuf* meta_gradient_create_interwoven (int width,
const GdkRGBA colors2[2],
int thickness2);
+
/* Generate an alpha gradient and multiply it with the existing alpha
* channel of the given pixbuf
*/