diff options
author | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2016-01-17 11:59:04 +0200 |
---|---|---|
committer | Alberts Muktupāvels <alberts.muktupavels@gmail.com> | 2016-03-24 20:01:07 +0200 |
commit | 533539e15c98f305d5b5a4b8c69f700e8f6d2406 (patch) | |
tree | a4ee3d11383a99745c50260da3c21c5f0b6d53c8 | |
parent | d06393b4952333883d66c2b0d570eedc19e8e7a0 (diff) | |
download | metacity-533539e15c98f305d5b5a4b8c69f700e8f6d2406.tar.gz |
gradient: sync code with mutter before it was removed
-rw-r--r-- | src/ui/gradient.c | 151 | ||||
-rw-r--r-- | src/ui/gradient.h | 8 |
2 files changed, 116 insertions, 43 deletions
diff --git a/src/ui/gradient.c b/src/ui/gradient.c index bb327ef8..1f0fffe5 100644 --- a/src/ui/gradient.c +++ b/src/ui/gradient.c @@ -20,6 +20,12 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +/** + * SECTION:gradient + * @title: Gradients + * @short_description: Metacity gradient rendering + */ + #include "gradient.h" #include "util.h" #include <string.h> @@ -61,7 +67,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; @@ -69,22 +75,29 @@ 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); } +/** + * 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, @@ -114,6 +127,16 @@ meta_gradient_create_simple (int width, 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, @@ -121,6 +144,7 @@ meta_gradient_create_multi (int width, int n_colors, MetaGradientType style) { + if (n_colors > 2) { switch (style) @@ -153,7 +177,16 @@ meta_gradient_create_multi (int width, return NULL; } -/* Interwoven essentially means we have two vertical gradients, +/** + * 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. @@ -168,14 +201,14 @@ 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; int rowstride; - pixbuf = blank_pixbuf (width, height, FALSE); + pixbuf = blank_pixbuf (width, height); if (pixbuf == NULL) return NULL; @@ -185,18 +218,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; + da2 = ((colors2[1].alpha-colors2[0].alpha)*0xffffff)/(int)height; for (i=0,k=0,l=0,ll=thickness1; i<height; i++) { @@ -207,17 +244,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) { @@ -236,10 +275,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; @@ -260,19 +301,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; @@ -283,26 +324,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 */ @@ -328,19 +375,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; @@ -350,17 +397,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++) { @@ -369,14 +420,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; } @@ -399,8 +452,8 @@ 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; @@ -414,7 +467,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; @@ -431,12 +484,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; } @@ -447,11 +500,11 @@ meta_gradient_create_diagonal (int width, int height, 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; @@ -460,7 +513,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; @@ -481,6 +534,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++) @@ -488,25 +542,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 */ @@ -519,11 +578,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; @@ -532,7 +591,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; @@ -553,33 +612,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) @@ -589,10 +653,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; @@ -609,7 +674,7 @@ meta_gradient_create_multi_vertical (int width, int height, static GdkPixbuf* meta_gradient_create_multi_diagonal (int width, int height, - const GdkRGBA *colors, + const GdkRGBA *colors, int count) { GdkPixbuf *pixbuf, *tmp; diff --git a/src/ui/gradient.h b/src/ui/gradient.h index 0f2fad24..af577b8e 100644 --- a/src/ui/gradient.h +++ b/src/ui/gradient.h @@ -25,6 +25,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, |