summaryrefslogtreecommitdiff
path: root/riscos/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'riscos/bitmap.c')
-rw-r--r--riscos/bitmap.c876
1 files changed, 0 insertions, 876 deletions
diff --git a/riscos/bitmap.c b/riscos/bitmap.c
deleted file mode 100644
index cc4be590c..000000000
--- a/riscos/bitmap.c
+++ /dev/null
@@ -1,876 +0,0 @@
-/*
- * Copyright 2004 James Bursa <bursa@users.sourceforge.net>
- * Copyright 2005 Richard Wilson <info@tinct.net>
- * Copyright 2008 Adrian Lees <adrianl@users.sourceforge.net>
- *
- * 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 <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file
- * RISC OS implementation of bitmap operations.
- *
- * This implements the interface given by image/bitmap.h using RISC OS
- * sprites.
- */
-
-#include <assert.h>
-#include <stdbool.h>
-#include <string.h>
-#include <swis.h>
-#include <rufl.h>
-#include <unixlib/local.h>
-#include <oslib/colourtrans.h>
-#include <oslib/osfile.h>
-#include <oslib/osfind.h>
-#include <oslib/osgbpb.h>
-#include <oslib/osspriteop.h>
-#include <oslib/wimp.h>
-
-#include "utils/nsoption.h"
-#include "utils/filename.h"
-#include "utils/log.h"
-#include "utils/messages.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"
-#include "riscos/tinct.h"
-#include "riscos/bitmap.h"
-
-/** Colour in the overlay sprite that allows the bitmap to show through */
-#define OVERLAY_INDEX 0xfe
-
-/** 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.
- *
- * \param bitmap the bitmap to initialise
- * \return true if bitmap initialised else false.
- */
-
-static bool bitmap_initialise(struct bitmap *bitmap)
-{
- unsigned int area_size;
- osspriteop_area *sprite_area;
- osspriteop_header *sprite;
-
- assert(!bitmap->sprite_area);
-
- area_size = 16 + 44 + bitmap->width * bitmap->height * 4;
- if (bitmap->state & BITMAP_CLEAR_MEMORY)
- bitmap->sprite_area = calloc(1, area_size);
- else
- bitmap->sprite_area = malloc(area_size);
-
- if (!bitmap->sprite_area)
- return false;
-
- /* area control block */
- sprite_area = bitmap->sprite_area;
- sprite_area->size = area_size;
- sprite_area->sprite_count = 1;
- sprite_area->first = 16;
- sprite_area->used = area_size;
-
- /* sprite control block */
- sprite = (osspriteop_header *) (sprite_area + 1);
- sprite->size = area_size - 16;
- memset(sprite->name, 0x00, 12);
- strncpy(sprite->name, "bitmap", 12);
- sprite->width = bitmap->width - 1;
- sprite->height = bitmap->height - 1;
- sprite->left_bit = 0;
- sprite->right_bit = 31;
- sprite->image = sprite->mask = 44;
- sprite->mode = tinct_SPRITE_MODE;
-
- return true;
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-void *riscos_bitmap_create(int width, int height, unsigned int state)
-{
- struct bitmap *bitmap;
-
- if (width == 0 || height == 0)
- return NULL;
-
- bitmap = calloc(1, sizeof(struct bitmap));
- if (!bitmap)
- return NULL;
- bitmap->width = width;
- bitmap->height = height;
- bitmap->state = state;
-
- return bitmap;
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-unsigned char *riscos_bitmap_get_buffer(void *vbitmap)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
- assert(bitmap);
-
- /* dynamically create the buffer */
- if (bitmap->sprite_area == NULL) {
- if (!bitmap_initialise(bitmap))
- return NULL;
- }
-
- /* image data area should exist */
- if (bitmap->sprite_area)
- return ((unsigned char *) (bitmap->sprite_area)) + 16 + 44;
-
- return NULL;
-}
-
-
-/**
- * Sets whether a bitmap should be plotted opaque
- *
- * \param vbitmap a bitmap, as returned by bitmap_create()
- * \param opaque whether the bitmap should be plotted opaque
- */
-static void bitmap_set_opaque(void *vbitmap, bool opaque)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
- assert(bitmap);
-
- if (opaque)
- bitmap->state |= BITMAP_OPAQUE;
- else
- bitmap->state &= ~BITMAP_OPAQUE;
-}
-
-
-/**
- * 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;
-}
-
-
-/**
- * Tests whether a bitmap has an opaque alpha channel
- *
- * \param vbitmap a bitmap, as returned by bitmap_create()
- * \return whether the bitmap is opaque
- */
-static bool bitmap_test_opaque(void *vbitmap)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
- unsigned char *sprite;
- unsigned int width, height, size;
- osspriteop_header *sprite_header;
- unsigned *p, *ep;
-
- assert(bitmap);
-
- sprite = riscos_bitmap_get_buffer(bitmap);
- if (!sprite)
- return false;
-
- width = bitmap_get_rowstride(bitmap);
-
- sprite_header = (osspriteop_header *) (bitmap->sprite_area + 1);
-
- height = (sprite_header->height + 1);
-
- size = width * height;
-
- p = (void *) sprite;
-
- ep = (void *) (sprite + (size & ~31));
- while (p < ep) {
- /* \todo prefetch(p, 128)? */
- if (((p[0] & p[1] & p[2] & p[3] & p[4] & p[5] & p[6] & p[7])
- & 0xff000000U) != 0xff000000U)
- return false;
- p += 8;
- }
-
- ep = (void *) (sprite + size);
- while (p < ep) {
- if ((*p & 0xff000000U) != 0xff000000U) return false;
- p++;
- }
-
- return true;
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-bool riscos_bitmap_get_opaque(void *vbitmap)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
- assert(bitmap);
- return (bitmap->state & BITMAP_OPAQUE);
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-void riscos_bitmap_destroy(void *vbitmap)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
-
- assert(bitmap);
-
- /* destroy bitmap */
- if (bitmap->sprite_area) {
- free(bitmap->sprite_area);
- }
-
- free(bitmap);
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-bool riscos_bitmap_save(void *vbitmap, const char *path, unsigned flags)
-{
- struct bitmap *bitmap = (struct bitmap *) vbitmap;
- os_error *error;
-
- if (bitmap == NULL) {
- ro_warn_user("SaveError", messages_get("SprIsNull"));
- return false;
- }
-
- if (!bitmap->sprite_area) {
- riscos_bitmap_get_buffer(bitmap);
- }
- if (!bitmap->sprite_area)
- return false;
-
- if (riscos_bitmap_get_opaque(bitmap)) {
- error = xosspriteop_save_sprite_file(osspriteop_USER_AREA,
- (bitmap->sprite_area), path);
- if (error) {
- LOG("xosspriteop_save_sprite_file: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("SaveError", error->errmess);
- return false;
- }
- return true;
- } else {
- /* to make the saved sprite useful we must convert from 'Tinct'
- * format to either a bi-level mask or a Select-style full
- * alpha channel */
- osspriteop_area *area = bitmap->sprite_area;
- osspriteop_header *hdr = (void *) ((char *) area + area->first);
- unsigned width = hdr->width + 1, height = hdr->height + 1;
- unsigned image_size = height * width * 4;
- unsigned char *chunk_buf;
- unsigned *p, *elp, *eip;
- unsigned mask_size;
- size_t chunk_pix;
- struct {
- osspriteop_area area;
- osspriteop_header hdr;
- } file_hdr;
- os_fw fw;
-
- /* we only support 32bpp sprites */
- if ((((unsigned)hdr->mode >> 27)&15) != 6) {
- assert(!"Unsupported sprite format in bitmap_save");
- return false;
- }
-
- chunk_buf = malloc(SAVE_CHUNK_SIZE);
- if (!chunk_buf) {
- ro_warn_user("NoMemory", NULL);
- return false;
- }
-
- file_hdr.area = *area;
- file_hdr.hdr = *hdr;
-
- if (flags & BITMAP_SAVE_FULL_ALPHA) {
- mask_size = ((width + 3) & ~3) * height;
- chunk_pix = SAVE_CHUNK_SIZE;
- file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode
- | (1U<<31));
- } else {
- mask_size = (((width + 31) & ~31)/8) * height;
- chunk_pix = SAVE_CHUNK_SIZE<<3;
- file_hdr.hdr.mode = (os_mode)((unsigned)file_hdr.hdr.mode
- & ~(1U<<31));
- }
-
- file_hdr.area.sprite_count = 1;
- file_hdr.area.first = sizeof(file_hdr.area);
- file_hdr.area.used = sizeof(file_hdr) + image_size + mask_size;
-
- file_hdr.hdr.image = sizeof(file_hdr.hdr);
- file_hdr.hdr.mask = file_hdr.hdr.image + image_size;
- file_hdr.hdr.size = file_hdr.hdr.mask + mask_size;
-
- error = xosfind_openoutw(0, path, NULL, &fw);
- if (error) {
- LOG("xosfind_openoutw: 0x%x: %s", error->errnum, error->errmess);
- free(chunk_buf);
- ro_warn_user("SaveError", error->errmess);
- return false;
- }
-
- p = (void *) ((char *) hdr + hdr->image);
-
- /* write out the area header, sprite header and image data */
- error = xosgbpb_writew(fw, (byte*)&file_hdr + 4,
- sizeof(file_hdr)-4, NULL);
- if (!error)
- error = xosgbpb_writew(fw, (byte*)p, image_size, NULL);
- if (error) {
- LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
- free(chunk_buf);
- xosfind_closew(fw);
- ro_warn_user("SaveError", error->errmess);
- return false;
- }
-
- /* then write out the mask data in chunks */
- eip = p + (width * height); /* end of image */
- elp = p + width; /* end of line */
-
- while (p < eip) {
- unsigned char *dp = chunk_buf;
- unsigned *ep = p + chunk_pix;
- if (ep > elp) ep = elp;
-
- if (flags & BITMAP_SAVE_FULL_ALPHA) {
- while (p < ep) {
- *dp++ = ((unsigned char*)p)[3];
- p++;
- }
- }
- else {
- unsigned char mb = 0;
- int msh = 0;
- while (p < ep) {
- if (((unsigned char*)p)[3]) mb |= (1 << msh);
- if (++msh >= 8) {
- *dp++ = mb;
- msh = 0;
- mb = 0;
- }
- p++;
- }
- if (msh > 0) *dp++ = mb;
- }
-
- if (p >= elp) { /* end of line yet? */
- /* align to word boundary */
- while ((int)dp & 3) *dp++ = 0;
- /* advance end of line pointer */
- elp += width;
- }
- error = xosgbpb_writew(fw, (byte*)chunk_buf, dp-chunk_buf, NULL);
- if (error) {
- LOG("xosgbpb_writew: 0x%x: %s", error->errnum, error->errmess);
- free(chunk_buf);
- xosfind_closew(fw);
- ro_warn_user("SaveError", error->errmess);
- return false;
- }
- }
-
- error = xosfind_closew(fw);
- if (error) {
- LOG("xosfind_closew: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("SaveError", error->errmess);
- }
-
- error = xosfile_set_type(path, osfile_TYPE_SPRITE);
- if (error) {
- LOG("xosfile_set_type: 0x%x: %s", error->errnum, error->errmess);
- ro_warn_user("SaveError", error->errmess);
- }
-
- free(chunk_buf);
- return true;
- }
-}
-
-
-/**
- * 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;
-}
-
-
-/**
- * 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;
-}
-
-
-/**
- * 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;
-}
-
-
-/**
- * Find the bytes per pixel of a bitmap
- *
- * \param vbitmap a bitmap, as returned by bitmap_create()
- * \return bytes per pixel
- */
-static size_t bitmap_get_bpp(void *vbitmap)
-{
- struct bitmap *bitmap = (struct bitmap *)vbitmap;
- assert(bitmap);
- return 4;
-}
-
-
-/* exported interface documented in riscos/bitmap.h */
-void riscos_bitmap_overlay_sprite(struct bitmap *bitmap,
- const osspriteop_header *s)
-{
- const os_colour *palette;
- const byte *sp, *mp;
- bool masked = false;
- bool alpha = false;
- os_error *error;
- int dp_offset;
- int sp_offset;
- unsigned *dp;
- int x, y;
- int w, h;
-
- assert(sprite_bpp(s) == 8);
-
- if ((unsigned)s->mode & 0x80000000U)
- alpha = true;
-
- error = xosspriteop_read_sprite_info(osspriteop_PTR,
- (osspriteop_area *)0x100,
- (osspriteop_id)s,
- &w, &h, NULL, NULL);
- if (error) {
- LOG("xosspriteop_read_sprite_info: 0x%x:%s", error->errnum, error->errmess);
- return;
- }
- sp_offset = ((s->width + 1) * 4) - w;
-
- if (w > bitmap->width)
- w = bitmap->width;
- if (h > bitmap->height)
- h = bitmap->height;
-
- dp_offset = bitmap_get_rowstride(bitmap) / 4;
-
- dp = (void*)riscos_bitmap_get_buffer(bitmap);
- if (!dp)
- return;
- sp = (byte*)s + s->image;
- mp = (byte*)s + s->mask;
-
- sp += s->left_bit / 8;
- mp += s->left_bit / 8;
-
- if (s->image > (int)sizeof(*s))
- palette = (os_colour*)(s + 1);
- else
- palette = default_palette8;
-
- if (s->mask != s->image) {
- masked = true;
- bitmap_set_opaque(bitmap, false);
- }
-
- /* (partially-)transparent pixels in the overlayed sprite retain
- * their transparency in the output bitmap; opaque sprite pixels
- * are also propagated to the bitmap, except those which are the
- * OVERLAY_INDEX colour which allow the original bitmap contents to
- * show through */
- for (y = 0; y < h; y++) {
- unsigned *sdp = dp;
- for(x = 0; x < w; x++) {
- os_colour d = ((unsigned)palette[(*sp) << 1]) >> 8;
- if (*sp++ == OVERLAY_INDEX)
- d = *dp;
- if (masked) {
- if (alpha)
- d |= ((*mp << 24) ^ 0xff000000U);
- else if (*mp)
- d |= 0xff000000U;
- }
- *dp++ = d;
- mp++;
- }
- dp = sdp + dp_offset;
- sp += sp_offset;
- mp += sp_offset;
- }
-}
-
-
-/**
- * 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,
- .set_opaque = bitmap_set_opaque,
- .get_opaque = riscos_bitmap_get_opaque,
- .test_opaque = bitmap_test_opaque,
- .get_buffer = riscos_bitmap_get_buffer,
- .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 = bitmap_modified,
- .render = riscos_bitmap_render,
-};
-
-struct gui_bitmap_table *riscos_bitmap_table = &bitmap_table;