Commit 116d27f9 authored by Andy Hertzfeld's avatar Andy Hertzfeld

implemented gradient backgrounds for the anti-aliased canvas. This isn't


        implemented gradient backgrounds for the anti-aliased canvas.  This
	isn't finished yet, so don't try to play around with it yet
parent ebf72ed6
2000-06-06 Andy Hertzfeld <andy@eazel.com>
made gradient backgrounds work with the anti-aliased canvas. This
isn't finished yet but will be soon.
* libnautilus-extensions/nautilus-background-canvas-group.c:
(nautilus_background_canvas_group_render):
call nautilus_background_draw_aa to draw the background
* libnautilus-extensions/nautilus-background.c:
(draw_pixbuf_tiled_aa), (nautilus_background_draw_aa):
made it call nautilus_gnome_canvas_fill_with_gradient
to fill with a gradient background if necessary
* libnautilus-extensions/nautilus-gnome-extensions.c,h:
(nautilus_gnome_canvas_item_get_world_bounds),
(nautilus_gnome_canvas_fill_with_gradient):
implemented nautilus_gnome_canvas_fill_with_gradient
2000-06-06 Ramiro Estrugo <ramiro@eazel.com>
* nautilus-widgets/nautilus-preferences.c:
......
......@@ -129,8 +129,8 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
static void
nautilus_background_canvas_group_render (GnomeCanvasItem *item, GnomeCanvasBuf *buffer)
{
NautilusBackground *background;
NautilusBackground *background;
background = nautilus_get_widget_background(GTK_WIDGET (item->canvas));
if (background != NULL)
nautilus_background_draw_aa(background, buffer);
......
......@@ -28,6 +28,7 @@
#include <gtk/gtksignal.h>
#include "nautilus-gdk-extensions.h"
#include "nautilus-gdk-pixbuf-extensions.h"
#include "nautilus-gnome-extensions.h"
#include "nautilus-background-canvas-group.h"
#include "nautilus-lib-self-check-functions.h"
#include "nautilus-gtk-macros.h"
......@@ -201,8 +202,9 @@ draw_pixbuf_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buf, double affine[6], int x_
affine[5] -= y_offset;
}
/* fill the canvas buffer with a tiled pixmap */
static void
draw_pixbuf_tiled(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
draw_pixbuf_tiled_aa(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
{
int x, y;
int start_x, start_y;
......@@ -247,14 +249,31 @@ draw_pixbuf_tiled(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
void nautilus_background_draw_aa (NautilusBackground *background,
GnomeCanvasBuf *buffer)
{
char *start_color_spec, *end_color_spec;
guint32 start_rgb, end_rgb;
gboolean horizontal_gradient;
if (background->details->tile_image) {
if (!buffer->is_buf) {
draw_pixbuf_tiled(background->details->tile_image, buffer);
buffer->is_buf = TRUE;
if (!buffer->is_buf) {
if (background->details->tile_image) {
draw_pixbuf_tiled_aa (background->details->tile_image, buffer);
} else {
start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color);
end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color);
horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color);
start_rgb = nautilus_parse_rgb_with_white_default (start_color_spec);
end_rgb = nautilus_parse_rgb_with_white_default (end_color_spec);
g_free (start_color_spec);
g_free (end_color_spec);
if (start_rgb != end_rgb) {
nautilus_gnome_canvas_fill_with_gradient(buffer, start_rgb, end_rgb,
horizontal_gradient);
} else
gnome_canvas_buf_ensure_buf(buffer);
}
} else {
gnome_canvas_buf_ensure_buf(buffer);
buffer->is_buf = TRUE;
}
}
......
......@@ -33,6 +33,9 @@
#include <libgnomeui/gnome-messagebox.h>
#include <libgnomeui/gnome-stock.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rect.h>
#include "nautilus-gdk-extensions.h"
#include "nautilus-string.h"
static void turn_on_line_wrap_flag_callback (GtkWidget *widget, gpointer callback_data);
......@@ -189,6 +192,95 @@ nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item,
}
}
/**
* nautilus_gnome_canvas_fill_with_gradient, for the anti-aliased canvas:
* @buffer: canvas buffer to draw into.
* @full_rect: rectangle of entire canvas for gradient color selection
* @start_color: Color for the left or top; pixel value does not matter.
* @end_color: Color for the right or bottom; pixel value does not matter.
* @horizontal: TRUE if the color changes from left to right. FALSE if from top to bottom.
*
* Fill the rectangle with a gradient.
* The color changes from start_color to end_color.
* This effect works best on true color displays.
*
* note that most of this routine is a clone of nautilus_fill_rectangle_with_gradient
* from nautilus-gdk-extensions.
*/
#define GRADIENT_BAND_SIZE 4
void
nautilus_gnome_canvas_fill_with_gradient (GnomeCanvasBuf *buffer,
guint32 start_rgb,
guint32 end_rgb,
gboolean horizontal)
{
GdkRectangle band_box;
guchar *bufptr;
gint16 *position;
guint16 *size;
gint num_bands;
guint16 last_band_size;
gdouble fraction;
gint y, band;
gint red_value, green_value, blue_value;
guint32 band_rgb;
g_return_if_fail (horizontal == FALSE || horizontal == TRUE);
/* Set up the band box so we can access it the same way for horizontal or vertical. */
band_box.x = buffer->rect.x0;
band_box.y = buffer->rect.y0;
band_box.width = buffer->rect.x1 - buffer->rect.x0;
band_box.height = buffer->rect.y1 - buffer->rect.y0;
position = horizontal ? &band_box.x : &band_box.y;
size = horizontal ? &band_box.width : &band_box.height;
/* Figure out how many bands we will need. */
num_bands = (*size + GRADIENT_BAND_SIZE - 1) / GRADIENT_BAND_SIZE;
last_band_size = GRADIENT_BAND_SIZE - (GRADIENT_BAND_SIZE * num_bands - *size);
/* Change the band box to be the size of a single band. */
*size = GRADIENT_BAND_SIZE;
/* Fill each band with a separate nautilus_draw_rectangle call. */
for (band = 0; band < num_bands; band++) {
/* Compute a new color value for each band. */
fraction = (double) *position / 2000; /* this is a temporary fudge */
band_rgb = nautilus_interpolate_color (fraction, start_rgb, end_rgb);
red_value = band_rgb >> 16;
green_value = (band_rgb >> 8) & 0xff;
blue_value = band_rgb & 0xff;
/* Last band may need to be a bit smaller to avoid writing outside the box.
* This is more efficient than changing and restoring the clip.
*/
if (band == num_bands - 1) {
*size = last_band_size;
}
/* use libart to fill the band rectangle with the color */
if (!horizontal)
bufptr = buffer->buf + (buffer->buf_rowstride * band * GRADIENT_BAND_SIZE);
else
bufptr = buffer->buf + (4 * band * GRADIENT_BAND_SIZE);
for (y = band_box.y; y < (band_box.y + band_box.height); y++) {
art_rgb_fill_run(bufptr,
red_value,
green_value,
blue_value,
band_box.width);
bufptr += buffer->buf_rowstride;
}
*position += *size;
}
}
static const char **
convert_varargs_to_name_array (va_list args)
{
......
......@@ -65,6 +65,11 @@ void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas
*/
void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item);
/* fill a canvas buffer with a gradient background */
void nautilus_gnome_canvas_fill_with_gradient (GnomeCanvasBuf *buffer,
guint32 start_rgb,
guint32 end_rgb,
gboolean horizontal);
/* More functions for ArtIRect and ArtDRect. */
gboolean nautilus_art_irect_equal (const ArtIRect *rect_a,
const ArtIRect *rect_b);
......
......@@ -129,8 +129,8 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
static void
nautilus_background_canvas_group_render (GnomeCanvasItem *item, GnomeCanvasBuf *buffer)
{
NautilusBackground *background;
NautilusBackground *background;
background = nautilus_get_widget_background(GTK_WIDGET (item->canvas));
if (background != NULL)
nautilus_background_draw_aa(background, buffer);
......
......@@ -28,6 +28,7 @@
#include <gtk/gtksignal.h>
#include "nautilus-gdk-extensions.h"
#include "nautilus-gdk-pixbuf-extensions.h"
#include "nautilus-gnome-extensions.h"
#include "nautilus-background-canvas-group.h"
#include "nautilus-lib-self-check-functions.h"
#include "nautilus-gtk-macros.h"
......@@ -201,8 +202,9 @@ draw_pixbuf_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buf, double affine[6], int x_
affine[5] -= y_offset;
}
/* fill the canvas buffer with a tiled pixmap */
static void
draw_pixbuf_tiled(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
draw_pixbuf_tiled_aa(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
{
int x, y;
int start_x, start_y;
......@@ -247,14 +249,31 @@ draw_pixbuf_tiled(GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
void nautilus_background_draw_aa (NautilusBackground *background,
GnomeCanvasBuf *buffer)
{
char *start_color_spec, *end_color_spec;
guint32 start_rgb, end_rgb;
gboolean horizontal_gradient;
if (background->details->tile_image) {
if (!buffer->is_buf) {
draw_pixbuf_tiled(background->details->tile_image, buffer);
buffer->is_buf = TRUE;
if (!buffer->is_buf) {
if (background->details->tile_image) {
draw_pixbuf_tiled_aa (background->details->tile_image, buffer);
} else {
start_color_spec = nautilus_gradient_get_start_color_spec (background->details->color);
end_color_spec = nautilus_gradient_get_end_color_spec (background->details->color);
horizontal_gradient = nautilus_gradient_is_horizontal (background->details->color);
start_rgb = nautilus_parse_rgb_with_white_default (start_color_spec);
end_rgb = nautilus_parse_rgb_with_white_default (end_color_spec);
g_free (start_color_spec);
g_free (end_color_spec);
if (start_rgb != end_rgb) {
nautilus_gnome_canvas_fill_with_gradient(buffer, start_rgb, end_rgb,
horizontal_gradient);
} else
gnome_canvas_buf_ensure_buf(buffer);
}
} else {
gnome_canvas_buf_ensure_buf(buffer);
buffer->is_buf = TRUE;
}
}
......
......@@ -33,6 +33,9 @@
#include <libgnomeui/gnome-messagebox.h>
#include <libgnomeui/gnome-stock.h>
#include <libgnomeui/gnome-uidefs.h>
#include <libart_lgpl/art_rgb.h>
#include <libart_lgpl/art_rect.h>
#include "nautilus-gdk-extensions.h"
#include "nautilus-string.h"
static void turn_on_line_wrap_flag_callback (GtkWidget *widget, gpointer callback_data);
......@@ -189,6 +192,95 @@ nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item,
}
}
/**
* nautilus_gnome_canvas_fill_with_gradient, for the anti-aliased canvas:
* @buffer: canvas buffer to draw into.
* @full_rect: rectangle of entire canvas for gradient color selection
* @start_color: Color for the left or top; pixel value does not matter.
* @end_color: Color for the right or bottom; pixel value does not matter.
* @horizontal: TRUE if the color changes from left to right. FALSE if from top to bottom.
*
* Fill the rectangle with a gradient.
* The color changes from start_color to end_color.
* This effect works best on true color displays.
*
* note that most of this routine is a clone of nautilus_fill_rectangle_with_gradient
* from nautilus-gdk-extensions.
*/
#define GRADIENT_BAND_SIZE 4
void
nautilus_gnome_canvas_fill_with_gradient (GnomeCanvasBuf *buffer,
guint32 start_rgb,
guint32 end_rgb,
gboolean horizontal)
{
GdkRectangle band_box;
guchar *bufptr;
gint16 *position;
guint16 *size;
gint num_bands;
guint16 last_band_size;
gdouble fraction;
gint y, band;
gint red_value, green_value, blue_value;
guint32 band_rgb;
g_return_if_fail (horizontal == FALSE || horizontal == TRUE);
/* Set up the band box so we can access it the same way for horizontal or vertical. */
band_box.x = buffer->rect.x0;
band_box.y = buffer->rect.y0;
band_box.width = buffer->rect.x1 - buffer->rect.x0;
band_box.height = buffer->rect.y1 - buffer->rect.y0;
position = horizontal ? &band_box.x : &band_box.y;
size = horizontal ? &band_box.width : &band_box.height;
/* Figure out how many bands we will need. */
num_bands = (*size + GRADIENT_BAND_SIZE - 1) / GRADIENT_BAND_SIZE;
last_band_size = GRADIENT_BAND_SIZE - (GRADIENT_BAND_SIZE * num_bands - *size);
/* Change the band box to be the size of a single band. */
*size = GRADIENT_BAND_SIZE;
/* Fill each band with a separate nautilus_draw_rectangle call. */
for (band = 0; band < num_bands; band++) {
/* Compute a new color value for each band. */
fraction = (double) *position / 2000; /* this is a temporary fudge */
band_rgb = nautilus_interpolate_color (fraction, start_rgb, end_rgb);
red_value = band_rgb >> 16;
green_value = (band_rgb >> 8) & 0xff;
blue_value = band_rgb & 0xff;
/* Last band may need to be a bit smaller to avoid writing outside the box.
* This is more efficient than changing and restoring the clip.
*/
if (band == num_bands - 1) {
*size = last_band_size;
}
/* use libart to fill the band rectangle with the color */
if (!horizontal)
bufptr = buffer->buf + (buffer->buf_rowstride * band * GRADIENT_BAND_SIZE);
else
bufptr = buffer->buf + (4 * band * GRADIENT_BAND_SIZE);
for (y = band_box.y; y < (band_box.y + band_box.height); y++) {
art_rgb_fill_run(bufptr,
red_value,
green_value,
blue_value,
band_box.width);
bufptr += buffer->buf_rowstride;
}
*position += *size;
}
}
static const char **
convert_varargs_to_name_array (va_list args)
{
......
......@@ -65,6 +65,11 @@ void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas
*/
void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item);
/* fill a canvas buffer with a gradient background */
void nautilus_gnome_canvas_fill_with_gradient (GnomeCanvasBuf *buffer,
guint32 start_rgb,
guint32 end_rgb,
gboolean horizontal);
/* More functions for ArtIRect and ArtDRect. */
gboolean nautilus_art_irect_equal (const ArtIRect *rect_a,
const ArtIRect *rect_b);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment