mirror of
https://github.com/brl/mutter.git
synced 2024-11-25 01:20:42 -05:00
change to use spiffy gradient code.
2002-01-06 Havoc Pennington <hp@pobox.com> * src/theme.c (meta_theme_get_gradient): change to use spiffy gradient code. * src/gradient.c: copy lovely gradient code from WindowMaker, as usual Dan and Alfredo have very nice code
This commit is contained in:
parent
d9934a2d8c
commit
ac85e1e225
@ -1,3 +1,11 @@
|
||||
2002-01-06 Havoc Pennington <hp@pobox.com>
|
||||
|
||||
* src/theme.c (meta_theme_get_gradient): change to use spiffy
|
||||
gradient code.
|
||||
|
||||
* src/gradient.c: copy lovely gradient code from WindowMaker,
|
||||
as usual Dan and Alfredo have very nice code
|
||||
|
||||
2002-01-06 Fatih Demir <kabalak@gtranslator.org>
|
||||
|
||||
* configure.in: Added "tr" to the languages list.
|
||||
|
@ -21,6 +21,8 @@ metacity_SOURCES= \
|
||||
frame.h \
|
||||
frames.c \
|
||||
frames.h \
|
||||
gradient.c \
|
||||
gradient.h \
|
||||
inlinepixbufs.h \
|
||||
keybindings.c \
|
||||
keybindings.h \
|
||||
@ -57,6 +59,12 @@ bin_PROGRAMS=metacity
|
||||
|
||||
metacity_LDADD= @METACITY_LIBS@
|
||||
|
||||
testgradient_SOURCES=gradient.h gradient.c testgradient.c
|
||||
|
||||
noinst_PROGRAMS=testgradient
|
||||
|
||||
testgradient_LDADD= @METACITY_LIBS@
|
||||
|
||||
desktopfilesdir=$(datadir)/gnome/wm-properties
|
||||
desktopfiles_DATA=metacity.desktop
|
||||
|
||||
|
63
src/frames.c
63
src/frames.c
@ -1758,41 +1758,42 @@ meta_frames_expose_event (GtkWidget *widget,
|
||||
layout_gc = widget->style->fg_gc[GTK_STATE_NORMAL];
|
||||
if (flags & META_FRAME_HAS_FOCUS)
|
||||
{
|
||||
GdkPixbuf *gradient;
|
||||
|
||||
layout_gc = widget->style->fg_gc[GTK_STATE_SELECTED];
|
||||
|
||||
#if 0
|
||||
/* Draw blue background */
|
||||
gdk_draw_rectangle (frame->window,
|
||||
widget->style->bg_gc[GTK_STATE_SELECTED],
|
||||
TRUE,
|
||||
fgeom.title_rect.x,
|
||||
fgeom.title_rect.y,
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height);
|
||||
#else
|
||||
{
|
||||
GdkPixbuf *gradient;
|
||||
gradient = meta_theme_get_gradient (META_GRADIENT_DIAGONAL,
|
||||
&widget->style->bg[GTK_STATE_SELECTED],
|
||||
&widget->style->bg[GTK_STATE_NORMAL],
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height);
|
||||
|
||||
gradient = meta_theme_get_gradient (META_GRADIENT_HORIZONTAL,
|
||||
&widget->style->bg[GTK_STATE_SELECTED],
|
||||
&widget->style->bg[GTK_STATE_NORMAL],
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height);
|
||||
if (gradient != NULL)
|
||||
{
|
||||
gdk_pixbuf_render_to_drawable (gradient,
|
||||
frame->window,
|
||||
widget->style->bg_gc[GTK_STATE_SELECTED],
|
||||
0, 0,
|
||||
fgeom.title_rect.x,
|
||||
fgeom.title_rect.y,
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (gradient,
|
||||
frame->window,
|
||||
widget->style->bg_gc[GTK_STATE_SELECTED],
|
||||
0, 0,
|
||||
fgeom.title_rect.x,
|
||||
fgeom.title_rect.y,
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (gradient));
|
||||
}
|
||||
#endif
|
||||
g_object_unref (G_OBJECT (gradient));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Fallback to plain selection color */
|
||||
gdk_draw_rectangle (frame->window,
|
||||
widget->style->bg_gc[GTK_STATE_SELECTED],
|
||||
TRUE,
|
||||
fgeom.title_rect.x,
|
||||
fgeom.title_rect.y,
|
||||
fgeom.title_rect.width,
|
||||
fgeom.title_rect.height);
|
||||
}
|
||||
}
|
||||
|
||||
if (frame->layout)
|
||||
|
853
src/gradient.c
Normal file
853
src/gradient.c
Normal file
@ -0,0 +1,853 @@
|
||||
/* Metacity 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. */
|
||||
|
||||
#include "gradient.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 GdkColor *from,
|
||||
const GdkColor *to);
|
||||
static GdkPixbuf* meta_gradient_create_vertical (int width,
|
||||
int height,
|
||||
const GdkColor *from,
|
||||
const GdkColor *to);
|
||||
static GdkPixbuf* meta_gradient_create_diagonal (int width,
|
||||
int height,
|
||||
const GdkColor *from,
|
||||
const GdkColor *to);
|
||||
static GdkPixbuf* meta_gradient_create_multi_horizontal (int width,
|
||||
int height,
|
||||
const GdkColor *colors,
|
||||
int count);
|
||||
static GdkPixbuf* meta_gradient_create_multi_vertical (int width,
|
||||
int height,
|
||||
const GdkColor *colors,
|
||||
int count);
|
||||
static GdkPixbuf* meta_gradient_create_multi_diagonal (int width,
|
||||
int height,
|
||||
const GdkColor *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);
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_simple (int width,
|
||||
int height,
|
||||
const GdkColor *from,
|
||||
const GdkColor *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);
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_multi (int width,
|
||||
int height,
|
||||
const GdkColor *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);
|
||||
}
|
||||
}
|
||||
else if (n_colors > 1)
|
||||
{
|
||||
return meta_gradient_create_simple (width, height, &colors[0], &colors[1],
|
||||
style);
|
||||
}
|
||||
else if (n_colors > 0)
|
||||
{
|
||||
return meta_gradient_create_simple (width, height, &colors[0], &colors[0],
|
||||
style);
|
||||
}
|
||||
g_assert_not_reached ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Interwoven essentially means we have two vertical gradients,
|
||||
* cut into horizontal strips of the given thickness, and then the strips
|
||||
* are alternated. I'm not sure what it's good for, just copied since
|
||||
* WindowMaker had it.
|
||||
*/
|
||||
GdkPixbuf*
|
||||
meta_gradient_create_interwoven (int width,
|
||||
int height,
|
||||
const GdkColor colors1[2],
|
||||
int thickness1,
|
||||
const GdkColor 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 rr, gg, bb;
|
||||
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 = colors1[0].red<<8;
|
||||
g1 = colors1[0].green<<8;
|
||||
b1 = colors1[0].blue<<8;
|
||||
|
||||
r2 = colors2[0].red<<8;
|
||||
g2 = colors2[0].green<<8;
|
||||
b2 = colors2[0].blue<<8;
|
||||
|
||||
dr1 = ((colors1[1].red-colors1[0].red)<<8)/(int)height;
|
||||
dg1 = ((colors1[1].green-colors1[0].green)<<8)/(int)height;
|
||||
db1 = ((colors1[1].blue-colors1[0].blue)<<8)/(int)height;
|
||||
|
||||
dr2 = ((colors2[1].red-colors2[0].red)<<8)/(int)height;
|
||||
dg2 = ((colors2[1].green-colors2[0].green)<<8)/(int)height;
|
||||
db2 = ((colors2[1].blue-colors2[0].blue)<<8)/(int)height;
|
||||
|
||||
for (i=0,k=0,l=0,ll=thickness1; i<height; i++)
|
||||
{
|
||||
ptr = pixels + i * rowstride;
|
||||
|
||||
if (k == 0)
|
||||
{
|
||||
rr = r1>>16;
|
||||
gg = g1>>16;
|
||||
bb = b1>>16;
|
||||
}
|
||||
else
|
||||
{
|
||||
rr = r2>>16;
|
||||
gg = g2>>16;
|
||||
bb = b2>>16;
|
||||
}
|
||||
for (j=0; j<width/8; j++)
|
||||
{
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
}
|
||||
switch (width%8)
|
||||
{
|
||||
case 7: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 6: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 5: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 4: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 3: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 2: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 1: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
}
|
||||
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 GdkColor *from,
|
||||
const GdkColor *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;
|
||||
|
||||
/* FIXME the no_padding = TRUE here is a workaround for a problem
|
||||
* create_diagonal that can't handle a funky rowstride
|
||||
*/
|
||||
pixbuf = blank_pixbuf (width, height, TRUE);
|
||||
if (pixbuf == NULL)
|
||||
return NULL;
|
||||
|
||||
pixels = gdk_pixbuf_get_pixels (pixbuf);
|
||||
ptr = pixels;
|
||||
rowstride = gdk_pixbuf_get_rowstride (pixbuf);
|
||||
|
||||
r0 = (guchar) (from->red / 256.0);
|
||||
g0 = (guchar) (from->green / 256.0);
|
||||
b0 = (guchar) (from->blue / 256.0);
|
||||
rf = (guchar) (to->red / 256.0);
|
||||
gf = (guchar) (to->green / 256.0);
|
||||
bf = (guchar) (to->blue / 256.0);
|
||||
|
||||
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 GdkColor *from,
|
||||
const GdkColor *to)
|
||||
{
|
||||
int i, j;
|
||||
long r, g, b, dr, dg, db;
|
||||
GdkPixbuf *pixbuf;
|
||||
unsigned char *ptr;
|
||||
unsigned char rr, gg, bb;
|
||||
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 / 256.0);
|
||||
g0 = (guchar) (from->green / 256.0);
|
||||
b0 = (guchar) (from->blue / 256.0);
|
||||
rf = (guchar) (to->red / 256.0);
|
||||
gf = (guchar) (to->green / 256.0);
|
||||
bf = (guchar) (to->blue / 256.0);
|
||||
|
||||
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;
|
||||
|
||||
rr = r>>16;
|
||||
gg = g>>16;
|
||||
bb = b>>16;
|
||||
for (j=0; j<width/8; j++)
|
||||
{
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
*(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
}
|
||||
switch (width%8)
|
||||
{
|
||||
case 7: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 6: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 5: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 4: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 3: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 2: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
case 1: *(ptr++) = rr; *(ptr++) = gg; *(ptr++) = bb;
|
||||
}
|
||||
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 GdkColor *from,
|
||||
const GdkColor *to)
|
||||
{
|
||||
GdkPixbuf *pixbuf, *tmp;
|
||||
int j;
|
||||
float a, offset;
|
||||
unsigned char *ptr;
|
||||
int r0, g0, b0;
|
||||
int rf, gf, bf;
|
||||
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);
|
||||
|
||||
/* FIXME here is the pixbuf that we require to have width == rowstride
|
||||
* resulting in no_padding = TRUE in create_horizontal
|
||||
*/
|
||||
tmp = meta_gradient_create_horizontal (2*width-1, 1, from, to);
|
||||
if (!tmp)
|
||||
{
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r0 = (guchar) (from->red / 256.0);
|
||||
g0 = (guchar) (from->green / 256.0);
|
||||
b0 = (guchar) (from->blue / 256.0);
|
||||
rf = (guchar) (to->red / 256.0);
|
||||
gf = (guchar) (to->green / 256.0);
|
||||
bf = (guchar) (to->blue / 256.0);
|
||||
|
||||
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)
|
||||
{
|
||||
/* FIXME this algorithm assumes rowstride == width in the source
|
||||
* pixbuf, because otherwise we'd accidentally copy junk pixels.
|
||||
*/
|
||||
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 GdkColor *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 = colors[0].red << 8;
|
||||
g = colors[0].green << 8;
|
||||
b = colors[0].blue << 8;
|
||||
|
||||
/* render the first line */
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)width2;
|
||||
dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)width2;
|
||||
db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(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 = colors[i].red << 8;
|
||||
g = colors[i].green << 8;
|
||||
b = colors[i].blue << 8;
|
||||
}
|
||||
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 GdkColor *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;
|
||||
unsigned char rr, gg, bb;
|
||||
int rowstride;
|
||||
int pad;
|
||||
|
||||
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);
|
||||
pad = rowstride - (width * 3);
|
||||
ptr = pixels;
|
||||
|
||||
if (count > height)
|
||||
count = height;
|
||||
|
||||
if (count > 1)
|
||||
height2 = height/(count-1);
|
||||
else
|
||||
height2 = height;
|
||||
|
||||
k = 0;
|
||||
|
||||
r = colors[0].red << 8;
|
||||
g = colors[0].green << 8;
|
||||
b = colors[0].blue << 8;
|
||||
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
dr = ((int)(colors[i].red - colors[i-1].red) <<8)/(int)height2;
|
||||
dg = ((int)(colors[i].green - colors[i-1].green)<<8)/(int)height2;
|
||||
db = ((int)(colors[i].blue - colors[i-1].blue) <<8)/(int)height2;
|
||||
|
||||
for (j=0; j<height2; j++)
|
||||
{
|
||||
rr = r>>16;
|
||||
gg = g>>16;
|
||||
bb = b>>16;
|
||||
|
||||
for (x=0; x<width/4; x++)
|
||||
{
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
}
|
||||
switch (width%4)
|
||||
{
|
||||
case 3: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
case 2: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
case 1: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
}
|
||||
|
||||
ptr += pad;
|
||||
|
||||
r += dr;
|
||||
g += dg;
|
||||
b += db;
|
||||
k++;
|
||||
}
|
||||
r = colors[i].red << 8;
|
||||
g = colors[i].green << 8;
|
||||
b = colors[i].blue << 8;
|
||||
}
|
||||
|
||||
rr = r>>16;
|
||||
gg = g>>16;
|
||||
bb = b>>16;
|
||||
|
||||
if (k<height)
|
||||
{
|
||||
tmp = ptr;
|
||||
for (x=0; x<width/4; x++)
|
||||
{
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
}
|
||||
switch (width%4)
|
||||
{
|
||||
case 3: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
case 2: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
case 1: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
|
||||
default: break;
|
||||
}
|
||||
|
||||
ptr += pad;
|
||||
|
||||
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 GdkColor *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;
|
||||
|
||||
/* FIXME here again is a bug that requires multi_horizontal
|
||||
* to have width == rowstride
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
#ifdef META_TEST_GRADIENTS
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef void (* RenderGradientFunc) (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
static void
|
||||
render_simple (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height,
|
||||
MetaGradientType type)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkColor from, to;
|
||||
|
||||
gdk_color_parse ("blue", &from);
|
||||
gdk_color_parse ("green", &to);
|
||||
|
||||
pixbuf = meta_gradient_create_simple (width, height,
|
||||
&from, &to,
|
||||
type);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable,
|
||||
gc,
|
||||
0, 0,
|
||||
0, 0, width, height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
render_vertical_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_VERTICAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_horizontal_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
expose_callback (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
RenderGradientFunc func = data;
|
||||
|
||||
(* func) (widget->window,
|
||||
widget->style->fg_gc[widget->state],
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GtkWidget*
|
||||
create_gradient_window (RenderGradientFunc func)
|
||||
{
|
||||
GtkWidget *window;
|
||||
GtkWidget *drawing_area;
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_POPUP);
|
||||
|
||||
drawing_area = gtk_drawing_area_new ();
|
||||
|
||||
gtk_widget_set_size_request (drawing_area, 175, 175);
|
||||
|
||||
g_signal_connect (G_OBJECT (drawing_area),
|
||||
"expose_event",
|
||||
G_CALLBACK (expose_callback),
|
||||
func);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void
|
||||
meta_gradient_test (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
window = create_gradient_window (render_vertical_func);
|
||||
gtk_window_move (GTK_WINDOW (window), 0, 0);
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
window = create_gradient_window (render_horizontal_func);
|
||||
gtk_window_move (GTK_WINDOW (window), 0, 200);
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
window = create_gradient_window (render_diagonal_func);
|
||||
gtk_window_move (GTK_WINDOW (window), 200, 0);
|
||||
gtk_widget_show_all (window);
|
||||
}
|
||||
#endif
|
||||
|
53
src/gradient.h
Normal file
53
src/gradient.h
Normal file
@ -0,0 +1,53 @@
|
||||
/* Metacity 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/gdkcolor.h>
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_GRADIENT_VERTICAL,
|
||||
META_GRADIENT_HORIZONTAL,
|
||||
META_GRADIENT_DIAGONAL
|
||||
} MetaGradientType;
|
||||
|
||||
|
||||
GdkPixbuf* meta_gradient_create_simple (int width,
|
||||
int height,
|
||||
const GdkColor *from,
|
||||
const GdkColor *to,
|
||||
MetaGradientType style);
|
||||
GdkPixbuf* meta_gradient_create_multi (int width,
|
||||
int height,
|
||||
const GdkColor *colors,
|
||||
int n_colors,
|
||||
MetaGradientType style);
|
||||
GdkPixbuf* meta_gradient_create_interwoven (int width,
|
||||
int height,
|
||||
const GdkColor colors1[2],
|
||||
int thickness1,
|
||||
const GdkColor colors2[2],
|
||||
int thickness2);
|
||||
|
||||
#endif
|
246
src/testgradient.c
Normal file
246
src/testgradient.c
Normal file
@ -0,0 +1,246 @@
|
||||
/* Metacity 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 "gradient.h"
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
typedef void (* RenderGradientFunc) (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width,
|
||||
int height);
|
||||
|
||||
static void
|
||||
render_simple (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height,
|
||||
MetaGradientType type)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
GdkColor from, to;
|
||||
|
||||
gdk_color_parse ("blue", &from);
|
||||
gdk_color_parse ("green", &to);
|
||||
|
||||
pixbuf = meta_gradient_create_simple (width, height,
|
||||
&from, &to,
|
||||
type);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable,
|
||||
gc,
|
||||
0, 0,
|
||||
0, 0, width, height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
render_vertical_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_VERTICAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_horizontal_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_simple (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_multi (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height,
|
||||
MetaGradientType type)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
#define N_COLORS 5
|
||||
GdkColor colors[N_COLORS];
|
||||
|
||||
gdk_color_parse ("red", &colors[0]);
|
||||
gdk_color_parse ("blue", &colors[1]);
|
||||
gdk_color_parse ("orange", &colors[2]);
|
||||
gdk_color_parse ("pink", &colors[3]);
|
||||
gdk_color_parse ("green", &colors[4]);
|
||||
|
||||
pixbuf = meta_gradient_create_multi (width, height,
|
||||
colors, N_COLORS,
|
||||
type);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable,
|
||||
gc,
|
||||
0, 0,
|
||||
0, 0, width, height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
render_vertical_multi_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (drawable, gc, width, height, META_GRADIENT_VERTICAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_horizontal_multi_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (drawable, gc, width, height, META_GRADIENT_HORIZONTAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_diagonal_multi_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
render_multi (drawable, gc, width, height, META_GRADIENT_DIAGONAL);
|
||||
}
|
||||
|
||||
static void
|
||||
render_interwoven_func (GdkDrawable *drawable,
|
||||
GdkGC *gc,
|
||||
int width, int height)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
#define N_COLORS 4
|
||||
GdkColor colors[N_COLORS];
|
||||
|
||||
gdk_color_parse ("red", &colors[0]);
|
||||
gdk_color_parse ("blue", &colors[1]);
|
||||
gdk_color_parse ("pink", &colors[2]);
|
||||
gdk_color_parse ("green", &colors[3]);
|
||||
|
||||
pixbuf = meta_gradient_create_interwoven (width, height,
|
||||
colors, height / 10,
|
||||
colors + 2, height / 14);
|
||||
|
||||
gdk_pixbuf_render_to_drawable (pixbuf,
|
||||
drawable,
|
||||
gc,
|
||||
0, 0,
|
||||
0, 0, width, height,
|
||||
GDK_RGB_DITHER_NORMAL,
|
||||
0, 0);
|
||||
|
||||
g_object_unref (G_OBJECT (pixbuf));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
expose_callback (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
RenderGradientFunc func = data;
|
||||
|
||||
(* func) (widget->window,
|
||||
widget->style->fg_gc[widget->state],
|
||||
widget->allocation.width,
|
||||
widget->allocation.height);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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),
|
||||
"expose_event",
|
||||
G_CALLBACK (expose_callback),
|
||||
func);
|
||||
|
||||
gtk_container_add (GTK_CONTAINER (window), drawing_area);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
static void
|
||||
meta_gradient_test (void)
|
||||
{
|
||||
GtkWidget *window;
|
||||
|
||||
window = create_gradient_window ("Simple vertical",
|
||||
render_vertical_func);
|
||||
|
||||
window = create_gradient_window ("Simple horizontal",
|
||||
render_horizontal_func);
|
||||
|
||||
window = create_gradient_window ("Simple diagonal",
|
||||
render_diagonal_func);
|
||||
|
||||
window = create_gradient_window ("Multi vertical",
|
||||
render_vertical_multi_func);
|
||||
|
||||
window = create_gradient_window ("Multi horizontal",
|
||||
render_horizontal_multi_func);
|
||||
|
||||
window = create_gradient_window ("Multi diagonal",
|
||||
render_diagonal_multi_func);
|
||||
|
||||
window = create_gradient_window ("Interwoven",
|
||||
render_interwoven_func);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
meta_gradient_test ();
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
58
src/theme.c
58
src/theme.c
@ -21,8 +21,10 @@
|
||||
|
||||
#include "theme.h"
|
||||
#include "util.h"
|
||||
#include "gradient.h"
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
/* fill_gradient routine from GNOME background-properties, CVS says
|
||||
* Michael Fulbright checked it in, Copyright 1998 Red Hat Inc.
|
||||
*/
|
||||
@ -101,6 +103,7 @@ fill_gradient (GdkPixbuf *pixbuf,
|
||||
|
||||
g_free (row);
|
||||
}
|
||||
#endif
|
||||
|
||||
typedef struct _CachedGradient CachedGradient;
|
||||
|
||||
@ -236,8 +239,8 @@ meta_theme_get_gradient (MetaGradientType type,
|
||||
"Requesting %s gradient one %d/%d/%d two %d/%d/%d "
|
||||
"%d x %d\n",
|
||||
type == META_GRADIENT_VERTICAL ? "vertical" : "horizontal",
|
||||
color_one->red / 255, color_one->green / 255, color_one->blue / 255,
|
||||
color_two->red / 255, color_two->green / 255, color_two->blue / 255,
|
||||
color_one->red / 256, color_one->green / 256, color_one->blue / 256,
|
||||
color_two->red / 256, color_two->green / 256, color_two->blue / 256,
|
||||
width, height);
|
||||
|
||||
if (gradient_cache == NULL)
|
||||
@ -266,6 +269,7 @@ meta_theme_get_gradient (MetaGradientType type,
|
||||
return cached->pixbuf;
|
||||
}
|
||||
|
||||
#if 0
|
||||
gradient.pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8,
|
||||
gradient.width, gradient.height);
|
||||
|
||||
@ -276,24 +280,50 @@ meta_theme_get_gradient (MetaGradientType type,
|
||||
gradient.width,
|
||||
gradient.height,
|
||||
0, 0);
|
||||
#else
|
||||
gradient.pixbuf = meta_gradient_create_simple (gradient.width,
|
||||
gradient.height,
|
||||
&gradient.color_one,
|
||||
&gradient.color_two,
|
||||
type);
|
||||
|
||||
cached = g_new (CachedGradient, 1);
|
||||
*cached = gradient;
|
||||
if (gradient.pixbuf == NULL)
|
||||
{
|
||||
meta_topic (META_DEBUG_GRADIENT_CACHE,
|
||||
"Not enough memory to create gradient of size %d bytes\n",
|
||||
GRADIENT_SIZE (&gradient));
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
g_hash_table_insert (gradient_cache, cached, cached);
|
||||
if (GRADIENT_SIZE (&gradient) > MAX_CACHE_SIZE)
|
||||
{
|
||||
cached = g_new (CachedGradient, 1);
|
||||
*cached = gradient;
|
||||
|
||||
meta_topic (META_DEBUG_GRADIENT_CACHE,
|
||||
"Caching newly-created gradient, size is %d bytes, total cache size %d bytes %d gradients, maximum %d bytes\n",
|
||||
GRADIENT_SIZE (cached),
|
||||
cache_size, g_hash_table_size (gradient_cache), MAX_CACHE_SIZE);
|
||||
g_hash_table_insert (gradient_cache, cached, cached);
|
||||
|
||||
cache_size += GRADIENT_SIZE (cached);
|
||||
meta_topic (META_DEBUG_GRADIENT_CACHE,
|
||||
"Caching newly-created gradient, size is %d bytes, total cache size %d bytes %d gradients, maximum %d bytes\n",
|
||||
GRADIENT_SIZE (cached),
|
||||
cache_size, g_hash_table_size (gradient_cache), MAX_CACHE_SIZE);
|
||||
|
||||
g_object_ref (G_OBJECT (cached->pixbuf)); /* to return to caller */
|
||||
retval = cached->pixbuf;
|
||||
cache_size += GRADIENT_SIZE (cached);
|
||||
|
||||
if (cache_size > MAX_CACHE_SIZE)
|
||||
expire_some_old_gradients (); /* may unref "cached->pixbuf" and free "cached" */
|
||||
g_object_ref (G_OBJECT (cached->pixbuf)); /* to return to caller */
|
||||
retval = cached->pixbuf;
|
||||
|
||||
if (cache_size > MAX_CACHE_SIZE)
|
||||
expire_some_old_gradients (); /* may unref "cached->pixbuf" and free "cached" */
|
||||
}
|
||||
else
|
||||
{
|
||||
meta_topic (META_DEBUG_GRADIENT_CACHE,
|
||||
"Gradient of size %d bytes is too large to cache\n",
|
||||
GRADIENT_SIZE (&gradient));
|
||||
|
||||
retval = gradient.pixbuf;
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
@ -23,16 +23,12 @@
|
||||
#define META_THEME_H
|
||||
|
||||
#include "frames.h"
|
||||
#include "gradient.h"
|
||||
|
||||
/* theme.[hc] is basically responsible for drawing parts of the UI using
|
||||
* theme data
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
META_GRADIENT_VERTICAL,
|
||||
META_GRADIENT_HORIZONTAL
|
||||
} MetaGradientType;
|
||||
|
||||
GdkPixbuf* meta_theme_get_gradient (MetaGradientType type,
|
||||
const GdkColor *color_one,
|
||||
|
Loading…
Reference in New Issue
Block a user