diff options
author | Mike Engber <engber@src.gnome.org> | 2000-10-03 00:26:57 +0000 |
---|---|---|
committer | Mike Engber <engber@src.gnome.org> | 2000-10-03 00:26:57 +0000 |
commit | d78afbc31c6c9e3ce40e7d866e60cf7c7cef3b18 (patch) | |
tree | 9f9897ce2b7e152d4c5a8f95a8096ba90de004b2 | |
parent | b84d41df38e50d1cdd69388e62d51d852638b6ad (diff) | |
download | nautilus-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:
23 files changed, 916 insertions, 714 deletions
@@ -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); |