summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Engber <engber@src.gnome.org>2000-10-03 00:26:57 +0000
committerMike Engber <engber@src.gnome.org>2000-10-03 00:26:57 +0000
commitd78afbc31c6c9e3ce40e7d866e60cf7c7cef3b18 (patch)
tree9f9897ce2b7e152d4c5a8f95a8096ba90de004b2
parentb84d41df38e50d1cdd69388e62d51d852638b6ad (diff)
downloadnautilus-d78afbc31c6c9e3ce40e7d866e60cf7c7cef3b18.tar.gz
More background drawing speedups - this time mainly for the non-aa case.
More background drawing speedups - this time mainly for the non-aa case. * libnautilus-extensions/nautilus-background-canvas-group.c: (nautilus_background_canvas_group_initialize_class), (nautilus_background_canvas_group_update), (nautilus_background_canvas_group_draw), (nautilus_background_canvas_group_render): * libnautilus-extensions/nautilus-background.c: (canvas_gradient_helper_v), (canvas_gradient_helper_h), (fill_canvas_from_gradient_buffer), (drawable_gradient_helper_v), (drawable_gradient_helper_h), (fill_drawable_from_gradient_buffer), (draw_pixbuf_tiled), (canvas_buf_from_pixbuf), (ensure_image_scaled), (nautilus_background_pre_draw), (nautilus_background_draw), (nautilus_background_draw_to_drawable), (draw_pixbuf_tiled_aa), (nautilus_background_draw_aa), (nautilus_background_draw_to_canvas), (nautilus_background_draw_flat_box): * libnautilus-extensions/nautilus-background.h: * libnautilus-extensions/nautilus-buffered-widget.c: (create_background_pixbuf_from_ancestor): * libnautilus-extensions/nautilus-directory-background.c: (image_loading_done_callback), (saved_settings_changed_callback): * libnautilus-extensions/nautilus-gdk-extensions.c: (nautilus_rgb16_to_rgb), (nautilus_rgb8_to_rgb), (nautilus_gdk_color_to_rgb): * libnautilus-extensions/nautilus-gdk-extensions.h: * libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c: * libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h: * libnautilus-extensions/nautilus-gnome-extensions.c: (nautilus_gnome_canvas_draw_pixbuf_helper), (nautilus_gnome_canvas_draw_pixbuf_helper_alpha), (nautilus_gnome_canvas_draw_pixbuf): * libnautilus-extensions/nautilus-gnome-extensions.h:
-rw-r--r--ChangeLog36
-rw-r--r--libnautilus-extensions/nautilus-background-canvas-group.c94
-rw-r--r--libnautilus-extensions/nautilus-background.c415
-rw-r--r--libnautilus-extensions/nautilus-background.h64
-rw-r--r--libnautilus-extensions/nautilus-buffered-widget.c23
-rw-r--r--libnautilus-extensions/nautilus-directory-background.c17
-rw-r--r--libnautilus-extensions/nautilus-gdk-extensions.c95
-rw-r--r--libnautilus-extensions/nautilus-gdk-extensions.h8
-rw-r--r--libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c60
-rw-r--r--libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h7
-rw-r--r--libnautilus-extensions/nautilus-gnome-extensions.c10
-rw-r--r--libnautilus-extensions/nautilus-gnome-extensions.h4
-rw-r--r--libnautilus-private/nautilus-background-canvas-group.c94
-rw-r--r--libnautilus-private/nautilus-background.c415
-rw-r--r--libnautilus-private/nautilus-background.h64
-rw-r--r--libnautilus-private/nautilus-buffered-widget.c23
-rw-r--r--libnautilus-private/nautilus-directory-background.c17
-rw-r--r--libnautilus-private/nautilus-gdk-extensions.c95
-rw-r--r--libnautilus-private/nautilus-gdk-extensions.h8
-rw-r--r--libnautilus-private/nautilus-gdk-pixbuf-extensions.c60
-rw-r--r--libnautilus-private/nautilus-gdk-pixbuf-extensions.h7
-rw-r--r--libnautilus-private/nautilus-gnome-extensions.c10
-rw-r--r--libnautilus-private/nautilus-gnome-extensions.h4
23 files changed, 916 insertions, 714 deletions
diff --git a/ChangeLog b/ChangeLog
index 64c50e2a4..bbdbbdf7d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,39 @@
+2000-10-02 Michael Engber <engber@eazel.com>
+
+ More background drawing speedups - this time mainly for
+ the non-aa case.
+ * libnautilus-extensions/nautilus-background-canvas-group.c:
+ (nautilus_background_canvas_group_initialize_class),
+ (nautilus_background_canvas_group_update),
+ (nautilus_background_canvas_group_draw),
+ (nautilus_background_canvas_group_render):
+ * libnautilus-extensions/nautilus-background.c:
+ (canvas_gradient_helper_v), (canvas_gradient_helper_h),
+ (fill_canvas_from_gradient_buffer), (drawable_gradient_helper_v),
+ (drawable_gradient_helper_h), (fill_drawable_from_gradient_buffer),
+ (draw_pixbuf_tiled), (canvas_buf_from_pixbuf),
+ (ensure_image_scaled), (nautilus_background_pre_draw),
+ (nautilus_background_draw), (nautilus_background_draw_to_drawable),
+ (draw_pixbuf_tiled_aa), (nautilus_background_draw_aa),
+ (nautilus_background_draw_to_canvas),
+ (nautilus_background_draw_flat_box):
+ * libnautilus-extensions/nautilus-background.h:
+ * libnautilus-extensions/nautilus-buffered-widget.c:
+ (create_background_pixbuf_from_ancestor):
+ * libnautilus-extensions/nautilus-directory-background.c:
+ (image_loading_done_callback), (saved_settings_changed_callback):
+ * libnautilus-extensions/nautilus-gdk-extensions.c:
+ (nautilus_rgb16_to_rgb), (nautilus_rgb8_to_rgb),
+ (nautilus_gdk_color_to_rgb):
+ * libnautilus-extensions/nautilus-gdk-extensions.h:
+ * libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c:
+ * libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h:
+ * libnautilus-extensions/nautilus-gnome-extensions.c:
+ (nautilus_gnome_canvas_draw_pixbuf_helper),
+ (nautilus_gnome_canvas_draw_pixbuf_helper_alpha),
+ (nautilus_gnome_canvas_draw_pixbuf):
+ * libnautilus-extensions/nautilus-gnome-extensions.h:
+
2000-10-02 Arlo Rose <arlo@eazel.com>
* icons/throbber/Makefile.am:
diff --git a/libnautilus-extensions/nautilus-background-canvas-group.c b/libnautilus-extensions/nautilus-background-canvas-group.c
index 5c40b2a98..d1664752d 100644
--- a/libnautilus-extensions/nautilus-background-canvas-group.c
+++ b/libnautilus-extensions/nautilus-background-canvas-group.c
@@ -34,23 +34,32 @@
#include "nautilus-gdk-extensions.h"
#include "nautilus-gtk-macros.h"
+#include <stdio.h>
+
static void nautilus_background_canvas_group_initialize_class (gpointer klass);
static void nautilus_background_canvas_group_initialize (gpointer object,
- gpointer klass);
-static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
- GdkDrawable *drawable,
- int x,
- int y,
- int width,
- int height);
-static void nautilus_background_canvas_group_render (GnomeCanvasItem *item,
- GnomeCanvasBuf *buffer);
+ gpointer klass);
+
+static void nautilus_background_canvas_group_update (GnomeCanvasItem *item,
+ double affine[6],
+ ArtSVP *clip_path,
+ gint flags);
+
+static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
+ GdkDrawable *drawable,
+ int x,
+ int y,
+ int width,
+ int height);
+static void nautilus_background_canvas_group_render (GnomeCanvasItem *item,
+ GnomeCanvasBuf *buffer);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusBackgroundCanvasGroup, nautilus_background_canvas_group, GNOME_TYPE_CANVAS_GROUP)
static void
nautilus_background_canvas_group_initialize_class (gpointer klass)
{
+ GNOME_CANVAS_ITEM_CLASS (klass)->update = nautilus_background_canvas_group_update;
GNOME_CANVAS_ITEM_CLASS (klass)->draw = nautilus_background_canvas_group_draw;
GNOME_CANVAS_ITEM_CLASS (klass)->render = nautilus_background_canvas_group_render;
}
@@ -61,13 +70,30 @@ nautilus_background_canvas_group_initialize (gpointer object, gpointer klass)
}
static void
-nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- int drawable_corner_x, int drawable_corner_y,
- int drawable_width, int drawable_height)
+nautilus_background_canvas_group_update (GnomeCanvasItem *item,
+ double affine[6],
+ ArtSVP *clip_path,
+ gint flags)
+{
+ NautilusBackground *background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
+
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
+
+ NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags));
+}
+
+static void
+nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
+ GdkDrawable *drawable,
+ int x,
+ int y,
+ int width,
+ int height)
{
NautilusBackground *background;
GdkGC *gc;
- GdkRectangle rectangle;
/* Draw the background. */
background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
@@ -83,21 +109,17 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
*/
gc = gdk_gc_new (drawable);
- /* The rectangle is the size of the entire viewed area
- * of the canvas. The corner is determined by the
- * current scroll position of the GtkLayout, and the
- * size is determined by the current size of the
- * widget. Since 0,0 is the corner of the drawable,
- * we need to offset the rectangle so it's relative to
- * the drawable's coordinates.
+ /* FIXME bugzilla.eazel.com 2280:
+ * It shouldn't be necessary to call nautilus_background_pre_draw here.
+ * However, nautilus_background_canvas_group_update (who should be the one
+ * spot we call nautilus_background_pre_draw from) doesn't seemed to get
+ * called prior to all drawing.
*/
- rectangle.x = GTK_LAYOUT (item->canvas)->xoffset - drawable_corner_x;
- rectangle.y = GTK_LAYOUT (item->canvas)->yoffset - drawable_corner_y;
- rectangle.width = GTK_WIDGET (item->canvas)->allocation.width;
- rectangle.height = GTK_WIDGET (item->canvas)->allocation.height;
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
- nautilus_background_draw (background, drawable, gc, &rectangle,
- -drawable_corner_x, -drawable_corner_y);
+ nautilus_background_draw (background, drawable, gc, x, y, width, height);
gdk_gc_unref (gc);
}
@@ -105,10 +127,7 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
/* Call through to the GnomeCanvasGroup implementation, which
* will draw all the canvas items.
*/
- NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw,
- (item, drawable,
- drawable_corner_x, drawable_corner_y,
- drawable_width, drawable_height));
+ NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw, (item, drawable, x, y, width, height));
}
@@ -120,10 +139,17 @@ nautilus_background_canvas_group_render (GnomeCanvasItem *item, GnomeCanvasBuf *
background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
if (background != NULL) {
- nautilus_background_draw_aa (background,
- buffer,
- GTK_WIDGET (item->canvas)->allocation.width,
- GTK_WIDGET (item->canvas)->allocation.height);
+ /* FIXME bugzilla.eazel.com 2280:
+ * It shouldn't be necessary to call nautilus_background_pre_draw here.
+ * However, nautilus_background_canvas_group_update (who should be the one
+ * spot we call nautilus_background_pre_draw from) doesn't seemed to get
+ * called prior to all drawing.
+ */
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
+
+ nautilus_background_draw_aa (background, buffer);
}
/* Call through to the GnomeCanvasGroup implementation, which will draw all
diff --git a/libnautilus-extensions/nautilus-background.c b/libnautilus-extensions/nautilus-background.c
index 39610f064..1e8d9af80 100644
--- a/libnautilus-extensions/nautilus-background.c
+++ b/libnautilus-extensions/nautilus-background.c
@@ -95,6 +95,16 @@ struct NautilusBackgroundDetails {
NautilusPixbufLoadHandle *load_image_handle;
gboolean combine_mode;
NautilusBackgroundImagePlacement image_placement;
+
+ /* The image_rect is the area (canvas relative) the image will cover.
+ * Note: image_rect_width/height are not always the same as the image's
+ * width and height - e.g. if the image is tiled the image rect covers
+ * the whole background.
+ */
+ int image_rect_x;
+ int image_rect_y;
+ int image_rect_width;
+ int image_rect_height;
};
static void
@@ -326,7 +336,7 @@ ensure_gradient_buffered (NautilusBackground *background, int dest_width, int de
}
static void
-gradient_helper_v (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
+canvas_gradient_helper_v (const GnomeCanvasBuf *buf, const art_u8 *gradient_buff)
{
int width = buf->rect.x1 - buf->rect.x0;
int height = buf->rect.y1 - buf->rect.y0;
@@ -346,7 +356,7 @@ gradient_helper_v (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
}
static void
-gradient_helper_h (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
+canvas_gradient_helper_h (const GnomeCanvasBuf *buf, const art_u8 *gradient_buff)
{
int width = buf->rect.x1 - buf->rect.x0;
int height = buf->rect.y1 - buf->rect.y0;
@@ -365,14 +375,93 @@ gradient_helper_h (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
}
static void
-fill_canvas_from_gradient_buffer (GnomeCanvasBuf *buf, NautilusBackground *background)
+fill_canvas_from_gradient_buffer (const GnomeCanvasBuf *buf, const NautilusBackground *background)
+{
+ g_return_if_fail (background->details->gradient_buffer != NULL);
+
+ /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix background
+ * scolling.
+ *
+ * I.e. currently you can scroll off the end of the gradient - and we
+ * handle this by pegging it the the last rgb value.
+ *
+ * It might be needed permanently after depending on how this is fixed.
+ * If we tie gradients to the boundry of icon placement (as opposed to
+ * window size) then when dragging an icon you might scroll off the
+ * end of the gradient - which will get recaluated after the drop.
+ */
+ if (background->details->gradient_is_horizontal) {
+ if (buf->rect.x1 > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GnomeCanvasBuf gradient = *buf;
+ GnomeCanvasBuf overflow = *buf;
+ gradient.rect.x1 = gradient.rect.x0 < background->details->gradient_num_pixels ? background->details->gradient_num_pixels : gradient.rect.x0;
+ overflow.buf += (gradient.rect.x1 - gradient.rect.x0) * 3;
+ overflow.rect.x0 = gradient.rect.x1;
+ nautilus_gnome_canvas_fill_rgb (&overflow, rgb888[0], rgb888[1], rgb888[2]);
+ canvas_gradient_helper_h (&gradient, background->details->gradient_buffer);
+ return;
+ }
+ } else {
+ if (buf->rect.y1 > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GnomeCanvasBuf gradient = *buf;
+ GnomeCanvasBuf overflow = *buf;
+ gradient.rect.y1 = gradient.rect.y0 < background->details->gradient_num_pixels ? background->details->gradient_num_pixels : gradient.rect.y0;
+ overflow.buf += (gradient.rect.y1 - gradient.rect.y0) * gradient.buf_rowstride;
+ overflow.rect.y0 = gradient.rect.y1;
+ nautilus_gnome_canvas_fill_rgb (&overflow, rgb888[0], rgb888[1], rgb888[2]);
+ canvas_gradient_helper_v (&gradient, background->details->gradient_buffer);
+ return;
+ }
+ }
+
+ (background->details->gradient_is_horizontal ? canvas_gradient_helper_h : canvas_gradient_helper_v) (buf, background->details->gradient_buffer);
+}
+
+static void
+drawable_gradient_helper_v (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rect, art_u8 *gradient_buff)
{
- int buf_edge;
+ int y;
+
+ gradient_buff += rect->y * 3;
+
+ for (y = 0; y < rect->height; ++y) {
+ art_u8 r = *gradient_buff++;
+ art_u8 g = *gradient_buff++;
+ art_u8 b = *gradient_buff++;
+ GdkColor color = {0, r << 8, g << 8, b << 8};
+ gdk_colormap_alloc_color (gdk_colormap_get_system (), &color, FALSE, TRUE);
+ gdk_gc_set_foreground (gc, &color);
+ gdk_draw_line (drawable, gc, 0, y, rect->width, y);
+ }
+}
+
+static void
+drawable_gradient_helper_h (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rect, art_u8 *gradient_buff)
+{
+ gradient_buff += rect->x * 3;
+
+ /* We can do the fill with a single call to gdk_draw_rgb_image_dithalign
+ * because we pass a rowstride of zero. Zero rowstride make gradient_buff
+ * act like a pixbuf of infinite height - with all identical rows.
+ */
+ gdk_draw_rgb_image_dithalign (drawable, gc, 0, 0, rect->width, rect->height, GDK_RGB_DITHER_NONE, gradient_buff, 0, 0, 0);
+}
+
+static void
+fill_drawable_from_gradient_buffer (GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height,
+ NautilusBackground *background)
+
+{
+ GdkRectangle rect = {drawable_x, drawable_y, drawable_width, drawable_height};
g_return_if_fail (background->details->gradient_buffer != NULL);
- /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix it so the
- * background doesn't scroll.
+ /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix background
+ * scolling.
*
* I.e. currently you can scroll off the end of the gradient - and we
* handle this by pegging it the the last rgb value.
@@ -382,20 +471,66 @@ fill_canvas_from_gradient_buffer (GnomeCanvasBuf *buf, NautilusBackground *backg
* window size) then when dragging an icon you might scroll off the
* end of the gradient - which will get recaluated after the drop.
*/
- buf_edge = background->details->gradient_is_horizontal ? buf->rect.x1 : buf->rect.y1;
- if (buf_edge > background->details->gradient_num_pixels) {
- art_u8 *rgb = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
- nautilus_gnome_canvas_fill_rgb (buf, rgb[0], rgb[1], rgb[2]);
- return;
+ if (background->details->gradient_is_horizontal) {
+ int drawable_end = rect.x + rect.width;
+ if (drawable_end > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GdkRectangle overflow;
+ rect.width = rect.x < background->details->gradient_num_pixels ? background->details->gradient_num_pixels - rect.x : 0;
+ /* overflow is in drawable relative coords (as opposed to canvas relative) */
+ overflow.x = rect.width;
+ overflow.y = 0;
+ overflow.width = drawable_width - rect.width;
+ overflow.height = drawable_height;
+ nautilus_fill_rectangle_with_color (drawable, gc, &overflow, nautilus_rgb8_to_rgb (rgb888[0], rgb888[1], rgb888[2]));
+ }
+ } else {
+ int drawable_end = rect.y + rect.height;
+ if (drawable_end > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GdkRectangle overflow;
+ rect.height = rect.y < background->details->gradient_num_pixels ? background->details->gradient_num_pixels - rect.y : 0;
+ /* overflow is in drawable relative coords (as opposed to canvas relative) */
+ overflow.x = 0;
+ overflow.y = rect.height;
+ overflow.width = drawable_width;
+ overflow.height = drawable_height - rect.height;
+ nautilus_fill_rectangle_with_color (drawable, gc, &overflow, nautilus_rgb8_to_rgb (rgb888[0], rgb888[1], rgb888[2]));
+ }
}
- (background->details->gradient_is_horizontal ? gradient_helper_h : gradient_helper_v) (buf, background->details->gradient_buffer);
+ (background->details->gradient_is_horizontal ? drawable_gradient_helper_h : drawable_gradient_helper_v)
+ (drawable, gc, &rect, background->details->gradient_buffer);
+}
+
+/* fill the canvas buffer with a tiled pixbuf */
+static void
+draw_pixbuf_tiled (GdkPixbuf *pixbuf, GdkDrawable *drawable, GdkGC *gc, int drawable_x, int drawable_y, int drawable_width, int drawable_height)
+{
+ int x, y;
+ int start_x, start_y;
+ int end_x, end_y;
+ int tile_width, tile_height;
+
+ tile_width = gdk_pixbuf_get_width (pixbuf);
+ tile_height = gdk_pixbuf_get_height (pixbuf);
+
+ start_x = -(drawable_x % tile_width);
+ start_y = -(drawable_y % tile_height);
+ end_x = drawable_x + drawable_width;
+ end_y = drawable_y + drawable_height;
+
+ for (y = start_y; y < end_y; y += tile_height) {
+ for (x = start_x; x < end_x; x += tile_width) {
+ gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc, 0, 0, x, y, tile_width, tile_height, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+ }
}
/* Initializes a pseudo-canvas buf so canvas drawing routines can be used to draw into a pixbuf.
*/
static void
-canvas_buf_from_pixmap (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, int width, int height)
+canvas_buf_from_pixbuf (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, int width, int height)
{
buf->buf = gdk_pixbuf_get_pixels (pixbuf);
buf->buf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@@ -409,13 +544,13 @@ canvas_buf_from_pixmap (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, in
}
static void
-ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_height, GdkRectangle *image_rect)
+ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_height)
{
if (background->details->image == NULL) {
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = 0;
- image_rect->height = 0;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = 0;
+ background->details->image_rect_height = 0;
} else {
int image_width;
int image_height;
@@ -467,147 +602,158 @@ ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_he
gdk_pixbuf_unref (background->details->image);
background->details->image = NULL;
start_loading_image (background);
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = 0;
- image_rect->height = 0;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = 0;
+ background->details->image_rect_height = 0;
} else if (background->details->image_placement == NAUTILUS_BACKGROUND_TILED) {
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = dest_width;
- image_rect->height = dest_height;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = dest_width;
+ background->details->image_rect_height = dest_height;
} else {
- image_rect->x = (dest_width - image_width) / 2;
- image_rect->y = (dest_height - image_height) / 2;
- image_rect->width = image_width;
- image_rect->height = image_height;
+ background->details->image_rect_x = (dest_width - image_width) / 2;
+ background->details->image_rect_y = (dest_height - image_height) / 2;
+ background->details->image_rect_width = image_width;
+ background->details->image_rect_height = image_height;
}
}
}
+void
+nautilus_background_pre_draw (NautilusBackground *background, int entire_width, int entire_height)
+{
+ ensure_image_scaled (background, entire_width, entire_height);
+ ensure_gradient_buffered (background, entire_width, entire_height);
+}
+
/* This routine is for gdk style rendering, which doesn't naturally
* support transparency, so we draw into a pixbuf offscreen if
* necessary.
*/
void
nautilus_background_draw (NautilusBackground *background,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- int origin_x,
- int origin_y)
+ GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height)
{
- GdkRectangle image_rect;
- GdkPixbuf *pixbuf;
- GnomeCanvasBuf buffer;
- int image_width;
- int image_height;
- char *start_color_spec, *end_color_spec;
- guint32 start_rgb, end_rgb;
- gboolean horizontal_gradient;
+ int drawable_right;
+ int drawable_bottom;
+ int image_rect_right;
+ int image_rect_bottom;
g_return_if_fail (NAUTILUS_IS_BACKGROUND (background));
if (background->details->combine_mode) {
+ GdkPixbuf *pixbuf;
+ GnomeCanvasBuf buffer;
+
/* allocate a pixbuf the size of the rectangle */
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, rectangle->width, rectangle->height);
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, drawable_width, drawable_height);
/* contrive a CanvasBuf structure to point to it */
- canvas_buf_from_pixmap (&buffer, pixbuf, rectangle->x, rectangle->y, rectangle->width, rectangle->height);
+ canvas_buf_from_pixbuf (&buffer, pixbuf, drawable_x, drawable_y, drawable_width, drawable_height);
/* invoke the anti-aliased code to do the work */
- nautilus_background_draw_aa (background, &buffer, rectangle->width, rectangle->height);
+ nautilus_background_draw_aa (background, &buffer);
/* blit the pixbuf to the drawable */
gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
0, 0,
- rectangle->x, rectangle->y, rectangle->width, rectangle->height,
- GDK_RGB_DITHER_NORMAL, origin_x, origin_y);
+ 0, 0,
+ drawable_width, drawable_height,
+ GDK_RGB_DITHER_NONE, 0, 0);
/* free things up and we're done */
gdk_pixbuf_unref (pixbuf);
return;
}
-
- ensure_image_scaled (background, rectangle->width, rectangle->height, &image_rect);
- /* FIXME bugzill.eazel.com 2280:
- * The rectangle we get passed here seems to be bogus.
- * It works since we end up drawing the whole image every time.
- * I think if we fix up the call (made in nautilus-background-canvas-group.c)
- * to pass the rect that needs updating, then we can optimize this.
- */
+ drawable_right = drawable_x + drawable_width;
+ drawable_bottom = drawable_y + drawable_height;
- if (!background->details->image || image_rect.width < rectangle->width || image_rect.height < rectangle->height) {
- 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);
-
- nautilus_fill_rectangle_with_gradient (drawable,
- gc,
- rectangle,
- start_rgb,
- end_rgb,
- horizontal_gradient);
+ image_rect_right = background->details->image_rect_x + background->details->image_rect_width;
+ image_rect_bottom = background->details->image_rect_y + background->details->image_rect_height;
+
+ if (!background->details->image ||
+ drawable_x < background->details->image_rect_x ||
+ drawable_y < background->details->image_rect_y ||
+ drawable_right > image_rect_right ||
+ drawable_bottom > image_rect_bottom) {
+ if (background->details->is_solid_color) {
+ GdkRectangle rect = {0 , 0, drawable_width, drawable_height};
+ nautilus_fill_rectangle_with_color (drawable, gc, &rect, nautilus_gdk_color_to_rgb (&background->details->solid_color));
+ } else {
+ fill_drawable_from_gradient_buffer (drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height, background);
+ }
}
if (background->details->image != NULL) {
switch (background->details->image_placement) {
case NAUTILUS_BACKGROUND_TILED:
- nautilus_gdk_pixbuf_render_to_drawable_tiled (background->details->image,
- drawable,
- gc,
- rectangle,
- GDK_RGB_DITHER_NORMAL,
- origin_x, origin_y);
+ draw_pixbuf_tiled (background->details->image, drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height);
break;
- default:
- g_assert_not_reached ();
- /* fall through */
case NAUTILUS_BACKGROUND_CENTERED:
case NAUTILUS_BACKGROUND_SCALED:
case NAUTILUS_BACKGROUND_SCALED_ASPECT:
- /* Since the image has already been scaled, all these cases
- * can be treated identically.
+ /* Since the image has already been scaled, all these cases can be treated identically.
*/
- image_width = gdk_pixbuf_get_width (background->details->image);
- image_height = gdk_pixbuf_get_height (background->details->image);
- gdk_pixbuf_render_to_drawable (background->details->image, drawable, gc,
- 0, 0,
- rectangle->x + (rectangle->width - image_width)/2,
- rectangle->y + (rectangle->height - image_height)/2,
- image_width, image_height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
+ if (drawable_x < image_rect_right &&
+ drawable_y < image_rect_bottom &&
+ drawable_right > background->details->image_rect_x &&
+ drawable_bottom > background->details->image_rect_y) {
+ int src_offset_x;
+ int src_offset_y;
+ int dst_offset_x;
+ int dst_offset_y;
+ int copy_width;
+ int copy_height;
+
+ if (drawable_x < background->details->image_rect_x) {
+ src_offset_x = 0;
+ dst_offset_x = background->details->image_rect_x - drawable_x;
+ } else {
+ src_offset_x = drawable_x - background->details->image_rect_x;
+ dst_offset_x = 0;
+ }
+
+ copy_width = drawable_right < image_rect_right ? drawable_width - dst_offset_x : image_rect_right - drawable_x;
+
+ if (drawable_y < background->details->image_rect_y) {
+ src_offset_y = 0;
+ dst_offset_y = background->details->image_rect_y - drawable_y;
+ } else {
+ src_offset_y = drawable_y - background->details->image_rect_y;
+ dst_offset_y = 0;
+ }
+
+ copy_height = drawable_bottom < image_rect_bottom ? drawable_height - dst_offset_y : image_rect_bottom - drawable_y;
+
+ gdk_pixbuf_render_to_drawable (background->details->image, drawable, gc,
+ src_offset_x, src_offset_y,
+ dst_offset_x, dst_offset_y,
+ copy_width, copy_height,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ }
break;
}
}
}
-static void
-draw_pixbuf_centered_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer,
- int entire_width, int entire_height)
+void
+nautilus_background_draw_to_drawable (NautilusBackground *background,
+ GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height,
+ int entire_width, int entire_height)
{
- int image_width;
- int image_height;
- int image_left;
- int image_top;
-
- image_width = gdk_pixbuf_get_width (pixbuf);
- image_height = gdk_pixbuf_get_height (pixbuf);
- image_left = (entire_width - image_width) / 2;
- image_top = (entire_height - image_height) / 2;
-
- nautilus_gnome_canvas_draw_pixmap (buffer, pixbuf, image_left, image_top);
+ nautilus_background_pre_draw (background, entire_width, entire_height);
+ nautilus_background_draw (background, drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height);
}
-/* fill the canvas buffer with a tiled pixmap */
+
+/* fill the canvas buffer with a tiled pixbuf */
static void
draw_pixbuf_tiled_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
{
@@ -623,24 +769,17 @@ draw_pixbuf_tiled_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
for (y = start_y; y < buffer->rect.y1; y += tile_height) {
for (x = start_x; x < buffer->rect.x1; x += tile_width) {
- nautilus_gnome_canvas_draw_pixmap (buffer, pixbuf, x, y);
+ nautilus_gnome_canvas_draw_pixbuf (buffer, pixbuf, x, y);
}
}
}
/* draw the background on the anti-aliased canvas */
void
-nautilus_background_draw_aa (NautilusBackground *background,
- GnomeCanvasBuf *buffer,
- int entire_width,
- int entire_height)
-{
- GdkRectangle image_rect;
-
+nautilus_background_draw_aa (NautilusBackground *background, GnomeCanvasBuf *buffer)
+{
g_return_if_fail (NAUTILUS_IS_BACKGROUND (background));
- ensure_image_scaled (background, entire_width, entire_height, &image_rect);
-
/* If the image has alpha - we always draw the gradient behind it.
* In principle, we could do better by having already drawn gradient behind
* the scaled image. However, this would add a significant amount of
@@ -648,20 +787,18 @@ nautilus_background_draw_aa (NautilusBackground *background,
* scaled image to a location on the screen because it holds a gradient.
* This is especially problematic for tiled images with alpha.
*/
-
if (!background->details->image ||
gdk_pixbuf_get_has_alpha (background->details->image) ||
- buffer->rect.x0 < image_rect.x ||
- buffer->rect.y0 < image_rect.y ||
- buffer->rect.x1 > (image_rect.x + image_rect.width) ||
- buffer->rect.y1 > (image_rect.y + image_rect.height)) {
+ buffer->rect.x0 < background->details->image_rect_x ||
+ buffer->rect.y0 < background->details->image_rect_y ||
+ buffer->rect.x1 > (background->details->image_rect_x + background->details->image_rect_width) ||
+ buffer->rect.y1 > (background->details->image_rect_y + background->details->image_rect_height)) {
if (background->details->is_solid_color) {
nautilus_gnome_canvas_fill_rgb (buffer,
- background->details->solid_color.red,
- background->details->solid_color.green,
- background->details->solid_color.blue);
+ background->details->solid_color.red >> 8,
+ background->details->solid_color.green >> 8,
+ background->details->solid_color.blue >> 8);
} else {
- ensure_gradient_buffered (background, entire_width, entire_height);
fill_canvas_from_gradient_buffer (buffer, background);
}
}
@@ -680,7 +817,10 @@ nautilus_background_draw_aa (NautilusBackground *background,
/* Since the image has already been scaled, all these cases
* can be treated identically.
*/
- draw_pixbuf_centered_aa (background->details->image, buffer, entire_width, entire_height);
+ nautilus_gnome_canvas_draw_pixbuf (buffer,
+ background->details->image,
+ background->details->image_rect_x,
+ background->details->image_rect_y);
break;
}
}
@@ -689,6 +829,16 @@ nautilus_background_draw_aa (NautilusBackground *background,
buffer->is_buf = TRUE;
}
+void
+nautilus_background_draw_to_canvas (NautilusBackground *background,
+ GnomeCanvasBuf *buffer,
+ int entire_width,
+ int entire_height)
+{
+ nautilus_background_pre_draw (background, entire_width, entire_height);
+ nautilus_background_draw_aa (background, buffer);
+}
+
char *
nautilus_background_get_color (NautilusBackground *background)
{
@@ -870,7 +1020,6 @@ nautilus_background_draw_flat_box (GtkStyle *style,
gboolean call_parent;
NautilusBackground *background;
GdkGC *gc;
- GdkRectangle rectangle;
call_parent = TRUE;
@@ -893,15 +1042,9 @@ nautilus_background_draw_flat_box (GtkStyle *style,
if (area)
gdk_gc_set_clip_rectangle (gc, area);
-
nautilus_gdk_window_update_sizes (window, &width, &height);
- rectangle.x = x;
- rectangle.y = y;
- rectangle.width = width;
- rectangle.height = height;
-
- nautilus_background_draw (background, window, gc,
- &rectangle, 0, 0);
+
+ nautilus_background_draw_to_drawable (background, window, gc, 0, 0, width, height, widget->allocation.width, widget->allocation.height);
}
static GtkStyleClass *
diff --git a/libnautilus-extensions/nautilus-background.h b/libnautilus-extensions/nautilus-background.h
index 6e5ed147a..ec9b691b2 100644
--- a/libnautilus-extensions/nautilus-background.h
+++ b/libnautilus-extensions/nautilus-background.h
@@ -91,20 +91,56 @@ gboolean nautilus_background_is_set
gboolean nautilus_background_is_loaded (NautilusBackground *background);
-/* Explicitly fills a rectangle with a background. */
-void nautilus_background_draw (NautilusBackground *background,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- int origin_x,
- int origin_y);
-
-
-/* Explicitly fills a rectangle with a background on the anti-aliased canvas. */
-void nautilus_background_draw_aa (NautilusBackground *background,
- GnomeCanvasBuf *buffer,
- int entire_width,
- int entire_height);
+/* For preping the background to be used in one of the two calls
+ * below. Only intended to be called by nautilus_background_canvas_group_update.
+ */
+void nautilus_background_pre_draw (NautilusBackground *background,
+ int entire_width,
+ int entire_height);
+
+/* For updating the canvas, non-aa case. Note: nautilus_background_pre_draw
+ * must have been previously called. Only intended to be called by
+ * nautilus_background_canvas_group_draw.
+ */
+void nautilus_background_draw (NautilusBackground *background,
+ GdkDrawable *drawable,
+ GdkGC *gc,
+ int drawable_x,
+ int drawable_y,
+ int drawable_width,
+ int drawable_height);
+
+/* For updating the canvas, aa case. Note: nautilus_background_pre_draw
+ * must have been previously called. Only intended to be called by
+ * nautilus_background_canvas_group_render.
+ */
+void nautilus_background_draw_aa (NautilusBackground *background,
+ GnomeCanvasBuf *buffer);
+
+/* Used to fill a drawable with a background.
+ * - entire_width/height describe the total area the background covers
+ * - drawable_x/y/width/height describe the portion of that area the drawable covers
+ */
+void nautilus_background_draw_to_drawable (NautilusBackground *background,
+ GdkDrawable *drawable,
+ GdkGC *gc,
+ int drawable_x,
+ int drawable_y,
+ int drawable_width,
+ int drawable_height,
+ int entire_width,
+ int entire_height);
+
+/* Used to fill a drawable with a background.
+ * - entire_width/height describe the total area the background covers
+ * - buffer is a portion of that area
+ */
+void nautilus_background_draw_to_canvas (NautilusBackground *background,
+ GnomeCanvasBuf *buffer,
+ int entire_width,
+ int entire_height);
+
+
/* Handles a dragged color being dropped on a widget to change the background color. */
diff --git a/libnautilus-extensions/nautilus-buffered-widget.c b/libnautilus-extensions/nautilus-buffered-widget.c
index 8bbcfba27..68975847e 100644
--- a/libnautilus-extensions/nautilus-buffered-widget.c
+++ b/libnautilus-extensions/nautilus-buffered-widget.c
@@ -556,25 +556,24 @@ create_background_pixbuf_from_ancestor (const NautilusBufferedWidget *buffered_w
if (background_ancestor != NULL) {
NautilusBackground *background;
GdkPixmap *pixmap;
- GdkRectangle background_area;
background = nautilus_get_widget_background (background_ancestor);
g_assert (NAUTILUS_IS_BACKGROUND (background));
-
- background_area.x = 0;
- background_area.y = 0;
- background_area.width = background_ancestor->allocation.width;
- background_area.height = background_ancestor->allocation.height;
-
- pixmap = gdk_pixmap_new (widget->window, background_area.width, background_area.height, -1);
-
- nautilus_background_draw (background, pixmap, buffered_widget->detail->copy_area_gc, &background_area, 0, 0);
+
+ pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+
+ nautilus_background_draw_to_drawable (background,
+ pixmap,
+ buffered_widget->detail->copy_area_gc,
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, widget->allocation.height,
+ background_ancestor->allocation.width, background_ancestor->allocation.height);
pixbuf = gdk_pixbuf_get_from_drawable (NULL,
pixmap,
gdk_rgb_get_cmap (),
- widget->allocation.x,
- widget->allocation.y,
+ 0,
+ 0,
0,
0,
widget->allocation.width,
diff --git a/libnautilus-extensions/nautilus-directory-background.c b/libnautilus-extensions/nautilus-directory-background.c
index 1073498ff..a89f337c3 100644
--- a/libnautilus-extensions/nautilus-directory-background.c
+++ b/libnautilus-extensions/nautilus-directory-background.c
@@ -481,7 +481,8 @@ image_loading_done_callback (NautilusBackground *background, gboolean successful
{
GdkGC *gc;
GdkPixmap *bg_pixmap;
- GdkRectangle screen_rectangle;
+ int width;
+ int height;
g_assert (NAUTILUS_IS_BACKGROUND (background));
@@ -494,15 +495,13 @@ image_loading_done_callback (NautilusBackground *background, gboolean successful
/* need to update the root view whether loading succeeded or not
*/
- screen_rectangle.x = 0;
- screen_rectangle.y = 0;
- screen_rectangle.width = gdk_screen_width ();
- screen_rectangle.height = gdk_screen_height ();
+ width = gdk_screen_width ();
+ height = gdk_screen_height ();
- bg_pixmap = make_root_pixmap (screen_rectangle.width, screen_rectangle.height);
+ bg_pixmap = make_root_pixmap (width, height);
gc = gdk_gc_new (bg_pixmap);
- nautilus_background_draw (background, bg_pixmap, gc, &screen_rectangle, 0, 0);
+ nautilus_background_draw_to_drawable (background, bg_pixmap, gc, 0, 0, width, height, width, height);
set_root_pixmap (bg_pixmap);
@@ -653,8 +652,8 @@ saved_settings_changed_callback (NautilusDirectory *directory,
background_changed_callback,
directory);
- nautilus_background_set_color (background, color);
- nautilus_background_set_image_uri (background, image);
+ nautilus_background_set_color (background, color);
+ nautilus_background_set_image_uri (background, image);
nautilus_background_set_combine_mode (background, combine);
nautilus_background_set_image_placement (background, placement);
diff --git a/libnautilus-extensions/nautilus-gdk-extensions.c b/libnautilus-extensions/nautilus-gdk-extensions.c
index da719642b..160a6732f 100644
--- a/libnautilus-extensions/nautilus-gdk-extensions.c
+++ b/libnautilus-extensions/nautilus-gdk-extensions.c
@@ -84,73 +84,6 @@ nautilus_fill_rectangle_with_color (GdkDrawable *drawable,
}
/**
- * nautilus_fill_rectangle_with_gradient:
- * @drawable: Target to draw into.
- * @gc: Graphics context (mainly for clip).
- * @rectangle: Rectangle to draw gradient in.
- * @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.
- */
-void
-nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- guint32 start_rgb,
- guint32 end_rgb,
- gboolean horizontal)
-{
- GdkRectangle band_box;
- gint16 *position;
- guint16 *size;
- gint num_bands;
- guint16 last_band_size;
- gdouble multiplier;
- gint band;
- guint32 band_rgb;
-
- g_return_if_fail (drawable != NULL);
- g_return_if_fail (gc != NULL);
- g_return_if_fail (rectangle != NULL);
- 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 = *rectangle;
- 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;
-
- /* Set up a multiplier to use to interpolate the colors as we go. */
- multiplier = num_bands <= 1 ? 0.0 : 1.0 / (num_bands - 1);
-
- /* 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. */
- band_rgb = nautilus_interpolate_color (band * multiplier, start_rgb, end_rgb);
-
- /* 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;
- }
-
- nautilus_fill_rectangle_with_color (drawable, gc, &band_box, band_rgb);
- *position += *size;
- }
-}
-
-/**
* nautilus_rectangle_contains:
* @rectangle: Rectangle possibly containing a point.
* @x: X coordinate of a point.
@@ -508,6 +441,24 @@ nautilus_parse_rgb_with_white_default (const char *color_spec)
| ((color.blue >> 8) & NAUTILUS_RGB_COLOR_BLUE);
}
+guint32
+nautilus_rgb16_to_rgb (gushort r, gushort g, gushort b)
+{
+ guint32 result;
+
+ result = (0xff0000 | (r & 0xff00));
+ result <<= 8;
+ result |= ((g & 0xff00) | (b >> 8));
+
+ return result;
+}
+
+guint32
+nautilus_rgb8_to_rgb (guchar r, guchar g, guchar b)
+{
+ return nautilus_rgb16_to_rgb (r << 8, g << 8, b << 8);
+}
+
/**
* nautilus_gdk_color_to_rgb
* @color: A GdkColor style color.
@@ -519,17 +470,11 @@ nautilus_parse_rgb_with_white_default (const char *color_spec)
guint32
nautilus_gdk_color_to_rgb (const GdkColor *color)
{
- guint32 result;
-
- result = (0xff0000 | (color->red & 0xff00));
- result <<= 8;
- result |= ((color->green & 0xff00) | (color->blue >> 8));
-
- return result;
+ return nautilus_rgb16_to_rgb (color->red, color->green, color->blue);
}
/**
- * nautilus_gdk_color_to_rgb
+ * nautilus_gdk_rgb_to_color
* @color: a gdk_rgb style value.
*
* Converts from a gdk_rgb value style to a GdkColor one.
diff --git a/libnautilus-extensions/nautilus-gdk-extensions.h b/libnautilus-extensions/nautilus-gdk-extensions.h
index ce4637bf1..43e37c129 100644
--- a/libnautilus-extensions/nautilus-gdk-extensions.h
+++ b/libnautilus-extensions/nautilus-gdk-extensions.h
@@ -85,6 +85,8 @@ guint32 nautilus_parse_rgb_with_default (const char *colo
guint32 nautilus_parse_rgb_with_white_default (const char *color_spec);
guint32 nautilus_rgb_shift_color (guint32 color,
float shift_by);
+guint32 nautilus_rgb16_to_rgb (gushort r, gushort g, gushort b);
+guint32 nautilus_rgb8_to_rgb (guchar r, guchar g, guchar b);
guint32 nautilus_gdk_color_to_rgb (const GdkColor *color);
GdkColor * nautilus_gdk_rgb_to_color (const guint32 color);
@@ -96,12 +98,6 @@ void nautilus_fill_rectangle_with_color (GdkDrawable *draw
GdkGC *gc,
const GdkRectangle *rectangle,
guint32 rgb);
-void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- guint32 start_rgb,
- guint32 end_rgb,
- gboolean horizontal_gradient);
/* A routine to get a 50% gray stippled bitmap for use in some types of highlighting. */
GdkBitmap *nautilus_stipple_bitmap (void);
diff --git a/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c b/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c
index fbde6f734..c35742e76 100644
--- a/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c
+++ b/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.c
@@ -281,63 +281,9 @@ nautilus_cancel_gdk_pixbuf_load (NautilusPixbufLoadHandle *handle)
free_pixbuf_load_handle (handle);
}
-void
-nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rect,
- GdkRgbDither dither,
- int x_dither,
- int y_dither)
-{
- int x, y;
- int start_x, start_y;
- int end_x, end_y;
- int tile_x, tile_y;
- int blit_x, blit_y;
- int tile_width, tile_height;
- int blit_width, blit_height;
- int tile_offset_x, tile_offset_y;
-
- tile_width = gdk_pixbuf_get_width (pixbuf);
- tile_height = gdk_pixbuf_get_height (pixbuf);
-
- tile_offset_x = (rect->x - x_dither) % tile_width;
- if (tile_offset_x < 0) {
- tile_offset_x += tile_width;
- }
- g_assert (tile_offset_x >= 0 && tile_offset_x < tile_width);
-
- tile_offset_y = (rect->y - y_dither) % tile_height;
- if (tile_offset_y < 0) {
- tile_offset_y += tile_height;
- }
- g_assert (tile_offset_y >= 0 && tile_offset_y < tile_height);
-
- start_x = rect->x - tile_offset_x;
- start_y = rect->y - tile_offset_y;
-
- end_x = rect->x + rect->width;
- end_y = rect->y + rect->height;
-
- for (x = start_x; x < end_x; x += tile_width) {
- blit_x = MAX (x, rect->x);
- tile_x = blit_x - x;
- blit_width = MIN (tile_width, end_x - x) - tile_x;
-
- for (y = start_y; y < end_y; y += tile_height) {
- blit_y = MAX (y, rect->y);
- tile_y = blit_y - y;
- blit_height = MIN (tile_height, end_y - y) - tile_y;
-
- gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
- tile_x, tile_y,
- blit_x, blit_y, blit_width, blit_height,
- dither, x_dither, y_dither);
- }
- }
-}
-
+/* FIXME
+ * This fn is only used by some test code, it should probably be removed
+ */
void
nautilus_gdk_pixbuf_render_to_pixbuf_tiled (GdkPixbuf *source_pixbuf,
GdkPixbuf *destination_pixbuf,
diff --git a/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h b/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h
index bdcb0f1c7..f6fe8f60d 100644
--- a/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h
+++ b/libnautilus-extensions/nautilus-gdk-pixbuf-extensions.h
@@ -55,13 +55,6 @@ void nautilus_cancel_gdk_pixbuf_load (Naut
/* Draw a GdkPixbuf tiled. */
-void nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *destination_rectangle,
- GdkRgbDither dither,
- int x_dither,
- int y_dither);
void nautilus_gdk_pixbuf_render_to_pixbuf_tiled (GdkPixbuf *source_pixbuf,
GdkPixbuf *destination_pixbuf,
const GdkRectangle *rect,
diff --git a/libnautilus-extensions/nautilus-gnome-extensions.c b/libnautilus-extensions/nautilus-gnome-extensions.c
index b82b5bc37..605ae93fe 100644
--- a/libnautilus-extensions/nautilus-gnome-extensions.c
+++ b/libnautilus-extensions/nautilus-gnome-extensions.c
@@ -196,7 +196,7 @@ nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item,
}
static void
-nautilus_gnome_canvas_draw_pixmap_helper (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
+nautilus_gnome_canvas_draw_pixbuf_helper (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
{
art_u8 *dst_limit = dst + copy_height * dst_rowstride;
int dst_bytes_per_row = copy_width * 3;
@@ -209,7 +209,7 @@ nautilus_gnome_canvas_draw_pixmap_helper (art_u8 *dst, int dst_rowstride, const
}
static void
-nautilus_gnome_canvas_draw_pixmap_helper_alpha (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
+nautilus_gnome_canvas_draw_pixbuf_helper_alpha (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
{
art_u8 *dst_limit = dst + copy_height * dst_rowstride;
int dst_bytes_per_row = copy_width * 3;
@@ -256,7 +256,7 @@ nautilus_gnome_canvas_draw_pixmap_helper_alpha (art_u8 *dst, int dst_rowstride,
* of the pixbuf in canvas space (NOT relative to the canvas buffer).
*/
void
-nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x, int y)
+nautilus_gnome_canvas_draw_pixbuf (GnomeCanvasBuf *buf, const GdkPixbuf *pixbuf, int x, int y)
{
art_u8 *dst;
int pixbuf_width, pixbuf_height;
@@ -306,7 +306,7 @@ nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x
}
if (gdk_pixbuf_get_has_alpha (pixbuf)) {
- nautilus_gnome_canvas_draw_pixmap_helper_alpha (
+ nautilus_gnome_canvas_draw_pixbuf_helper_alpha (
dst,
buf->buf_rowstride,
gdk_pixbuf_get_pixels (pixbuf) + copy_left * 4 + copy_top * gdk_pixbuf_get_rowstride (pixbuf),
@@ -314,7 +314,7 @@ nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x
copy_right - copy_left,
copy_bottom - copy_top);
} else {
- nautilus_gnome_canvas_draw_pixmap_helper (
+ nautilus_gnome_canvas_draw_pixbuf_helper (
dst,
buf->buf_rowstride,
gdk_pixbuf_get_pixels (pixbuf) + copy_left * 3 + copy_top * gdk_pixbuf_get_rowstride (pixbuf),
diff --git a/libnautilus-extensions/nautilus-gnome-extensions.h b/libnautilus-extensions/nautilus-gnome-extensions.h
index e4dd8ef21..645f12e50 100644
--- a/libnautilus-extensions/nautilus-gnome-extensions.h
+++ b/libnautilus-extensions/nautilus-gnome-extensions.h
@@ -94,8 +94,8 @@ void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas
*/
void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item);
-void nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf,
- GdkPixbuf *pixbuf,
+void nautilus_gnome_canvas_draw_pixbuf (GnomeCanvasBuf *buf,
+ const GdkPixbuf *pixbuf,
int x,
int y);
diff --git a/libnautilus-private/nautilus-background-canvas-group.c b/libnautilus-private/nautilus-background-canvas-group.c
index 5c40b2a98..d1664752d 100644
--- a/libnautilus-private/nautilus-background-canvas-group.c
+++ b/libnautilus-private/nautilus-background-canvas-group.c
@@ -34,23 +34,32 @@
#include "nautilus-gdk-extensions.h"
#include "nautilus-gtk-macros.h"
+#include <stdio.h>
+
static void nautilus_background_canvas_group_initialize_class (gpointer klass);
static void nautilus_background_canvas_group_initialize (gpointer object,
- gpointer klass);
-static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
- GdkDrawable *drawable,
- int x,
- int y,
- int width,
- int height);
-static void nautilus_background_canvas_group_render (GnomeCanvasItem *item,
- GnomeCanvasBuf *buffer);
+ gpointer klass);
+
+static void nautilus_background_canvas_group_update (GnomeCanvasItem *item,
+ double affine[6],
+ ArtSVP *clip_path,
+ gint flags);
+
+static void nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
+ GdkDrawable *drawable,
+ int x,
+ int y,
+ int width,
+ int height);
+static void nautilus_background_canvas_group_render (GnomeCanvasItem *item,
+ GnomeCanvasBuf *buffer);
NAUTILUS_DEFINE_CLASS_BOILERPLATE (NautilusBackgroundCanvasGroup, nautilus_background_canvas_group, GNOME_TYPE_CANVAS_GROUP)
static void
nautilus_background_canvas_group_initialize_class (gpointer klass)
{
+ GNOME_CANVAS_ITEM_CLASS (klass)->update = nautilus_background_canvas_group_update;
GNOME_CANVAS_ITEM_CLASS (klass)->draw = nautilus_background_canvas_group_draw;
GNOME_CANVAS_ITEM_CLASS (klass)->render = nautilus_background_canvas_group_render;
}
@@ -61,13 +70,30 @@ nautilus_background_canvas_group_initialize (gpointer object, gpointer klass)
}
static void
-nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
- int drawable_corner_x, int drawable_corner_y,
- int drawable_width, int drawable_height)
+nautilus_background_canvas_group_update (GnomeCanvasItem *item,
+ double affine[6],
+ ArtSVP *clip_path,
+ gint flags)
+{
+ NautilusBackground *background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
+
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
+
+ NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, update, (item, affine, clip_path, flags));
+}
+
+static void
+nautilus_background_canvas_group_draw (GnomeCanvasItem *item,
+ GdkDrawable *drawable,
+ int x,
+ int y,
+ int width,
+ int height)
{
NautilusBackground *background;
GdkGC *gc;
- GdkRectangle rectangle;
/* Draw the background. */
background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
@@ -83,21 +109,17 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
*/
gc = gdk_gc_new (drawable);
- /* The rectangle is the size of the entire viewed area
- * of the canvas. The corner is determined by the
- * current scroll position of the GtkLayout, and the
- * size is determined by the current size of the
- * widget. Since 0,0 is the corner of the drawable,
- * we need to offset the rectangle so it's relative to
- * the drawable's coordinates.
+ /* FIXME bugzilla.eazel.com 2280:
+ * It shouldn't be necessary to call nautilus_background_pre_draw here.
+ * However, nautilus_background_canvas_group_update (who should be the one
+ * spot we call nautilus_background_pre_draw from) doesn't seemed to get
+ * called prior to all drawing.
*/
- rectangle.x = GTK_LAYOUT (item->canvas)->xoffset - drawable_corner_x;
- rectangle.y = GTK_LAYOUT (item->canvas)->yoffset - drawable_corner_y;
- rectangle.width = GTK_WIDGET (item->canvas)->allocation.width;
- rectangle.height = GTK_WIDGET (item->canvas)->allocation.height;
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
- nautilus_background_draw (background, drawable, gc, &rectangle,
- -drawable_corner_x, -drawable_corner_y);
+ nautilus_background_draw (background, drawable, gc, x, y, width, height);
gdk_gc_unref (gc);
}
@@ -105,10 +127,7 @@ nautilus_background_canvas_group_draw (GnomeCanvasItem *item, GdkDrawable *drawa
/* Call through to the GnomeCanvasGroup implementation, which
* will draw all the canvas items.
*/
- NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw,
- (item, drawable,
- drawable_corner_x, drawable_corner_y,
- drawable_width, drawable_height));
+ NAUTILUS_CALL_PARENT_CLASS (GNOME_CANVAS_ITEM_CLASS, draw, (item, drawable, x, y, width, height));
}
@@ -120,10 +139,17 @@ nautilus_background_canvas_group_render (GnomeCanvasItem *item, GnomeCanvasBuf *
background = nautilus_get_widget_background (GTK_WIDGET (item->canvas));
if (background != NULL) {
- nautilus_background_draw_aa (background,
- buffer,
- GTK_WIDGET (item->canvas)->allocation.width,
- GTK_WIDGET (item->canvas)->allocation.height);
+ /* FIXME bugzilla.eazel.com 2280:
+ * It shouldn't be necessary to call nautilus_background_pre_draw here.
+ * However, nautilus_background_canvas_group_update (who should be the one
+ * spot we call nautilus_background_pre_draw from) doesn't seemed to get
+ * called prior to all drawing.
+ */
+ nautilus_background_pre_draw (background,
+ GTK_WIDGET (item->canvas)->allocation.width,
+ GTK_WIDGET (item->canvas)->allocation.height);
+
+ nautilus_background_draw_aa (background, buffer);
}
/* Call through to the GnomeCanvasGroup implementation, which will draw all
diff --git a/libnautilus-private/nautilus-background.c b/libnautilus-private/nautilus-background.c
index 39610f064..1e8d9af80 100644
--- a/libnautilus-private/nautilus-background.c
+++ b/libnautilus-private/nautilus-background.c
@@ -95,6 +95,16 @@ struct NautilusBackgroundDetails {
NautilusPixbufLoadHandle *load_image_handle;
gboolean combine_mode;
NautilusBackgroundImagePlacement image_placement;
+
+ /* The image_rect is the area (canvas relative) the image will cover.
+ * Note: image_rect_width/height are not always the same as the image's
+ * width and height - e.g. if the image is tiled the image rect covers
+ * the whole background.
+ */
+ int image_rect_x;
+ int image_rect_y;
+ int image_rect_width;
+ int image_rect_height;
};
static void
@@ -326,7 +336,7 @@ ensure_gradient_buffered (NautilusBackground *background, int dest_width, int de
}
static void
-gradient_helper_v (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
+canvas_gradient_helper_v (const GnomeCanvasBuf *buf, const art_u8 *gradient_buff)
{
int width = buf->rect.x1 - buf->rect.x0;
int height = buf->rect.y1 - buf->rect.y0;
@@ -346,7 +356,7 @@ gradient_helper_v (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
}
static void
-gradient_helper_h (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
+canvas_gradient_helper_h (const GnomeCanvasBuf *buf, const art_u8 *gradient_buff)
{
int width = buf->rect.x1 - buf->rect.x0;
int height = buf->rect.y1 - buf->rect.y0;
@@ -365,14 +375,93 @@ gradient_helper_h (GnomeCanvasBuf *buf, art_u8 *gradient_buff)
}
static void
-fill_canvas_from_gradient_buffer (GnomeCanvasBuf *buf, NautilusBackground *background)
+fill_canvas_from_gradient_buffer (const GnomeCanvasBuf *buf, const NautilusBackground *background)
+{
+ g_return_if_fail (background->details->gradient_buffer != NULL);
+
+ /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix background
+ * scolling.
+ *
+ * I.e. currently you can scroll off the end of the gradient - and we
+ * handle this by pegging it the the last rgb value.
+ *
+ * It might be needed permanently after depending on how this is fixed.
+ * If we tie gradients to the boundry of icon placement (as opposed to
+ * window size) then when dragging an icon you might scroll off the
+ * end of the gradient - which will get recaluated after the drop.
+ */
+ if (background->details->gradient_is_horizontal) {
+ if (buf->rect.x1 > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GnomeCanvasBuf gradient = *buf;
+ GnomeCanvasBuf overflow = *buf;
+ gradient.rect.x1 = gradient.rect.x0 < background->details->gradient_num_pixels ? background->details->gradient_num_pixels : gradient.rect.x0;
+ overflow.buf += (gradient.rect.x1 - gradient.rect.x0) * 3;
+ overflow.rect.x0 = gradient.rect.x1;
+ nautilus_gnome_canvas_fill_rgb (&overflow, rgb888[0], rgb888[1], rgb888[2]);
+ canvas_gradient_helper_h (&gradient, background->details->gradient_buffer);
+ return;
+ }
+ } else {
+ if (buf->rect.y1 > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GnomeCanvasBuf gradient = *buf;
+ GnomeCanvasBuf overflow = *buf;
+ gradient.rect.y1 = gradient.rect.y0 < background->details->gradient_num_pixels ? background->details->gradient_num_pixels : gradient.rect.y0;
+ overflow.buf += (gradient.rect.y1 - gradient.rect.y0) * gradient.buf_rowstride;
+ overflow.rect.y0 = gradient.rect.y1;
+ nautilus_gnome_canvas_fill_rgb (&overflow, rgb888[0], rgb888[1], rgb888[2]);
+ canvas_gradient_helper_v (&gradient, background->details->gradient_buffer);
+ return;
+ }
+ }
+
+ (background->details->gradient_is_horizontal ? canvas_gradient_helper_h : canvas_gradient_helper_v) (buf, background->details->gradient_buffer);
+}
+
+static void
+drawable_gradient_helper_v (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rect, art_u8 *gradient_buff)
{
- int buf_edge;
+ int y;
+
+ gradient_buff += rect->y * 3;
+
+ for (y = 0; y < rect->height; ++y) {
+ art_u8 r = *gradient_buff++;
+ art_u8 g = *gradient_buff++;
+ art_u8 b = *gradient_buff++;
+ GdkColor color = {0, r << 8, g << 8, b << 8};
+ gdk_colormap_alloc_color (gdk_colormap_get_system (), &color, FALSE, TRUE);
+ gdk_gc_set_foreground (gc, &color);
+ gdk_draw_line (drawable, gc, 0, y, rect->width, y);
+ }
+}
+
+static void
+drawable_gradient_helper_h (GdkDrawable *drawable, GdkGC *gc, const GdkRectangle *rect, art_u8 *gradient_buff)
+{
+ gradient_buff += rect->x * 3;
+
+ /* We can do the fill with a single call to gdk_draw_rgb_image_dithalign
+ * because we pass a rowstride of zero. Zero rowstride make gradient_buff
+ * act like a pixbuf of infinite height - with all identical rows.
+ */
+ gdk_draw_rgb_image_dithalign (drawable, gc, 0, 0, rect->width, rect->height, GDK_RGB_DITHER_NONE, gradient_buff, 0, 0, 0);
+}
+
+static void
+fill_drawable_from_gradient_buffer (GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height,
+ NautilusBackground *background)
+
+{
+ GdkRectangle rect = {drawable_x, drawable_y, drawable_width, drawable_height};
g_return_if_fail (background->details->gradient_buffer != NULL);
- /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix it so the
- * background doesn't scroll.
+ /* FIXME bugzilla.eazel.com 415: This hack is needed till we fix background
+ * scolling.
*
* I.e. currently you can scroll off the end of the gradient - and we
* handle this by pegging it the the last rgb value.
@@ -382,20 +471,66 @@ fill_canvas_from_gradient_buffer (GnomeCanvasBuf *buf, NautilusBackground *backg
* window size) then when dragging an icon you might scroll off the
* end of the gradient - which will get recaluated after the drop.
*/
- buf_edge = background->details->gradient_is_horizontal ? buf->rect.x1 : buf->rect.y1;
- if (buf_edge > background->details->gradient_num_pixels) {
- art_u8 *rgb = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
- nautilus_gnome_canvas_fill_rgb (buf, rgb[0], rgb[1], rgb[2]);
- return;
+ if (background->details->gradient_is_horizontal) {
+ int drawable_end = rect.x + rect.width;
+ if (drawable_end > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GdkRectangle overflow;
+ rect.width = rect.x < background->details->gradient_num_pixels ? background->details->gradient_num_pixels - rect.x : 0;
+ /* overflow is in drawable relative coords (as opposed to canvas relative) */
+ overflow.x = rect.width;
+ overflow.y = 0;
+ overflow.width = drawable_width - rect.width;
+ overflow.height = drawable_height;
+ nautilus_fill_rectangle_with_color (drawable, gc, &overflow, nautilus_rgb8_to_rgb (rgb888[0], rgb888[1], rgb888[2]));
+ }
+ } else {
+ int drawable_end = rect.y + rect.height;
+ if (drawable_end > background->details->gradient_num_pixels) {
+ art_u8 *rgb888 = background->details->gradient_buffer + (background->details->gradient_num_pixels - 1) * 3;
+ GdkRectangle overflow;
+ rect.height = rect.y < background->details->gradient_num_pixels ? background->details->gradient_num_pixels - rect.y : 0;
+ /* overflow is in drawable relative coords (as opposed to canvas relative) */
+ overflow.x = 0;
+ overflow.y = rect.height;
+ overflow.width = drawable_width;
+ overflow.height = drawable_height - rect.height;
+ nautilus_fill_rectangle_with_color (drawable, gc, &overflow, nautilus_rgb8_to_rgb (rgb888[0], rgb888[1], rgb888[2]));
+ }
}
- (background->details->gradient_is_horizontal ? gradient_helper_h : gradient_helper_v) (buf, background->details->gradient_buffer);
+ (background->details->gradient_is_horizontal ? drawable_gradient_helper_h : drawable_gradient_helper_v)
+ (drawable, gc, &rect, background->details->gradient_buffer);
+}
+
+/* fill the canvas buffer with a tiled pixbuf */
+static void
+draw_pixbuf_tiled (GdkPixbuf *pixbuf, GdkDrawable *drawable, GdkGC *gc, int drawable_x, int drawable_y, int drawable_width, int drawable_height)
+{
+ int x, y;
+ int start_x, start_y;
+ int end_x, end_y;
+ int tile_width, tile_height;
+
+ tile_width = gdk_pixbuf_get_width (pixbuf);
+ tile_height = gdk_pixbuf_get_height (pixbuf);
+
+ start_x = -(drawable_x % tile_width);
+ start_y = -(drawable_y % tile_height);
+ end_x = drawable_x + drawable_width;
+ end_y = drawable_y + drawable_height;
+
+ for (y = start_y; y < end_y; y += tile_height) {
+ for (x = start_x; x < end_x; x += tile_width) {
+ gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc, 0, 0, x, y, tile_width, tile_height, GDK_RGB_DITHER_NONE, 0, 0);
+ }
+ }
}
/* Initializes a pseudo-canvas buf so canvas drawing routines can be used to draw into a pixbuf.
*/
static void
-canvas_buf_from_pixmap (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, int width, int height)
+canvas_buf_from_pixbuf (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, int width, int height)
{
buf->buf = gdk_pixbuf_get_pixels (pixbuf);
buf->buf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
@@ -409,13 +544,13 @@ canvas_buf_from_pixmap (GnomeCanvasBuf* buf, GdkPixbuf *pixbuf, int x, int y, in
}
static void
-ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_height, GdkRectangle *image_rect)
+ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_height)
{
if (background->details->image == NULL) {
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = 0;
- image_rect->height = 0;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = 0;
+ background->details->image_rect_height = 0;
} else {
int image_width;
int image_height;
@@ -467,147 +602,158 @@ ensure_image_scaled (NautilusBackground *background, int dest_width, int dest_he
gdk_pixbuf_unref (background->details->image);
background->details->image = NULL;
start_loading_image (background);
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = 0;
- image_rect->height = 0;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = 0;
+ background->details->image_rect_height = 0;
} else if (background->details->image_placement == NAUTILUS_BACKGROUND_TILED) {
- image_rect->x = 0;
- image_rect->y = 0;
- image_rect->width = dest_width;
- image_rect->height = dest_height;
+ background->details->image_rect_x = 0;
+ background->details->image_rect_y = 0;
+ background->details->image_rect_width = dest_width;
+ background->details->image_rect_height = dest_height;
} else {
- image_rect->x = (dest_width - image_width) / 2;
- image_rect->y = (dest_height - image_height) / 2;
- image_rect->width = image_width;
- image_rect->height = image_height;
+ background->details->image_rect_x = (dest_width - image_width) / 2;
+ background->details->image_rect_y = (dest_height - image_height) / 2;
+ background->details->image_rect_width = image_width;
+ background->details->image_rect_height = image_height;
}
}
}
+void
+nautilus_background_pre_draw (NautilusBackground *background, int entire_width, int entire_height)
+{
+ ensure_image_scaled (background, entire_width, entire_height);
+ ensure_gradient_buffered (background, entire_width, entire_height);
+}
+
/* This routine is for gdk style rendering, which doesn't naturally
* support transparency, so we draw into a pixbuf offscreen if
* necessary.
*/
void
nautilus_background_draw (NautilusBackground *background,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- int origin_x,
- int origin_y)
+ GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height)
{
- GdkRectangle image_rect;
- GdkPixbuf *pixbuf;
- GnomeCanvasBuf buffer;
- int image_width;
- int image_height;
- char *start_color_spec, *end_color_spec;
- guint32 start_rgb, end_rgb;
- gboolean horizontal_gradient;
+ int drawable_right;
+ int drawable_bottom;
+ int image_rect_right;
+ int image_rect_bottom;
g_return_if_fail (NAUTILUS_IS_BACKGROUND (background));
if (background->details->combine_mode) {
+ GdkPixbuf *pixbuf;
+ GnomeCanvasBuf buffer;
+
/* allocate a pixbuf the size of the rectangle */
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, rectangle->width, rectangle->height);
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, drawable_width, drawable_height);
/* contrive a CanvasBuf structure to point to it */
- canvas_buf_from_pixmap (&buffer, pixbuf, rectangle->x, rectangle->y, rectangle->width, rectangle->height);
+ canvas_buf_from_pixbuf (&buffer, pixbuf, drawable_x, drawable_y, drawable_width, drawable_height);
/* invoke the anti-aliased code to do the work */
- nautilus_background_draw_aa (background, &buffer, rectangle->width, rectangle->height);
+ nautilus_background_draw_aa (background, &buffer);
/* blit the pixbuf to the drawable */
gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
0, 0,
- rectangle->x, rectangle->y, rectangle->width, rectangle->height,
- GDK_RGB_DITHER_NORMAL, origin_x, origin_y);
+ 0, 0,
+ drawable_width, drawable_height,
+ GDK_RGB_DITHER_NONE, 0, 0);
/* free things up and we're done */
gdk_pixbuf_unref (pixbuf);
return;
}
-
- ensure_image_scaled (background, rectangle->width, rectangle->height, &image_rect);
- /* FIXME bugzill.eazel.com 2280:
- * The rectangle we get passed here seems to be bogus.
- * It works since we end up drawing the whole image every time.
- * I think if we fix up the call (made in nautilus-background-canvas-group.c)
- * to pass the rect that needs updating, then we can optimize this.
- */
+ drawable_right = drawable_x + drawable_width;
+ drawable_bottom = drawable_y + drawable_height;
- if (!background->details->image || image_rect.width < rectangle->width || image_rect.height < rectangle->height) {
- 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);
-
- nautilus_fill_rectangle_with_gradient (drawable,
- gc,
- rectangle,
- start_rgb,
- end_rgb,
- horizontal_gradient);
+ image_rect_right = background->details->image_rect_x + background->details->image_rect_width;
+ image_rect_bottom = background->details->image_rect_y + background->details->image_rect_height;
+
+ if (!background->details->image ||
+ drawable_x < background->details->image_rect_x ||
+ drawable_y < background->details->image_rect_y ||
+ drawable_right > image_rect_right ||
+ drawable_bottom > image_rect_bottom) {
+ if (background->details->is_solid_color) {
+ GdkRectangle rect = {0 , 0, drawable_width, drawable_height};
+ nautilus_fill_rectangle_with_color (drawable, gc, &rect, nautilus_gdk_color_to_rgb (&background->details->solid_color));
+ } else {
+ fill_drawable_from_gradient_buffer (drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height, background);
+ }
}
if (background->details->image != NULL) {
switch (background->details->image_placement) {
case NAUTILUS_BACKGROUND_TILED:
- nautilus_gdk_pixbuf_render_to_drawable_tiled (background->details->image,
- drawable,
- gc,
- rectangle,
- GDK_RGB_DITHER_NORMAL,
- origin_x, origin_y);
+ draw_pixbuf_tiled (background->details->image, drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height);
break;
- default:
- g_assert_not_reached ();
- /* fall through */
case NAUTILUS_BACKGROUND_CENTERED:
case NAUTILUS_BACKGROUND_SCALED:
case NAUTILUS_BACKGROUND_SCALED_ASPECT:
- /* Since the image has already been scaled, all these cases
- * can be treated identically.
+ /* Since the image has already been scaled, all these cases can be treated identically.
*/
- image_width = gdk_pixbuf_get_width (background->details->image);
- image_height = gdk_pixbuf_get_height (background->details->image);
- gdk_pixbuf_render_to_drawable (background->details->image, drawable, gc,
- 0, 0,
- rectangle->x + (rectangle->width - image_width)/2,
- rectangle->y + (rectangle->height - image_height)/2,
- image_width, image_height,
- GDK_RGB_DITHER_NORMAL, 0, 0);
+ if (drawable_x < image_rect_right &&
+ drawable_y < image_rect_bottom &&
+ drawable_right > background->details->image_rect_x &&
+ drawable_bottom > background->details->image_rect_y) {
+ int src_offset_x;
+ int src_offset_y;
+ int dst_offset_x;
+ int dst_offset_y;
+ int copy_width;
+ int copy_height;
+
+ if (drawable_x < background->details->image_rect_x) {
+ src_offset_x = 0;
+ dst_offset_x = background->details->image_rect_x - drawable_x;
+ } else {
+ src_offset_x = drawable_x - background->details->image_rect_x;
+ dst_offset_x = 0;
+ }
+
+ copy_width = drawable_right < image_rect_right ? drawable_width - dst_offset_x : image_rect_right - drawable_x;
+
+ if (drawable_y < background->details->image_rect_y) {
+ src_offset_y = 0;
+ dst_offset_y = background->details->image_rect_y - drawable_y;
+ } else {
+ src_offset_y = drawable_y - background->details->image_rect_y;
+ dst_offset_y = 0;
+ }
+
+ copy_height = drawable_bottom < image_rect_bottom ? drawable_height - dst_offset_y : image_rect_bottom - drawable_y;
+
+ gdk_pixbuf_render_to_drawable (background->details->image, drawable, gc,
+ src_offset_x, src_offset_y,
+ dst_offset_x, dst_offset_y,
+ copy_width, copy_height,
+ GDK_RGB_DITHER_NONE, 0, 0);
+ }
break;
}
}
}
-static void
-draw_pixbuf_centered_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer,
- int entire_width, int entire_height)
+void
+nautilus_background_draw_to_drawable (NautilusBackground *background,
+ GdkDrawable *drawable, GdkGC *gc,
+ int drawable_x, int drawable_y,
+ int drawable_width, int drawable_height,
+ int entire_width, int entire_height)
{
- int image_width;
- int image_height;
- int image_left;
- int image_top;
-
- image_width = gdk_pixbuf_get_width (pixbuf);
- image_height = gdk_pixbuf_get_height (pixbuf);
- image_left = (entire_width - image_width) / 2;
- image_top = (entire_height - image_height) / 2;
-
- nautilus_gnome_canvas_draw_pixmap (buffer, pixbuf, image_left, image_top);
+ nautilus_background_pre_draw (background, entire_width, entire_height);
+ nautilus_background_draw (background, drawable, gc, drawable_x, drawable_y, drawable_width, drawable_height);
}
-/* fill the canvas buffer with a tiled pixmap */
+
+/* fill the canvas buffer with a tiled pixbuf */
static void
draw_pixbuf_tiled_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
{
@@ -623,24 +769,17 @@ draw_pixbuf_tiled_aa (GdkPixbuf *pixbuf, GnomeCanvasBuf *buffer)
for (y = start_y; y < buffer->rect.y1; y += tile_height) {
for (x = start_x; x < buffer->rect.x1; x += tile_width) {
- nautilus_gnome_canvas_draw_pixmap (buffer, pixbuf, x, y);
+ nautilus_gnome_canvas_draw_pixbuf (buffer, pixbuf, x, y);
}
}
}
/* draw the background on the anti-aliased canvas */
void
-nautilus_background_draw_aa (NautilusBackground *background,
- GnomeCanvasBuf *buffer,
- int entire_width,
- int entire_height)
-{
- GdkRectangle image_rect;
-
+nautilus_background_draw_aa (NautilusBackground *background, GnomeCanvasBuf *buffer)
+{
g_return_if_fail (NAUTILUS_IS_BACKGROUND (background));
- ensure_image_scaled (background, entire_width, entire_height, &image_rect);
-
/* If the image has alpha - we always draw the gradient behind it.
* In principle, we could do better by having already drawn gradient behind
* the scaled image. However, this would add a significant amount of
@@ -648,20 +787,18 @@ nautilus_background_draw_aa (NautilusBackground *background,
* scaled image to a location on the screen because it holds a gradient.
* This is especially problematic for tiled images with alpha.
*/
-
if (!background->details->image ||
gdk_pixbuf_get_has_alpha (background->details->image) ||
- buffer->rect.x0 < image_rect.x ||
- buffer->rect.y0 < image_rect.y ||
- buffer->rect.x1 > (image_rect.x + image_rect.width) ||
- buffer->rect.y1 > (image_rect.y + image_rect.height)) {
+ buffer->rect.x0 < background->details->image_rect_x ||
+ buffer->rect.y0 < background->details->image_rect_y ||
+ buffer->rect.x1 > (background->details->image_rect_x + background->details->image_rect_width) ||
+ buffer->rect.y1 > (background->details->image_rect_y + background->details->image_rect_height)) {
if (background->details->is_solid_color) {
nautilus_gnome_canvas_fill_rgb (buffer,
- background->details->solid_color.red,
- background->details->solid_color.green,
- background->details->solid_color.blue);
+ background->details->solid_color.red >> 8,
+ background->details->solid_color.green >> 8,
+ background->details->solid_color.blue >> 8);
} else {
- ensure_gradient_buffered (background, entire_width, entire_height);
fill_canvas_from_gradient_buffer (buffer, background);
}
}
@@ -680,7 +817,10 @@ nautilus_background_draw_aa (NautilusBackground *background,
/* Since the image has already been scaled, all these cases
* can be treated identically.
*/
- draw_pixbuf_centered_aa (background->details->image, buffer, entire_width, entire_height);
+ nautilus_gnome_canvas_draw_pixbuf (buffer,
+ background->details->image,
+ background->details->image_rect_x,
+ background->details->image_rect_y);
break;
}
}
@@ -689,6 +829,16 @@ nautilus_background_draw_aa (NautilusBackground *background,
buffer->is_buf = TRUE;
}
+void
+nautilus_background_draw_to_canvas (NautilusBackground *background,
+ GnomeCanvasBuf *buffer,
+ int entire_width,
+ int entire_height)
+{
+ nautilus_background_pre_draw (background, entire_width, entire_height);
+ nautilus_background_draw_aa (background, buffer);
+}
+
char *
nautilus_background_get_color (NautilusBackground *background)
{
@@ -870,7 +1020,6 @@ nautilus_background_draw_flat_box (GtkStyle *style,
gboolean call_parent;
NautilusBackground *background;
GdkGC *gc;
- GdkRectangle rectangle;
call_parent = TRUE;
@@ -893,15 +1042,9 @@ nautilus_background_draw_flat_box (GtkStyle *style,
if (area)
gdk_gc_set_clip_rectangle (gc, area);
-
nautilus_gdk_window_update_sizes (window, &width, &height);
- rectangle.x = x;
- rectangle.y = y;
- rectangle.width = width;
- rectangle.height = height;
-
- nautilus_background_draw (background, window, gc,
- &rectangle, 0, 0);
+
+ nautilus_background_draw_to_drawable (background, window, gc, 0, 0, width, height, widget->allocation.width, widget->allocation.height);
}
static GtkStyleClass *
diff --git a/libnautilus-private/nautilus-background.h b/libnautilus-private/nautilus-background.h
index 6e5ed147a..ec9b691b2 100644
--- a/libnautilus-private/nautilus-background.h
+++ b/libnautilus-private/nautilus-background.h
@@ -91,20 +91,56 @@ gboolean nautilus_background_is_set
gboolean nautilus_background_is_loaded (NautilusBackground *background);
-/* Explicitly fills a rectangle with a background. */
-void nautilus_background_draw (NautilusBackground *background,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- int origin_x,
- int origin_y);
-
-
-/* Explicitly fills a rectangle with a background on the anti-aliased canvas. */
-void nautilus_background_draw_aa (NautilusBackground *background,
- GnomeCanvasBuf *buffer,
- int entire_width,
- int entire_height);
+/* For preping the background to be used in one of the two calls
+ * below. Only intended to be called by nautilus_background_canvas_group_update.
+ */
+void nautilus_background_pre_draw (NautilusBackground *background,
+ int entire_width,
+ int entire_height);
+
+/* For updating the canvas, non-aa case. Note: nautilus_background_pre_draw
+ * must have been previously called. Only intended to be called by
+ * nautilus_background_canvas_group_draw.
+ */
+void nautilus_background_draw (NautilusBackground *background,
+ GdkDrawable *drawable,
+ GdkGC *gc,
+ int drawable_x,
+ int drawable_y,
+ int drawable_width,
+ int drawable_height);
+
+/* For updating the canvas, aa case. Note: nautilus_background_pre_draw
+ * must have been previously called. Only intended to be called by
+ * nautilus_background_canvas_group_render.
+ */
+void nautilus_background_draw_aa (NautilusBackground *background,
+ GnomeCanvasBuf *buffer);
+
+/* Used to fill a drawable with a background.
+ * - entire_width/height describe the total area the background covers
+ * - drawable_x/y/width/height describe the portion of that area the drawable covers
+ */
+void nautilus_background_draw_to_drawable (NautilusBackground *background,
+ GdkDrawable *drawable,
+ GdkGC *gc,
+ int drawable_x,
+ int drawable_y,
+ int drawable_width,
+ int drawable_height,
+ int entire_width,
+ int entire_height);
+
+/* Used to fill a drawable with a background.
+ * - entire_width/height describe the total area the background covers
+ * - buffer is a portion of that area
+ */
+void nautilus_background_draw_to_canvas (NautilusBackground *background,
+ GnomeCanvasBuf *buffer,
+ int entire_width,
+ int entire_height);
+
+
/* Handles a dragged color being dropped on a widget to change the background color. */
diff --git a/libnautilus-private/nautilus-buffered-widget.c b/libnautilus-private/nautilus-buffered-widget.c
index 8bbcfba27..68975847e 100644
--- a/libnautilus-private/nautilus-buffered-widget.c
+++ b/libnautilus-private/nautilus-buffered-widget.c
@@ -556,25 +556,24 @@ create_background_pixbuf_from_ancestor (const NautilusBufferedWidget *buffered_w
if (background_ancestor != NULL) {
NautilusBackground *background;
GdkPixmap *pixmap;
- GdkRectangle background_area;
background = nautilus_get_widget_background (background_ancestor);
g_assert (NAUTILUS_IS_BACKGROUND (background));
-
- background_area.x = 0;
- background_area.y = 0;
- background_area.width = background_ancestor->allocation.width;
- background_area.height = background_ancestor->allocation.height;
-
- pixmap = gdk_pixmap_new (widget->window, background_area.width, background_area.height, -1);
-
- nautilus_background_draw (background, pixmap, buffered_widget->detail->copy_area_gc, &background_area, 0, 0);
+
+ pixmap = gdk_pixmap_new (widget->window, widget->allocation.width, widget->allocation.height, -1);
+
+ nautilus_background_draw_to_drawable (background,
+ pixmap,
+ buffered_widget->detail->copy_area_gc,
+ widget->allocation.x, widget->allocation.y,
+ widget->allocation.width, widget->allocation.height,
+ background_ancestor->allocation.width, background_ancestor->allocation.height);
pixbuf = gdk_pixbuf_get_from_drawable (NULL,
pixmap,
gdk_rgb_get_cmap (),
- widget->allocation.x,
- widget->allocation.y,
+ 0,
+ 0,
0,
0,
widget->allocation.width,
diff --git a/libnautilus-private/nautilus-directory-background.c b/libnautilus-private/nautilus-directory-background.c
index 1073498ff..a89f337c3 100644
--- a/libnautilus-private/nautilus-directory-background.c
+++ b/libnautilus-private/nautilus-directory-background.c
@@ -481,7 +481,8 @@ image_loading_done_callback (NautilusBackground *background, gboolean successful
{
GdkGC *gc;
GdkPixmap *bg_pixmap;
- GdkRectangle screen_rectangle;
+ int width;
+ int height;
g_assert (NAUTILUS_IS_BACKGROUND (background));
@@ -494,15 +495,13 @@ image_loading_done_callback (NautilusBackground *background, gboolean successful
/* need to update the root view whether loading succeeded or not
*/
- screen_rectangle.x = 0;
- screen_rectangle.y = 0;
- screen_rectangle.width = gdk_screen_width ();
- screen_rectangle.height = gdk_screen_height ();
+ width = gdk_screen_width ();
+ height = gdk_screen_height ();
- bg_pixmap = make_root_pixmap (screen_rectangle.width, screen_rectangle.height);
+ bg_pixmap = make_root_pixmap (width, height);
gc = gdk_gc_new (bg_pixmap);
- nautilus_background_draw (background, bg_pixmap, gc, &screen_rectangle, 0, 0);
+ nautilus_background_draw_to_drawable (background, bg_pixmap, gc, 0, 0, width, height, width, height);
set_root_pixmap (bg_pixmap);
@@ -653,8 +652,8 @@ saved_settings_changed_callback (NautilusDirectory *directory,
background_changed_callback,
directory);
- nautilus_background_set_color (background, color);
- nautilus_background_set_image_uri (background, image);
+ nautilus_background_set_color (background, color);
+ nautilus_background_set_image_uri (background, image);
nautilus_background_set_combine_mode (background, combine);
nautilus_background_set_image_placement (background, placement);
diff --git a/libnautilus-private/nautilus-gdk-extensions.c b/libnautilus-private/nautilus-gdk-extensions.c
index da719642b..160a6732f 100644
--- a/libnautilus-private/nautilus-gdk-extensions.c
+++ b/libnautilus-private/nautilus-gdk-extensions.c
@@ -84,73 +84,6 @@ nautilus_fill_rectangle_with_color (GdkDrawable *drawable,
}
/**
- * nautilus_fill_rectangle_with_gradient:
- * @drawable: Target to draw into.
- * @gc: Graphics context (mainly for clip).
- * @rectangle: Rectangle to draw gradient in.
- * @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.
- */
-void
-nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- guint32 start_rgb,
- guint32 end_rgb,
- gboolean horizontal)
-{
- GdkRectangle band_box;
- gint16 *position;
- guint16 *size;
- gint num_bands;
- guint16 last_band_size;
- gdouble multiplier;
- gint band;
- guint32 band_rgb;
-
- g_return_if_fail (drawable != NULL);
- g_return_if_fail (gc != NULL);
- g_return_if_fail (rectangle != NULL);
- 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 = *rectangle;
- 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;
-
- /* Set up a multiplier to use to interpolate the colors as we go. */
- multiplier = num_bands <= 1 ? 0.0 : 1.0 / (num_bands - 1);
-
- /* 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. */
- band_rgb = nautilus_interpolate_color (band * multiplier, start_rgb, end_rgb);
-
- /* 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;
- }
-
- nautilus_fill_rectangle_with_color (drawable, gc, &band_box, band_rgb);
- *position += *size;
- }
-}
-
-/**
* nautilus_rectangle_contains:
* @rectangle: Rectangle possibly containing a point.
* @x: X coordinate of a point.
@@ -508,6 +441,24 @@ nautilus_parse_rgb_with_white_default (const char *color_spec)
| ((color.blue >> 8) & NAUTILUS_RGB_COLOR_BLUE);
}
+guint32
+nautilus_rgb16_to_rgb (gushort r, gushort g, gushort b)
+{
+ guint32 result;
+
+ result = (0xff0000 | (r & 0xff00));
+ result <<= 8;
+ result |= ((g & 0xff00) | (b >> 8));
+
+ return result;
+}
+
+guint32
+nautilus_rgb8_to_rgb (guchar r, guchar g, guchar b)
+{
+ return nautilus_rgb16_to_rgb (r << 8, g << 8, b << 8);
+}
+
/**
* nautilus_gdk_color_to_rgb
* @color: A GdkColor style color.
@@ -519,17 +470,11 @@ nautilus_parse_rgb_with_white_default (const char *color_spec)
guint32
nautilus_gdk_color_to_rgb (const GdkColor *color)
{
- guint32 result;
-
- result = (0xff0000 | (color->red & 0xff00));
- result <<= 8;
- result |= ((color->green & 0xff00) | (color->blue >> 8));
-
- return result;
+ return nautilus_rgb16_to_rgb (color->red, color->green, color->blue);
}
/**
- * nautilus_gdk_color_to_rgb
+ * nautilus_gdk_rgb_to_color
* @color: a gdk_rgb style value.
*
* Converts from a gdk_rgb value style to a GdkColor one.
diff --git a/libnautilus-private/nautilus-gdk-extensions.h b/libnautilus-private/nautilus-gdk-extensions.h
index ce4637bf1..43e37c129 100644
--- a/libnautilus-private/nautilus-gdk-extensions.h
+++ b/libnautilus-private/nautilus-gdk-extensions.h
@@ -85,6 +85,8 @@ guint32 nautilus_parse_rgb_with_default (const char *colo
guint32 nautilus_parse_rgb_with_white_default (const char *color_spec);
guint32 nautilus_rgb_shift_color (guint32 color,
float shift_by);
+guint32 nautilus_rgb16_to_rgb (gushort r, gushort g, gushort b);
+guint32 nautilus_rgb8_to_rgb (guchar r, guchar g, guchar b);
guint32 nautilus_gdk_color_to_rgb (const GdkColor *color);
GdkColor * nautilus_gdk_rgb_to_color (const guint32 color);
@@ -96,12 +98,6 @@ void nautilus_fill_rectangle_with_color (GdkDrawable *draw
GdkGC *gc,
const GdkRectangle *rectangle,
guint32 rgb);
-void nautilus_fill_rectangle_with_gradient (GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rectangle,
- guint32 start_rgb,
- guint32 end_rgb,
- gboolean horizontal_gradient);
/* A routine to get a 50% gray stippled bitmap for use in some types of highlighting. */
GdkBitmap *nautilus_stipple_bitmap (void);
diff --git a/libnautilus-private/nautilus-gdk-pixbuf-extensions.c b/libnautilus-private/nautilus-gdk-pixbuf-extensions.c
index fbde6f734..c35742e76 100644
--- a/libnautilus-private/nautilus-gdk-pixbuf-extensions.c
+++ b/libnautilus-private/nautilus-gdk-pixbuf-extensions.c
@@ -281,63 +281,9 @@ nautilus_cancel_gdk_pixbuf_load (NautilusPixbufLoadHandle *handle)
free_pixbuf_load_handle (handle);
}
-void
-nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *rect,
- GdkRgbDither dither,
- int x_dither,
- int y_dither)
-{
- int x, y;
- int start_x, start_y;
- int end_x, end_y;
- int tile_x, tile_y;
- int blit_x, blit_y;
- int tile_width, tile_height;
- int blit_width, blit_height;
- int tile_offset_x, tile_offset_y;
-
- tile_width = gdk_pixbuf_get_width (pixbuf);
- tile_height = gdk_pixbuf_get_height (pixbuf);
-
- tile_offset_x = (rect->x - x_dither) % tile_width;
- if (tile_offset_x < 0) {
- tile_offset_x += tile_width;
- }
- g_assert (tile_offset_x >= 0 && tile_offset_x < tile_width);
-
- tile_offset_y = (rect->y - y_dither) % tile_height;
- if (tile_offset_y < 0) {
- tile_offset_y += tile_height;
- }
- g_assert (tile_offset_y >= 0 && tile_offset_y < tile_height);
-
- start_x = rect->x - tile_offset_x;
- start_y = rect->y - tile_offset_y;
-
- end_x = rect->x + rect->width;
- end_y = rect->y + rect->height;
-
- for (x = start_x; x < end_x; x += tile_width) {
- blit_x = MAX (x, rect->x);
- tile_x = blit_x - x;
- blit_width = MIN (tile_width, end_x - x) - tile_x;
-
- for (y = start_y; y < end_y; y += tile_height) {
- blit_y = MAX (y, rect->y);
- tile_y = blit_y - y;
- blit_height = MIN (tile_height, end_y - y) - tile_y;
-
- gdk_pixbuf_render_to_drawable (pixbuf, drawable, gc,
- tile_x, tile_y,
- blit_x, blit_y, blit_width, blit_height,
- dither, x_dither, y_dither);
- }
- }
-}
-
+/* FIXME
+ * This fn is only used by some test code, it should probably be removed
+ */
void
nautilus_gdk_pixbuf_render_to_pixbuf_tiled (GdkPixbuf *source_pixbuf,
GdkPixbuf *destination_pixbuf,
diff --git a/libnautilus-private/nautilus-gdk-pixbuf-extensions.h b/libnautilus-private/nautilus-gdk-pixbuf-extensions.h
index bdcb0f1c7..f6fe8f60d 100644
--- a/libnautilus-private/nautilus-gdk-pixbuf-extensions.h
+++ b/libnautilus-private/nautilus-gdk-pixbuf-extensions.h
@@ -55,13 +55,6 @@ void nautilus_cancel_gdk_pixbuf_load (Naut
/* Draw a GdkPixbuf tiled. */
-void nautilus_gdk_pixbuf_render_to_drawable_tiled (GdkPixbuf *pixbuf,
- GdkDrawable *drawable,
- GdkGC *gc,
- const GdkRectangle *destination_rectangle,
- GdkRgbDither dither,
- int x_dither,
- int y_dither);
void nautilus_gdk_pixbuf_render_to_pixbuf_tiled (GdkPixbuf *source_pixbuf,
GdkPixbuf *destination_pixbuf,
const GdkRectangle *rect,
diff --git a/libnautilus-private/nautilus-gnome-extensions.c b/libnautilus-private/nautilus-gnome-extensions.c
index b82b5bc37..605ae93fe 100644
--- a/libnautilus-private/nautilus-gnome-extensions.c
+++ b/libnautilus-private/nautilus-gnome-extensions.c
@@ -196,7 +196,7 @@ nautilus_gnome_canvas_item_get_world_bounds (GnomeCanvasItem *item,
}
static void
-nautilus_gnome_canvas_draw_pixmap_helper (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
+nautilus_gnome_canvas_draw_pixbuf_helper (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
{
art_u8 *dst_limit = dst + copy_height * dst_rowstride;
int dst_bytes_per_row = copy_width * 3;
@@ -209,7 +209,7 @@ nautilus_gnome_canvas_draw_pixmap_helper (art_u8 *dst, int dst_rowstride, const
}
static void
-nautilus_gnome_canvas_draw_pixmap_helper_alpha (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
+nautilus_gnome_canvas_draw_pixbuf_helper_alpha (art_u8 *dst, int dst_rowstride, const art_u8 *src, int src_rowstride, int copy_width, int copy_height)
{
art_u8 *dst_limit = dst + copy_height * dst_rowstride;
int dst_bytes_per_row = copy_width * 3;
@@ -256,7 +256,7 @@ nautilus_gnome_canvas_draw_pixmap_helper_alpha (art_u8 *dst, int dst_rowstride,
* of the pixbuf in canvas space (NOT relative to the canvas buffer).
*/
void
-nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x, int y)
+nautilus_gnome_canvas_draw_pixbuf (GnomeCanvasBuf *buf, const GdkPixbuf *pixbuf, int x, int y)
{
art_u8 *dst;
int pixbuf_width, pixbuf_height;
@@ -306,7 +306,7 @@ nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x
}
if (gdk_pixbuf_get_has_alpha (pixbuf)) {
- nautilus_gnome_canvas_draw_pixmap_helper_alpha (
+ nautilus_gnome_canvas_draw_pixbuf_helper_alpha (
dst,
buf->buf_rowstride,
gdk_pixbuf_get_pixels (pixbuf) + copy_left * 4 + copy_top * gdk_pixbuf_get_rowstride (pixbuf),
@@ -314,7 +314,7 @@ nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf, GdkPixbuf *pixbuf, int x
copy_right - copy_left,
copy_bottom - copy_top);
} else {
- nautilus_gnome_canvas_draw_pixmap_helper (
+ nautilus_gnome_canvas_draw_pixbuf_helper (
dst,
buf->buf_rowstride,
gdk_pixbuf_get_pixels (pixbuf) + copy_left * 3 + copy_top * gdk_pixbuf_get_rowstride (pixbuf),
diff --git a/libnautilus-private/nautilus-gnome-extensions.h b/libnautilus-private/nautilus-gnome-extensions.h
index e4dd8ef21..645f12e50 100644
--- a/libnautilus-private/nautilus-gnome-extensions.h
+++ b/libnautilus-private/nautilus-gnome-extensions.h
@@ -94,8 +94,8 @@ void nautilus_gnome_canvas_request_redraw_rectangle (GnomeCanvas
*/
void nautilus_gnome_canvas_item_request_redraw (GnomeCanvasItem *item);
-void nautilus_gnome_canvas_draw_pixmap (GnomeCanvasBuf *buf,
- GdkPixbuf *pixbuf,
+void nautilus_gnome_canvas_draw_pixbuf (GnomeCanvasBuf *buf,
+ const GdkPixbuf *pixbuf,
int x,
int y);