aboutsummaryrefslogtreecommitdiffstats
path: root/eazel-engine/src/eazel-theme-gradient.c
diff options
context:
space:
mode:
Diffstat (limited to 'eazel-engine/src/eazel-theme-gradient.c')
-rw-r--r--eazel-engine/src/eazel-theme-gradient.c360
1 files changed, 0 insertions, 360 deletions
diff --git a/eazel-engine/src/eazel-theme-gradient.c b/eazel-engine/src/eazel-theme-gradient.c
deleted file mode 100644
index fad6d4c..0000000
--- a/eazel-engine/src/eazel-theme-gradient.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* eazel-theme-gradient.c -- code for drawing gradients
-
- Copyright (C) 2000 Eazel, Inc.
-
- 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., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id: eazel-theme-gradient.c,v 1.6 2001/01/18 01:20:04 jsh Exp $
-
- Authors: John Harper <jsh@eazel.com> */
-
-/* AIX requires this to be the first thing in the file. */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#ifndef __GNUC__
-# if HAVE_ALLOCA_H
-# include <alloca.h>
-# else
-# ifdef _AIX
- #pragma alloca
-# else
-# ifndef alloca /* predefined by HP cc +Olibcalls */
- char *alloca ();
-# endif
-# endif
-# endif
-#endif
-
-#include "eazel-theme.h"
-#include <gdk/gdkrgb.h>
-#include <stdlib.h>
-
-static GdkRgbDither dither_mode = GDK_RGB_DITHER_MAX;
-
-eazel_engine_gradient *
-eazel_engine_gradient_new (eazel_engine_gradient_direction direction,
- GdkColor *from, GSList *components)
-{
- eazel_engine_gradient *g;
-
- g_return_val_if_fail (from != NULL, NULL);
-
- g = g_new (eazel_engine_gradient, 1);
- g->refcount = 1;
- g->direction = direction;
- g->from = *from;
- g->components = components;
- return g;
-}
-
-eazel_engine_gradient *
-eazel_engine_gradient_ref (eazel_engine_gradient *g)
-{
- g_return_val_if_fail (g != NULL, NULL);
-
- g->refcount++;
- return g;
-}
-
-void
-eazel_engine_gradient_unref (eazel_engine_gradient *g)
-{
- g_return_if_fail (g != NULL);
- g->refcount--;
-
- if (g->refcount == 0)
- {
- GSList *x;
- for (x = g->components; x != 0; x = x->next)
- g_free (x->data);
- g_slist_free (g->components);
- g_free (g);
- }
-}
-
-eazel_engine_gradient *
-eazel_engine_make_two_point_gradient (eazel_engine_gradient_direction direction,
- gulong from_rgb, gulong to_rgb)
-{
- GdkColor from, to;
- eazel_engine_gradient_component *component;
-
- g_return_val_if_fail (direction != GRADIENT_NONE, NULL);
-
- from.red = (from_rgb >> 16) & 255;
- from.red |= from.red << 8;
- from.green = (from_rgb >> 8) & 255;
- from.green |= from.green << 8;
- from.blue = (from_rgb >> 0) & 255;
- from.blue |= from.blue << 8;
-
- to.red = (to_rgb >> 16) & 255;
- to.red |= to.red << 8;
- to.green = (to_rgb >> 8) & 255;
- to.green |= to.green << 8;
- to.blue = (to_rgb >> 0) & 255;
- to.blue |= to.blue << 8;
-
- component = g_new (eazel_engine_gradient_component, 1);
- component->color = to;
- component->weight = 1.0;
-
- return eazel_engine_gradient_new (direction, &from,
- g_slist_prepend (NULL, component));
-}
-
-
-/* rendering */
-
-static inline void
-fill_gradient_rgb_buffer_1 (const GdkColor *from, const GdkColor *to,
- int rgb_total, guchar *rgb_buf,
- int rgb_first, int rgb_last)
-{
- int delta_r = to->red - from->red;
- int delta_g = to->green - from->green;
- int delta_b = to->blue - from->blue;
- guchar *rgb_ptr = rgb_buf;
- int i;
-
- g_return_if_fail (rgb_first <= rgb_last && rgb_last <= rgb_total);
-
- for (i = rgb_first; i < rgb_last; i++)
- {
- *rgb_ptr++ = (from->red + (delta_r * i) / rgb_total) >> 8;
- *rgb_ptr++ = (from->green + (delta_g * i) / rgb_total) >> 8;
- *rgb_ptr++ = (from->blue + (delta_b * i) / rgb_total) >> 8;
- }
-}
-
-void
-eazel_engine_fill_gradient_rgb_buffer (const eazel_engine_gradient *gradient,
- int rgb_total, guchar *rgb_buf,
- int rgb_first, int rgb_last)
-{
- g_return_if_fail (gradient != NULL);
- g_return_if_fail (rgb_buf != NULL);
-
- if (gradient->components == 0)
- {
- /* Single color `gradient' */
- fill_gradient_rgb_buffer_1 (&gradient->from, &gradient->from,
- rgb_total, rgb_buf, rgb_first, rgb_last);
- }
- else
- {
- float total_weight, weight_ptr;
- int rgb_ptr;
- GSList *x;
- const GdkColor *pred;
-
- total_weight = 0.0;
- for (x = gradient->components; x != 0; x = x->next)
- {
- eazel_engine_gradient_component *c = x->data;
- total_weight += c->weight;
- }
-
- rgb_ptr = 0;
- weight_ptr = 0.0;
- pred = &gradient->from;
- for (x = gradient->components; x != 0; x = x->next)
- {
- eazel_engine_gradient_component *c = x->data;
- int rgb_chunk = (c->weight * rgb_total) / total_weight;
-
- int first = MAX (rgb_first, rgb_ptr);
- int last = MIN (rgb_last, rgb_ptr + rgb_chunk);
-
- if (x->next == 0)
- last = rgb_last;
-
- if (last > first)
- {
- fill_gradient_rgb_buffer_1 (pred, &c->color,
- last - first,
- rgb_buf + rgb_ptr * 3,
- first - rgb_ptr,
- last - rgb_ptr);
- }
-
- pred = &c->color;
- weight_ptr += c->weight;
- rgb_ptr += rgb_chunk;
- }
- }
-}
-
-static void
-draw_vertical_gradient (GdkDrawable *drawable, GdkGC *gc,
- const GdkRectangle *full_rect,
- const GdkRectangle *clip_rect,
- const eazel_engine_gradient *gradient)
-{
- int rgb_size = clip_rect->height;
- guchar *rgb = alloca (rgb_size * 3), *ptr;
-
- eazel_engine_fill_gradient_rgb_buffer (gradient, full_rect->height, rgb,
- clip_rect->y - full_rect->y,
- (clip_rect->y + clip_rect->height)
- - full_rect->y);
-
- if (dither_mode == GDK_RGB_DITHER_NONE)
- {
- GdkColormap *sys_lut = gdk_colormap_get_system ();
- GdkGCValues old_values;
- int y;
-
- gdk_gc_get_values (gc, &old_values);
-
- ptr = rgb;
- for (y = clip_rect->y; y < clip_rect->y + clip_rect->height; y++)
- {
- guchar r = *ptr++;
- guchar g = *ptr++;
- guchar b = *ptr++;
- GdkColor color = { 0, r << 8, g << 8, b << 8 };
- gdk_colormap_alloc_color (sys_lut, &color, FALSE, TRUE);
- gdk_gc_set_foreground (gc, &color);
- gdk_draw_line (drawable, gc, clip_rect->x, y,
- clip_rect->x + clip_rect->width - 1, y);
- }
-
- gdk_gc_set_foreground (gc, &old_values.foreground);
- }
- else
- {
- guchar *xrgb = alloca (clip_rect->width * clip_rect->height * 3);
- int x, y;
- guchar *ptr_in = rgb, *ptr_out = xrgb;
- for (y = 0; y < clip_rect->height; y++)
- {
- guchar r = *ptr_in++;
- guchar g = *ptr_in++;
- guchar b = *ptr_in++;
- for (x = 0; x < clip_rect->width; x++)
- {
- *ptr_out++ = r;
- *ptr_out++ = g;
- *ptr_out++ = b;
- }
- }
- gdk_draw_rgb_image (drawable, gc, clip_rect->x, clip_rect->y,
- clip_rect->width, clip_rect->height,
- dither_mode, xrgb, clip_rect->width * 3);
- }
-}
-
-static void
-draw_horizontal_gradient (GdkDrawable *drawable, GdkGC *gc,
- const GdkRectangle *full_rect,
- const GdkRectangle *clip_rect,
- const eazel_engine_gradient *gradient)
-{
- int rgb_size = clip_rect->width;
- guchar *rgb = alloca (rgb_size * 3), *ptr;
-
- eazel_engine_fill_gradient_rgb_buffer (gradient, full_rect->width, rgb,
- clip_rect->x - full_rect->x,
- (clip_rect->x + clip_rect->width)
- - full_rect->x);
-
- if (dither_mode == GDK_RGB_DITHER_NONE)
- {
- GdkColormap *sys_lut = gdk_colormap_get_system ();
- GdkGCValues old_values;
- int x;
-
- gdk_gc_get_values (gc, &old_values);
-
- ptr = rgb;
- for (x = clip_rect->x; x < clip_rect->x + clip_rect->width; x++)
- {
- guchar r = *ptr++;
- guchar g = *ptr++;
- guchar b = *ptr++;
- GdkColor color = { 0, r << 8, g << 8, b << 8 };
- gdk_colormap_alloc_color (sys_lut, &color, FALSE, TRUE);
- gdk_gc_set_foreground (gc, &color);
- gdk_draw_line (drawable, gc, x, clip_rect->y,
- x, clip_rect->y + clip_rect->height - 1);
- }
-
- gdk_gc_set_foreground (gc, &old_values.foreground);
- }
- else
- {
- /* Using a row-stride of zero means we only need a single
- row of rgb-data (inspired by nautilus-background.c) */
- gdk_draw_rgb_image (drawable, gc, clip_rect->x, clip_rect->y,
- clip_rect->width, clip_rect->height,
- dither_mode, rgb, 0);
- }
-}
-
-void
-eazel_engine_draw_gradient (GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *full_rect,
- const GdkRectangle *clip_rect,
- const eazel_engine_gradient *gradient)
-{
- if (gradient->direction == GRADIENT_VERTICAL)
- {
- draw_vertical_gradient (drawable, gc, full_rect, clip_rect, gradient);
- }
- else if (gradient->direction == GRADIENT_HORIZONTAL)
- {
- draw_horizontal_gradient (drawable, gc, full_rect, clip_rect, gradient);
- }
-}
-
-void
-eazel_engine_set_bg_gradient (GdkWindow *window,
- eazel_engine_gradient *gradient)
-{
- /* Render a tile of the specified gradient to a pixmap, then
- set it as the background pixmap of the window. */
-
- GdkRectangle area = { 0, 0 };
- GdkPixmap *pixmap;
- GdkGC *pixmap_gc;
-
- int window_x, window_y, window_width, window_height, window_depth;
-
- gdk_window_get_geometry (window, &window_x, &window_y,
- &window_width, &window_height, &window_depth);
-
- if (gradient->direction == GRADIENT_VERTICAL)
- {
- area.width = 32;
- area.height = window_height;
- }
- else
- {
- area.width = window_width;
- area.height = 32;
- }
-
- pixmap = gdk_pixmap_new (window, area.width, area.height, window_depth);
- pixmap_gc = gdk_gc_new (pixmap);
-
- eazel_engine_draw_gradient (pixmap, pixmap_gc, &area, &area, gradient);
-
- gdk_window_set_back_pixmap (window, pixmap, FALSE);
- gdk_gc_unref (pixmap_gc);
- gdk_pixmap_unref (pixmap);
-}