r13346 vince - in /branches/vince/netsurf-cairo: gtk/bitmap.c gtk/bitmap.h gtk/plotters.c image/image.c
by netsurf@semichrome.net
Author: vince
Date: Sat Dec 24 18:56:02 2011
New Revision: 13346
URL: http://source.netsurf-browser.org?rev=13346&view=rev
Log:
cope with completely transparent spacers
cache scaled cairo bitmaps
Modified:
branches/vince/netsurf-cairo/gtk/bitmap.c
branches/vince/netsurf-cairo/gtk/bitmap.h
branches/vince/netsurf-cairo/gtk/plotters.c
branches/vince/netsurf-cairo/image/image.c
Modified: branches/vince/netsurf-cairo/gtk/bitmap.c
URL: http://source.netsurf-browser.org/branches/vince/netsurf-cairo/gtk/bitmap...
==============================================================================
--- branches/vince/netsurf-cairo/gtk/bitmap.c (original)
+++ branches/vince/netsurf-cairo/gtk/bitmap.c Sat Dec 24 18:56:02 2011
@@ -133,6 +133,7 @@
unsigned char *pixels;
int pcount;
int ploop;
+
assert(gbitmap);
pixels = cairo_image_surface_get_data(gbitmap->surface);
@@ -140,7 +141,7 @@
pcount = cairo_image_surface_get_stride(gbitmap->surface) *
cairo_image_surface_get_height(gbitmap->surface);
- for (ploop=3; ploop < pcount; ploop+=4) {
+ for (ploop = 3; ploop < pcount; ploop += 4) {
if (pixels[ploop] != 0xff) {
return false;
}
@@ -236,7 +237,12 @@
struct bitmap *gbitmap = (struct bitmap *)vbitmap;
assert(gbitmap);
- cairo_surface_destroy(gbitmap->surface);
+ if (gbitmap->surface != NULL) {
+ cairo_surface_destroy(gbitmap->surface);
+ }
+ if (gbitmap->scsurface != NULL) {
+ cairo_surface_destroy(gbitmap->scsurface);
+ }
free(gbitmap);
}
Modified: branches/vince/netsurf-cairo/gtk/bitmap.h
URL: http://source.netsurf-browser.org/branches/vince/netsurf-cairo/gtk/bitmap...
==============================================================================
--- branches/vince/netsurf-cairo/gtk/bitmap.h (original)
+++ branches/vince/netsurf-cairo/gtk/bitmap.h Sat Dec 24 18:56:02 2011
@@ -23,7 +23,8 @@
#include "image/bitmap.h"
struct bitmap {
- cairo_surface_t *surface;
+ cairo_surface_t *surface; /* original cairo surface */
+ cairo_surface_t *scsurface; /* scaled surface */
bool converted; /** set if the surface data has been converted */
};
Modified: branches/vince/netsurf-cairo/gtk/plotters.c
URL: http://source.netsurf-browser.org/branches/vince/netsurf-cairo/gtk/plotte...
==============================================================================
--- branches/vince/netsurf-cairo/gtk/plotters.c (original)
+++ branches/vince/netsurf-cairo/gtk/plotters.c Sat Dec 24 18:56:02 2011
@@ -280,7 +280,7 @@
static bool nsgtk_plot_pixbuf(int x, int y, int width, int height,
- cairo_surface_t *bmsurface, colour bg)
+ struct bitmap *bitmap, colour bg)
{
/* XXX: This currently ignores the background colour supplied.
* Does this matter?
@@ -289,6 +289,8 @@
int x0, y0, x1, y1;
int dsrcx, dsrcy, dwidth, dheight;
int bmwidth, bmheight;
+
+ cairo_surface_t *bmsurface = bitmap->surface;
/* Bail early if we can */
if (width == 0 || height == 0)
@@ -351,32 +353,44 @@
} else {
/* Bitmap is scaled */
- cairo_surface_t *scsurface = cairo_surface_create_similar(bmsurface,CAIRO_CONTENT_COLOR_ALPHA, width, height);
- cairo_t *cr = cairo_create (scsurface);
-
- /* Scale *before* setting the source surface (1) */
- cairo_scale (cr, (double)width / bmwidth, (double)height / bmheight);
- cairo_set_source_surface (cr, bmsurface, 0, 0);
-
- /* To avoid getting the edge pixels blended with 0 alpha, which would
- * occur with the default EXTEND_NONE. Use EXTEND_PAD for 1.2 or newer (2)
- */
- cairo_pattern_set_extend (cairo_get_source(cr), CAIRO_EXTEND_REFLECT);
-
- /* Replace the destination with the source instead of overlaying */
- cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
-
- /* Do the actual drawing */
- cairo_paint (cr);
+ if ((bitmap->scsurface != NULL) &&
+ ((cairo_image_surface_get_width(bitmap->scsurface) != width) ||
+ (cairo_image_surface_get_height(bitmap->scsurface) != height))){
+ cairo_surface_destroy(bitmap->scsurface);
+ bitmap->scsurface = NULL;
+ }
+
+ if (bitmap->scsurface == NULL) {
+ bitmap->scsurface = cairo_surface_create_similar(bmsurface,CAIRO_CONTENT_COLOR_ALPHA, width, height);
+ cairo_t *cr = cairo_create(bitmap->scsurface);
+
+ /* Scale *before* setting the source surface (1) */
+ cairo_scale(cr, (double)width / bmwidth, (double)height / bmheight);
+ cairo_set_source_surface(cr, bmsurface, 0, 0);
+
+ /* To avoid getting the edge pixels blended with 0
+ * alpha, which would occur with the default
+ * EXTEND_NONE. Use EXTEND_PAD for 1.2 or newer (2)
+ */
+ cairo_pattern_set_extend(cairo_get_source(cr),
+ CAIRO_EXTEND_REFLECT);
+
+ /* Replace the destination with the source instead of
+ * overlaying
+ */
+ cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+
+ /* Do the actual drawing */
+ cairo_paint(cr);
- cairo_destroy (cr);
-
+ cairo_destroy(cr);
+
+ }
/* Plot the scaled bitmap */
- cairo_set_source_surface(current_cr, scsurface, x, y);
+ cairo_set_source_surface(current_cr, bitmap->scsurface, x, y);
cairo_rectangle(current_cr, dsrcx, dsrcy, dwidth, dheight);
cairo_fill(current_cr);
- cairo_surface_destroy(scsurface);
}
@@ -391,35 +405,43 @@
bool repeat_x = (flags & BITMAPF_REPEAT_X);
bool repeat_y = (flags & BITMAPF_REPEAT_Y);
- cairo_surface_t *bmsurface = bitmap->surface;
-
if (!(repeat_x || repeat_y)) {
/* Not repeating at all, so just pass it on */
- return nsgtk_plot_pixbuf(x, y, width, height, bmsurface, bg);
+ return nsgtk_plot_pixbuf(x, y, width, height, bitmap, bg);
}
width = bitmap_get_width(bitmap);
height = bitmap_get_height(bitmap);
-
- if (y > cliprect.y)
+ /* Bail early if we can */
+ if (width == 0 || height == 0)
+ /* Nothing to plot */
+ return true;
+
+ if (y > cliprect.y) {
doneheight = (cliprect.y - height) + ((y - cliprect.y) % height);
- else
+ } else {
doneheight = y;
+ }
while (doneheight < (cliprect.y + cliprect.height)) {
- if (x > cliprect.x)
+ if (x > cliprect.x) {
donewidth = (cliprect.x - width) + ((x - cliprect.x) % width);
- else
+ } else {
donewidth = x;
+ }
+
while (donewidth < (cliprect.x + cliprect.width)) {
nsgtk_plot_pixbuf(donewidth, doneheight,
- width, height, bmsurface, bg);
+ width, height, bitmap, bg);
donewidth += width;
- if (!repeat_x) break;
+ if (!repeat_x)
+ break;
}
doneheight += height;
- if (!repeat_y) break;
+
+ if (!repeat_y)
+ break;
}
return true;
Modified: branches/vince/netsurf-cairo/image/image.c
URL: http://source.netsurf-browser.org/branches/vince/netsurf-cairo/image/imag...
==============================================================================
--- branches/vince/netsurf-cairo/image/image.c (original)
+++ branches/vince/netsurf-cairo/image/image.c Sat Dec 24 18:56:02 2011
@@ -131,14 +131,16 @@
plot_style_t fill_style;
struct rect area;
- if (bitmap_get_opaque(bitmap)) {
- width = bitmap_get_width(bitmap);
- if (width == 1) {
- height = bitmap_get_height(bitmap);
- if (height == 1) {
- /* optimise 1x1 bitmap plot */
- pixel = bitmap_get_buffer(bitmap);
- fill_style.fill_colour = pixel_to_colour(pixel);
+ width = bitmap_get_width(bitmap);
+ if (width == 1) {
+ height = bitmap_get_height(bitmap);
+ if (height == 1) {
+ /* optimise 1x1 bitmap plot */
+ pixel = bitmap_get_buffer(bitmap);
+ fill_style.fill_colour = pixel_to_colour(pixel);
+
+ if (bitmap_get_opaque(bitmap) ||
+ ((fill_style.fill_colour & 0xff000000) == 0xff000000)) {
area = *clip;
@@ -154,11 +156,14 @@
fill_style.stroke_type = PLOT_OP_TYPE_NONE;
fill_style.fill_type = PLOT_OP_TYPE_SOLID;
- /* LOG(("area %d,%d -> %d,%d", area.x0, area.y0, area.x1, area.y1)); */
+
return ctx->plot->rectangle(area.x0, area.y0,
- area.x1, area.y1,
- &fill_style);
+ area.x1, area.y1,
+ &fill_style);
+ } else if ((fill_style.fill_colour & 0xff000000) == 0) {
+ /* transparent pixel used as spacer, skip it */
+ return true;
}
}
}