diff options
author | Daniel Silverstone <dsilvers@netsurf-browser.org> | 2006-08-09 15:06:14 +0000 |
---|---|---|
committer | Daniel Silverstone <dsilvers@netsurf-browser.org> | 2006-08-09 15:06:14 +0000 |
commit | 6d7357e2cb1b106d5da8082958b23bdbe628d052 (patch) | |
tree | c03d6baa0abbf1f6c0298248c0232d164e863127 /gtk | |
parent | 5e1f0332add2458c4eb142bff4becdebe197325a (diff) | |
download | netsurf-6d7357e2cb1b106d5da8082958b23bdbe628d052.tar.gz netsurf-6d7357e2cb1b106d5da8082958b23bdbe628d052.tar.bz2 |
Merge 2818:HEAD of branches/dsilvers/gtk-bitmap-pretile
svn path=/trunk/netsurf/; revision=2824
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtk_bitmap.c | 139 | ||||
-rw-r--r-- | gtk/gtk_bitmap.h | 22 | ||||
-rw-r--r-- | gtk/gtk_plotters.c | 35 | ||||
-rw-r--r-- | gtk/gtk_thumbnail.c | 3 |
4 files changed, 184 insertions, 15 deletions
diff --git a/gtk/gtk_bitmap.c b/gtk/gtk_bitmap.c index d70b27ac9..e33b436d0 100644 --- a/gtk/gtk_bitmap.c +++ b/gtk/gtk_bitmap.c @@ -19,9 +19,18 @@ #include "netsurf/content/content.h" #include "netsurf/gtk/gtk_window.h" #include "netsurf/image/bitmap.h" +#include "netsurf/utils/log.h" -struct bitmap; +struct bitmap { + GdkPixbuf *primary; + GdkPixbuf *pretile_x; + GdkPixbuf *pretile_y; + GdkPixbuf *pretile_xy; +}; + +#define MIN_PRETILE_WIDTH 256 +#define MIN_PRETILE_HEIGHT 256 /** @@ -35,9 +44,11 @@ struct bitmap; struct bitmap *bitmap_create(int width, int height, unsigned int state) { - GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, - width, height); - return (struct bitmap *) pixbuf; + struct bitmap *bmp = malloc(sizeof(struct bitmap)); + bmp->primary = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, + width, height); + bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL; + return bmp; } @@ -94,7 +105,7 @@ bool bitmap_get_opaque(struct bitmap *bitmap) char *bitmap_get_buffer(struct bitmap *bitmap) { assert(bitmap); - return (char *)gdk_pixbuf_get_pixels((GdkPixbuf *) bitmap); + return (char *)gdk_pixbuf_get_pixels(bitmap->primary); } @@ -108,10 +119,20 @@ char *bitmap_get_buffer(struct bitmap *bitmap) size_t bitmap_get_rowstride(struct bitmap *bitmap) { assert(bitmap); - return gdk_pixbuf_get_rowstride((GdkPixbuf *) bitmap); + return gdk_pixbuf_get_rowstride(bitmap->primary); } +static void +gtk_bitmap_free_pretiles(struct bitmap *bitmap) +{ +#define FREE_TILE(XY) if (bitmap->pretile_##XY) g_object_unref(bitmap->pretile_##XY); bitmap->pretile_##XY = NULL + FREE_TILE(x); + FREE_TILE(y); + FREE_TILE(xy); +#undef FREE_TILE +} + /** * Free a bitmap. * @@ -121,7 +142,9 @@ size_t bitmap_get_rowstride(struct bitmap *bitmap) void bitmap_destroy(struct bitmap *bitmap) { assert(bitmap); - g_object_unref((GdkPixbuf *) bitmap); + gtk_bitmap_free_pretiles(bitmap); + g_object_unref(bitmap->primary); + free(bitmap); } @@ -145,6 +168,7 @@ bool bitmap_save(struct bitmap *bitmap, const char *path) * \param bitmap a bitmap, as returned by bitmap_create() */ void bitmap_modified(struct bitmap *bitmap) { + gtk_bitmap_free_pretiles(bitmap); } @@ -159,3 +183,104 @@ void bitmap_modified(struct bitmap *bitmap) { void bitmap_set_suspendable(struct bitmap *bitmap, void *private_word, void (*invalidate)(struct bitmap *bitmap, void *private_word)) { } + +static GdkPixbuf * +gtk_bitmap_generate_pretile(GdkPixbuf *primary, int repeat_x, int repeat_y) +{ + int width = gdk_pixbuf_get_width(primary); + int height = gdk_pixbuf_get_height(primary); + size_t primary_stride = gdk_pixbuf_get_rowstride(primary); + GdkPixbuf *result = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8, + width * repeat_x, height * repeat_y); + char *target_buffer = (char *)gdk_pixbuf_get_pixels(result); + size_t target_stride = gdk_pixbuf_get_rowstride(result); + int x,y,row; + /* This algorithm won't work if the strides are not multiples */ + assert(target_stride == (primary_stride * repeat_x)); + + if (repeat_x == 1 && repeat_y == 1) { + g_object_ref(primary); + g_object_unref(result); + return primary; + } + + for (y = 0; y < repeat_y; ++y) { + char *primary_buffer = (char *)gdk_pixbuf_get_pixels(primary); + for (row = 0; row < height; ++row) { + for (x = 0; x < repeat_x; ++x) { + memcpy(target_buffer, + primary_buffer, primary_stride); + target_buffer += primary_stride; + } + primary_buffer += primary_stride; + } + } + return result; +} + +/** + * The primary image associated with this bitmap object. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +GdkPixbuf * +gtk_bitmap_get_primary(struct bitmap* bitmap) +{ + return bitmap->primary; +} + +/** + * The X-pretiled image associated with this bitmap object. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +GdkPixbuf * +gtk_bitmap_get_pretile_x(struct bitmap* bitmap) +{ + if (!bitmap->pretile_x) { + int width = gdk_pixbuf_get_width(bitmap->primary); + int height = gdk_pixbuf_get_height(bitmap->primary); + int xmult = (MIN_PRETILE_WIDTH + width - 1)/width; + LOG(("Pretiling %p for X*%d", bitmap, xmult)); + bitmap->pretile_x = gtk_bitmap_generate_pretile(bitmap->primary, xmult, 1); + } + return bitmap->pretile_x; + +} + +/** + * The Y-pretiled image associated with this bitmap object. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +GdkPixbuf * +gtk_bitmap_get_pretile_y(struct bitmap* bitmap) +{ + if (!bitmap->pretile_y) { + int width = gdk_pixbuf_get_width(bitmap->primary); + int height = gdk_pixbuf_get_height(bitmap->primary); + int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height; + LOG(("Pretiling %p for Y*%d", bitmap, ymult)); + bitmap->pretile_y = gtk_bitmap_generate_pretile(bitmap->primary, 1, ymult); + } + return bitmap->pretile_y; +} + +/** + * The XY-pretiled image associated with this bitmap object. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +GdkPixbuf * +gtk_bitmap_get_pretile_xy(struct bitmap* bitmap) +{ + if (!bitmap->pretile_xy) { + int width = gdk_pixbuf_get_width(bitmap->primary); + int height = gdk_pixbuf_get_height(bitmap->primary); + int xmult = (MIN_PRETILE_WIDTH + width - 1)/width; + int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height; + LOG(("Pretiling %p for X*%d Y*%d", bitmap, xmult, ymult)); + bitmap->pretile_xy = gtk_bitmap_generate_pretile(bitmap->primary, xmult, ymult); + } + return bitmap->pretile_xy; +} diff --git a/gtk/gtk_bitmap.h b/gtk/gtk_bitmap.h new file mode 100644 index 000000000..719bb0ab5 --- /dev/null +++ b/gtk/gtk_bitmap.h @@ -0,0 +1,22 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2006 Daniel Silverstone <dsilvers@digital-scurf.org> + */ + +#ifndef NS_GTK_BITMAP_H +#define NS_GTK_BITMAP_H + +#include <gdk/gdk.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include "netsurf/image/bitmap.h" + +GdkPixbuf *gtk_bitmap_get_primary(struct bitmap*); +GdkPixbuf *gtk_bitmap_get_pretile_x(struct bitmap*); +GdkPixbuf *gtk_bitmap_get_pretile_y(struct bitmap*); +GdkPixbuf *gtk_bitmap_get_pretile_xy(struct bitmap*); + + + +#endif /* NS_GTK_BITMAP_H */ diff --git a/gtk/gtk_plotters.c b/gtk/gtk_plotters.c index 773137381..27e5a78a3 100644 --- a/gtk/gtk_plotters.c +++ b/gtk/gtk_plotters.c @@ -26,6 +26,7 @@ #include "netsurf/utils/log.h" #include "netsurf/desktop/options.h" #include "netsurf/gtk/options.h" +#include "netsurf/gtk/gtk_bitmap.h" static bool nsgtk_plot_clg(colour c); static bool nsgtk_plot_rectangle(int x0, int y0, int width, int height, @@ -256,13 +257,12 @@ bool nsgtk_plot_arc(int x, int y, int radius, int angle1, int angle2, colour c) return true; } -bool nsgtk_plot_bitmap(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg) +static bool nsgtk_plot_pixbuf(int x, int y, int width, int height, + GdkPixbuf *pixbuf, colour bg) { /* XXX: This currently ignores the background colour supplied. * Does this matter? */ - GdkPixbuf *pixbuf = (GdkPixbuf *) bitmap; if (width == 0 || height == 0) return true; @@ -298,18 +298,39 @@ bool nsgtk_plot_bitmap(int x, int y, int width, int height, return true; } +bool nsgtk_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg) +{ + GdkPixbuf *pixbuf = gtk_bitmap_get_primary(bitmap); + nsgtk_plot_pixbuf(x, y, width, height, pixbuf, bg); +} bool nsgtk_plot_bitmap_tile(int x, int y, int width, int height, struct bitmap *bitmap, colour bg, bool repeat_x, bool repeat_y) { int doneheight = 0, donewidth = 0; - + GdkPixbuf *primary; + GdkPixbuf *pretiled; + if (!(repeat_x || repeat_y)) { /* Not repeating at all, so just pass it on */ return nsgtk_plot_bitmap(x,y,width,height,bitmap,bg); } - + + if (repeat_x && !repeat_y) + pretiled = gtk_bitmap_get_pretile_x(bitmap); + if (repeat_x && repeat_y) + pretiled = gtk_bitmap_get_pretile_xy(bitmap); + if (!repeat_x && repeat_y) + pretiled = gtk_bitmap_get_pretile_y(bitmap); + primary = gtk_bitmap_get_primary(bitmap); + /* use the primary and pretiled widths to scale the w/h provided */ + width *= gdk_pixbuf_get_width(pretiled); + width /= gdk_pixbuf_get_width(primary); + height *= gdk_pixbuf_get_height(pretiled); + height /= gdk_pixbuf_get_height(primary); + if (y > cliprect.y) doneheight = (cliprect.y - height) + ((y - cliprect.y) % height); else @@ -321,8 +342,8 @@ bool nsgtk_plot_bitmap_tile(int x, int y, int width, int height, else donewidth = x; while (donewidth < (cliprect.x + cliprect.width)) { - nsgtk_plot_bitmap(donewidth, doneheight, - width, height, bitmap, bg); + nsgtk_plot_pixbuf(donewidth, doneheight, + width, height, pretiled, bg); donewidth += width; if (!repeat_x) break; } diff --git a/gtk/gtk_thumbnail.c b/gtk/gtk_thumbnail.c index 4d4fea11c..c5e03c479 100644 --- a/gtk/gtk_thumbnail.c +++ b/gtk/gtk_thumbnail.c @@ -24,6 +24,7 @@ #include "netsurf/utils/log.h" #include "netsurf/gtk/gtk_window.h" #include "netsurf/gtk/gtk_plotters.h" +#include "netsurf/gtk/gtk_bitmap.h" /** * Create a thumbnail of a page. @@ -35,7 +36,7 @@ bool thumbnail_create(struct content *content, struct bitmap *bitmap, const char *url) { - GdkPixbuf *pixbuf = (GdkPixbuf *) bitmap; + GdkPixbuf *pixbuf = gtk_bitmap_get_primary(bitmap); gint width = gdk_pixbuf_get_width(pixbuf); gint height = gdk_pixbuf_get_height(pixbuf); gint depth = (gdk_screen_get_system_visual(gdk_screen_get_default()))->depth; |