From 2e4f67f3f9c5cb626bec9713b976691bbec5f200 Mon Sep 17 00:00:00 2001 From: "Jasper St. Pierre" Date: Fri, 28 Oct 2011 13:08:48 -0400 Subject: [PATCH] theme: Remove our own gradient stuff Part one of porting to cairo. This requires removing support for a seldomly used feature in the theme format - alpha gradients on tint, icon and image. Grepping through gnome-themes-standard and searching for code, I couldn't find any usage of this feature, so I consider it safe to remove. Thanks to Benjamin Otte for helping me clean this up. https://bugzilla.gnome.org/show_bug.cgi?id=662962 --- src/Makefile.am | 7 +- src/meta/gradient.h | 65 ---- src/ui/gradient.c | 865 ----------------------------------------- src/ui/testgradient.c | 317 --------------- src/ui/theme-parser.c | 19 +- src/ui/theme-private.h | 19 +- src/ui/theme.c | 163 ++++---- 7 files changed, 83 insertions(+), 1372 deletions(-) delete mode 100644 src/meta/gradient.h delete mode 100644 src/ui/gradient.c delete mode 100644 src/ui/testgradient.c diff --git a/src/Makefile.am b/src/Makefile.am index d5b398c08..ea6794d76 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,8 +88,6 @@ libmutter_la_SOURCES = \ core/eventqueue.h \ core/frame.c \ core/frame.h \ - ui/gradient.c \ - meta/gradient.h \ core/group-private.h \ core/group-props.c \ core/group-props.h \ @@ -163,7 +161,6 @@ libmutterinclude_base_headers = \ meta/compositor.h \ meta/display.h \ meta/errors.h \ - meta/gradient.h \ meta/group.h \ meta/keybindings.h \ meta/main.h \ @@ -236,13 +233,11 @@ endif mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter.la testboxes_SOURCES = core/testboxes.c -testgradient_SOURCES = ui/testgradient.c testasyncgetprop_SOURCES = core/testasyncgetprop.c -noinst_PROGRAMS=testboxes testgradient testasyncgetprop +noinst_PROGRAMS=testboxes testasyncgetprop testboxes_LDADD = $(MUTTER_LIBS) libmutter.la -testgradient_LDADD = $(MUTTER_LIBS) libmutter.la testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la @INTLTOOL_DESKTOP_RULE@ diff --git a/src/meta/gradient.h b/src/meta/gradient.h deleted file mode 100644 index 5e9db8a04..000000000 --- a/src/meta/gradient.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter gradient rendering */ - -/* - * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in - * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. */ - -#ifndef META_GRADIENT_H -#define META_GRADIENT_H - -#include -#include - -typedef enum -{ - META_GRADIENT_VERTICAL, - META_GRADIENT_HORIZONTAL, - META_GRADIENT_DIAGONAL, - META_GRADIENT_LAST -} MetaGradientType; - -GdkPixbuf* meta_gradient_create_simple (int width, - int height, - const GdkRGBA *from, - const GdkRGBA *to, - MetaGradientType style); -GdkPixbuf* meta_gradient_create_multi (int width, - int height, - const GdkRGBA *colors, - int n_colors, - MetaGradientType style); -GdkPixbuf* meta_gradient_create_interwoven (int width, - int height, - const GdkRGBA colors1[2], - int thickness1, - const GdkRGBA colors2[2], - int thickness2); - - -/* Generate an alpha gradient and multiply it with the existing alpha - * channel of the given pixbuf - */ -void meta_gradient_add_alpha (GdkPixbuf *pixbuf, - const guchar *alphas, - int n_alphas, - MetaGradientType type); - - -#endif diff --git a/src/ui/gradient.c b/src/ui/gradient.c deleted file mode 100644 index 21ae422e4..000000000 --- a/src/ui/gradient.c +++ /dev/null @@ -1,865 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Metacity gradient rendering */ - -/* - * Copyright (C) 2001 Havoc Pennington, 99% copied from wrlib in - * WindowMaker, Copyright (C) 1997-2000 Dan Pascu and Alfredo Kojima - * Copyright (C) 2005 Elijah Newren - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. */ - -#include -#include -#include - -/* 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); - - -/* Used as the destroy notification function for gdk_pixbuf_new() */ -static void -free_buffer (guchar *pixels, gpointer data) -{ - g_free (pixels); -} - -static GdkPixbuf* -blank_pixbuf (int width, int height, gboolean no_padding) -{ - guchar *buf; - int rowstride; - - 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); - - buf = g_try_malloc (height * rowstride); - if (!buf) - return NULL; - - return gdk_pixbuf_new_from_data (buf, GDK_COLORSPACE_RGB, - FALSE, 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, - 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; -} - -/** - * 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; - } - } - 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) - * - * 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>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-- - * Renders a horizontal linear gradient of the specified size in the - * GdkPixbuf format with a border of the specified type. - * - * Returns: - * A 24bit GdkPixbuf with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ -static GdkPixbuf* -meta_gradient_create_horizontal (int width, int height, - const GdkRGBA *from, - const GdkRGBA *to) -{ - int i; - long r, g, b, dr, dg, db; - GdkPixbuf *pixbuf; - unsigned char *ptr; - unsigned char *pixels; - int r0, g0, b0; - int rf, gf, bf; - int rowstride; - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - ptr = pixels; - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - r0 = (guchar) (from->red * 0xff); - g0 = (guchar) (from->green * 0xff); - b0 = (guchar) (from->blue * 0xff); - rf = (guchar) (to->red * 0xff); - gf = (guchar) (to->green * 0xff); - bf = (guchar) (to->blue * 0xff); - - r = r0 << 16; - g = g0 << 16; - b = b0 << 16; - - dr = ((rf-r0)<<16)/(int)width; - dg = ((gf-g0)<<16)/(int)width; - db = ((bf-b0)<<16)/(int)width; - /* render the first line */ - for (i=0; i>16); - *(ptr++) = (unsigned char)(g>>16); - *(ptr++) = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - } - - /* copy the first line to the other lines */ - for (i=1; ired * 0xff); - g0 = (guchar) (from->green * 0xff); - b0 = (guchar) (from->blue * 0xff); - rf = (guchar) (to->red * 0xff); - gf = (guchar) (to->green * 0xff); - bf = (guchar) (to->blue * 0xff); - - r = r0<<16; - g = g0<<16; - b = b0<<16; - - dr = ((rf-r0)<<16)/(int)height; - dg = ((gf-g0)<<16)/(int)height; - db = ((bf-b0)<<16)/(int)height; - - for (i=0; i>16); - ptr[1] = (unsigned char)(g>>16); - ptr[2] = (unsigned char)(b>>16); - - for (j=1; j <= width/2; j *= 2) - memcpy (&(ptr[j*3]), ptr, j*3); - memcpy (&(ptr[j*3]), ptr, (width - j)*3); - - r+=dr; - g+=dg; - b+=db; - } - return pixbuf; -} - - -/* - *---------------------------------------------------------------------- - * meta_gradient_create_diagonal-- - * Renders a diagonal linear gradient of the specified size in the - * GdkPixbuf format with a border of the specified type. - * - * Returns: - * A 24bit GdkPixbuf with the gradient (no alpha channel). - * - * Side effects: - * None - *---------------------------------------------------------------------- - */ - - -static GdkPixbuf* -meta_gradient_create_diagonal (int width, int height, - const GdkRGBA *from, - const GdkRGBA *to) -{ - GdkPixbuf *pixbuf, *tmp; - int j; - float a, offset; - unsigned char *ptr; - unsigned char *pixels; - int rowstride; - - if (width == 1) - return meta_gradient_create_vertical (width, height, from, to); - else if (height == 1) - return meta_gradient_create_horizontal (width, height, from, to); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to); - if (!tmp) - { - g_object_unref (G_OBJECT (pixbuf)); - return NULL; - } - - ptr = gdk_pixbuf_get_pixels (tmp); - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0.0; j 2, NULL); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - ptr = pixels; - - if (count > width) - count = width; - - if (count > 1) - width2 = width/(count-1); - else - width2 = width; - - k = 0; - - r = (long)(colors[0].red * 0xffffff); - g = (long)(colors[0].green * 0xffffff); - b = (long)(colors[0].blue * 0xffffff); - - /* render the first line */ - for (i=1; i>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - r += dr; - g += dg; - b += db; - k++; - } - r = (long)(colors[i].red * 0xffffff); - g = (long)(colors[i].green * 0xffffff); - b = (long)(colors[i].blue * 0xffffff); - } - for (j=k; j>16); - *ptr++ = (unsigned char)(g>>16); - *ptr++ = (unsigned char)(b>>16); - } - - /* copy the first line to the other lines */ - for (i=1; i 2, NULL); - - pixbuf = blank_pixbuf (width, height, FALSE); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - ptr = pixels; - - if (count > height) - count = height; - - if (count > 1) - height2 = height/(count-1); - else - height2 = height; - - k = 0; - - r = (long)(colors[0].red * 0xffffff); - g = (long)(colors[0].green * 0xffffff); - b = (long)(colors[0].blue * 0xffffff); - - for (i=1; i>16); - ptr[1] = (unsigned char)(g>>16); - ptr[2] = (unsigned char)(b>>16); - - for (x=1; x <= width/2; x *= 2) - memcpy (&(ptr[x*3]), ptr, x*3); - memcpy (&(ptr[x*3]), ptr, (width - x)*3); - - ptr += rowstride; - - r += dr; - g += dg; - b += db; - k++; - } - r = (long)(colors[i].red * 0xffffff); - g = (long)(colors[i].green * 0xffffff); - b = (long)(colors[i].blue * 0xffffff); - } - - if (k>16); - ptr[1] = (unsigned char) (g>>16); - ptr[2] = (unsigned char) (b>>16); - - for (x=1; x <= width/2; x *= 2) - memcpy (&(ptr[x*3]), ptr, x*3); - memcpy (&(ptr[x*3]), ptr, (width - x)*3); - - ptr += rowstride; - - for (j=k+1; j 2, NULL); - - if (width == 1) - return meta_gradient_create_multi_vertical (width, height, colors, count); - else if (height == 1) - return meta_gradient_create_multi_horizontal (width, height, colors, count); - - pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, - width, height); - if (pixbuf == NULL) - return NULL; - - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - if (count > width) - count = width; - if (count > height) - count = height; - - if (count > 2) - tmp = meta_gradient_create_multi_horizontal (2*width-1, 1, colors, count); - else - /* wrlib multiplies these colors by 256 before passing them in, but - * I think it's a bug in wrlib, so changed here. I could be wrong - * though, if we notice two-color multi diagonals not working. - */ - tmp = meta_gradient_create_horizontal (2*width-1, 1, - &colors[0], &colors[1]); - - if (!tmp) - { - g_object_unref (G_OBJECT (pixbuf)); - return NULL; - } - ptr = gdk_pixbuf_get_pixels (tmp); - - a = ((float)(width - 1))/((float)(height - 1)); - width = width * 3; - - /* copy the first line to the other lines with corresponding offset */ - for (j=0, offset=0; j 0); - - if (n_alphas == 1) - { - /* Optimize this */ - simple_multiply_alpha (pixbuf, alphas[0]); - return; - } - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - - gradient = g_new (unsigned char, width); - gradient_end = gradient + width; - - if (n_alphas > width) - n_alphas = width; - - if (n_alphas > 1) - width2 = width / (n_alphas - 1); - else - width2 = width; - - a = alphas[0] << 8; - gradient_p = gradient; - - /* render the gradient into an array */ - for (i = 1; i < n_alphas; i++) - { - da = (((int)(alphas[i] - (int) alphas[i-1])) << 8) / (int) width2; - - for (j = 0; j < width2; j++) - { - *gradient_p++ = (a >> 8); - - a += da; - } - - a = alphas[i] << 8; - } - - /* get leftover pixels */ - while (gradient_p != gradient_end) - { - *gradient_p++ = a >> 8; - } - - /* Now for each line of the pixbuf, fill in with the gradient */ - pixels = gdk_pixbuf_get_pixels (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - - p = pixels; - i = 0; - while (i < height) - { - unsigned char *row_end = p + rowstride; - gradient_p = gradient; - - p += 3; - while (gradient_p != gradient_end) - { - /* multiply the two alpha channels. not sure this is right. - * but some end cases are that if the pixbuf contains 255, - * then it should be modified to contain "alpha"; if the - * pixbuf contains 0, it should remain 0. - */ - /* ((*p / 255.0) * (alpha / 255.0)) * 255; */ - *p = (guchar) (((int) *p * (int) *gradient_p) / (int) 255); - - p += 4; - ++gradient_p; - } - - p = row_end; - ++i; - } - - g_free (gradient); -} - -void -meta_gradient_add_alpha (GdkPixbuf *pixbuf, - const guchar *alphas, - int n_alphas, - MetaGradientType type) -{ - g_return_if_fail (GDK_IS_PIXBUF (pixbuf)); - g_return_if_fail (gdk_pixbuf_get_has_alpha (pixbuf)); - g_return_if_fail (n_alphas > 0); - - switch (type) - { - case META_GRADIENT_HORIZONTAL: - meta_gradient_add_alpha_horizontal (pixbuf, alphas, n_alphas); - break; - - case META_GRADIENT_VERTICAL: - g_printerr ("metacity: vertical alpha channel gradient not implemented yet\n"); - break; - - case META_GRADIENT_DIAGONAL: - g_printerr ("metacity: diagonal alpha channel gradient not implemented yet\n"); - break; - - case META_GRADIENT_LAST: - g_assert_not_reached (); - break; - } -} diff --git a/src/ui/testgradient.c b/src/ui/testgradient.c deleted file mode 100644 index c66c9e52f..000000000 --- a/src/ui/testgradient.c +++ /dev/null @@ -1,317 +0,0 @@ -/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ - -/* Mutter gradient test program */ - -/* - * Copyright (C) 2002 Havoc Pennington - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. */ - -#include -#include - -typedef void (* RenderGradientFunc) (cairo_t *cr, - int width, - int height); - -static void -draw_checkerboard (cairo_t *cr, - int width, - int height) -{ - gint i, j, xcount, ycount; - GdkRGBA color1, color2; - -#define CHECK_SIZE 10 -#define SPACING 2 - - color1.red = 30000. / 65535.; - color1.green = 30000. / 65535.; - color1.blue = 30000. / 65535.; - color1.alpha = 1.0; - - color2.red = 50000. / 65535.; - color2.green = 50000. / 65535.; - color2.blue = 50000. / 65535.; - color2.alpha = 1.0; - - xcount = 0; - i = SPACING; - while (i < width) - { - j = SPACING; - ycount = xcount % 2; /* start with even/odd depending on row */ - while (j < height) - { - if (ycount % 2) - gdk_cairo_set_source_rgba (cr, &color1); - else - gdk_cairo_set_source_rgba (cr, &color2); - - /* If we're outside event->area, this will do nothing. - * It might be mildly more efficient if we handled - * the clipping ourselves, but again we're feeling lazy. - */ - cairo_rectangle (cr, i, j, CHECK_SIZE, CHECK_SIZE); - cairo_fill (cr); - - j += CHECK_SIZE + SPACING; - ++ycount; - } - - i += CHECK_SIZE + SPACING; - ++xcount; - } -} - -static void -render_simple (cairo_t *cr, - int width, int height, - MetaGradientType type, - gboolean with_alpha) -{ - GdkPixbuf *pixbuf; - GdkRGBA from, to; - - gdk_rgba_parse (&from, "blue"); - gdk_rgba_parse (&to, "green"); - - pixbuf = meta_gradient_create_simple (width, height, - &from, &to, - type); - - if (with_alpha) - { - const unsigned char alphas[] = { 0xff, 0xaa, 0x2f, 0x0, 0xcc, 0xff, 0xff }; - - if (!gdk_pixbuf_get_has_alpha (pixbuf)) - { - GdkPixbuf *new_pixbuf; - - new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - - meta_gradient_add_alpha (pixbuf, - alphas, G_N_ELEMENTS (alphas), - META_GRADIENT_HORIZONTAL); - - draw_checkerboard (cr , width, height); - } - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -} - -static void -render_vertical_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_VERTICAL, FALSE); -} - -static void -render_horizontal_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_HORIZONTAL, FALSE); -} - -static void -render_diagonal_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_DIAGONAL, FALSE); -} - -static void -render_diagonal_alpha_func (cairo_t *cr, - int width, int height) -{ - render_simple (cr, width, height, META_GRADIENT_DIAGONAL, TRUE); -} - -static void -render_multi (cairo_t *cr, - int width, int height, - MetaGradientType type) -{ - GdkPixbuf *pixbuf; -#define N_COLORS 5 - GdkRGBA colors[N_COLORS]; - - gdk_rgba_parse (&colors[0], "red"); - gdk_rgba_parse (&colors[1], "blue"); - gdk_rgba_parse (&colors[2], "orange"); - gdk_rgba_parse (&colors[3], "pink"); - gdk_rgba_parse (&colors[4], "green"); - - pixbuf = meta_gradient_create_multi (width, height, - colors, N_COLORS, - type); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -#undef N_COLORS -} - -static void -render_vertical_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_VERTICAL); -} - -static void -render_horizontal_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_HORIZONTAL); -} - -static void -render_diagonal_multi_func (cairo_t *cr, - int width, int height) -{ - render_multi (cr, width, height, META_GRADIENT_DIAGONAL); -} - -static void -render_interwoven_func (cairo_t *cr, - int width, int height) -{ - GdkPixbuf *pixbuf; -#define N_COLORS 4 - GdkRGBA colors[N_COLORS]; - - gdk_rgba_parse (&colors[0], "red"); - gdk_rgba_parse (&colors[1], "blue"); - gdk_rgba_parse (&colors[2], "pink"); - gdk_rgba_parse (&colors[3], "green"); - - pixbuf = meta_gradient_create_interwoven (width, height, - colors, height / 10, - colors + 2, height / 14); - - gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0); - cairo_rectangle (cr, 0, 0, width, height); - cairo_fill (cr); - - g_object_unref (G_OBJECT (pixbuf)); -} - -static gboolean -draw_callback (GtkWidget *widget, - cairo_t *cr, - gpointer data) -{ - RenderGradientFunc func = data; - GtkStyleContext *style; - GdkRGBA color; - - style = gtk_widget_get_style_context (widget); - - gtk_style_context_save (style); - gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget)); - gtk_style_context_lookup_color (style, "foreground-color", &color); - gtk_style_context_restore (style); - - gdk_cairo_set_source_rgba (cr, &color); - - (* func) (cr, - gtk_widget_get_allocated_width (widget), - gtk_widget_get_allocated_height (widget)); - - return FALSE; -} - -static GtkWidget* -create_gradient_window (const char *title, - RenderGradientFunc func) -{ - GtkWidget *window; - GtkWidget *drawing_area; - - window = gtk_window_new (GTK_WINDOW_TOPLEVEL); - - gtk_window_set_title (GTK_WINDOW (window), title); - - drawing_area = gtk_drawing_area_new (); - - gtk_widget_set_size_request (drawing_area, 1, 1); - - gtk_window_set_default_size (GTK_WINDOW (window), 175, 175); - - g_signal_connect (G_OBJECT (drawing_area), - "draw", - G_CALLBACK (draw_callback), - func); - - gtk_container_add (GTK_CONTAINER (window), drawing_area); - - gtk_widget_show_all (window); - - return window; -} - -static void -meta_gradient_test (void) -{ - create_gradient_window ("Simple vertical", - render_vertical_func); - - create_gradient_window ("Simple horizontal", - render_horizontal_func); - - create_gradient_window ("Simple diagonal", - render_diagonal_func); - - create_gradient_window ("Multi vertical", - render_vertical_multi_func); - - create_gradient_window ("Multi horizontal", - render_horizontal_multi_func); - - create_gradient_window ("Multi diagonal", - render_diagonal_multi_func); - - create_gradient_window ("Interwoven", - render_interwoven_func); - - create_gradient_window ("Simple diagonal with horizontal multi alpha", - render_diagonal_alpha_func); - -} - -int -main (int argc, char **argv) -{ - gtk_init (&argc, &argv); - - meta_gradient_test (); - - gtk_main (); - - return 0; -} - diff --git a/src/ui/theme-parser.c b/src/ui/theme-parser.c index 906354122..709a609b8 100644 --- a/src/ui/theme-parser.c +++ b/src/ui/theme-parser.c @@ -2147,10 +2147,8 @@ parse_draw_op_element (GMarkupParseContext *context, const char *y; const char *width; const char *height; - const char *alpha; const char *colorize; const char *fill_type; - MetaAlphaGradientSpec *alpha_spec; GdkPixbuf *pixbuf; MetaColorSpec *colorize_spec = NULL; MetaImageFillType fill_type_val; @@ -2162,7 +2160,7 @@ parse_draw_op_element (GMarkupParseContext *context, error, "!x", &x, "!y", &y, "!width", &width, "!height", &height, - "alpha", &alpha, "!filename", &filename, + "!filename", &filename, "colorize", &colorize, "fill_type", &fill_type, NULL)) @@ -2220,13 +2218,6 @@ parse_draw_op_element (GMarkupParseContext *context, return; } } - - alpha_spec = NULL; - if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) - { - g_object_unref (G_OBJECT (pixbuf)); - return; - } op = meta_draw_op_new (META_DRAW_IMAGE); @@ -2238,7 +2229,6 @@ parse_draw_op_element (GMarkupParseContext *context, op->data.image.width = meta_draw_spec_new (info->theme, width, NULL); op->data.image.height = meta_draw_spec_new (info->theme, height, NULL); - op->data.image.alpha_spec = alpha_spec; op->data.image.fill_type = fill_type_val; /* Check for vertical & horizontal stripes */ @@ -2529,16 +2519,13 @@ parse_draw_op_element (GMarkupParseContext *context, const char *y; const char *width; const char *height; - const char *alpha; const char *fill_type; - MetaAlphaGradientSpec *alpha_spec; MetaImageFillType fill_type_val; if (!locate_attributes (context, element_name, attribute_names, attribute_values, error, "!x", &x, "!y", &y, "!width", &width, "!height", &height, - "alpha", &alpha, "fill_type", &fill_type, NULL)) return; @@ -2570,9 +2557,6 @@ parse_draw_op_element (GMarkupParseContext *context, } } - alpha_spec = NULL; - if (alpha && !parse_alpha (alpha, &alpha_spec, context, error)) - return; op = meta_draw_op_new (META_DRAW_ICON); @@ -2581,7 +2565,6 @@ parse_draw_op_element (GMarkupParseContext *context, op->data.icon.width = meta_draw_spec_new (info->theme, width, NULL); op->data.icon.height = meta_draw_spec_new (info->theme, height, NULL); - op->data.icon.alpha_spec = alpha_spec; op->data.icon.fill_type = fill_type_val; g_assert (info->op_list); diff --git a/src/ui/theme-private.h b/src/ui/theme-private.h index 0f28b31a8..f9f4da67b 100644 --- a/src/ui/theme-private.h +++ b/src/ui/theme-private.h @@ -25,7 +25,6 @@ #define META_THEME_PRIVATE_H #include -#include #include #include #include @@ -274,6 +273,14 @@ typedef enum META_IMAGE_FILL_TILE } MetaImageFillType; +typedef enum +{ + META_GRADIENT_VERTICAL, + META_GRADIENT_HORIZONTAL, + META_GRADIENT_DIAGONAL, + META_GRADIENT_LAST +} MetaGradientType; + typedef enum { META_COLOR_SPEC_BASIC, @@ -540,7 +547,6 @@ struct _MetaDrawOp struct { MetaColorSpec *colorize_spec; - MetaAlphaGradientSpec *alpha_spec; GdkPixbuf *pixbuf; MetaDrawSpec *x; MetaDrawSpec *y; @@ -583,7 +589,6 @@ struct _MetaDrawOp } gtk_vline; struct { - MetaAlphaGradientSpec *alpha_spec; MetaDrawSpec *x; MetaDrawSpec *y; MetaDrawSpec *width; @@ -991,8 +996,12 @@ gboolean meta_draw_op_list_contains (MetaDrawOpList *op_list, MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type); void meta_gradient_spec_free (MetaGradientSpec *desc); -GdkPixbuf* meta_gradient_spec_render (const MetaGradientSpec *desc, - GtkStyleContext *gtk_style, +void meta_gradient_spec_render (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + cairo_t *cr, + GtkStyleContext *style, + int x, + int y, int width, int height); gboolean meta_gradient_spec_validate (MetaGradientSpec *spec, diff --git a/src/ui/theme.c b/src/ui/theme.c index d923fbed3..e92503118 100644 --- a/src/ui/theme.c +++ b/src/ui/theme.c @@ -38,7 +38,6 @@ #include #include "theme-private.h" #include -#include #include #include #include @@ -998,42 +997,91 @@ meta_gradient_spec_free (MetaGradientSpec *spec) g_free (spec); } -GdkPixbuf* -meta_gradient_spec_render (const MetaGradientSpec *spec, - GtkStyleContext *style, - int width, - int height) +static cairo_pattern_t * +meta_gradient_spec_pattern (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + GtkStyleContext *style) { + cairo_pattern_t *pattern; int n_colors; - GdkRGBA *colors; GSList *tmp; int i; - GdkPixbuf *pixbuf; + + if (spec->type == META_GRADIENT_HORIZONTAL) + pattern = cairo_pattern_create_linear (0, 0, 1, 0); + if (spec->type == META_GRADIENT_VERTICAL) + pattern = cairo_pattern_create_linear (0, 0, 0, 1); + else if (spec->type == META_GRADIENT_DIAGONAL) + pattern = cairo_pattern_create_linear (0, 0, 1, 1); + else + g_assert_not_reached (); n_colors = g_slist_length (spec->color_specs); if (n_colors == 0) return NULL; - colors = g_new (GdkRGBA, n_colors); + if (alpha_spec != NULL) + g_assert (n_colors == alpha_spec->n_alphas); i = 0; tmp = spec->color_specs; while (tmp != NULL) { - meta_color_spec_render (tmp->data, style, &colors[i]); + GdkRGBA color; + + meta_color_spec_render (tmp->data, style, &color); + + if (alpha_spec != NULL) + cairo_pattern_add_color_stop_rgba (pattern, + i / (float)n_colors, + color.red, + color.green, + color.blue, + alpha_spec->alphas[i]); + else + cairo_pattern_add_color_stop_rgb (pattern, + i / (float)n_colors, + color.red, + color.green, + color.blue); tmp = tmp->next; ++i; } - pixbuf = meta_gradient_create_multi (width, height, - colors, n_colors, - spec->type); + return pattern; +} - g_free (colors); - return pixbuf; +void +meta_gradient_spec_render (const MetaGradientSpec *spec, + const MetaAlphaGradientSpec *alpha_spec, + cairo_t *cr, + GtkStyleContext *style, + int x, + int y, + int width, + int height) +{ + cairo_pattern_t *pattern; + + cairo_save (cr); + + pattern = meta_gradient_spec_pattern (spec, alpha_spec, style); + if (pattern == NULL) + return; + + cairo_rectangle (cr, x, y, width, height); + + cairo_translate (cr, x, y); + cairo_scale (cr, width, height); + + cairo_set_source (cr, pattern); + cairo_fill (cr); + cairo_pattern_destroy (pattern); + + cairo_restore (cr); } gboolean @@ -3046,9 +3094,6 @@ meta_draw_op_free (MetaDrawOp *op) break; case META_DRAW_IMAGE: - if (op->data.image.alpha_spec) - meta_alpha_gradient_spec_free (op->data.image.alpha_spec); - if (op->data.image.pixbuf) g_object_unref (G_OBJECT (op->data.image.pixbuf)); @@ -3085,9 +3130,6 @@ meta_draw_op_free (MetaDrawOp *op) break; case META_DRAW_ICON: - if (op->data.icon.alpha_spec) - meta_alpha_gradient_spec_free (op->data.icon.alpha_spec); - meta_draw_spec_free (op->data.icon.x); meta_draw_spec_free (op->data.icon.y); meta_draw_spec_free (op->data.icon.width); @@ -3132,42 +3174,6 @@ meta_draw_op_free (MetaDrawOp *op) g_free (op); } -static GdkPixbuf* -apply_alpha (GdkPixbuf *pixbuf, - MetaAlphaGradientSpec *spec, - gboolean force_copy) -{ - GdkPixbuf *new_pixbuf; - gboolean needs_alpha; - - g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL); - - needs_alpha = spec && (spec->n_alphas > 1 || - spec->alphas[0] != 0xff); - - if (!needs_alpha) - return pixbuf; - - if (!gdk_pixbuf_get_has_alpha (pixbuf)) - { - new_pixbuf = gdk_pixbuf_add_alpha (pixbuf, FALSE, 0, 0, 0); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - else if (force_copy) - { - new_pixbuf = gdk_pixbuf_copy (pixbuf); - g_object_unref (G_OBJECT (pixbuf)); - pixbuf = new_pixbuf; - } - - g_assert (gdk_pixbuf_get_has_alpha (pixbuf)); - - meta_gradient_add_alpha (pixbuf, spec->alphas, spec->n_alphas, spec->type); - - return pixbuf; -} - static GdkPixbuf* pixbuf_tile (GdkPixbuf *tile, int width, @@ -3298,7 +3304,6 @@ replicate_cols (GdkPixbuf *src, static GdkPixbuf* scale_and_alpha_pixbuf (GdkPixbuf *src, - MetaAlphaGradientSpec *alpha_spec, MetaImageFillType fill_type, int width, int height, @@ -3380,9 +3385,6 @@ scale_and_alpha_pixbuf (GdkPixbuf *src, } } } - - if (pixbuf) - pixbuf = apply_alpha (pixbuf, alpha_spec, pixbuf == src); return pixbuf; } @@ -3449,32 +3451,12 @@ draw_op_as_pixbuf (const MetaDrawOp *op, gdk_pixbuf_fill (pixbuf, rgba); } - else - { - rgba = GDK_COLOR_RGBA (color); - - gdk_pixbuf_fill (pixbuf, rgba); - - meta_gradient_add_alpha (pixbuf, - op->data.tint.alpha_spec->alphas, - op->data.tint.alpha_spec->n_alphas, - op->data.tint.alpha_spec->type); - } } break; case META_DRAW_GRADIENT: - { - pixbuf = meta_gradient_spec_render (op->data.gradient.gradient_spec, - context, width, height); - - pixbuf = apply_alpha (pixbuf, - op->data.gradient.alpha_spec, - FALSE); - } break; - case META_DRAW_IMAGE: { if (op->data.image.colorize_spec) @@ -3501,7 +3483,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op, if (op->data.image.colorize_cache_pixbuf) { pixbuf = scale_and_alpha_pixbuf (op->data.image.colorize_cache_pixbuf, - op->data.image.alpha_spec, op->data.image.fill_type, width, height, op->data.image.vertical_stripes, @@ -3511,7 +3492,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op, else { pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf, - op->data.image.alpha_spec, op->data.image.fill_type, width, height, op->data.image.vertical_stripes, @@ -3530,13 +3510,11 @@ draw_op_as_pixbuf (const MetaDrawOp *op, width <= gdk_pixbuf_get_width (info->mini_icon) && height <= gdk_pixbuf_get_height (info->mini_icon)) pixbuf = scale_and_alpha_pixbuf (info->mini_icon, - op->data.icon.alpha_spec, op->data.icon.fill_type, width, height, FALSE, FALSE); else if (info->icon) pixbuf = scale_and_alpha_pixbuf (info->icon, - op->data.icon.alpha_spec, op->data.icon.fill_type, width, height, FALSE, FALSE); @@ -3816,23 +3794,16 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op, case META_DRAW_GRADIENT: { int rx, ry, rwidth, rheight; - GdkPixbuf *pixbuf; rx = parse_x_position_unchecked (op->data.gradient.x, env); ry = parse_y_position_unchecked (op->data.gradient.y, env); rwidth = parse_size_unchecked (op->data.gradient.width, env); rheight = parse_size_unchecked (op->data.gradient.height, env); - pixbuf = draw_op_as_pixbuf (op, style_gtk, info, - rwidth, rheight); - - if (pixbuf) - { - gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry); - cairo_paint (cr); - - g_object_unref (G_OBJECT (pixbuf)); - } + meta_gradient_spec_render (op->data.gradient.gradient_spec, + op->data.gradient.alpha_spec, + cr, style_gtk, + rx, ry, rwidth, rheight); } break;