From de98108e7f5dde136164a6e74596d70fd1289397 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 22 Apr 2015 23:13:24 +0100 Subject: [PATCH 01/13] Add render to bitmap operations and update gtk to provide it. --- desktop/gui_factory.c | 4 ++ gtk/bitmap.c | 116 ++++++++++++++++++++++++++++++++++++------ image/bitmap.h | 33 +++++++----- 3 files changed, 126 insertions(+), 27 deletions(-) diff --git a/desktop/gui_factory.c b/desktop/gui_factory.c index cab11eb0a..50244e334 100644 --- a/desktop/gui_factory.c +++ b/desktop/gui_factory.c @@ -620,6 +620,10 @@ static nserror verify_bitmap_register(struct gui_bitmap_table *gbt) return NSERROR_BAD_PARAMETER; } + if (gbt->render == NULL) { + return NSERROR_BAD_PARAMETER; + } + return NSERROR_OK; } diff --git a/gtk/bitmap.c b/gtk/bitmap.c index 978838d2e..6e53154c4 100644 --- a/gtk/bitmap.c +++ b/gtk/bitmap.c @@ -32,8 +32,11 @@ #include "utils/log.h" #include "content/content.h" #include "image/bitmap.h" +#include "desktop/plotters.h" +#include "desktop/thumbnail.h" #include "gtk/scaffolding.h" +#include "gtk/plotters.h" #include "gtk/bitmap.h" @@ -86,17 +89,17 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) if (fmt == CAIRO_FORMAT_RGB24) { if (opaque == false) { /* opaque to transparent */ - nsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, - cairo_image_surface_get_width(gbitmap->surface), + nsurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, + cairo_image_surface_get_width(gbitmap->surface), cairo_image_surface_get_height(gbitmap->surface)); } - + } else { if (opaque == true) { /* transparent to opaque */ - nsurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, - cairo_image_surface_get_width(gbitmap->surface), + nsurface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, + cairo_image_surface_get_width(gbitmap->surface), cairo_image_surface_get_height(gbitmap->surface)); } @@ -106,8 +109,8 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) if (cairo_surface_status(nsurface) != CAIRO_STATUS_SUCCESS) { cairo_surface_destroy(nsurface); } else { - memcpy(cairo_image_surface_get_data(nsurface), - cairo_image_surface_get_data(gbitmap->surface), + memcpy(cairo_image_surface_get_data(nsurface), + cairo_image_surface_get_data(gbitmap->surface), cairo_image_surface_get_stride(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface)); cairo_surface_destroy(gbitmap->surface); gbitmap->surface = nsurface; @@ -116,7 +119,7 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) } - } + } } @@ -137,13 +140,13 @@ static bool bitmap_test_opaque(void *vbitmap) pixels = cairo_image_surface_get_data(gbitmap->surface); - pcount = cairo_image_surface_get_stride(gbitmap->surface) * + pcount = cairo_image_surface_get_stride(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface); for (ploop = 3; ploop < pcount; ploop += 4) { if (pixels[ploop] != 0xff) { return false; - } + } } return true; @@ -190,7 +193,7 @@ static unsigned char *bitmap_get_buffer(void *vbitmap) cairo_format_t fmt; assert(gbitmap); - + cairo_surface_flush(gbitmap->surface); pixels = cairo_image_surface_get_data(gbitmap->surface); @@ -259,7 +262,7 @@ static unsigned char *bitmap_get_buffer(void *vbitmap) } gbitmap->converted = false; - + return (unsigned char *) pixels; } @@ -341,7 +344,7 @@ static void bitmap_modified(void *vbitmap) { struct bitmap *gbitmap = (struct bitmap *)vbitmap; int pixel_loop; - int pixel_count; + int pixel_count; uint8_t *pixels; uint32_t t, r, g, b; cairo_format_t fmt; @@ -350,7 +353,7 @@ static void bitmap_modified(void *vbitmap) fmt = cairo_image_surface_get_format(gbitmap->surface); - pixel_count = cairo_image_surface_get_width(gbitmap->surface) * + pixel_count = cairo_image_surface_get_width(gbitmap->surface) * cairo_image_surface_get_height(gbitmap->surface); pixels = cairo_image_surface_get_data(gbitmap->surface); @@ -411,7 +414,7 @@ static void bitmap_modified(void *vbitmap) #endif } } - + cairo_surface_mark_dirty(gbitmap->surface); gbitmap->converted = true; @@ -435,6 +438,88 @@ int nsgtk_bitmap_get_height(void *vbitmap) return cairo_image_surface_get_height(gbitmap->surface); } +/** + * Render content into a bitmap. + * + * \param content content structure to thumbnail + * \param bitmap the bitmap to draw to + * \return true on success and bitmap updated else false + */ +static nserror +bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) +{ + cairo_surface_t *dsurface = bitmap->surface; + cairo_surface_t *surface; + cairo_t *old_cr; + gint dwidth, dheight; + int cwidth, cheight; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &nsgtk_plotters + }; + + assert(content); + assert(bitmap); + + dwidth = cairo_image_surface_get_width(dsurface); + dheight = cairo_image_surface_get_height(dsurface); + + /* Calculate size of buffer to render the content into */ + /* Get the width from the content width, unless it exceeds 1024, + * in which case we use 1024. This means we never create excessively + * large render buffers for huge contents, which would eat memory and + * cripple performance. + */ + cwidth = min(max(content_get_width(content), dwidth), 1024); + + /* The height is set in proportion with the width, according to the + * aspect ratio of the required thumbnail. */ + cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth; + + /* Create surface to render into */ + surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight); + + if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { + cairo_surface_destroy(surface); + return false; + } + + old_cr = current_cr; + current_cr = cairo_create(surface); + + /* render the content */ + thumbnail_redraw(content, cwidth, cheight, &ctx); + + cairo_destroy(current_cr); + current_cr = old_cr; + + cairo_t *cr = cairo_create(dsurface); + + /* Scale *before* setting the source surface (1) */ + cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight); + cairo_set_source_surface (cr, surface, 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_surface_destroy(surface); + + return NSERROR_OK; +} + + static struct gui_bitmap_table bitmap_table = { .create = bitmap_create, .destroy = bitmap_destroy, @@ -448,6 +533,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *nsgtk_bitmap_table = &bitmap_table; diff --git a/image/bitmap.h b/image/bitmap.h index b121f8abd..ef6c1b49b 100644 --- a/image/bitmap.h +++ b/image/bitmap.h @@ -28,27 +28,27 @@ * For example, an opaque 1x1 pixel image would yield the following bitmap * data: * - * Red : 0xff 0x00 0x00 0x00 - * Green: 0x00 0xff 0x00 0x00 - * Blue : 0x00 0x00 0xff 0x00 + * > Red : 0xff 0x00 0x00 0x00 + * > Green: 0x00 0xff 0x00 0x00 + * > Blue : 0x00 0x00 0xff 0x00 * * Any attempt to read pixels by casting bitmap data to uint32_t or similar * will need to cater for the order of bytes in a word being different on * big and little endian systems. To avoid confusion, it is recommended * that pixel data is loaded as follows: * - * uint32_t read_pixel(const uint8_t *bmp) - * { - * // red green blue alpha - * return bmp[0] | (bmp[1] << 8) | (bmp[2] << 16) | (bmp[3] << 24); - * } + * uint32_t read_pixel(const uint8_t *bmp) + * { + * // red green blue alpha + * return bmp[0] | (bmp[1] << 8) | (bmp[2] << 16) | (bmp[3] << 24); + * } * * and *not* as follows: * - * uint32_t read_pixel(const uint8_t *bmp) - * { - * return *((uint32_t *) bmp); - * } + * uint32_t read_pixel(const uint8_t *bmp) + * { + * return *((uint32_t *) bmp); + * } */ #ifndef _NETSURF_IMAGE_BITMAP_H_ @@ -61,6 +61,7 @@ struct content; struct bitmap; +struct hlcache_handle; /** * Bitmap operations. @@ -163,6 +164,14 @@ struct gui_bitmap_table { * \param bitmap The bitmap set as modified. */ void (*modified)(void *bitmap); + + /** + * Render content into a bitmap. + * + * \param bitmap The bitmap to render into. + * \param content The content to render. + */ + nserror (*render)(struct bitmap *bitmap, struct hlcache_handle *content); }; #endif From ea2e1c4d987421ff8b96a098566c6bd24bac3bef Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 23 Apr 2015 15:47:28 +0100 Subject: [PATCH 02/13] Add scaled content redraw interface. Add a new interface to the content to allow automaticaly scaled content redraws. This is intended to replace the thumbnail_redraw interface with something more generic. --- content/content.c | 73 +++++++++++++++++++++++++++++++++++++++++++++-- content/content.h | 21 ++++++++++++++ 2 files changed, 92 insertions(+), 2 deletions(-) diff --git a/content/content.c b/content/content.c index a6ca97817..cf0216453 100644 --- a/content/content.c +++ b/content/content.c @@ -33,7 +33,9 @@ #include "content/content_protected.h" #include "content/hlcache.h" #include "image/bitmap.h" +#include "desktop/knockout.h" #include "desktop/browser.h" +#include "desktop/plotters.h" #include "desktop/gui_internal.h" #include "utils/nsoption.h" @@ -551,8 +553,7 @@ void content__request_redraw(struct content *c, /** * Display content on screen with optional tiling. * - * Calls the redraw_tile function for the content, or emulates it with the - * redraw function if it doesn't exist. + * Calls the redraw function for the content. */ bool content_redraw(hlcache_handle *h, struct content_redraw_data *data, @@ -576,6 +577,74 @@ bool content_redraw(hlcache_handle *h, struct content_redraw_data *data, } +/* exported interface, documented in content/content.h */ +bool content_scaled_redraw(struct hlcache_handle *h, + int width, int height, const struct redraw_context *ctx) +{ + struct content *c = hlcache_handle_get_content(h); + struct redraw_context new_ctx = *ctx; + struct rect clip; + struct content_redraw_data data; + bool plot_ok = true; + + assert(c != NULL); + + /* ensure it is safe to attempt redraw */ + if (c->locked) { + return true; + } + + /* ensure we have a redrawable content */ + if (c->handler->redraw == NULL) { + return true; + } + + LOG(("Content %p %dx%d ctx:%p", c, width, height, ctx)); + + if (ctx->plot->option_knockout) { + knockout_plot_start(ctx, &new_ctx); + } + + /* Set clip rectangle to required thumbnail size */ + clip.x0 = 0; + clip.y0 = 0; + clip.x1 = width; + clip.y1 = height; + + new_ctx.plot->clip(&clip); + + /* Plot white background */ + plot_ok &= new_ctx.plot->rectangle(clip.x0, clip.y0, clip.x1, clip.y1, + plot_style_fill_white); + + + /* Set up content redraw data */ + data.x = 0; + data.y = 0; + data.width = width; + data.height = height; + + data.background_colour = 0xFFFFFF; + data.repeat_x = false; + data.repeat_y = false; + + /* Find the scale factor to use if the content has a width */ + if (c->width) { + data.scale = (float)width / (float)c->width; + } else { + data.scale = 1.0; + } + + /* Render the content */ + plot_ok &= c->handler->redraw(c, &data, &clip, &new_ctx); + + if (ctx->plot->option_knockout) { + knockout_plot_end(); + } + + return plot_ok; +} + /** * Register a user for callbacks. * diff --git a/content/content.h b/content/content.h index f0761d748..6c05df9c5 100644 --- a/content/content.h +++ b/content/content.h @@ -270,6 +270,27 @@ void content_mouse_action(struct hlcache_handle *h, struct browser_window *bw, bool content_keypress(struct hlcache_handle *h, uint32_t key); bool content_redraw(struct hlcache_handle *h, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx); + + +/** + * Redraw a content with scale set for horizontal fit. + * + * Redraws the content at a specified width and height with the + * content drawing scaled to fit within the area. + * + * \param content The content to redraw + * \param width The target width + * \param height The target height + * \param ctx current redraw context + * \return true if successful, false otherwise + * + * The thumbnail is guaranteed to be filled to its width/height extents, so + * there is no need to render a solid background first. + * + * Units for width and height are pixels. + */ +bool content_scaled_redraw(struct hlcache_handle *content, int width, int height, const struct redraw_context *ctx); + void content_open(struct hlcache_handle *h, struct browser_window *bw, struct content *page, struct object_params *params); void content_close(struct hlcache_handle *h); From 8ccbc960d354e55d6fc18df9a4e44e05e1c18a39 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 23 Apr 2015 16:52:59 +0100 Subject: [PATCH 03/13] Change gtk bitmap render to use scaled content redraw. --- gtk/bitmap.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/gtk/bitmap.c b/gtk/bitmap.c index 6e53154c4..fa86ff178 100644 --- a/gtk/bitmap.c +++ b/gtk/bitmap.c @@ -33,7 +33,6 @@ #include "content/content.h" #include "image/bitmap.h" #include "desktop/plotters.h" -#include "desktop/thumbnail.h" #include "gtk/scaffolding.h" #include "gtk/plotters.h" @@ -441,8 +440,8 @@ int nsgtk_bitmap_get_height(void *vbitmap) /** * Render content into a bitmap. * - * \param content content structure to thumbnail - * \param bitmap the bitmap to draw to + * \param bitmap The bitmap to draw to + * \param content The content to render * \return true on success and bitmap updated else false */ static nserror @@ -489,7 +488,7 @@ bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) current_cr = cairo_create(surface); /* render the content */ - thumbnail_redraw(content, cwidth, cheight, &ctx); + content_scaled_redraw(content, cwidth, cheight, &ctx); cairo_destroy(current_cr); current_cr = old_cr; From ee78742363632583f283d0187d6b464284636f43 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 23 Apr 2015 22:23:09 +0100 Subject: [PATCH 04/13] change browser history to use bitmap render interface for thumbnails --- desktop/browser_history.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/desktop/browser_history.c b/desktop/browser_history.c index e7fd87583..95f85bb6c 100644 --- a/desktop/browser_history.c +++ b/desktop/browser_history.c @@ -41,7 +41,6 @@ #include "desktop/browser_history.h" #include "desktop/browser_private.h" #include "desktop/plotters.h" -#include "desktop/thumbnail.h" #include "desktop/font.h" #define WIDTH 100 @@ -281,13 +280,18 @@ browser_window_history__redraw_entry(struct history *history, rect.y0 = y0 + yoffset; rect.x1 = x1 + xoffset; rect.y1 = y1 + yoffset; - if(!plot->clip(&rect)) + if (!plot->clip(&rect)) { return false; + } } - if (!plot->bitmap(entry->x + xoffset, entry->y + yoffset, WIDTH, HEIGHT, - entry->bitmap, 0xffffff, 0)) - return false; + /* Only attempt to plot bitmap if it is present */ + if (entry->bitmap != NULL) { + plot->bitmap(entry->x + xoffset, + entry->y + yoffset, + WIDTH, HEIGHT, + entry->bitmap, 0xffffff, 0); + } if (!plot->rectangle(entry->x - 1 + xoffset, entry->y - 1 + yoffset, entry->x + xoffset + WIDTH, @@ -466,6 +470,7 @@ nserror browser_window_history_add(struct browser_window *bw, nsurl *nsurl = hlcache_handle_get_url(content); char *title; struct bitmap *bitmap; + nserror ret; assert(bw); assert(bw->history); @@ -516,7 +521,8 @@ nserror browser_window_history_add(struct browser_window *bw, BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE); if (bitmap != NULL) { - if (thumbnail_create(content, bitmap)) { + ret = guit->bitmap->render(bitmap, content); + if (ret == NSERROR_OK) { /* Successful thumbnail so register it * with the url. */ @@ -525,7 +531,7 @@ nserror browser_window_history_add(struct browser_window *bw, /* Thumbnailing failed. Ignore it * silently but clean up bitmap. */ - LOG(("Thumbnail bitmap creation failed")); + LOG(("Thumbnail renderfailed")); guit->bitmap->destroy(bitmap); bitmap = NULL; } @@ -565,7 +571,7 @@ nserror browser_window_history_update(struct browser_window *bw, free(history->current->page.title); history->current->page.title = title; - thumbnail_create(content, history->current->bitmap); + guit->bitmap->render(history->current->bitmap, content); return NSERROR_OK; } From 7e2f1094ce8d527c07e06dea164d7647d6605a4f Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 23 Apr 2015 22:31:40 +0100 Subject: [PATCH 05/13] Remove unused thumbnail sources from core and gtk --- desktop/Makefile | 2 +- desktop/thumbnail.c | 110 --------------------------------------- desktop/thumbnail.h | 55 -------------------- gtk/Makefile.target | 2 +- gtk/thumbnail.c | 122 -------------------------------------------- 5 files changed, 2 insertions(+), 289 deletions(-) delete mode 100644 desktop/thumbnail.c delete mode 100644 desktop/thumbnail.h delete mode 100644 gtk/thumbnail.c diff --git a/desktop/Makefile b/desktop/Makefile index 894b51861..f7f660d51 100644 --- a/desktop/Makefile +++ b/desktop/Makefile @@ -2,7 +2,7 @@ S_DESKTOP := cookie_manager.c knockout.c hotlist.c mouse.c \ plot_style.c print.c search.c searchweb.c scrollbar.c \ - sslcert_viewer.c textarea.c thumbnail.c tree.c version.c \ + sslcert_viewer.c textarea.c tree.c version.c \ system_colour.c global_history.c treeview.c S_DESKTOP := $(addprefix desktop/,$(S_DESKTOP)) diff --git a/desktop/thumbnail.c b/desktop/thumbnail.c deleted file mode 100644 index d7aed007a..000000000 --- a/desktop/thumbnail.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2011 Michael Drake - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Core thumbnail handling (implementation). - */ - -#include -#include - -#include "content/content.h" -#include "content/hlcache.h" -#include "desktop/browser.h" -#include "desktop/knockout.h" -#include "utils/nsoption.h" -#include "desktop/plotters.h" -#include "desktop/thumbnail.h" -#include "utils/log.h" - - -/** - * Get scale at which thumbnail will be rendered for a given content and - * thumbnail size. - * - * \param content The content to redraw for thumbnail - * \param width The thumbnail width - * \return scale thumbnail will be rendered at - * - * Units for width and height are pixels. - */ -static float thumbnail_get_redraw_scale(struct hlcache_handle *content, - int width) -{ - assert(content); - - if (content_get_width(content)) - return (float)width / (float)content_get_width(content); - else - return 1.0; -} - - -/* exported interface, documented in thumbnail.h */ -bool thumbnail_redraw(struct hlcache_handle *content, - int width, int height, const struct redraw_context *ctx) -{ - struct redraw_context new_ctx = *ctx; - struct rect clip; - struct content_redraw_data data; - float scale; - bool plot_ok = true; - - assert(content); - - LOG(("Content %p %dx%d ctx:%p", content, width, height, ctx)); - - if (ctx->plot->option_knockout) { - knockout_plot_start(ctx, &new_ctx); - } - - /* Set clip rectangle to required thumbnail size */ - clip.x0 = 0; - clip.y0 = 0; - clip.x1 = width; - clip.y1 = height; - - new_ctx.plot->clip(&clip); - - /* Plot white background */ - plot_ok &= new_ctx.plot->rectangle(clip.x0, clip.y0, clip.x1, clip.y1, - plot_style_fill_white); - - /* Find the scale we're using */ - scale = thumbnail_get_redraw_scale(content, width); - - /* Set up content redraw data */ - data.x = 0; - data.y = 0; - data.width = width; - data.height = height; - - data.background_colour = 0xFFFFFF; - data.scale = scale; - data.repeat_x = false; - data.repeat_y = false; - - /* Render the content */ - plot_ok &= content_redraw(content, &data, &clip, &new_ctx); - - if (ctx->plot->option_knockout) { - knockout_plot_end(); - } - - return plot_ok; -} diff --git a/desktop/thumbnail.h b/desktop/thumbnail.h deleted file mode 100644 index ef31f7ec3..000000000 --- a/desktop/thumbnail.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2011 Michael Drake - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Thumbail handling (interface). - */ - -#ifndef _NETSURF_DESKTOP_THUMBNAIL_H_ -#define _NETSURF_DESKTOP_THUMBNAIL_H_ - -#include - -struct hlcache_handle; -struct redraw_context; -struct bitmap; - -/** - * Redraw a content for thumbnailing - * - * Calls the redraw function for the content, - * - * \param content The content to redraw for thumbnail - * \param width The thumbnail width - * \param height The thumbnail height - * \param ctx current redraw context - * \return true if successful, false otherwise - * - * The thumbnail is guaranteed to be filled to its width/height extents, so - * there is no need to render a solid background first. - * - * Units for width and height are pixels. - */ -bool thumbnail_redraw(struct hlcache_handle *content, int width, int height, - const struct redraw_context *ctx); - - -/* In platform specific thumbnail.c. */ -bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap); - -#endif diff --git a/gtk/Makefile.target b/gtk/Makefile.target index 8378c1096..ee757f5f0 100644 --- a/gtk/Makefile.target +++ b/gtk/Makefile.target @@ -107,7 +107,7 @@ S_PIXBUF := $(eval $(foreach V,$(filter GTK_IMAGE_%,$(.VARIABLES)),$(call convert_image,$($(V)),$(OBJROOT)/$(patsubst GTK_IMAGE_%,%,$(V)).c,$(patsubst GTK_IMAGE_%,%,$(V))_pixdata))) # S_GTK are sources purely for the GTK build -S_GTK := font_pango.c bitmap.c gui.c schedule.c thumbnail.c plotters.c \ +S_GTK := font_pango.c bitmap.c gui.c schedule.c plotters.c \ treeview.c scaffolding.c gdk.c completion.c login.c throbber.c \ selection.c history.c window.c fetch.c download.c menu.c \ print.c search.c tabs.c theme.c toolbar.c gettext.c \ diff --git a/gtk/thumbnail.c b/gtk/thumbnail.c deleted file mode 100644 index 2ee33fba6..000000000 --- a/gtk/thumbnail.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2006 Rob Kendrick - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Page thumbnail creation (implementation). - * - * Thumbnails are created by setting the current drawing contexts to the - * bitmap (a gdk pixbuf) we are passed, and plotting the page at a small - * scale. - */ - -#include -#include -#include - -#include "utils/log.h" -#include "utils/utils.h" -#include "content/content.h" -#include "content/hlcache.h" -#include "desktop/plotters.h" -#include "desktop/browser.h" -#include "desktop/thumbnail.h" - -#include "gtk/scaffolding.h" -#include "gtk/plotters.h" -#include "gtk/bitmap.h" - -/** - * Create a thumbnail of a page. - * - * \param content content structure to thumbnail - * \param bitmap the bitmap to draw to - * \return true on success and bitmap updated else false - */ -bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap) -{ - cairo_surface_t *dsurface = bitmap->surface; - cairo_surface_t *surface; - cairo_t *old_cr; - gint dwidth, dheight; - int cwidth, cheight; - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &nsgtk_plotters - }; - - assert(content); - assert(bitmap); - - dwidth = cairo_image_surface_get_width(dsurface); - dheight = cairo_image_surface_get_height(dsurface); - - /* Calculate size of buffer to render the content into */ - /* Get the width from the content width, unless it exceeds 1024, - * in which case we use 1024. This means we never create excessively - * large render buffers for huge contents, which would eat memory and - * cripple performance. - */ - cwidth = min(max(content_get_width(content), dwidth), 1024); - - /* The height is set in proportion with the width, according to the - * aspect ratio of the required thumbnail. */ - cheight = ((cwidth * dheight) + (dwidth / 2)) / dwidth; - - /* Create surface to render into */ - surface = cairo_surface_create_similar(dsurface, CAIRO_CONTENT_COLOR_ALPHA, cwidth, cheight); - - if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { - cairo_surface_destroy(surface); - return false; - } - - old_cr = current_cr; - current_cr = cairo_create(surface); - - /* render the content */ - thumbnail_redraw(content, cwidth, cheight, &ctx); - - cairo_destroy(current_cr); - current_cr = old_cr; - - cairo_t *cr = cairo_create(dsurface); - - /* Scale *before* setting the source surface (1) */ - cairo_scale (cr, (double)dwidth / cwidth, (double)dheight / cheight); - cairo_set_source_surface (cr, surface, 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_surface_destroy(surface); - - return true; -} - From 1a22eb2b658215ccb1d5281a4b30a2055fe6b8f6 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 23 Apr 2015 22:48:01 +0100 Subject: [PATCH 06/13] Convert framebuffer to use bitmap render from thumbnail API --- framebuffer/Makefile.target | 5 +- framebuffer/bitmap.c | 80 +++++++++++++++++++++++++++++- framebuffer/thumbnail.c | 97 ------------------------------------- 3 files changed, 81 insertions(+), 101 deletions(-) delete mode 100644 framebuffer/thumbnail.c diff --git a/framebuffer/Makefile.target b/framebuffer/Makefile.target index d652c8a44..0431abf69 100644 --- a/framebuffer/Makefile.target +++ b/framebuffer/Makefile.target @@ -163,9 +163,8 @@ $(eval $(foreach V,$(filter FB_FONT_$(NETSURF_FB_FONTLIB)_%,$(.VARIABLES)),$(cal # ---------------------------------------------------------------------------- # S_FRAMEBUFFER are sources purely for the framebuffer build -S_FRAMEBUFFER := gui.c framebuffer.c schedule.c \ - thumbnail.c misc.c bitmap.c fetch.c findfile.c \ - localhistory.c clipboard.c +S_FRAMEBUFFER := gui.c framebuffer.c schedule.c misc.c bitmap.c fetch.c \ + findfile.c localhistory.c clipboard.c S_FRAMEBUFFER_FBTK := fbtk.c event.c fill.c bitmap.c user.c window.c \ text.c scroll.c osk.c diff --git a/framebuffer/bitmap.c b/framebuffer/bitmap.c index 713cf840a..9f5b02524 100644 --- a/framebuffer/bitmap.c +++ b/framebuffer/bitmap.c @@ -26,10 +26,17 @@ #include #include #include +#include -#include "image/bitmap.h" #include "utils/log.h" +#include "utils/utils.h" +#include "image/bitmap.h" +#include "desktop/plotters.h" +#include "content/content.h" +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/framebuffer.h" #include "framebuffer/bitmap.h" /** @@ -249,6 +256,76 @@ static size_t bitmap_get_bpp(void *bitmap) return 4; } +/** + * Render content into a bitmap. + * + * \param bitmap the bitmap to draw to + * \param content content structure to render + * \return true on success and bitmap updated else false + */ +static nserror +bitmap_render(struct bitmap *bitmap, + struct hlcache_handle *content) +{ + nsfb_t *tbm = (nsfb_t *)bitmap; /* target bitmap */ + nsfb_t *bm; /* temporary bitmap */ + nsfb_t *current; /* current main fb */ + int width, height; /* target bitmap width height */ + int cwidth, cheight;/* content width /height */ + nsfb_bbox_t loc; + + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &fb_plotters + }; + + nsfb_get_geometry(tbm, &width, &height, NULL); + + LOG(("width %d, height %d", width, height)); + + /* Calculate size of buffer to render the content into */ + /* We get the width from the content width, unless it exceeds 1024, + * in which case we use 1024. This means we never create excessively + * large render buffers for huge contents, which would eat memory and + * cripple performance. */ + cwidth = min(content_get_width(content), 1024); + /* The height is set in proportion with the width, according to the + * aspect ratio of the required thumbnail. */ + cheight = ((cwidth * height) + (width / 2)) / width; + + /* create temporary surface */ + bm = nsfb_new(NSFB_SURFACE_RAM); + if (bm == NULL) { + return NSERROR_NOMEM; + } + + nsfb_set_geometry(bm, cwidth, cheight, NSFB_FMT_XBGR8888); + + if (nsfb_init(bm) == -1) { + nsfb_free(bm); + return NSERROR_NOMEM; + } + + current = framebuffer_set_surface(bm); + + /* render the content into temporary surface */ + content_scaled_redraw(content, cwidth, cheight, &ctx); + + framebuffer_set_surface(current); + + loc.x0 = 0; + loc.y0 = 0; + loc.x1 = width; + loc.y1 = height; + + nsfb_plot_copy(bm, NULL, tbm, &loc); + + nsfb_free(bm); + + return NSERROR_OK; +} + static struct gui_bitmap_table bitmap_table = { .create = bitmap_create, .destroy = bitmap_destroy, @@ -262,6 +339,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *framebuffer_bitmap_table = &bitmap_table; diff --git a/framebuffer/thumbnail.c b/framebuffer/thumbnail.c deleted file mode 100644 index 24067fd2f..000000000 --- a/framebuffer/thumbnail.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2008 Chris Young - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include -#include - -#include "utils/log.h" -#include "utils/utils.h" -#include "desktop/plotters.h" -#include "desktop/thumbnail.h" -#include "content/urldb.h" -#include "content/content.h" - -#include "framebuffer/gui.h" -#include "framebuffer/fbtk.h" -#include "framebuffer/framebuffer.h" - -bool -thumbnail_create(struct hlcache_handle *content, - struct bitmap *bitmap) -{ - nsfb_t *tbm = (nsfb_t *)bitmap; /* target bitmap */ - nsfb_t *bm; /* temporary bitmap */ - nsfb_t *current; /* current main fb */ - int width, height; /* target bitmap width height */ - int cwidth, cheight;/* content width /height */ - nsfb_bbox_t loc; - - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &fb_plotters - }; - - - nsfb_get_geometry(tbm, &width, &height, NULL); - - LOG(("width %d, height %d", width, height)); - - /* Calculate size of buffer to render the content into */ - /* We get the width from the content width, unless it exceeds 1024, - * in which case we use 1024. This means we never create excessively - * large render buffers for huge contents, which would eat memory and - * cripple performance. */ - cwidth = min(content_get_width(content), 1024); - /* The height is set in proportion with the width, according to the - * aspect ratio of the required thumbnail. */ - cheight = ((cwidth * height) + (width / 2)) / width; - - /* create temporary surface */ - bm = nsfb_new(NSFB_SURFACE_RAM); - if (bm == NULL) { - return false; - } - - nsfb_set_geometry(bm, cwidth, cheight, NSFB_FMT_XBGR8888); - - if (nsfb_init(bm) == -1) { - nsfb_free(bm); - return false; - } - - current = framebuffer_set_surface(bm); - - /* render the content into temporary surface */ - thumbnail_redraw(content, cwidth, cheight, &ctx); - - framebuffer_set_surface(current); - - loc.x0 = 0; - loc.y0 = 0; - loc.x1 = width; - loc.y1 = height; - - nsfb_plot_copy(bm, NULL, tbm, &loc); - - nsfb_free(bm); - - return true; -} From 4e7dcde2b056c16a96dde6adcadb29a65ca72fde Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 10:54:32 +0100 Subject: [PATCH 07/13] Update monkey to use bitmap render API --- monkey/Makefile.target | 5 ++--- monkey/bitmap.c | 9 +++++++++ monkey/thumbnail.c | 30 ------------------------------ 3 files changed, 11 insertions(+), 33 deletions(-) delete mode 100644 monkey/thumbnail.c diff --git a/monkey/Makefile.target b/monkey/Makefile.target index cb7bf1717..4f73ad068 100644 --- a/monkey/Makefile.target +++ b/monkey/Makefile.target @@ -57,9 +57,8 @@ endif # ---------------------------------------------------------------------------- # S_MONKEY are sources purely for the MONKEY build -S_MONKEY := main.c utils.c filetype.c schedule.c \ - bitmap.c plot.c browser.c download.c thumbnail.c \ - 401login.c cert.c font.c poll.c dispatch.c fetch.c +S_MONKEY := main.c utils.c filetype.c schedule.c bitmap.c plot.c browser.c \ + download.c 401login.c cert.c font.c poll.c dispatch.c fetch.c S_MONKEY := $(addprefix monkey/,$(S_MONKEY)) diff --git a/monkey/bitmap.c b/monkey/bitmap.c index 16c98b594..5605073ba 100644 --- a/monkey/bitmap.c +++ b/monkey/bitmap.c @@ -20,6 +20,7 @@ #include #include +#include "utils/errors.h" #include "image/bitmap.h" #include "monkey/bitmap.h" @@ -123,6 +124,13 @@ static int bitmap_get_height(void *bitmap) return bmap->height; } +static nserror bitmap_render(struct bitmap *bitmap, + struct hlcache_handle *content) +{ + fprintf(stdout, "GENERIC BITMAP RENDER\n"); + return NSERROR_OK; +} + static struct gui_bitmap_table bitmap_table = { .create = bitmap_create, .destroy = bitmap_destroy, @@ -136,6 +144,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *monkey_bitmap_table = &bitmap_table; diff --git a/monkey/thumbnail.c b/monkey/thumbnail.c deleted file mode 100644 index b49944b12..000000000 --- a/monkey/thumbnail.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2011 Daniel Silverstone - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "desktop/thumbnail.h" -#include "content/hlcache.h" - -#include "monkey/browser.h" - -bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap) -{ - fprintf(stdout, "GENERIC THUMBNAIL\n"); - return false; -} From 124de5775a3a469d797a805ebe1f97312f7e1a0c Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 11:56:19 +0100 Subject: [PATCH 08/13] Update amiga to use bitmap render API --- amiga/Makefile.target | 2 +- amiga/bitmap.c | 78 +++++++++++++++++++++++++++- amiga/icon.c | 6 +-- amiga/thumbnail.c | 117 ------------------------------------------ 4 files changed, 81 insertions(+), 122 deletions(-) delete mode 100755 amiga/thumbnail.c diff --git a/amiga/Makefile.target b/amiga/Makefile.target index 5c7bc3b45..4f9efb56b 100644 --- a/amiga/Makefile.target +++ b/amiga/Makefile.target @@ -68,7 +68,7 @@ MESSAGES_FILTER=ami # S_AMIGA are sources purely for the Amiga build S_AMIGA := gui.c tree.c history.c hotlist.c schedule.c file.c \ - thumbnail.c misc.c bitmap.c font.c filetype.c utf8.c login.c \ + misc.c bitmap.c font.c filetype.c utf8.c login.c \ plotters.c object.c menu.c save_pdf.c arexx.c version.c \ cookies.c context_menu.c clipboard.c help.c font_scan.c \ launch.c search.c history_local.c download.c iff_dr2d.c \ diff --git a/amiga/bitmap.c b/amiga/bitmap.c index 67e7b15ea..bb47ae321 100644 --- a/amiga/bitmap.c +++ b/amiga/bitmap.c @@ -24,14 +24,15 @@ #include #endif #include -#include "utils/nsoption.h" #include #include #include #include #include +#include #include "assert.h" +#include "utils/nsoption.h" #include "utils/messages.h" #include "desktop/mouse.h" #include "desktop/gui_window.h" @@ -505,6 +506,80 @@ struct BitMap *ami_bitmap_get_native(struct bitmap *bitmap, } } +static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle *content) +{ + struct BitScaleArgs bsa; + int plot_width; + int plot_height; + int redraw_tile_size = nsoption_int(redraw_tile_size_x); + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &amiplot + }; + + if(nsoption_int(redraw_tile_size_y) < nsoption_int(redraw_tile_size_x)) + redraw_tile_size = nsoption_int(redraw_tile_size_y); + + plot_width = MIN(content_get_width(content), redraw_tile_size); + plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) / + bitmap->width; + + bitmap->nativebm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32, + BMF_CLEAR, browserglob.bm, RGBFB_A8R8G8B8); + + bitmap->nativebmwidth = bitmap->width; + bitmap->nativebmheight = bitmap->height; + ami_clearclipreg(&browserglob); + + content_scaled_redraw(content, plot_width, plot_height, &ctx); + +#ifdef __amigaos4__ + if(__builtin_expect(GfxBase->LibNode.lib_Version >= 53, 1)) { + /* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) */ + float resample_scale = bitmap->width / (float)plot_width; + uint32 flags = COMPFLAG_IgnoreDestAlpha; + if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter; + + CompositeTags(COMPOSITE_Src,browserglob.bm,bitmap->nativebm, + COMPTAG_ScaleX, + COMP_FLOAT_TO_FIX(resample_scale), + COMPTAG_ScaleY, + COMP_FLOAT_TO_FIX(resample_scale), + COMPTAG_Flags,flags, + COMPTAG_DestX,0, + COMPTAG_DestY,0, + COMPTAG_DestWidth,bitmap->width, + COMPTAG_DestHeight,bitmap->height, + COMPTAG_OffsetX,0, + COMPTAG_OffsetY,0, + COMPTAG_FriendBitMap, scrn->RastPort.BitMap, + TAG_DONE); + } else +#endif + { + bsa.bsa_SrcX = 0; + bsa.bsa_SrcY = 0; + bsa.bsa_SrcWidth = plot_width; + bsa.bsa_SrcHeight = plot_height; + bsa.bsa_DestX = 0; + bsa.bsa_DestY = 0; + // bsa.bsa_DestWidth = width; + // bsa.bsa_DestHeight = height; + bsa.bsa_XSrcFactor = plot_width; + bsa.bsa_XDestFactor = bitmap->width; + bsa.bsa_YSrcFactor = plot_height; + bsa.bsa_YDestFactor = bitmap->height; + bsa.bsa_SrcBitMap = browserglob.bm; + bsa.bsa_DestBitMap = bitmap->nativebm; + bsa.bsa_Flags = 0; + + BitMapScale(&bsa); + } + + return true; +} + static struct gui_bitmap_table bitmap_table = { .create = amiga_bitmap_create, .destroy = amiga_bitmap_destroy, @@ -518,6 +593,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = amiga_bitmap_save, .modified = amiga_bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *amiga_bitmap_table = &bitmap_table; diff --git a/amiga/icon.c b/amiga/icon.c index 042e1a826..fd39fddde 100644 --- a/amiga/icon.c +++ b/amiga/icon.c @@ -37,13 +37,13 @@ #endif #include -#include "desktop/plotters.h" -#include "image/bitmap.h" -#include "content/content_protected.h" #include "utils/log.h" #include "utils/messages.h" #include "utils/utils.h" #include "utils/file.h" +#include "desktop/plotters.h" +#include "image/bitmap.h" +#include "content/content_protected.h" #include "amiga/os3support.h" #include "amiga/bitmap.h" diff --git a/amiga/thumbnail.c b/amiga/thumbnail.c deleted file mode 100755 index 04417bbe8..000000000 --- a/amiga/thumbnail.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2008,2009 Chris Young - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "amiga/os3support.h" - -#include -#include -#ifdef __amigaos4__ -#include -#include -#endif -#include - -#include - -#include "amiga/os3support.h" -#include "desktop/browser.h" -#include "utils/nsoption.h" -#include "content/urldb.h" -#include "desktop/plotters.h" -#include "desktop/thumbnail.h" -#include "desktop/mouse.h" -#include "desktop/gui_window.h" - -#include "amiga/gui.h" -#include "amiga/bitmap.h" -#include "amiga/rtg.h" - -bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap) -{ - struct BitScaleArgs bsa; - int plot_width; - int plot_height; - int redraw_tile_size = nsoption_int(redraw_tile_size_x); - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &amiplot - }; - - if(nsoption_int(redraw_tile_size_y) < nsoption_int(redraw_tile_size_x)) - redraw_tile_size = nsoption_int(redraw_tile_size_y); - - plot_width = MIN(content_get_width(content), redraw_tile_size); - plot_height = ((plot_width * bitmap->height) + (bitmap->width / 2)) / - bitmap->width; - - bitmap->nativebm = ami_rtg_allocbitmap(bitmap->width, bitmap->height, 32, - BMF_CLEAR, browserglob.bm, RGBFB_A8R8G8B8); - - bitmap->nativebmwidth = bitmap->width; - bitmap->nativebmheight = bitmap->height; - ami_clearclipreg(&browserglob); - - thumbnail_redraw(content, plot_width, plot_height, &ctx); - -#ifdef __amigaos4__ - if(__builtin_expect(GfxBase->LibNode.lib_Version >= 53, 1)) { - /* AutoDoc says v52, but this function isn't in OS4.0, so checking for v53 (OS4.1) */ - float resample_scale = bitmap->width / (float)plot_width; - uint32 flags = COMPFLAG_IgnoreDestAlpha; - if(nsoption_bool(scale_quality)) flags |= COMPFLAG_SrcFilter; - - CompositeTags(COMPOSITE_Src,browserglob.bm,bitmap->nativebm, - COMPTAG_ScaleX, - COMP_FLOAT_TO_FIX(resample_scale), - COMPTAG_ScaleY, - COMP_FLOAT_TO_FIX(resample_scale), - COMPTAG_Flags,flags, - COMPTAG_DestX,0, - COMPTAG_DestY,0, - COMPTAG_DestWidth,bitmap->width, - COMPTAG_DestHeight,bitmap->height, - COMPTAG_OffsetX,0, - COMPTAG_OffsetY,0, - COMPTAG_FriendBitMap, scrn->RastPort.BitMap, - TAG_DONE); - } else -#endif - { - bsa.bsa_SrcX = 0; - bsa.bsa_SrcY = 0; - bsa.bsa_SrcWidth = plot_width; - bsa.bsa_SrcHeight = plot_height; - bsa.bsa_DestX = 0; - bsa.bsa_DestY = 0; - // bsa.bsa_DestWidth = width; - // bsa.bsa_DestHeight = height; - bsa.bsa_XSrcFactor = plot_width; - bsa.bsa_XDestFactor = bitmap->width; - bsa.bsa_YSrcFactor = plot_height; - bsa.bsa_YDestFactor = bitmap->height; - bsa.bsa_SrcBitMap = browserglob.bm; - bsa.bsa_DestBitMap = bitmap->nativebm; - bsa.bsa_Flags = 0; - - BitMapScale(&bsa); - } - - return true; -} - From 818b8276df618bd9dbc32e915e58a69e55d95801 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 13:28:20 +0100 Subject: [PATCH 09/13] Convert atari to bitmap render interface --- atari/Makefile.target | 1 - atari/bitmap.c | 6 ++++++ atari/plot/plot.c | 2 +- atari/thumbnail.c | 24 ------------------------ 4 files changed, 7 insertions(+), 26 deletions(-) delete mode 100755 atari/thumbnail.c diff --git a/atari/Makefile.target b/atari/Makefile.target index 2b488e5c2..34be8a915 100644 --- a/atari/Makefile.target +++ b/atari/Makefile.target @@ -100,7 +100,6 @@ S_ATARI := \ statusbar.c \ settings.c \ toolbar.c \ - thumbnail.c \ treeview.c \ plot/plot.c \ plot/fontplot.c \ diff --git a/atari/bitmap.c b/atari/bitmap.c index 72e5a20e5..431d97dc8 100755 --- a/atari/bitmap.c +++ b/atari/bitmap.c @@ -426,6 +426,11 @@ bool atari_bitmap_resize(struct bitmap *img, HermesHandle hermes_h, return(true); } +static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) +{ + return NSERROR_NOT_IMPLEMENTED; +} + static struct gui_bitmap_table bitmap_table = { .create = atari_bitmap_create, .destroy = atari_bitmap_destroy, @@ -439,6 +444,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *atari_bitmap_table = &bitmap_table; diff --git a/atari/plot/plot.c b/atari/plot/plot.c index 583429ace..ac998a4d5 100755 --- a/atari/plot/plot.c +++ b/atari/plot/plot.c @@ -25,10 +25,10 @@ #include #include -#include "image/bitmap.h" #include "utils/log.h" #include "utils/utf8.h" #include "utils/utils.h" +#include "image/bitmap.h" #include "desktop/plotters.h" #include "desktop/mouse.h" diff --git a/atari/thumbnail.c b/atari/thumbnail.c deleted file mode 100755 index 75656ec19..000000000 --- a/atari/thumbnail.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2010 Ole Loots - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "desktop/thumbnail.h" - -bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap) -{ - return false; -} From 217aa3adc121e55d996d0ab9669cba71fe0b7a40 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 13:52:39 +0100 Subject: [PATCH 10/13] Convert beos to bitmap render API --- beos/Makefile.target | 3 +- beos/bitmap.cpp | 463 ++++++++++++++++++++++++++++--------------- beos/thumbnail.cpp | 163 --------------- 3 files changed, 299 insertions(+), 330 deletions(-) delete mode 100644 beos/thumbnail.cpp diff --git a/beos/Makefile.target b/beos/Makefile.target index 8b41a96b7..0c8838555 100644 --- a/beos/Makefile.target +++ b/beos/Makefile.target @@ -95,8 +95,7 @@ endif # S_BEOS are sources purely for the BeOS build S_BEOS := about.cpp bitmap.cpp download.cpp fetch_rsrc.cpp filetype.cpp \ font.cpp gui.cpp login.cpp gui_options.cpp plotters.cpp \ - scaffolding.cpp search.cpp schedule.cpp thumbnail.cpp \ - throbber.cpp window.cpp + scaffolding.cpp search.cpp schedule.cpp throbber.cpp window.cpp S_BEOS := $(addprefix beos/,$(S_BEOS)) RDEF_BEOS := res.rdef diff --git a/beos/bitmap.cpp b/beos/bitmap.cpp index 9a4ee521b..2ed73a4c1 100644 --- a/beos/bitmap.cpp +++ b/beos/bitmap.cpp @@ -16,15 +16,16 @@ * along with this program. If not, see . */ -/** \file - * Generic bitmap handling (BeOS implementation). +/** + * \file + * BeOS implementation of generic bitmaps. * - * This implements the interface given by desktop/bitmap.h using BBitmap. + * This implements the interface given by image/bitmap.h using BBitmap. */ #define __STDBOOL_H__ 1 -//#include #include +#include #include #include #include @@ -32,22 +33,31 @@ #include #include #include +#include + extern "C" { -#include "content/content.h" -#include "image/bitmap.h" #include "utils/log.h" +#include "content/content.h" +#include "content/urldb.h" +#include "desktop/plotters.h" +#include "desktop/browser.h" +#include "desktop/font.h" +#include "image/bitmap.h" } + #include "beos/bitmap.h" #include "beos/gui.h" #include "beos/scaffolding.h" +#include "beos/plotters.h" + struct bitmap { - BBitmap *primary; - BBitmap *shadow; // in NetSurf's ABGR order - BBitmap *pretile_x; - BBitmap *pretile_y; - BBitmap *pretile_xy; - bool opaque; + BBitmap *primary; + BBitmap *shadow; // in NetSurf's ABGR order + BBitmap *pretile_x; + BBitmap *pretile_y; + BBitmap *pretile_xy; + bool opaque; }; #define MIN_PRETILE_WIDTH 256 @@ -64,7 +74,7 @@ struct bitmap { * * \param src Source 32-bit pixels arranged in ABGR order. * \param dst Output data in BGRA order. - * \param width Width of the bitmap + * \param width Width of the bitmap * \param height Height of the bitmap * \param rowstride Number of bytes to skip after each row (this implementation * requires this to be a multiple of 4.) @@ -75,28 +85,28 @@ static inline void nsbeos_rgba_to_bgra(void *src, int height, size_t rowstride) { - struct abgr { uint8 a, b, g, r; }; - struct rgba { uint8 r, g, b ,a; }; - struct bgra { uint8 b, g, r, a; }; - struct rgba *from = (struct rgba *)src; - struct bgra *to = (struct bgra *)dst; + struct abgr { uint8 a, b, g, r; }; + struct rgba { uint8 r, g, b ,a; }; + struct bgra { uint8 b, g, r, a; }; + struct rgba *from = (struct rgba *)src; + struct bgra *to = (struct bgra *)dst; - rowstride >>= 2; + rowstride >>= 2; - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - to[x].b = from[x].b; - to[x].g = from[x].g; - to[x].r = from[x].r; - to[x].a = from[x].a; - /* - if (from[x].a == 0) - *(rgb_color *)&to[x] = B_TRANSPARENT_32_BIT; - */ - } - from += rowstride; - to += rowstride; - } + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + to[x].b = from[x].b; + to[x].g = from[x].g; + to[x].r = from[x].r; + to[x].a = from[x].a; + /* + if (from[x].a == 0) + *(rgb_color *)&to[x] = B_TRANSPARENT_32_BIT; + */ + } + from += rowstride; + to += rowstride; + } } @@ -108,27 +118,26 @@ static inline void nsbeos_rgba_to_bgra(void *src, * \param state a flag word indicating the initial state * \return an opaque struct bitmap, or NULL on memory exhaustion */ - void *bitmap_create(int width, int height, unsigned int state) { - struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap)); - if (bmp == NULL) - return NULL; + struct bitmap *bmp = (struct bitmap *)malloc(sizeof(struct bitmap)); + if (bmp == NULL) + return NULL; - int32 flags = 0; - if (state & BITMAP_CLEAR_MEMORY) - flags |= B_BITMAP_CLEAR_TO_WHITE; + int32 flags = 0; + if (state & BITMAP_CLEAR_MEMORY) + flags |= B_BITMAP_CLEAR_TO_WHITE; - BRect frame(0, 0, width - 1, height - 1); - //XXX: bytes per row ? - bmp->primary = new BBitmap(frame, flags, B_RGBA32); - bmp->shadow = new BBitmap(frame, flags, B_RGBA32); + BRect frame(0, 0, width - 1, height - 1); + //XXX: bytes per row ? + bmp->primary = new BBitmap(frame, flags, B_RGBA32); + bmp->shadow = new BBitmap(frame, flags, B_RGBA32); - bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL; + bmp->pretile_x = bmp->pretile_y = bmp->pretile_xy = NULL; - bmp->opaque = (state & BITMAP_OPAQUE) != 0; + bmp->opaque = (state & BITMAP_OPAQUE) != 0; - return bmp; + return bmp; } @@ -140,9 +149,9 @@ void *bitmap_create(int width, int height, unsigned int state) */ void bitmap_set_opaque(void *vbitmap, bool opaque) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - bitmap->opaque = opaque; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + bitmap->opaque = opaque; } @@ -154,10 +163,10 @@ void bitmap_set_opaque(void *vbitmap, bool opaque) */ bool bitmap_test_opaque(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); -/* todo: test if bitmap is opaque */ - return false; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + /* todo: test if bitmap is opaque */ + return false; } @@ -168,9 +177,9 @@ bool bitmap_test_opaque(void *vbitmap) */ bool bitmap_get_opaque(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - return bitmap->opaque; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + return bitmap->opaque; } @@ -186,9 +195,9 @@ bool bitmap_get_opaque(void *vbitmap) unsigned char *bitmap_get_buffer(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - return (unsigned char *)(bitmap->shadow->Bits()); + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + return (unsigned char *)(bitmap->shadow->Bits()); } @@ -198,12 +207,11 @@ unsigned char *bitmap_get_buffer(void *vbitmap) * \param vbitmap a bitmap, as returned by bitmap_create() * \return width of a pixel row in the bitmap */ - size_t bitmap_get_rowstride(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - return (bitmap->primary->BytesPerRow()); + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + return (bitmap->primary->BytesPerRow()); } @@ -213,39 +221,42 @@ size_t bitmap_get_rowstride(void *vbitmap) * \param vbitmap a bitmap, as returned by bitmap_create() * \return bytes per pixels of the bitmap */ - size_t bitmap_get_bpp(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - return 4; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + return 4; } -static void -nsbeos_bitmap_free_pretiles(struct bitmap *bitmap) +/** + * Free pretiles of a bitmap. + * + * \param bitmap The bitmap to free the pretiles of. + */ +static void nsbeos_bitmap_free_pretiles(struct bitmap *bitmap) { #define FREE_TILE(XY) if (bitmap->pretile_##XY) delete (bitmap->pretile_##XY); bitmap->pretile_##XY = NULL - FREE_TILE(x); - FREE_TILE(y); - FREE_TILE(xy); + FREE_TILE(x); + FREE_TILE(y); + FREE_TILE(xy); #undef FREE_TILE } + /** * Free a bitmap. * * \param vbitmap a bitmap, as returned by bitmap_create() */ - void bitmap_destroy(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - assert(bitmap); - nsbeos_bitmap_free_pretiles(bitmap); - delete bitmap->primary; - delete bitmap->shadow; - free(bitmap); + struct bitmap *bitmap = (struct bitmap *)vbitmap; + assert(bitmap); + nsbeos_bitmap_free_pretiles(bitmap); + delete bitmap->primary; + delete bitmap->shadow; + free(bitmap); } @@ -257,22 +268,21 @@ void bitmap_destroy(void *vbitmap) * \param flags modify the behaviour of the save * \return true on success, false on error and error reported */ - bool bitmap_save(void *vbitmap, const char *path, unsigned flags) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - BTranslatorRoster *roster = BTranslatorRoster::Default(); - BBitmapStream stream(bitmap->primary); - BFile file(path, B_WRITE_ONLY | B_CREATE_FILE); - uint32 type = B_PNG_FORMAT; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + BTranslatorRoster *roster = BTranslatorRoster::Default(); + BBitmapStream stream(bitmap->primary); + BFile file(path, B_WRITE_ONLY | B_CREATE_FILE); + uint32 type = B_PNG_FORMAT; - if (file.InitCheck() < B_OK) - return false; + if (file.InitCheck() < B_OK) + return false; - if (roster->Translate(&stream, NULL, NULL, &file, type) < B_OK) - return false; + if (roster->Translate(&stream, NULL, NULL, &file, type) < B_OK) + return false; - return true; + return true; } @@ -283,63 +293,67 @@ bool bitmap_save(void *vbitmap, const char *path, unsigned flags) */ void bitmap_modified(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - // convert the shadow (ABGR) to into the primary bitmap - nsbeos_rgba_to_bgra(bitmap->shadow->Bits(), bitmap->primary->Bits(), - bitmap->primary->Bounds().Width() + 1, - bitmap->primary->Bounds().Height() + 1, - bitmap->primary->BytesPerRow()); - nsbeos_bitmap_free_pretiles(bitmap); + struct bitmap *bitmap = (struct bitmap *)vbitmap; + // convert the shadow (ABGR) to into the primary bitmap + nsbeos_rgba_to_bgra(bitmap->shadow->Bits(), bitmap->primary->Bits(), + bitmap->primary->Bounds().Width() + 1, + bitmap->primary->Bounds().Height() + 1, + bitmap->primary->BytesPerRow()); + nsbeos_bitmap_free_pretiles(bitmap); } + int bitmap_get_width(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - return bitmap->primary->Bounds().Width() + 1; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + return bitmap->primary->Bounds().Width() + 1; } + int bitmap_get_height(void *vbitmap) { - struct bitmap *bitmap = (struct bitmap *)vbitmap; - return bitmap->primary->Bounds().Height() + 1; + struct bitmap *bitmap = (struct bitmap *)vbitmap; + return bitmap->primary->Bounds().Height() + 1; } + static BBitmap * nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y) { - int width = primary->Bounds().Width() + 1; - int height = primary->Bounds().Height() + 1; - size_t primary_stride = primary->BytesPerRow(); - BRect frame(0, 0, width * repeat_x - 1, height * repeat_y - 1); - BBitmap *result = new BBitmap(frame, 0, B_RGBA32); + int width = primary->Bounds().Width() + 1; + int height = primary->Bounds().Height() + 1; + size_t primary_stride = primary->BytesPerRow(); + BRect frame(0, 0, width * repeat_x - 1, height * repeat_y - 1); + BBitmap *result = new BBitmap(frame, 0, B_RGBA32); - char *target_buffer = (char *)result->Bits(); - int x,y,row; - /* This algorithm won't work if the strides are not multiples */ - assert((size_t)(result->BytesPerRow()) == - (primary_stride * repeat_x)); + char *target_buffer = (char *)result->Bits(); + int x,y,row; + /* This algorithm won't work if the strides are not multiples */ + assert((size_t)(result->BytesPerRow()) == + (primary_stride * repeat_x)); - if (repeat_x == 1 && repeat_y == 1) { - delete result; - // just return a copy - return new BBitmap(primary); - } + if (repeat_x == 1 && repeat_y == 1) { + delete result; + // just return a copy + return new BBitmap(primary); + } - for (y = 0; y < repeat_y; ++y) { - char *primary_buffer = (char *)primary->Bits(); - 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; + for (y = 0; y < repeat_y; ++y) { + char *primary_buffer = (char *)primary->Bits(); + 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. * @@ -348,9 +362,10 @@ nsbeos_bitmap_generate_pretile(BBitmap *primary, int repeat_x, int repeat_y) BBitmap * nsbeos_bitmap_get_primary(struct bitmap* bitmap) { - return bitmap->primary; + return bitmap->primary; } + /** * The X-pretiled image associated with this bitmap object. * @@ -359,16 +374,17 @@ nsbeos_bitmap_get_primary(struct bitmap* bitmap) BBitmap * nsbeos_bitmap_get_pretile_x(struct bitmap* bitmap) { - if (!bitmap->pretile_x) { - int width = bitmap->primary->Bounds().Width() + 1; - int xmult = (MIN_PRETILE_WIDTH + width - 1)/width; - LOG(("Pretiling %p for X*%d", bitmap, xmult)); - bitmap->pretile_x = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, 1); - } - return bitmap->pretile_x; + if (!bitmap->pretile_x) { + int width = bitmap->primary->Bounds().Width() + 1; + int xmult = (MIN_PRETILE_WIDTH + width - 1)/width; + LOG(("Pretiling %p for X*%d", bitmap, xmult)); + bitmap->pretile_x = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, 1); + } + return bitmap->pretile_x; } + /** * The Y-pretiled image associated with this bitmap object. * @@ -377,15 +393,16 @@ nsbeos_bitmap_get_pretile_x(struct bitmap* bitmap) BBitmap * nsbeos_bitmap_get_pretile_y(struct bitmap* bitmap) { - if (!bitmap->pretile_y) { - int height = bitmap->primary->Bounds().Height() + 1; - int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height; - LOG(("Pretiling %p for Y*%d", bitmap, ymult)); - bitmap->pretile_y = nsbeos_bitmap_generate_pretile(bitmap->primary, 1, ymult); - } - return bitmap->pretile_y; + if (!bitmap->pretile_y) { + int height = bitmap->primary->Bounds().Height() + 1; + int ymult = (MIN_PRETILE_HEIGHT + height - 1)/height; + LOG(("Pretiling %p for Y*%d", bitmap, ymult)); + bitmap->pretile_y = nsbeos_bitmap_generate_pretile(bitmap->primary, 1, ymult); + } + return bitmap->pretile_y; } + /** * The XY-pretiled image associated with this bitmap object. * @@ -394,30 +411,146 @@ nsbeos_bitmap_get_pretile_y(struct bitmap* bitmap) BBitmap * nsbeos_bitmap_get_pretile_xy(struct bitmap* bitmap) { - if (!bitmap->pretile_xy) { - int width = bitmap->primary->Bounds().Width() + 1; - int height = bitmap->primary->Bounds().Height() + 1; - 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 = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, ymult); - } - return bitmap->pretile_xy; + if (!bitmap->pretile_xy) { + int width = bitmap->primary->Bounds().Width() + 1; + int height = bitmap->primary->Bounds().Height() + 1; + 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 = nsbeos_bitmap_generate_pretile(bitmap->primary, xmult, ymult); + } + return bitmap->pretile_xy; } + +/** + * Create a thumbnail of a page. + * + * \param bitmap the bitmap to draw to + * \param content content structure to thumbnail + * \return true on success and bitmap updated else false + */ +static nserror bitmap_render(struct bitmap *bitmap, hlcache_handle *content) +{ + BBitmap *thumbnail; + BBitmap *small; + BBitmap *big; + BView *oldView; + BView *view; + BView *thumbView; + float width; + float height; + int big_width; + int big_height; + int depth; + + struct redraw_context ctx; + ctx.interactive = false; + ctx.background_images = true; + ctx.plot = &nsbeos_plotters; + + assert(content); + assert(bitmap); + + thumbnail = nsbeos_bitmap_get_primary(bitmap); + width = thumbnail->Bounds().Width(); + height = thumbnail->Bounds().Height(); + depth = 32; + + big_width = MIN(content_get_width(content), 1024); + big_height = (int)(((big_width * height) + (width / 2)) / width); + + BRect contentRect(0, 0, big_width - 1, big_height - 1); + big = new BBitmap(contentRect, B_BITMAP_ACCEPTS_VIEWS, B_RGB32); + + if (big->InitCheck() < B_OK) { + delete big; + return NSERROR_NOMEM; + } + + small = new BBitmap(thumbnail->Bounds(), + B_BITMAP_ACCEPTS_VIEWS, B_RGB32); + + if (small->InitCheck() < B_OK) { + delete small; + delete big; + return NSERROR_NOMEM; + } + + //XXX: _lock ? + // backup the current gc + oldView = nsbeos_current_gc(); + + view = new BView(contentRect, "thumbnailer", + B_FOLLOW_NONE, B_WILL_DRAW); + big->AddChild(view); + + thumbView = new BView(small->Bounds(), "thumbnail", + B_FOLLOW_NONE, B_WILL_DRAW); + small->AddChild(thumbView); + + view->LockLooper(); + + /* impose our view on the content... */ + nsbeos_current_gc_set(view); + + /* render the content */ + content_scaled_redraw(content, big_width, big_height, &ctx); + + view->Sync(); + view->UnlockLooper(); + + // restore the current gc + nsbeos_current_gc_set(oldView); + + + // now scale it down + //XXX: use Zeta's bilinear scaler ? + //#ifdef B_ZETA_VERSION + // err = ScaleBitmap(*shot, *scaledBmp); + //#else + thumbView->LockLooper(); + thumbView->DrawBitmap(big, big->Bounds(), small->Bounds()); + thumbView->Sync(); + thumbView->UnlockLooper(); + + small->LockBits(); + thumbnail->LockBits(); + + // copy it to the bitmap + memcpy(thumbnail->Bits(), small->Bits(), thumbnail->BitsLength()); + + thumbnail->UnlockBits(); + small->UnlockBits(); + + bitmap_modified(bitmap); + + // cleanup + small->RemoveChild(thumbView); + delete thumbView; + delete small; + big->RemoveChild(view); + delete view; + delete big; + + return NSERROR_OK; +} + + static struct gui_bitmap_table bitmap_table = { - .create = bitmap_create, - .destroy = bitmap_destroy, - .set_opaque = bitmap_set_opaque, - .get_opaque = bitmap_get_opaque, - .test_opaque = bitmap_test_opaque, - .get_buffer = bitmap_get_buffer, - .get_rowstride = bitmap_get_rowstride, - .get_width = bitmap_get_width, - .get_height = bitmap_get_height, - .get_bpp = bitmap_get_bpp, - .save = bitmap_save, - .modified = bitmap_modified, + .create = bitmap_create, + .destroy = bitmap_destroy, + .set_opaque = bitmap_set_opaque, + .get_opaque = bitmap_get_opaque, + .test_opaque = bitmap_test_opaque, + .get_buffer = bitmap_get_buffer, + .get_rowstride = bitmap_get_rowstride, + .get_width = bitmap_get_width, + .get_height = bitmap_get_height, + .get_bpp = bitmap_get_bpp, + .save = bitmap_save, + .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *beos_bitmap_table = &bitmap_table; diff --git a/beos/thumbnail.cpp b/beos/thumbnail.cpp deleted file mode 100644 index 80944a52b..000000000 --- a/beos/thumbnail.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright 2008 François Revol - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Page thumbnail creation (implementation). - * - * Thumbnails are created by setting the current drawing contexts to a BView - * attached to the BBitmap we are passed, and plotting the page at a small - * scale. - */ - -#define __STDBOOL_H__ 1 -#include -#include -#include -#include -extern "C" { -#include "content/content.h" -#include "content/urldb.h" -#include "desktop/plotters.h" -#include "desktop/browser.h" -#include "desktop/thumbnail.h" -#include "image/bitmap.h" -#include "desktop/font.h" -#include "utils/log.h" -} -#include "beos/scaffolding.h" -#include "beos/plotters.h" -#include "beos/bitmap.h" - -// Zeta PRIVATE: in libzeta for now. -extern status_t ScaleBitmap(const BBitmap& inBitmap, BBitmap& outBitmap); - -#warning XXX do we need to set bitmap:shadow ? - - -/** - * Create a thumbnail of a page. - * - * \param content content structure to thumbnail - * \param bitmap the bitmap to draw to - * \return true on success and bitmap updated else false - */ -bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap) -{ - BBitmap *thumbnail; - BBitmap *small; - BBitmap *big; - BView *oldView; - BView *view; - BView *thumbView; - float width; - float height; - int big_width; - int big_height; - int depth; - - struct redraw_context ctx; - ctx.interactive = false; - ctx.background_images = true; - ctx.plot = &nsbeos_plotters; - - assert(content); - assert(bitmap); - - thumbnail = nsbeos_bitmap_get_primary(bitmap); - width = thumbnail->Bounds().Width(); - height = thumbnail->Bounds().Height(); - depth = 32; - - big_width = MIN(content_get_width(content), 1024); - big_height = (int)(((big_width * height) + (width / 2)) / width); - - BRect contentRect(0, 0, big_width - 1, big_height - 1); - big = new BBitmap(contentRect, B_BITMAP_ACCEPTS_VIEWS, B_RGB32); - - if (big->InitCheck() < B_OK) { - delete big; - return false; - } - - small = new BBitmap(thumbnail->Bounds(), - B_BITMAP_ACCEPTS_VIEWS, B_RGB32); - - if (small->InitCheck() < B_OK) { - delete small; - delete big; - return false; - } - - //XXX: _lock ? - // backup the current gc - oldView = nsbeos_current_gc(); - - view = new BView(contentRect, "thumbnailer", - B_FOLLOW_NONE, B_WILL_DRAW); - big->AddChild(view); - - thumbView = new BView(small->Bounds(), "thumbnail", - B_FOLLOW_NONE, B_WILL_DRAW); - small->AddChild(thumbView); - - view->LockLooper(); - - /* impose our view on the content... */ - nsbeos_current_gc_set(view); - - /* render the content */ - thumbnail_redraw(content, big_width, big_height, &ctx); - - view->Sync(); - view->UnlockLooper(); - - // restore the current gc - nsbeos_current_gc_set(oldView); - - - // now scale it down -//XXX: use Zeta's bilinear scaler ? -//#ifdef B_ZETA_VERSION -// err = ScaleBitmap(*shot, *scaledBmp); -//#else - thumbView->LockLooper(); - thumbView->DrawBitmap(big, big->Bounds(), small->Bounds()); - thumbView->Sync(); - thumbView->UnlockLooper(); - - small->LockBits(); - thumbnail->LockBits(); - - // copy it to the bitmap - memcpy(thumbnail->Bits(), small->Bits(), thumbnail->BitsLength()); - - thumbnail->UnlockBits(); - small->UnlockBits(); - - bitmap_modified(bitmap); - - // cleanup - small->RemoveChild(thumbView); - delete thumbView; - delete small; - big->RemoveChild(view); - delete view; - delete big; - - return true; -} From 2df03e2d85e061ad2c787e849d4b0a19a560be32 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 15:29:10 +0100 Subject: [PATCH 11/13] Convert windows to use the bitmap render interface --- windows/Makefile.target | 2 +- windows/bitmap.c | 102 ++++++++++++++++++++++++++++++++-------- windows/thumbnail.c | 89 ----------------------------------- 3 files changed, 84 insertions(+), 109 deletions(-) delete mode 100644 windows/thumbnail.c diff --git a/windows/Makefile.target b/windows/Makefile.target index a8c3282ec..0e08356f0 100644 --- a/windows/Makefile.target +++ b/windows/Makefile.target @@ -59,7 +59,7 @@ S_RESOURCES := windows_resource.o # S_WINDOWS are sources purely for the windows build S_WINDOWS := main.c window.c gui.c drawable.c misc.c plot.c findfile.c \ font.c bitmap.c about.c prefs.c download.c filetype.c \ - localhistory.c schedule.c thumbnail.c windbg.c pointers.c + localhistory.c schedule.c windbg.c pointers.c S_WINDOWS := $(addprefix windows/,$(S_WINDOWS)) # This is the final source build list diff --git a/windows/bitmap.c b/windows/bitmap.c index f0108609e..f7505b0c4 100644 --- a/windows/bitmap.c +++ b/windows/bitmap.c @@ -17,6 +17,11 @@ * along with this program. If not, see . */ +/** + * \file + * win32 implementation of the bitmap operations. + */ + #include "utils/config.h" #include @@ -26,7 +31,9 @@ #include "utils/log.h" #include "image/bitmap.h" +#include "content/content.h" +#include "windows/plot.h" #include "windows/bitmap.h" /** @@ -50,10 +57,10 @@ void *win32_bitmap_create(int width, int height, unsigned int state) if (pbmi == NULL) { return NULL; } - pbmi->bV5Size = sizeof(BITMAPV5HEADER); - pbmi->bV5Width = width; - pbmi->bV5Height = -height; - pbmi->bV5Planes = 1; + pbmi->bV5Size = sizeof(BITMAPV5HEADER); + pbmi->bV5Width = width; + pbmi->bV5Height = -height; + pbmi->bV5Planes = 1; pbmi->bV5BitCount = 32; pbmi->bV5Compression = BI_BITFIELDS; @@ -110,7 +117,7 @@ static unsigned char *bitmap_get_buffer(void *bitmap) LOG(("NULL bitmap!")); return NULL; } - + return bm->pixdata; } @@ -157,8 +164,8 @@ void win32_bitmap_destroy(void *bitmap) /** * Save a bitmap in the platform's native format. * - * \param bitmap a bitmap, as returned by bitmap_create() - * \param path pathname for file + * \param bitmap a bitmap, as returned by bitmap_create() + * \param path pathname for file * \param flags flags controlling how the bitmap is saved. * \return true on success, false on error and error reported */ @@ -183,7 +190,7 @@ static void bitmap_modified(void *bitmap) { * \param opaque whether the bitmap should be plotted opaque */ static void bitmap_set_opaque(void *bitmap, bool opaque) -{ +{ struct bitmap *bm = bitmap; if (bitmap == NULL) { @@ -217,8 +224,8 @@ static bool bitmap_test_opaque(void *bitmap) while (tst-- > 0) { if (bm->pixdata[(tst << 2) + 3] != 0xff) { LOG(("bitmap %p has transparency",bm)); - return false; - } + return false; + } } LOG(("bitmap %p is opaque", bm)); return true; @@ -293,24 +300,24 @@ struct bitmap *bitmap_scale(struct bitmap *prescale, int width, int height) vv = (int)((i * prescale->height) / height) * prescale->width; for (ii = 0; ii < width; ii++) { retpixdata[v + ii] = inpixdata[vv + (int) - ((ii * prescale->width) / width)]; + ((ii * prescale->width) / width)]; } } return ret; - + } struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height, - bitmap_flags_t flags) + bitmap_flags_t flags) { struct bitmap *ret = malloc(sizeof(struct bitmap)); if (ret == NULL) return NULL; int i, hrepeat, vrepeat, repeat; - vrepeat = ((flags & BITMAPF_REPEAT_Y) != 0) ? - ((height + untiled->height - 1) / untiled->height) : 1; - hrepeat = ((flags & BITMAPF_REPEAT_X) != 0) ? - ((width + untiled->width - 1) / untiled->width) : 1; + vrepeat = ((flags & BITMAPF_REPEAT_Y) != 0) ? + ((height + untiled->height - 1) / untiled->height) : 1; + hrepeat = ((flags & BITMAPF_REPEAT_X) != 0) ? + ((width + untiled->width - 1) / untiled->width) : 1; width = untiled->width * hrepeat; height = untiled->height * vrepeat; uint8_t *indata = untiled->pixdata; @@ -330,7 +337,7 @@ struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height, } indata += stride; } - + /* vertical tiling */ stride = untiled->height * width * 4; newdata = ret->pixdata + stride; @@ -338,13 +345,69 @@ struct bitmap *bitmap_pretile(struct bitmap *untiled, int width, int height, for (repeat = 1; repeat < vrepeat; repeat++) { memcpy(newdata, indata, stride); - newdata += stride; + newdata += stride; } ret->width = width; ret->height = height; return ret; } +static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) +{ + int width; + int height; + HDC hdc, bufferdc, minidc; + struct bitmap *fsbitmap; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &win_plotters + }; + + width = min(content_get_width(content), 1024); + height = ((width * bitmap->height) + (bitmap->width / 2)) / + bitmap->width; + + LOG(("bitmap %p for content %p width %d, height %d", + bitmap, content, width, height)); + + /* create two memory device contexts to put the bitmaps in */ + bufferdc = CreateCompatibleDC(NULL); + if ((bufferdc == NULL)) { + return NSERROR_NOMEM; + } + + minidc = CreateCompatibleDC(NULL); + if ((minidc == NULL)) { + DeleteDC(bufferdc); + return NSERROR_NOMEM; + } + + /* create a full size bitmap and plot into it */ + fsbitmap = win32_bitmap_create(width, height, BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE); + + SelectObject(bufferdc, fsbitmap->windib); + + hdc = plot_hdc; + plot_hdc = bufferdc; + /* render the content */ + content_scaled_redraw(content, width, height, &ctx); + plot_hdc = hdc; + + /* scale bitmap bufferbm into minibm */ + SelectObject(minidc, bitmap->windib); + + bitmap->opaque = true; + + StretchBlt(minidc, 0, 0, bitmap->width, bitmap->height, bufferdc, 0, 0, width, height, SRCCOPY); + + DeleteDC(bufferdc); + DeleteDC(minidc); + win32_bitmap_destroy(fsbitmap); + + return NSERROR_OK; +} + static struct gui_bitmap_table bitmap_table = { .create = win32_bitmap_create, .destroy = win32_bitmap_destroy, @@ -358,6 +421,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *win32_bitmap_table = &bitmap_table; diff --git a/windows/thumbnail.c b/windows/thumbnail.c deleted file mode 100644 index 2cf678347..000000000 --- a/windows/thumbnail.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2009 Mark Benjamin - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "utils/config.h" - -#include - -#include "utils/log.h" -#include "desktop/browser.h" -#include "desktop/thumbnail.h" -#include "image/bitmap.h" - -#include "windows/bitmap.h" -#include "windows/gui.h" -#include "windows/plot.h" -#include "content/hlcache.h" - - -bool -thumbnail_create(hlcache_handle *content, - struct bitmap *bitmap) -{ - int width; - int height; - HDC hdc, bufferdc, minidc; - struct bitmap *fsbitmap; - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &win_plotters - }; - - width = min(content_get_width(content), 1024); - height = ((width * bitmap->height) + (bitmap->width / 2)) / - bitmap->width; - - LOG(("bitmap %p for content %p width %d, height %d", - bitmap, content, width, height)); - - /* create two memory device contexts to put the bitmaps in */ - bufferdc = CreateCompatibleDC(NULL); - if ((bufferdc == NULL)) { - return false; - } - - minidc = CreateCompatibleDC(NULL); - if ((minidc == NULL)) { - DeleteDC(bufferdc); - return false; - } - - /* create a full size bitmap and plot into it */ - fsbitmap = win32_bitmap_create(width, height, BITMAP_NEW | BITMAP_CLEAR_MEMORY | BITMAP_OPAQUE); - - SelectObject(bufferdc, fsbitmap->windib); - - hdc = plot_hdc; - plot_hdc = bufferdc; - thumbnail_redraw(content, width, height, &ctx); - plot_hdc = hdc; - - /* scale bitmap bufferbm into minibm */ - SelectObject(minidc, bitmap->windib); - - bitmap->opaque = true; - - StretchBlt(minidc, 0, 0, bitmap->width, bitmap->height, bufferdc, 0, 0, width, height, SRCCOPY); - - DeleteDC(bufferdc); - DeleteDC(minidc); - win32_bitmap_destroy(fsbitmap); - - return true; -} From 596a62e20ea45f8c78b58b32860e0254f9f0f16a Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 15:46:40 +0100 Subject: [PATCH 12/13] Convert cocoa to use bitmap render API --- cocoa/Makefile.target | 1 - cocoa/bitmap.m | 119 +++++++++++++++++++++++++++++------------- cocoa/thumbnail.m | 65 ----------------------- 3 files changed, 84 insertions(+), 101 deletions(-) delete mode 100644 cocoa/thumbnail.m diff --git a/cocoa/Makefile.target b/cocoa/Makefile.target index 144219988..19040930d 100644 --- a/cocoa/Makefile.target +++ b/cocoa/Makefile.target @@ -87,7 +87,6 @@ S_COCOA := \ plotter.m \ schedule.m \ selection.m \ - thumbnail.m \ utils.m \ ArrowBox.m \ ArrowWindow.m \ diff --git a/cocoa/bitmap.m b/cocoa/bitmap.m index 52777bc7a..39a144841 100644 --- a/cocoa/bitmap.m +++ b/cocoa/bitmap.m @@ -16,11 +16,21 @@ * along with this program. If not, see . */ +/** + * \file + * Cocoa implementation of bitmap operations. + */ + #import -#import "cocoa/bitmap.h" - +#import "desktop/browser.h" +#import "desktop/plotters.h" #import "image/bitmap.h" +#import "content/urldb.h" +#import "content/content.h" + +#import "cocoa/plotter.h" +#import "cocoa/bitmap.h" #define BITS_PER_SAMPLE (8) #define SAMPLES_PER_PIXEL (4) @@ -65,24 +75,25 @@ void bitmap_destroy(void *bitmap) CGImageRelease( image ); NSMapRemove( cache, bitmap ); } - + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; [bmp release]; } void *bitmap_create(int width, int height, unsigned int state) { - NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL - pixelsWide: width - pixelsHigh: height - bitsPerSample: BITS_PER_SAMPLE - samplesPerPixel: SAMPLES_PER_PIXEL - hasAlpha: YES - isPlanar: NO - colorSpaceName: NSDeviceRGBColorSpace - bitmapFormat: NSAlphaNonpremultipliedBitmapFormat - bytesPerRow: BYTES_PER_PIXEL * width - bitsPerPixel: BITS_PER_PIXEL]; + NSBitmapImageRep *bmp = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: width + pixelsHigh: height + bitsPerSample: BITS_PER_SAMPLE + samplesPerPixel: SAMPLES_PER_PIXEL + hasAlpha: YES + isPlanar: NO + colorSpaceName: NSDeviceRGBColorSpace + bitmapFormat: NSAlphaNonpremultipliedBitmapFormat + bytesPerRow: BYTES_PER_PIXEL * width + bitsPerPixel: BITS_PER_PIXEL]; return bmp; } @@ -118,12 +129,12 @@ size_t bitmap_get_bpp(void *bitmap) bool bitmap_test_opaque(void *bitmap) { NSCParameterAssert( bitmap_get_bpp( bitmap ) == BYTES_PER_PIXEL ); - + unsigned char *buf = bitmap_get_buffer( bitmap ); - + const size_t height = bitmap_get_height( bitmap ); const size_t width = bitmap_get_width( bitmap ); - + const size_t line_step = bitmap_get_rowstride( bitmap ) - BYTES_PER_PIXEL * width; for (size_t y = 0; y < height; y++) { @@ -133,7 +144,7 @@ bool bitmap_test_opaque(void *bitmap) } buf += line_step; } - + return true; } @@ -141,7 +152,7 @@ bool bitmap_save(void *bitmap, const char *path, unsigned flags) { NSCParameterAssert( NULL != bitmap ); NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; - + NSData *tiff = [bmp TIFFRepresentation]; return [tiff writeToFile: [NSString stringWithUTF8String: path] atomically: YES]; } @@ -165,7 +176,7 @@ CGImageRef cocoa_get_cgimage( void *bitmap ) result = cocoa_prepare_bitmap( bitmap ); NSMapInsertKnownAbsent( cache, bitmap, result ); } - + return result; } @@ -181,40 +192,77 @@ static inline NSMapTable *cocoa_get_bitmap_cache( void ) static CGImageRef cocoa_prepare_bitmap( void *bitmap ) { NSCParameterAssert( NULL != bitmap ); - + NSBitmapImageRep *bmp = (NSBitmapImageRep *)bitmap; - + size_t w = [bmp pixelsWide]; size_t h = [bmp pixelsHigh]; - + CGImageRef original = [bmp CGImage]; - + if (h <= 1) return CGImageRetain( original ); - + void *data = malloc( 4 * w * h ); - + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE, - BYTES_PER_PIXEL * w, colorSpace, - [bmp isOpaque] ? kCGImageAlphaNoneSkipLast - : kCGImageAlphaPremultipliedLast ); + CGContextRef context = CGBitmapContextCreate( data, w, h, BITS_PER_SAMPLE, + BYTES_PER_PIXEL * w, colorSpace, + [bmp isOpaque] ? kCGImageAlphaNoneSkipLast + : kCGImageAlphaPremultipliedLast ); CGColorSpaceRelease( colorSpace ); - + CGContextTranslateCTM( context, 0.0, h ); CGContextScaleCTM( context, 1.0, -1.0 ); - + CGRect rect = CGRectMake( 0, 0, w, h ); CGContextClearRect( context, rect ); CGContextDrawImage( context, rect, original ); - + CGImageRef result = CGBitmapContextCreateImage( context ); - + CGContextRelease( context ); free( data ); - + return result; } +static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) +{ + int bwidth = bitmap_get_width( bitmap ); + int bheight = bitmap_get_height( bitmap ); + + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &cocoa_plotters + }; + + CGColorSpaceRef cspace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ); + CGContextRef bitmapContext = CGBitmapContextCreate( bitmap_get_buffer( bitmap ), + bwidth, bheight, + bitmap_get_bpp( bitmap ) * 8 / 4, + bitmap_get_rowstride( bitmap ), + cspace, kCGImageAlphaNoneSkipLast ); + CGColorSpaceRelease( cspace ); + + size_t width = MIN( content_get_width( content ), 1024 ); + size_t height = ((width * bheight) + bwidth / 2) / bwidth; + + CGContextTranslateCTM( bitmapContext, 0, bheight ); + CGContextScaleCTM( bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height ); + + [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: bitmapContext flipped: YES]]; + + content_scaled_redraw( content, width, height, &ctx ); + + [NSGraphicsContext setCurrentContext: nil]; + CGContextRelease( bitmapContext ); + + bitmap_modified( bitmap ); + + return true; +} + static struct gui_bitmap_table bitmap_table = { .create = bitmap_create, .destroy = bitmap_destroy, @@ -228,6 +276,7 @@ static struct gui_bitmap_table bitmap_table = { .get_bpp = bitmap_get_bpp, .save = bitmap_save, .modified = bitmap_modified, + .render = bitmap_render, }; struct gui_bitmap_table *cocoa_bitmap_table = &bitmap_table; diff --git a/cocoa/thumbnail.m b/cocoa/thumbnail.m deleted file mode 100644 index bb018bc30..000000000 --- a/cocoa/thumbnail.m +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2011 Sven Weidauer - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#import - -#import "desktop/browser.h" -#import "desktop/plotters.h" -#import "desktop/thumbnail.h" -#import "content/urldb.h" -#import "cocoa/plotter.h" -#import "image/bitmap.h" - -/* In platform specific thumbnail.c. */ -bool thumbnail_create(struct hlcache_handle *content, struct bitmap *bitmap) -{ - int bwidth = bitmap_get_width( bitmap ); - int bheight = bitmap_get_height( bitmap ); - - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &cocoa_plotters - }; - - CGColorSpaceRef cspace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB ); - CGContextRef bitmapContext = CGBitmapContextCreate( bitmap_get_buffer( bitmap ), - bwidth, bheight, - bitmap_get_bpp( bitmap ) * 8 / 4, - bitmap_get_rowstride( bitmap ), - cspace, kCGImageAlphaNoneSkipLast ); - CGColorSpaceRelease( cspace ); - - size_t width = MIN( content_get_width( content ), 1024 ); - size_t height = ((width * bheight) + bwidth / 2) / bwidth; - - CGContextTranslateCTM( bitmapContext, 0, bheight ); - CGContextScaleCTM( bitmapContext, (CGFloat)bwidth / width, -(CGFloat)bheight / height ); - - [NSGraphicsContext setCurrentContext: [NSGraphicsContext graphicsContextWithGraphicsPort: bitmapContext flipped: YES]]; - - thumbnail_redraw( content, width, height, &ctx ); - - [NSGraphicsContext setCurrentContext: nil]; - CGContextRelease( bitmapContext ); - - bitmap_modified( bitmap ); - - return true; -} - From 75d3fdc42e4b92f73efa93271c4bb37b1be6a650 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 23:49:49 +0100 Subject: [PATCH 13/13] Convert RISC OS to use bitmap render operation --- desktop/browser.c | 2 +- riscos/Makefile.target | 2 +- riscos/bitmap.c | 364 +++++++++++++++++++++++++++++++++++++++-- riscos/bitmap.h | 51 ++---- riscos/save.c | 6 +- riscos/thumbnail.c | 363 ---------------------------------------- riscos/thumbnail.h | 32 ---- riscos/window.c | 6 +- 8 files changed, 371 insertions(+), 455 deletions(-) delete mode 100644 riscos/thumbnail.c delete mode 100644 riscos/thumbnail.h diff --git a/desktop/browser.c b/desktop/browser.c index 74d15f654..abda8853a 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -1363,7 +1363,7 @@ static nserror browser_window_callback(hlcache_handle *c, * explode or overwrite the node for the previous URL. * * We call it after, rather than before urldb_add_url - * because history_add calls thumbnail_create, which + * because history_add calls bitmap render, which * tries to register the thumbnail with urldb. That * thumbnail registration fails if the url doesn't * exist in urldb already, and only urldb-registered diff --git a/riscos/Makefile.target b/riscos/Makefile.target index b2eb8927b..23e3fd05d 100644 --- a/riscos/Makefile.target +++ b/riscos/Makefile.target @@ -69,7 +69,7 @@ S_RISCOS := 401login.c assert.c bitmap.c buffer.c cookies.c configure.c \ image.c menus.c message.c mouse.c palettes.c plotters.c \ print.c query.c save.c save_draw.c save_pdf.c schedule.c \ search.c searchweb.c sslcert.c textarea.c \ - textselection.c theme.c theme_install.c thumbnail.c toolbar.c \ + textselection.c theme.c theme_install.c toolbar.c \ treeview.c ucstables.c uri.c url_complete.c url_protocol.c \ url_suggest.c wimp.c wimp_event.c window.c \ $(addprefix content-handlers/,artworks.c awrender.s draw.c \ diff --git a/riscos/bitmap.c b/riscos/bitmap.c index 6e1b9cca1..2cc85c4b7 100644 --- a/riscos/bitmap.c +++ b/riscos/bitmap.c @@ -18,10 +18,11 @@ * along with this program. If not, see . */ -/** \file - * Generic bitmap handling (RISC OS implementation). +/** + * \file + * RISC OS implementation of bitmap operations. * - * This implements the interface given by desktop/bitmap.h using RISC OS + * This implements the interface given by image/bitmap.h using RISC OS * sprites. */ @@ -29,7 +30,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -40,9 +43,11 @@ #include "utils/filename.h" #include "utils/log.h" #include "utils/utils.h" +#include "desktop/plotters.h" #include "content/content.h" #include "image/bitmap.h" +#include "riscos/gui.h" #include "riscos/image.h" #include "riscos/palettes.h" #include "riscos/content-handlers/sprite.h" @@ -55,6 +60,20 @@ /** Size of buffer used when constructing mask data to be saved */ #define SAVE_CHUNK_SIZE 4096 +/** + * Whether we can use 32bpp sprites + */ +static int thumbnail_32bpp_available = -1; + +/** + * Sprite output context saving + */ +struct thumbnail_save_area { + osspriteop_save_area *save_area; + int context1; + int context2; + int context3; +}; /** * Initialise a bitmaps sprite area. @@ -160,8 +179,13 @@ static void bitmap_set_opaque(void *vbitmap, bool opaque) } -/* exported interface documented in riscos/bitmap.h */ -size_t riscos_bitmap_get_rowstride(void *vbitmap) +/** + * Find the width of a pixel row in bytes. + * + * \param vbitmap A bitmap, as returned by riscos_bitmap_create() + * \return width of a pixel row in the bitmap + */ +static size_t bitmap_get_rowstride(void *vbitmap) { struct bitmap *bitmap = (struct bitmap *) vbitmap; return bitmap->width * 4; @@ -188,7 +212,7 @@ static bool bitmap_test_opaque(void *vbitmap) if (!sprite) return false; - width = riscos_bitmap_get_rowstride(bitmap); + width = bitmap_get_rowstride(bitmap); sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1); @@ -408,24 +432,38 @@ bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags) } -/* exported interface documented in riscos/bitmap.h */ -void riscos_bitmap_modified(void *vbitmap) +/** + * The bitmap image has changed, so flush any persistent cache. + * + * \param vbitmap a bitmap, as returned by bitmap_create() + */ +static void bitmap_modified(void *vbitmap) { struct bitmap *bitmap = (struct bitmap *) vbitmap; bitmap->state |= BITMAP_MODIFIED; } -/* exported interface documented in riscos/bitmap.h */ -int riscos_bitmap_get_width(void *vbitmap) +/** + * Get the width of a bitmap. + * + * \param vbitmap A bitmap, as returned by bitmap_create() + * \return The bitmaps width in pixels. + */ +static int bitmap_get_width(void *vbitmap) { struct bitmap *bitmap = (struct bitmap *) vbitmap; return bitmap->width; } -/* exported interface documented in riscos/bitmap.h */ -int riscos_bitmap_get_height(void *vbitmap) +/** + * Get the height of a bitmap. + * + * \param vbitmap A bitmap, as returned by bitmap_create() + * \return The bitmaps height in pixels. + */ +static int bitmap_get_height(void *vbitmap) { struct bitmap *bitmap = (struct bitmap *) vbitmap; return bitmap->height; @@ -482,7 +520,7 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, if (h > bitmap->height) h = bitmap->height; - dp_offset = riscos_bitmap_get_rowstride(bitmap) / 4; + dp_offset = bitmap_get_rowstride(bitmap) / 4; dp = (void*)riscos_bitmap_get_buffer(bitmap); if (!dp) @@ -529,6 +567,297 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, } } + +/** + * Creates an 8bpp canvas. + * + * \param bitmap the bitmap to clone the size of + * \return a sprite area containing an 8bpp sprite + */ +static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) +{ + unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height; + bool opaque = riscos_bitmap_get_opaque(bitmap); + osspriteop_header *sprite_header = NULL; + osspriteop_area *sprite_area = NULL; + unsigned area_size; + + /* clone the sprite */ + area_size = sizeof(osspriteop_area) + + sizeof(osspriteop_header) + + image_size + + 2048; + + if (!opaque) area_size += image_size; + + sprite_area = (osspriteop_area *)malloc(area_size); + if (!sprite_area) { + LOG(("no memory for malloc()")); + return NULL; + } + sprite_area->size = area_size; + sprite_area->sprite_count = 1; + sprite_area->first = 16; + sprite_area->used = area_size; + sprite_header = (osspriteop_header *)(sprite_area + 1); + sprite_header->size = area_size - sizeof(osspriteop_area); + memset(sprite_header->name, 0x00, 12); + strcpy(sprite_header->name, "bitmap"); + sprite_header->left_bit = 0; + sprite_header->height = bitmap->height - 1; + sprite_header->mode = os_MODE8BPP90X90; + sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31; + sprite_header->width = ((bitmap->width + 3) >> 2) - 1; + sprite_header->image = sizeof(osspriteop_header) + 2048; + sprite_header->mask = sizeof(osspriteop_header) + 2048; + if (!opaque) sprite_header->mask += image_size; + + /* create the palette. we don't read the necessary size like + * we really should as we know it's going to have 256 entries + * of 8 bytes = 2048. */ + xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90, + (osspriteop_id)0, + (os_palette *)(sprite_header + 1), 2048, + (colourtrans_palette_flags)(1 << 1), 0); + return sprite_area; +} + + +/** + * Switches output to the specified sprite and returns the previous context. + */ +static struct thumbnail_save_area* +thumbnail_switch_output(osspriteop_area *sprite_area, + osspriteop_header *sprite_header) +{ + struct thumbnail_save_area *save_area; + int size; + + /* create a save area */ + save_area = calloc(sizeof(struct thumbnail_save_area), 1); + if (save_area == NULL) return NULL; + + /* allocate OS_SpriteOp save area */ + if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area, + (osspriteop_id)sprite_header, &size)) { + free(save_area); + return NULL; + } + + /* create the save area */ + save_area->save_area = malloc((unsigned)size); + if (save_area->save_area == NULL) { + free(save_area); + return NULL; + } + save_area->save_area->a[0] = 0; + + /* switch output to sprite */ + if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area, + (osspriteop_id)sprite_header, save_area->save_area, + 0, &save_area->context1, &save_area->context2, + &save_area->context3)) { + free(save_area->save_area); + free(save_area); + return NULL; + } + return save_area; +} + + +/** + * Restores output to the specified context, and destroys it. + */ +static void thumbnail_restore_output(struct thumbnail_save_area *save_area) +{ + /* we don't care if we err, as there's nothing we can do about it */ + xosspriteop_switch_output_to_sprite(osspriteop_PTR, + (osspriteop_area *)save_area->context1, + (osspriteop_id)save_area->context2, + (osspriteop_save_area *)save_area->context3, + 0, 0, 0, 0); + free(save_area->save_area); + free(save_area); +} + + +/** + * Convert a bitmap to 8bpp. + * + * \param bitmap the bitmap to convert + * \return a sprite area containing an 8bpp sprite + */ +osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap) +{ + struct thumbnail_save_area *save_area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return NULL; + sprite_header = (osspriteop_header *)(sprite_area + 1); + + + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); + if (save_area == NULL) { + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; + } + _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), + (osspriteop_header *)(bitmap->sprite_area + 1), + 0, 0, + tinct_ERROR_DIFFUSE); + thumbnail_restore_output(save_area); + + if (sprite_header->image != sprite_header->mask) { + /* build the sprite mask from the alpha channel */ + void *buf = riscos_bitmap_get_buffer(bitmap); + unsigned *dp = (unsigned *) buf; + if (!dp) + return sprite_area; + int w = bitmap_get_width(bitmap); + int h = bitmap_get_height(bitmap); + int dp_offset = bitmap_get_rowstride(bitmap) / 4 - w; + int mp_offset = ((sprite_header->width + 1) * 4) - w; + byte *mp = (byte*)sprite_header + sprite_header->mask; + bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0; + + while (h-- > 0) { + int x = 0; + for(x = 0; x < w; x++) { + unsigned d = *dp++; + if (alpha) + *mp++ = (d >> 24) ^ 0xff; + else + *mp++ = (d < 0xff000000U) ? 0 : 0xff; + } + dp += dp_offset; + mp += mp_offset; + } + } + + return sprite_area; +} + + + + +/** + * Check to see whether 32bpp sprites are available. + * + * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available + * in case the user has a 3rd party patch to enable them. + */ +static void thumbnail_test(void) +{ + unsigned int area_size; + osspriteop_area *sprite_area; + + /* try to create a 1x1 32bpp sprite */ + area_size = sizeof(osspriteop_area) + + sizeof(osspriteop_header) + sizeof(int); + if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { + LOG(("Insufficient memory to perform sprite test.")); + return; + } + sprite_area->size = area_size + 1; + sprite_area->sprite_count = 0; + sprite_area->first = 16; + sprite_area->used = 16; + if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, + "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) + thumbnail_32bpp_available = 0; + else + thumbnail_32bpp_available = 1; + free(sprite_area); +} + + +/* exported interface documented in riscos/bitmap.h */ +nserror riscos_bitmap_render(struct bitmap *bitmap, + struct hlcache_handle *content) +{ + struct thumbnail_save_area *save_area; + osspriteop_area *sprite_area = NULL; + osspriteop_header *sprite_header = NULL; + struct redraw_context ctx = { + .interactive = false, + .background_images = true, + .plot = &ro_plotters + }; + + assert(content); + assert(bitmap); + + LOG(("content %p in bitmap %p", content, bitmap)); + + /* check if we have access to 32bpp sprites natively */ + if (thumbnail_32bpp_available == -1) { + thumbnail_test(); + } + + /* if we don't support 32bpp sprites then we redirect to an 8bpp + * image and then convert back. + */ + if (thumbnail_32bpp_available != 1) { + sprite_area = thumbnail_create_8bpp(bitmap); + if (!sprite_area) + return false; + sprite_header = (osspriteop_header *)(sprite_area + 1); + } else { + const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); + if (!pixbufp || !bitmap->sprite_area) + return false; + sprite_area = bitmap->sprite_area; + sprite_header = (osspriteop_header *)(sprite_area + 1); + } + + /* set up the plotters */ + ro_plot_origin_x = 0; + ro_plot_origin_y = bitmap->height * 2; + + /* switch output and redraw */ + save_area = thumbnail_switch_output(sprite_area, sprite_header); + if (!save_area) { + if (thumbnail_32bpp_available != 1) + free(sprite_area); + return false; + } + rufl_invalidate_cache(); + colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL, + os_ACTION_OVERWRITE, 0); + + /* render the content */ + content_scaled_redraw(content, bitmap->width, bitmap->height, &ctx); + + thumbnail_restore_output(save_area); + rufl_invalidate_cache(); + + /* if we changed to 8bpp then go back to 32bpp */ + if (thumbnail_32bpp_available != 1) { + const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); + _kernel_oserror *error; + + if (!pixbufp || !bitmap->sprite_area) { + free(sprite_area); + return false; + } + error = _swix(Tinct_ConvertSprite, _INR(2,3), + sprite_header, + (osspriteop_header *)(bitmap->sprite_area + 1)); + free(sprite_area); + if (error) + return false; + } + + bitmap_modified(bitmap); + + return NSERROR_OK; +} + static struct gui_bitmap_table bitmap_table = { .create = riscos_bitmap_create, .destroy = riscos_bitmap_destroy, @@ -536,12 +865,13 @@ static struct gui_bitmap_table bitmap_table = { .get_opaque = riscos_bitmap_get_opaque, .test_opaque = bitmap_test_opaque, .get_buffer = riscos_bitmap_get_buffer, - .get_rowstride = riscos_bitmap_get_rowstride, - .get_width = riscos_bitmap_get_width, - .get_height = riscos_bitmap_get_height, + .get_rowstride = bitmap_get_rowstride, + .get_width = bitmap_get_width, + .get_height = bitmap_get_height, .get_bpp = bitmap_get_bpp, .save = riscos_bitmap_save, - .modified = riscos_bitmap_modified, + .modified = bitmap_modified, + .render = riscos_bitmap_render, }; struct gui_bitmap_table *riscos_bitmap_table = &bitmap_table; diff --git a/riscos/bitmap.h b/riscos/bitmap.h index 36eaea60e..3aca30de6 100644 --- a/riscos/bitmap.h +++ b/riscos/bitmap.h @@ -21,6 +21,8 @@ struct osspriteop_area; struct osspriteop_header; +struct hlcache_handle; +struct bitmap; /** bitmap operations table */ struct gui_bitmap_table *riscos_bitmap_table; @@ -40,6 +42,22 @@ struct bitmap { struct osspriteop_area *sprite_area; /**< Uncompressed data, or NULL */ }; +/** + * Convert bitmap to 8bpp sprite. + * + * \param bitmap the bitmap to convert. + * \return The converted sprite. + */ +struct osspriteop_area *riscos_bitmap_convert_8bpp(struct bitmap *bitmap); + +/** + * Render content into bitmap. + * + * \param bitmap the bitmap to draw to + * \param content content structure to render + * \return true on success and bitmap updated else false + */ +nserror riscos_bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content); /** * Overlay a sprite onto the given bitmap @@ -49,7 +67,6 @@ struct bitmap { */ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const struct osspriteop_header *s); - /** * Create a bitmap. * @@ -60,7 +77,6 @@ void riscos_bitmap_overlay_sprite(struct bitmap *bitmap, const struct osspriteop */ void *riscos_bitmap_create(int width, int height, unsigned int state); - /** * Free a bitmap. * @@ -80,37 +96,6 @@ void riscos_bitmap_destroy(void *vbitmap); */ unsigned char *riscos_bitmap_get_buffer(void *vbitmap); -/** - * The bitmap image has changed, so flush any persistent cache. - * - * \param vbitmap a bitmap, as returned by bitmap_create() - */ -void riscos_bitmap_modified(void *vbitmap); - -/** - * Get the width of a bitmap. - * - * \param vbitmap A bitmap, as returned by bitmap_create() - * \return The bitmaps width in pixels. - */ -int riscos_bitmap_get_width(void *vbitmap); - -/** - * Get the height of a bitmap. - * - * \param vbitmap A bitmap, as returned by bitmap_create() - * \return The bitmaps height in pixels. - */ -int riscos_bitmap_get_height(void *vbitmap); - -/** - * Find the width of a pixel row in bytes. - * - * \param vbitmap A bitmap, as returned by riscos_bitmap_create() - * \return width of a pixel row in the bitmap - */ -size_t riscos_bitmap_get_rowstride(void *vbitmap); - /** * Gets whether a bitmap should be plotted opaque * diff --git a/riscos/save.c b/riscos/save.c index 6b27db470..1d2fce484 100644 --- a/riscos/save.c +++ b/riscos/save.c @@ -49,7 +49,6 @@ #include "desktop/version.h" #include "desktop/save_complete.h" #include "desktop/save_text.h" -#include "desktop/thumbnail.h" #include "desktop/gui_window.h" #include "image/bitmap.h" #include "render/form.h" @@ -66,7 +65,6 @@ #include "riscos/save_draw.h" #include "riscos/save_pdf.h" #include "riscos/textselection.h" -#include "riscos/thumbnail.h" #include "riscos/wimp.h" #include "riscos/wimp_event.h" #include "riscos/ucstables.h" @@ -1375,8 +1373,8 @@ bool ro_gui_save_create_thumbnail(hlcache_handle *h, const char *name) LOG(("Thumbnail initialisation failed.")); return false; } - thumbnail_create(h, bitmap); - area = thumbnail_convert_8bpp(bitmap); + riscos_bitmap_render(bitmap, h); + area = riscos_bitmap_convert_8bpp(bitmap); riscos_bitmap_destroy(bitmap); if (!area) { LOG(("Thumbnail conversion failed.")); diff --git a/riscos/thumbnail.c b/riscos/thumbnail.c deleted file mode 100644 index ee21747f5..000000000 --- a/riscos/thumbnail.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 2004 James Bursa - * Copyright 2005 Richard Wilson - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** \file - * Page thumbnail creation (implementation). - * - * Thumbnails are created by redirecting output to a sprite and rendering the - * page at a small scale. - */ - -#include -#include -#include -#include "rufl.h" -#include "oslib/colourtrans.h" -#include "oslib/osfile.h" -#include "oslib/osspriteop.h" - -#include "utils/nsoption.h" -#include "utils/log.h" -#include "content/content.h" -#include "content/hlcache.h" -#include "desktop/plotters.h" -#include "desktop/thumbnail.h" -#include "image/bitmap.h" - -#include "riscos/bitmap.h" -#include "riscos/gui.h" -#include "riscos/oslib_pre7.h" -#include "riscos/thumbnail.h" -#include "riscos/tinct.h" - -/* Whether we can use 32bpp sprites -*/ -static int thumbnail_32bpp_available = -1; - - -/* Sprite output context saving -*/ -struct thumbnail_save_area { - osspriteop_save_area *save_area; - int context1; - int context2; - int context3; -}; - - -/* Internal prototypes -*/ -static osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap); -static void thumbnail_test(void); -static struct thumbnail_save_area* thumbnail_switch_output( - osspriteop_area *sprite_area, - osspriteop_header *sprite_header); -static void thumbnail_restore_output(struct thumbnail_save_area *save_area); - - -/** - * Create a thumbnail of a page. - * - * \param content content structure to thumbnail - * \param bitmap the bitmap to draw to - * \return true on success and bitmap updated else false - */ -bool thumbnail_create(hlcache_handle *content, struct bitmap *bitmap) -{ - struct thumbnail_save_area *save_area; - osspriteop_area *sprite_area = NULL; - osspriteop_header *sprite_header = NULL; - struct redraw_context ctx = { - .interactive = false, - .background_images = true, - .plot = &ro_plotters - }; - - assert(content); - assert(bitmap); - - LOG(("content %p in bitmap %p", content, bitmap)); - - /* check if we have access to 32bpp sprites natively */ - if (thumbnail_32bpp_available == -1) { - thumbnail_test(); - } - - /* if we don't support 32bpp sprites then we redirect to an 8bpp - * image and then convert back. - */ - if (thumbnail_32bpp_available != 1) { - sprite_area = thumbnail_create_8bpp(bitmap); - if (!sprite_area) - return false; - sprite_header = (osspriteop_header *)(sprite_area + 1); - } else { - const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); - if (!pixbufp || !bitmap->sprite_area) - return false; - sprite_area = bitmap->sprite_area; - sprite_header = (osspriteop_header *)(sprite_area + 1); - } - - /* set up the plotters */ - ro_plot_origin_x = 0; - ro_plot_origin_y = bitmap->height * 2; - - /* switch output and redraw */ - save_area = thumbnail_switch_output(sprite_area, sprite_header); - if (!save_area) { - if (thumbnail_32bpp_available != 1) - free(sprite_area); - return false; - } - rufl_invalidate_cache(); - colourtrans_set_gcol(os_COLOUR_WHITE, colourtrans_SET_BG_GCOL, - os_ACTION_OVERWRITE, 0); - - thumbnail_redraw(content, bitmap->width, bitmap->height, &ctx); - - thumbnail_restore_output(save_area); - rufl_invalidate_cache(); - - /* if we changed to 8bpp then go back to 32bpp */ - if (thumbnail_32bpp_available != 1) { - const uint8_t *pixbufp = riscos_bitmap_get_buffer(bitmap); - _kernel_oserror *error; - - if (!pixbufp || !bitmap->sprite_area) { - free(sprite_area); - return false; - } - error = _swix(Tinct_ConvertSprite, _INR(2,3), - sprite_header, - (osspriteop_header *)(bitmap->sprite_area + 1)); - free(sprite_area); - if (error) - return false; - } - - riscos_bitmap_modified(bitmap); - return true; -} - - -/** - * Convert a bitmap to 8bpp. - * - * \param bitmap the bitmap to convert - * \return a sprite area containing an 8bpp sprite - */ -osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap) -{ - struct thumbnail_save_area *save_area; - osspriteop_area *sprite_area = NULL; - osspriteop_header *sprite_header = NULL; - - sprite_area = thumbnail_create_8bpp(bitmap); - if (!sprite_area) - return NULL; - sprite_header = (osspriteop_header *)(sprite_area + 1); - - - /* switch output and redraw */ - save_area = thumbnail_switch_output(sprite_area, sprite_header); - if (save_area == NULL) { - if (thumbnail_32bpp_available != 1) - free(sprite_area); - return false; - } - _swix(Tinct_Plot, _IN(2) | _IN(3) | _IN(4) | _IN(7), - (osspriteop_header *)(bitmap->sprite_area + 1), - 0, 0, - tinct_ERROR_DIFFUSE); - thumbnail_restore_output(save_area); - - if (sprite_header->image != sprite_header->mask) { - /* build the sprite mask from the alpha channel */ - void *buf = riscos_bitmap_get_buffer(bitmap); - unsigned *dp = (unsigned *) buf; - if (!dp) - return sprite_area; - int w = riscos_bitmap_get_width(bitmap); - int h = riscos_bitmap_get_height(bitmap); - int dp_offset = riscos_bitmap_get_rowstride(bitmap) / 4 - w; - int mp_offset = ((sprite_header->width + 1) * 4) - w; - byte *mp = (byte*)sprite_header + sprite_header->mask; - bool alpha = ((unsigned)sprite_header->mode & 0x80000000U) != 0; - - while (h-- > 0) { - int x = 0; - for(x = 0; x < w; x++) { - unsigned d = *dp++; - if (alpha) - *mp++ = (d >> 24) ^ 0xff; - else - *mp++ = (d < 0xff000000U) ? 0 : 0xff; - } - dp += dp_offset; - mp += mp_offset; - } - } - - return sprite_area; -} - - -/** - * Creates an 8bpp canvas. - * - * \param bitmap the bitmap to clone the size of - * \return a sprite area containing an 8bpp sprite - */ -osspriteop_area *thumbnail_create_8bpp(struct bitmap *bitmap) -{ - unsigned image_size = ((bitmap->width + 3) & ~3) * bitmap->height; - bool opaque = riscos_bitmap_get_opaque(bitmap); - osspriteop_header *sprite_header = NULL; - osspriteop_area *sprite_area = NULL; - unsigned area_size; - - /* clone the sprite */ - area_size = sizeof(osspriteop_area) + - sizeof(osspriteop_header) + - image_size + - 2048; - - if (!opaque) area_size += image_size; - - sprite_area = (osspriteop_area *)malloc(area_size); - if (!sprite_area) { - LOG(("no memory for malloc()")); - return NULL; - } - sprite_area->size = area_size; - sprite_area->sprite_count = 1; - sprite_area->first = 16; - sprite_area->used = area_size; - sprite_header = (osspriteop_header *)(sprite_area + 1); - sprite_header->size = area_size - sizeof(osspriteop_area); - memset(sprite_header->name, 0x00, 12); - strcpy(sprite_header->name, "bitmap"); - sprite_header->left_bit = 0; - sprite_header->height = bitmap->height - 1; - sprite_header->mode = os_MODE8BPP90X90; - sprite_header->right_bit = ((bitmap->width << 3) - 1) & 31; - sprite_header->width = ((bitmap->width + 3) >> 2) - 1; - sprite_header->image = sizeof(osspriteop_header) + 2048; - sprite_header->mask = sizeof(osspriteop_header) + 2048; - if (!opaque) sprite_header->mask += image_size; - - /* create the palette. we don't read the necessary size like - * we really should as we know it's going to have 256 entries - * of 8 bytes = 2048. */ - xcolourtrans_read_palette((osspriteop_area *)os_MODE8BPP90X90, - (osspriteop_id)0, - (os_palette *)(sprite_header + 1), 2048, - (colourtrans_palette_flags)(1 << 1), 0); - return sprite_area; -} - - -/** - * Check to see whether 32bpp sprites are available. - * - * Rather than using Wimp_ReadSysInfo we test if 32bpp sprites are available - * in case the user has a 3rd party patch to enable them. - */ -static void thumbnail_test(void) -{ - unsigned int area_size; - osspriteop_area *sprite_area; - - /* try to create a 1x1 32bpp sprite */ - area_size = sizeof(osspriteop_area) + - sizeof(osspriteop_header) + sizeof(int); - if ((sprite_area = (osspriteop_area *)malloc(area_size)) == NULL) { - LOG(("Insufficient memory to perform sprite test.")); - return; - } - sprite_area->size = area_size + 1; - sprite_area->sprite_count = 0; - sprite_area->first = 16; - sprite_area->used = 16; - if (xosspriteop_create_sprite(osspriteop_NAME, sprite_area, - "test", false, 1, 1, (os_mode)tinct_SPRITE_MODE)) - thumbnail_32bpp_available = 0; - else - thumbnail_32bpp_available = 1; - free(sprite_area); -} - - -/** - * Switches output to the specified sprite and returns the previous context. - */ -static struct thumbnail_save_area* thumbnail_switch_output( - osspriteop_area *sprite_area, - osspriteop_header *sprite_header) -{ - struct thumbnail_save_area *save_area; - int size; - - /* create a save area */ - save_area = calloc(sizeof(struct thumbnail_save_area), 1); - if (save_area == NULL) return NULL; - - /* allocate OS_SpriteOp save area */ - if (xosspriteop_read_save_area_size(osspriteop_PTR, sprite_area, - (osspriteop_id)sprite_header, &size)) { - free(save_area); - return NULL; - } - - /* create the save area */ - save_area->save_area = malloc((unsigned)size); - if (save_area->save_area == NULL) { - free(save_area); - return NULL; - } - save_area->save_area->a[0] = 0; - - /* switch output to sprite */ - if (xosspriteop_switch_output_to_sprite(osspriteop_PTR, sprite_area, - (osspriteop_id)sprite_header, save_area->save_area, - 0, &save_area->context1, &save_area->context2, - &save_area->context3)) { - free(save_area->save_area); - free(save_area); - return NULL; - } - return save_area; -} - - -/** - * Restores output to the specified context, and destroys it. - */ -static void thumbnail_restore_output(struct thumbnail_save_area *save_area) -{ - /* we don't care if we err, as there's nothing we can do about it */ - xosspriteop_switch_output_to_sprite(osspriteop_PTR, - (osspriteop_area *)save_area->context1, - (osspriteop_id)save_area->context2, - (osspriteop_save_area *)save_area->context3, - 0, 0, 0, 0); - free(save_area->save_area); - free(save_area); -} diff --git a/riscos/thumbnail.h b/riscos/thumbnail.h deleted file mode 100644 index 4cd88bb35..000000000 --- a/riscos/thumbnail.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2004 James Bursa - * Copyright 2005 Richard Wilson - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file - * Page thumbnail creation interface. - */ - -#ifndef _NETSURF_RISCOS_THUMBNAIL_H_ -#define _NETSURF_RISCOS_THUMBNAIL_H_ - -struct osspriteop_area; - -struct osspriteop_area *thumbnail_convert_8bpp(struct bitmap *bitmap); - -#endif diff --git a/riscos/window.c b/riscos/window.c index d15dd3cad..7f80bc8c9 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -60,7 +60,6 @@ #include "desktop/mouse.h" #include "desktop/plotters.h" #include "desktop/textinput.h" -#include "desktop/thumbnail.h" #include "desktop/tree.h" #include "desktop/gui_window.h" #include "image/bitmap.h" @@ -82,7 +81,6 @@ #include "riscos/content-handlers/sprite.h" #include "riscos/textselection.h" #include "riscos/toolbar.h" -#include "riscos/thumbnail.h" #include "riscos/url_complete.h" #include "riscos/url_suggest.h" #include "riscos/wimp.h" @@ -3418,11 +3416,11 @@ void ro_gui_window_iconise(struct gui_window *g, LOG(("Thumbnail initialisation failed.")); return; } - thumbnail_create(h, bitmap); + riscos_bitmap_render(bitmap, h); if (overlay) { riscos_bitmap_overlay_sprite(bitmap, overlay); } - area = thumbnail_convert_8bpp(bitmap); + area = riscos_bitmap_convert_8bpp(bitmap); riscos_bitmap_destroy(bitmap); if (!area) { LOG(("Thumbnail conversion failed."));