From 75d3fdc42e4b92f73efa93271c4bb37b1be6a650 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 24 Apr 2015 23:49:49 +0100 Subject: Convert RISC OS to use bitmap render operation --- 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 +- 7 files changed, 370 insertions(+), 454 deletions(-) delete mode 100644 riscos/thumbnail.c delete mode 100644 riscos/thumbnail.h (limited to 'riscos') 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.")); -- cgit v1.2.3