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
This commit is contained in:
Jasper St. Pierre 2011-10-28 13:08:48 -04:00
parent 69c11b59c4
commit 2e4f67f3f9
7 changed files with 83 additions and 1372 deletions

View File

@ -88,8 +88,6 @@ libmutter_la_SOURCES = \
core/eventqueue.h \ core/eventqueue.h \
core/frame.c \ core/frame.c \
core/frame.h \ core/frame.h \
ui/gradient.c \
meta/gradient.h \
core/group-private.h \ core/group-private.h \
core/group-props.c \ core/group-props.c \
core/group-props.h \ core/group-props.h \
@ -163,7 +161,6 @@ libmutterinclude_base_headers = \
meta/compositor.h \ meta/compositor.h \
meta/display.h \ meta/display.h \
meta/errors.h \ meta/errors.h \
meta/gradient.h \
meta/group.h \ meta/group.h \
meta/keybindings.h \ meta/keybindings.h \
meta/main.h \ meta/main.h \
@ -236,13 +233,11 @@ endif
mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter.la mutter_theme_viewer_LDADD= $(MUTTER_LIBS) libmutter.la
testboxes_SOURCES = core/testboxes.c testboxes_SOURCES = core/testboxes.c
testgradient_SOURCES = ui/testgradient.c
testasyncgetprop_SOURCES = core/testasyncgetprop.c testasyncgetprop_SOURCES = core/testasyncgetprop.c
noinst_PROGRAMS=testboxes testgradient testasyncgetprop noinst_PROGRAMS=testboxes testasyncgetprop
testboxes_LDADD = $(MUTTER_LIBS) libmutter.la testboxes_LDADD = $(MUTTER_LIBS) libmutter.la
testgradient_LDADD = $(MUTTER_LIBS) libmutter.la
testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la testasyncgetprop_LDADD = $(MUTTER_LIBS) libmutter.la
@INTLTOOL_DESKTOP_RULE@ @INTLTOOL_DESKTOP_RULE@

View File

@ -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 <gdk-pixbuf/gdk-pixbuf.h>
#include <gdk/gdk.h>
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

View File

@ -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 <meta/gradient.h>
#include <meta/util.h>
#include <string.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);
/* 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<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--
* 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<width; i++)
{
*(ptr++) = (unsigned char)(r>>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; i<height; i++)
{
memcpy (&(pixels[i*rowstride]), pixels, rowstride);
}
return pixbuf;
}
/*
*----------------------------------------------------------------------
* meta_gradient_create_vertical--
* Renders a vertical 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_vertical (int width, int height,
const GdkRGBA *from,
const GdkRGBA *to)
{
int i, j;
long r, g, b, dr, dg, db;
GdkPixbuf *pixbuf;
unsigned char *ptr;
int r0, g0, b0;
int rf, gf, bf;
int rowstride;
unsigned char *pixels;
pixbuf = blank_pixbuf (width, height, FALSE);
if (pixbuf == NULL)
return NULL;
pixels = gdk_pixbuf_get_pixels (pixbuf);
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)height;
dg = ((gf-g0)<<16)/(int)height;
db = ((bf-b0)<<16)/(int)height;
for (i=0; i<height; i++)
{
ptr = pixels + i * rowstride;
ptr[0] = (unsigned char)(r>>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<rowstride*height; j += rowstride)
{
memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
offset += a;
}
g_object_unref (G_OBJECT (tmp));
return pixbuf;
}
static GdkPixbuf*
meta_gradient_create_multi_horizontal (int width, int height,
const GdkRGBA *colors,
int count)
{
int i, j, k;
long r, g, b, dr, dg, db;
GdkPixbuf *pixbuf;
unsigned char *ptr;
unsigned char *pixels;
int width2;
int rowstride;
g_return_val_if_fail (count > 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<count; i++)
{
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;
for (j=0; j<width2; j++)
{
*ptr++ = (unsigned char)(r>>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<width; j++)
{
*ptr++ = (unsigned char)(r>>16);
*ptr++ = (unsigned char)(g>>16);
*ptr++ = (unsigned char)(b>>16);
}
/* copy the first line to the other lines */
for (i=1; i<height; i++)
{
memcpy (&(pixels[i*rowstride]), pixels, rowstride);
}
return pixbuf;
}
static GdkPixbuf*
meta_gradient_create_multi_vertical (int width, int height,
const GdkRGBA *colors,
int count)
{
int i, j, k;
long r, g, b, dr, dg, db;
GdkPixbuf *pixbuf;
unsigned char *ptr, *tmp, *pixels;
int height2;
int x;
int rowstride;
g_return_val_if_fail (count > 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<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;
for (j=0; j<height2; j++)
{
ptr[0] = (unsigned char)(r>>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<height)
{
tmp = ptr;
ptr[0] = (unsigned char) (r>>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<height; j++)
{
memcpy (ptr, tmp, rowstride);
ptr += rowstride;
}
}
return pixbuf;
}
static GdkPixbuf*
meta_gradient_create_multi_diagonal (int width, int height,
const GdkRGBA *colors,
int count)
{
GdkPixbuf *pixbuf, *tmp;
float a, offset;
int j;
unsigned char *ptr;
unsigned char *pixels;
int rowstride;
g_return_val_if_fail (count > 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<rowstride*height; j += rowstride)
{
memcpy (&(pixels[j]), &ptr[3*(int)offset], width);
offset += a;
}
g_object_unref (G_OBJECT (tmp));
return pixbuf;
}
static void
simple_multiply_alpha (GdkPixbuf *pixbuf,
guchar alpha)
{
guchar *pixels;
int rowstride;
int height;
int row;
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
if (alpha == 255)
return;
g_assert (gdk_pixbuf_get_has_alpha (pixbuf));
pixels = gdk_pixbuf_get_pixels (pixbuf);
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
row = 0;
while (row < height)
{
guchar *p;
guchar *end;
p = pixels + row * rowstride;
end = p + rowstride;
while (p != end)
{
p += 3; /* skip RGB */
/* 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) alpha) / (int) 255);
++p; /* skip A */
}
++row;
}
}
static void
meta_gradient_add_alpha_horizontal (GdkPixbuf *pixbuf,
const unsigned char *alphas,
int n_alphas)
{
int i, j;
long a, da;
unsigned char *p;
unsigned char *pixels;
int width2;
int rowstride;
int width, height;
unsigned char *gradient;
unsigned char *gradient_p;
unsigned char *gradient_end;
g_return_if_fail (n_alphas > 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;
}
}

View File

@ -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 <meta/gradient.h>
#include <gtk/gtk.h>
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;
}

View File

@ -2147,10 +2147,8 @@ parse_draw_op_element (GMarkupParseContext *context,
const char *y; const char *y;
const char *width; const char *width;
const char *height; const char *height;
const char *alpha;
const char *colorize; const char *colorize;
const char *fill_type; const char *fill_type;
MetaAlphaGradientSpec *alpha_spec;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
MetaColorSpec *colorize_spec = NULL; MetaColorSpec *colorize_spec = NULL;
MetaImageFillType fill_type_val; MetaImageFillType fill_type_val;
@ -2162,7 +2160,7 @@ parse_draw_op_element (GMarkupParseContext *context,
error, error,
"!x", &x, "!y", &y, "!x", &x, "!y", &y,
"!width", &width, "!height", &height, "!width", &width, "!height", &height,
"alpha", &alpha, "!filename", &filename, "!filename", &filename,
"colorize", &colorize, "colorize", &colorize,
"fill_type", &fill_type, "fill_type", &fill_type,
NULL)) NULL))
@ -2220,13 +2218,6 @@ parse_draw_op_element (GMarkupParseContext *context,
return; 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); 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.width = meta_draw_spec_new (info->theme, width, NULL);
op->data.image.height = meta_draw_spec_new (info->theme, height, 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; op->data.image.fill_type = fill_type_val;
/* Check for vertical & horizontal stripes */ /* Check for vertical & horizontal stripes */
@ -2529,16 +2519,13 @@ parse_draw_op_element (GMarkupParseContext *context,
const char *y; const char *y;
const char *width; const char *width;
const char *height; const char *height;
const char *alpha;
const char *fill_type; const char *fill_type;
MetaAlphaGradientSpec *alpha_spec;
MetaImageFillType fill_type_val; MetaImageFillType fill_type_val;
if (!locate_attributes (context, element_name, attribute_names, attribute_values, if (!locate_attributes (context, element_name, attribute_names, attribute_values,
error, error,
"!x", &x, "!y", &y, "!x", &x, "!y", &y,
"!width", &width, "!height", &height, "!width", &width, "!height", &height,
"alpha", &alpha,
"fill_type", &fill_type, "fill_type", &fill_type,
NULL)) NULL))
return; 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); 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.width = meta_draw_spec_new (info->theme, width, NULL);
op->data.icon.height = meta_draw_spec_new (info->theme, height, 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; op->data.icon.fill_type = fill_type_val;
g_assert (info->op_list); g_assert (info->op_list);

View File

@ -25,7 +25,6 @@
#define META_THEME_PRIVATE_H #define META_THEME_PRIVATE_H
#include <meta/boxes.h> #include <meta/boxes.h>
#include <meta/gradient.h>
#include <meta/theme.h> #include <meta/theme.h>
#include <meta/common.h> #include <meta/common.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -274,6 +273,14 @@ typedef enum
META_IMAGE_FILL_TILE META_IMAGE_FILL_TILE
} MetaImageFillType; } MetaImageFillType;
typedef enum
{
META_GRADIENT_VERTICAL,
META_GRADIENT_HORIZONTAL,
META_GRADIENT_DIAGONAL,
META_GRADIENT_LAST
} MetaGradientType;
typedef enum typedef enum
{ {
META_COLOR_SPEC_BASIC, META_COLOR_SPEC_BASIC,
@ -540,7 +547,6 @@ struct _MetaDrawOp
struct { struct {
MetaColorSpec *colorize_spec; MetaColorSpec *colorize_spec;
MetaAlphaGradientSpec *alpha_spec;
GdkPixbuf *pixbuf; GdkPixbuf *pixbuf;
MetaDrawSpec *x; MetaDrawSpec *x;
MetaDrawSpec *y; MetaDrawSpec *y;
@ -583,7 +589,6 @@ struct _MetaDrawOp
} gtk_vline; } gtk_vline;
struct { struct {
MetaAlphaGradientSpec *alpha_spec;
MetaDrawSpec *x; MetaDrawSpec *x;
MetaDrawSpec *y; MetaDrawSpec *y;
MetaDrawSpec *width; MetaDrawSpec *width;
@ -991,8 +996,12 @@ gboolean meta_draw_op_list_contains (MetaDrawOpList *op_list,
MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type); MetaGradientSpec* meta_gradient_spec_new (MetaGradientType type);
void meta_gradient_spec_free (MetaGradientSpec *desc); void meta_gradient_spec_free (MetaGradientSpec *desc);
GdkPixbuf* meta_gradient_spec_render (const MetaGradientSpec *desc, void meta_gradient_spec_render (const MetaGradientSpec *spec,
GtkStyleContext *gtk_style, const MetaAlphaGradientSpec *alpha_spec,
cairo_t *cr,
GtkStyleContext *style,
int x,
int y,
int width, int width,
int height); int height);
gboolean meta_gradient_spec_validate (MetaGradientSpec *spec, gboolean meta_gradient_spec_validate (MetaGradientSpec *spec,

View File

@ -38,7 +38,6 @@
#include <config.h> #include <config.h>
#include "theme-private.h" #include "theme-private.h"
#include <meta/util.h> #include <meta/util.h>
#include <meta/gradient.h>
#include <meta/prefs.h> #include <meta/prefs.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <string.h> #include <string.h>
@ -998,42 +997,91 @@ meta_gradient_spec_free (MetaGradientSpec *spec)
g_free (spec); g_free (spec);
} }
GdkPixbuf* static cairo_pattern_t *
meta_gradient_spec_render (const MetaGradientSpec *spec, meta_gradient_spec_pattern (const MetaGradientSpec *spec,
GtkStyleContext *style, const MetaAlphaGradientSpec *alpha_spec,
int width, GtkStyleContext *style)
int height)
{ {
cairo_pattern_t *pattern;
int n_colors; int n_colors;
GdkRGBA *colors;
GSList *tmp; GSList *tmp;
int i; 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); n_colors = g_slist_length (spec->color_specs);
if (n_colors == 0) if (n_colors == 0)
return NULL; return NULL;
colors = g_new (GdkRGBA, n_colors); if (alpha_spec != NULL)
g_assert (n_colors == alpha_spec->n_alphas);
i = 0; i = 0;
tmp = spec->color_specs; tmp = spec->color_specs;
while (tmp != NULL) 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; tmp = tmp->next;
++i; ++i;
} }
pixbuf = meta_gradient_create_multi (width, height, return pattern;
colors, n_colors, }
spec->type);
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 gboolean
@ -3046,9 +3094,6 @@ meta_draw_op_free (MetaDrawOp *op)
break; break;
case META_DRAW_IMAGE: 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) if (op->data.image.pixbuf)
g_object_unref (G_OBJECT (op->data.image.pixbuf)); g_object_unref (G_OBJECT (op->data.image.pixbuf));
@ -3085,9 +3130,6 @@ meta_draw_op_free (MetaDrawOp *op)
break; break;
case META_DRAW_ICON: 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.x);
meta_draw_spec_free (op->data.icon.y); meta_draw_spec_free (op->data.icon.y);
meta_draw_spec_free (op->data.icon.width); meta_draw_spec_free (op->data.icon.width);
@ -3132,42 +3174,6 @@ meta_draw_op_free (MetaDrawOp *op)
g_free (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* static GdkPixbuf*
pixbuf_tile (GdkPixbuf *tile, pixbuf_tile (GdkPixbuf *tile,
int width, int width,
@ -3298,7 +3304,6 @@ replicate_cols (GdkPixbuf *src,
static GdkPixbuf* static GdkPixbuf*
scale_and_alpha_pixbuf (GdkPixbuf *src, scale_and_alpha_pixbuf (GdkPixbuf *src,
MetaAlphaGradientSpec *alpha_spec,
MetaImageFillType fill_type, MetaImageFillType fill_type,
int width, int width,
int height, int height,
@ -3380,9 +3385,6 @@ scale_and_alpha_pixbuf (GdkPixbuf *src,
} }
} }
} }
if (pixbuf)
pixbuf = apply_alpha (pixbuf, alpha_spec, pixbuf == src);
return pixbuf; return pixbuf;
} }
@ -3449,32 +3451,12 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
gdk_pixbuf_fill (pixbuf, rgba); 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; break;
case META_DRAW_GRADIENT: 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; break;
case META_DRAW_IMAGE: case META_DRAW_IMAGE:
{ {
if (op->data.image.colorize_spec) if (op->data.image.colorize_spec)
@ -3501,7 +3483,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
if (op->data.image.colorize_cache_pixbuf) if (op->data.image.colorize_cache_pixbuf)
{ {
pixbuf = scale_and_alpha_pixbuf (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, op->data.image.fill_type,
width, height, width, height,
op->data.image.vertical_stripes, op->data.image.vertical_stripes,
@ -3511,7 +3492,6 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
else else
{ {
pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf, pixbuf = scale_and_alpha_pixbuf (op->data.image.pixbuf,
op->data.image.alpha_spec,
op->data.image.fill_type, op->data.image.fill_type,
width, height, width, height,
op->data.image.vertical_stripes, op->data.image.vertical_stripes,
@ -3530,13 +3510,11 @@ draw_op_as_pixbuf (const MetaDrawOp *op,
width <= gdk_pixbuf_get_width (info->mini_icon) && width <= gdk_pixbuf_get_width (info->mini_icon) &&
height <= gdk_pixbuf_get_height (info->mini_icon)) height <= gdk_pixbuf_get_height (info->mini_icon))
pixbuf = scale_and_alpha_pixbuf (info->mini_icon, pixbuf = scale_and_alpha_pixbuf (info->mini_icon,
op->data.icon.alpha_spec,
op->data.icon.fill_type, op->data.icon.fill_type,
width, height, width, height,
FALSE, FALSE); FALSE, FALSE);
else if (info->icon) else if (info->icon)
pixbuf = scale_and_alpha_pixbuf (info->icon, pixbuf = scale_and_alpha_pixbuf (info->icon,
op->data.icon.alpha_spec,
op->data.icon.fill_type, op->data.icon.fill_type,
width, height, width, height,
FALSE, FALSE); FALSE, FALSE);
@ -3816,23 +3794,16 @@ meta_draw_op_draw_with_env (const MetaDrawOp *op,
case META_DRAW_GRADIENT: case META_DRAW_GRADIENT:
{ {
int rx, ry, rwidth, rheight; int rx, ry, rwidth, rheight;
GdkPixbuf *pixbuf;
rx = parse_x_position_unchecked (op->data.gradient.x, env); rx = parse_x_position_unchecked (op->data.gradient.x, env);
ry = parse_y_position_unchecked (op->data.gradient.y, env); ry = parse_y_position_unchecked (op->data.gradient.y, env);
rwidth = parse_size_unchecked (op->data.gradient.width, env); rwidth = parse_size_unchecked (op->data.gradient.width, env);
rheight = parse_size_unchecked (op->data.gradient.height, env); rheight = parse_size_unchecked (op->data.gradient.height, env);
pixbuf = draw_op_as_pixbuf (op, style_gtk, info, meta_gradient_spec_render (op->data.gradient.gradient_spec,
rwidth, rheight); op->data.gradient.alpha_spec,
cr, style_gtk,
if (pixbuf) rx, ry, rwidth, rheight);
{
gdk_cairo_set_source_pixbuf (cr, pixbuf, rx, ry);
cairo_paint (cr);
g_object_unref (G_OBJECT (pixbuf));
}
} }
break; break;