Author: dsilvers
Date: Wed Aug 9 15:46:40 2006
New Revision: 2821
URL:
http://svn.semichrome.net?rev=2821&view=rev
Log:
Initial stab at pretiling in GTK frontend
Modified:
branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.c
branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.h
branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_plotters.c
Modified: branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.c
URL:
http://svn.semichrome.net/branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bi...
==============================================================================
--- branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.c (original)
+++ branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.c Wed Aug 9 15:46:40 2006
@@ -19,11 +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 {
GdkPixbuf *primary;
+ GdkPixbuf *pretile_x;
+ GdkPixbuf *pretile_y;
+ GdkPixbuf *pretile_xy;
};
+
+#define MIN_PRETILE_WIDTH 256
+#define MIN_PRETILE_HEIGHT 256
/**
@@ -40,6 +47,7 @@
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;
}
@@ -115,6 +123,16 @@
}
+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.
*
@@ -124,6 +142,7 @@
void bitmap_destroy(struct bitmap *bitmap)
{
assert(bitmap);
+ gtk_bitmap_free_pretiles(bitmap);
g_object_unref(bitmap->primary);
free(bitmap);
}
@@ -149,6 +168,7 @@
* \param bitmap a bitmap, as returned by bitmap_create()
*/
void bitmap_modified(struct bitmap *bitmap) {
+ gtk_bitmap_free_pretiles(bitmap);
}
@@ -164,6 +184,34 @@
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));
+
+ 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.
*
@@ -174,3 +222,44 @@
{
return bitmap->primary;
}
+
+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;
+
+}
+
+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;
+}
+
+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;
+}
Modified: branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.h
URL:
http://svn.semichrome.net/branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bi...
==============================================================================
--- branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.h (original)
+++ branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_bitmap.h Wed Aug 9 15:46:40 2006
@@ -13,6 +13,10 @@
#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 */
Modified: branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_plotters.c
URL:
http://svn.semichrome.net/branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_pl...
==============================================================================
--- branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_plotters.c (original)
+++ branches/dsilvers/gtk-bitmap-pretile/gtk/gtk_plotters.c Wed Aug 9 15:46:40 2006
@@ -257,13 +257,12 @@
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 = gtk_bitmap_get_primary(bitmap);
if (width == 0 || height == 0)
return true;
@@ -299,18 +298,39 @@
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
@@ -322,8 +342,8 @@
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;
}