From 2348b134924e8b24fba02f068a16c6fb308af88a Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 31 Aug 2011 12:12:41 +0000 Subject: refactor bitmap out of generic content structure svn path=/trunk/netsurf/; revision=12686 --- amiga/dt_anim.c | 27 +++++++++++++++-------- amiga/dt_picture.c | 38 +++++++++++++++++++++---------- amiga/icon.c | 38 +++++++++++++++++++++---------- cocoa/apple_image.m | 23 +++++++++++++++---- content/content.c | 54 +++++++++++++++++++++++++++++++++++++++++---- content/content.h | 1 + content/content_protected.h | 10 +++++---- image/bmp.c | 18 +++++++++++---- image/gif.c | 18 +++++++++++---- image/ico.c | 18 +++++++++++---- image/jpeg.c | 22 ++++++++++++++---- image/mng.c | 47 +++++++++++++++++++++++++-------------- image/nssprite.c | 33 ++++++++++++++++++--------- image/png.c | 10 +++++++-- image/rsvg.c | 16 ++++++++++---- image/webp.c | 30 ++++++++++++++++++------- render/html_redraw.c | 42 +++++++++++++++++------------------ 17 files changed, 320 insertions(+), 125 deletions(-) diff --git a/amiga/dt_anim.c b/amiga/dt_anim.c index 54f9867d6..f5e20e958 100644 --- a/amiga/dt_anim.c +++ b/amiga/dt_anim.c @@ -44,6 +44,8 @@ typedef struct amiga_dt_anim_content { struct content base; + struct bitmap *bitmap; /**< Created NetSurf bitmap */ + Object *dto; int x; int y; @@ -70,6 +72,13 @@ static void amiga_dt_anim_close(struct content *c); static nserror amiga_dt_anim_clone(const struct content *old, struct content **newc); static content_type amiga_dt_anim_content_type(lwc_string *mime_type); +static void *amiga_dt_anim_get_internal(const struct content *c, void *context) +{ + amiga_dt_anim_content *adta_c = (amiga_dt_anim_content *)c; + + return adta_c->bitmap; +} + static const content_handler amiga_dt_anim_content_handler = { .create = amiga_dt_anim_create, .data_complete = amiga_dt_anim_convert, @@ -79,6 +88,7 @@ static const content_handler amiga_dt_anim_content_handler = { .open = amiga_dt_anim_open, .close = amiga_dt_anim_close, .clone = amiga_dt_anim_clone, + .get_internal = amiga_dt_anim_get_internal, .type = amiga_dt_anim_content_type, .no_share = false, }; @@ -183,14 +193,14 @@ bool amiga_dt_anim_convert(struct content *c) width = (int)bmh->bmh_Width; height = (int)bmh->bmh_Height; - c->bitmap = bitmap_create(width, height, bm_flags); - if (!c->bitmap) { + plugin->bitmap = bitmap_create(width, height, bm_flags); + if (!plugin->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - bm_buffer = bitmap_get_buffer(c->bitmap); + bm_buffer = bitmap_get_buffer(plugin->bitmap); adt_frame.MethodID = ADTM_LOADFRAME; adt_frame.alf_TimeStamp = 0; @@ -227,7 +237,7 @@ bool amiga_dt_anim_convert(struct content *c) content__set_title(c, title); */ - bitmap_modified(c->bitmap); + bitmap_modified(plugin->bitmap); content_set_ready(c); content_set_done(c); @@ -242,8 +252,8 @@ void amiga_dt_anim_destroy(struct content *c) LOG(("amiga_dt_anim_destroy")); - if (c->bitmap != NULL) - bitmap_destroy(c->bitmap); + if (plugin->bitmap != NULL) + bitmap_destroy(plugin->bitmap); DisposeDTObject(plugin->dto); @@ -255,18 +265,17 @@ bool amiga_dt_anim_redraw(struct content *c, const struct redraw_context *ctx) { amiga_dt_anim_content *plugin = (amiga_dt_anim_content *) c; + bitmap_flags_t flags = BITMAPF_NONE; LOG(("amiga_dt_anim_redraw")); - bitmap_flags_t flags = BITMAPF_NONE; - if (data->repeat_x) flags |= BITMAPF_REPEAT_X; if (data->repeat_y) flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + plugin->bitmap, data->background_colour, flags); } /** diff --git a/amiga/dt_picture.c b/amiga/dt_picture.c index ebf8ba3fe..b36352506 100644 --- a/amiga/dt_picture.c +++ b/amiga/dt_picture.c @@ -40,6 +40,8 @@ typedef struct amiga_dt_picture_content { struct content base; + struct bitmap *bitmap; /**< Created NetSurf bitmap */ + Object *dto; int x; int y; @@ -59,12 +61,20 @@ static bool amiga_dt_picture_redraw(struct content *c, static nserror amiga_dt_picture_clone(const struct content *old, struct content **newc); static content_type amiga_dt_picture_content_type(lwc_string *mime_type); +static void *amiga_dt_picture_get_internal(const struct content *c, void *context) +{ + amiga_dt_picture_content *pic_c = (amiga_dt_picture_content *) c; + + return pic_c->bitmap; +} + static const content_handler amiga_dt_picture_content_handler = { .create = amiga_dt_picture_create, .data_complete = amiga_dt_picture_convert, .destroy = amiga_dt_picture_destroy, .redraw = amiga_dt_picture_redraw, .clone = amiga_dt_picture_clone, + .get_internal = amiga_dt_picture_get_internal, .type = amiga_dt_picture_content_type, .no_share = false, }; @@ -171,17 +181,17 @@ bool amiga_dt_picture_convert(struct content *c) width = (int)bmh->bmh_Width; height = (int)bmh->bmh_Height; - c->bitmap = bitmap_create(width, height, bm_flags); - if (!c->bitmap) { + plugin->bitmap = bitmap_create(width, height, bm_flags); + if (!plugin->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - bm_buffer = bitmap_get_buffer(c->bitmap); + bm_buffer = bitmap_get_buffer(plugin->bitmap); IDoMethod(plugin->dto, PDTM_READPIXELARRAY, - bm_buffer, bm_format, bitmap_get_rowstride(c->bitmap), + bm_buffer, bm_format, bitmap_get_rowstride(plugin->bitmap), 0, 0, width, height); } else return false; @@ -197,7 +207,7 @@ bool amiga_dt_picture_convert(struct content *c) content__set_title(c, title); */ - bitmap_modified(c->bitmap); + bitmap_modified(plugin->bitmap); content_set_ready(c); content_set_done(c); @@ -212,8 +222,9 @@ void amiga_dt_picture_destroy(struct content *c) LOG(("amiga_dt_picture_destroy")); - if (c->bitmap != NULL) - bitmap_destroy(c->bitmap); + if (plugin->bitmap != NULL) { + bitmap_destroy(plugin->bitmap); + } DisposeDTObject(plugin->dto); @@ -221,19 +232,22 @@ void amiga_dt_picture_destroy(struct content *c) } bool amiga_dt_picture_redraw(struct content *c, - struct content_redraw_data *data, const struct rect *clip, + struct content_redraw_data *data, + const struct rect *clip, const struct redraw_context *ctx) { - LOG(("amiga_dt_picture_redraw")); + amiga_dt_picture_content *plugin = (amiga_dt_picture_content *) c; bitmap_flags_t flags = BITMAPF_NONE; + LOG(("amiga_dt_picture_redraw")); + if (data->repeat_x) flags |= BITMAPF_REPEAT_X; if (data->repeat_y) flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + plugin->bitmap, data->background_colour, flags); } nserror amiga_dt_picture_clone(const struct content *old, struct content **newc) @@ -254,8 +268,8 @@ nserror amiga_dt_picture_clone(const struct content *old, struct content **newc) } /* We "clone" the old content by replaying conversion */ - if (old->status == CONTENT_STATUS_READY || - old->status == CONTENT_STATUS_DONE) { + if ((old->status == CONTENT_STATUS_READY) || + (old->status == CONTENT_STATUS_DONE)) { if (amiga_dt_picture_convert(&plugin->base) == false) { content_destroy(&plugin->base); return NSERROR_CLONE_FAILED; diff --git a/amiga/icon.c b/amiga/icon.c index afa1d4c1a..eb6725efc 100644 --- a/amiga/icon.c +++ b/amiga/icon.c @@ -58,6 +58,8 @@ ULONG *amiga_icon_convertcolouricon32(UBYTE *icondata, ULONG width, ULONG height typedef struct amiga_icon_content { struct content base; + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } amiga_icon_content; static nserror amiga_icon_create(const content_handler *handler, @@ -73,12 +75,20 @@ static nserror amiga_icon_clone(const struct content *old, struct content **newc); static content_type amiga_icon_content_type(lwc_string *mime_type); +static void *amiga_icon_get_internal(const struct content *c, void *context) +{ + amiga_icon_content *icon_c = (amiga_icon_content *)c; + + return icon_c->bitmap; +} + static const content_handler amiga_icon_content_handler = { .create = amiga_icon_create, .data_complete = amiga_icon_convert, .destroy = amiga_icon_destroy, .redraw = amiga_icon_redraw, .clone = amiga_icon_clone, + .get_internal = amiga_icon_get_internal, .type = amiga_icon_content_type, .no_share = false, }; @@ -134,21 +144,21 @@ nserror amiga_icon_create(const content_handler *handler, llcache_handle *llcache, const char *fallback_charset, bool quirks, struct content **c) { - amiga_icon_content *ai; + amiga_icon_content *ai_content; nserror error; - ai = talloc_zero(0, amiga_icon_content); - if (ai == NULL) + ai_content = talloc_zero(0, amiga_icon_content); + if (ai_content == NULL) return NSERROR_NOMEM; - error = content__init(&ai->base, handler, imime_type, params, + error = content__init(&ai_content->base, handler, imime_type, params, llcache, fallback_charset, quirks); if (error != NSERROR_OK) { - talloc_free(ai); + talloc_free(ai_content); return error; } - *c = (struct content *) ai; + *c = (struct content *)ai_content; return NSERROR_OK; } @@ -161,6 +171,7 @@ nserror amiga_icon_create(const content_handler *handler, bool amiga_icon_convert(struct content *c) { + amiga_icon_content *icon_c = (amiga_icon_content *)c; union content_msg_data msg_data; struct DiskObject *dobj; ULONG *imagebuf; @@ -213,8 +224,8 @@ bool amiga_icon_convert(struct content *c) return false; } - c->bitmap = bitmap_create(width, height, BITMAP_NEW); - if (!c->bitmap) { + icon_c->bitmap = bitmap_create(width, height, BITMAP_NEW); + if (!icon_c->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); if(dobj) FreeDiskObject(dobj); @@ -260,7 +271,7 @@ bool amiga_icon_convert(struct content *c) c->width = width; c->height = height; - bitmap_modified(c->bitmap); + bitmap_modified(icon_c->bitmap); content_set_ready(c); content_set_done(c); content_set_status(c, ""); @@ -280,8 +291,10 @@ bool amiga_icon_convert(struct content *c) void amiga_icon_destroy(struct content *c) { - if (c->bitmap != NULL) - bitmap_destroy(c->bitmap); + amiga_icon_content *icon_c = (amiga_icon_content *)c; + + if (icon_c->bitmap != NULL) + bitmap_destroy(icon_c->bitmap); } @@ -293,6 +306,7 @@ bool amiga_icon_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + amiga_icon_content *icon_c = (amiga_icon_content *)c; bitmap_flags_t flags = BITMAPF_NONE; if (data->repeat_x) @@ -301,7 +315,7 @@ bool amiga_icon_redraw(struct content *c, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + icon_c->bitmap, data->background_colour, flags); } diff --git a/cocoa/apple_image.m b/cocoa/apple_image.m index 11251d4e9..c6f3ae50c 100644 --- a/cocoa/apple_image.m +++ b/cocoa/apple_image.m @@ -30,6 +30,9 @@ typedef struct apple_image_content { struct content base; + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ + NSUInteger frames; NSUInteger currentFrame; int *frameTimes; @@ -47,12 +50,20 @@ static nserror apple_image_clone(const struct content *old, struct content **newc); static content_type apple_image_content_type(lwc_string *mime_type); +static void *apple_image_get_internal(const struct content *c, void *context) +{ + apple_image_content *ai_c = (apple_image_content *)c; + + return ai_c->bitmap; +} + static const content_handler apple_image_content_handler = { .create = apple_image_create, .data_complete = apple_image_convert, .destroy = apple_image_destroy, .redraw = apple_image_redraw, .clone = apple_image_clone, + .get_internal = apple_image_get_internal, .type = apple_image_content_type, .no_share = false }; @@ -156,6 +167,7 @@ static void animate_image_cb( void *ptr ) bool apple_image_convert(struct content *c) { + apple_image_content *ai_c = (apple_image_content *)c; unsigned long size; const char *bytes = content__get_source_data(c, &size); @@ -171,7 +183,7 @@ bool apple_image_convert(struct content *c) c->width = [image pixelsWide]; c->height = [image pixelsHigh]; - c->bitmap = (void *)image; + ai_c->bitmap = (void *)image; NSString *url = [NSString stringWithUTF8String: llcache_handle_get_url( content_get_llcache_handle( c ) )]; NSString *title = [NSString stringWithFormat: @"%@ (%dx%d)", [url lastPathComponent], c->width, c->height]; @@ -201,8 +213,10 @@ bool apple_image_convert(struct content *c) void apple_image_destroy(struct content *c) { - [(id)c->bitmap release]; - c->bitmap = NULL; + apple_image_content *ai_c = (apple_image_content *)c; + + [(id)ai_c->bitmap release]; + ai_c->bitmap = NULL; schedule_remove( animate_image_cb, c ); } @@ -246,6 +260,7 @@ content_type apple_image_content_type(lwc_string *mime_type) bool apple_image_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + apple_image_content *ai_c = (apple_image_content *)c; bitmap_flags_t flags = BITMAPF_NONE; if (data->repeat_x) @@ -254,7 +269,7 @@ bool apple_image_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + ai_c->bitmap, data->background_colour, flags); } #endif /* WITH_APPLE_IMAGE */ diff --git a/content/content.c b/content/content.c index f792e794a..db186e8cc 100644 --- a/content/content.c +++ b/content/content.c @@ -103,7 +103,6 @@ nserror content__init(struct content *c, const content_handler *handler, c->available_width = 0; c->quirks = quirks; c->refresh = 0; - c->bitmap = NULL; c->time = wallclock(); c->size = 0; c->title = NULL; @@ -959,6 +958,7 @@ const char *content__get_refresh_url(struct content *c) return c->refresh; } + /** * Retrieve the bitmap contained in an image content * @@ -972,10 +972,56 @@ struct bitmap *content_get_bitmap(hlcache_handle *h) struct bitmap *content__get_bitmap(struct content *c) { - if (c == NULL) - return NULL; + struct bitmap *bitmap = NULL; + + if ((c != NULL) && + (c->handler != NULL) && + (c->handler->type != NULL) && + (c->handler->type(NULL) == CONTENT_IMAGE) && + (c->handler->get_internal != NULL) ) { + bitmap = c->handler->get_internal(c, NULL); + } + + return bitmap; +} + + +/** + * Determine if a content is opaque from handle + * + * \param h high level cache handle to retrieve opacity from. + * \return false if the content is not opaque or information is not + * known else true. + */ +bool content_get_opaque(hlcache_handle *h) +{ + return content__get_opaque(hlcache_handle_get_content(h)); +} + +/** + * Determine if a content is opaque + * + * \param c Content to retrieve opacity from + * \return false if the content is not opaque or information is not + * known else true. + */ +bool content__get_opaque(struct content *c) +{ + bool opaque = false; + + if ((c != NULL) && + (c->handler != NULL) && + (c->handler->type != NULL) && + (c->handler->type(NULL) == CONTENT_IMAGE) && + (c->handler->get_internal != NULL) ) { + struct bitmap *bitmap = NULL; + bitmap = c->handler->get_internal(c, NULL); + if (bitmap != NULL) { + opaque = bitmap_get_opaque(bitmap); + } + } - return c->bitmap; + return opaque; } diff --git a/content/content.h b/content/content.h index 40e7f2089..1b2a8d097 100644 --- a/content/content.h +++ b/content/content.h @@ -174,6 +174,7 @@ const char *content_get_source_data(struct hlcache_handle *c, void content_invalidate_reuse_data(struct hlcache_handle *c); const char *content_get_refresh_url(struct hlcache_handle *c); struct bitmap *content_get_bitmap(struct hlcache_handle *c); +bool content_get_opaque(struct hlcache_handle *h); bool content_get_quirks(struct hlcache_handle *c); bool content_is_locked(struct hlcache_handle *h); diff --git a/content/content_protected.h b/content/content_protected.h index d113508e4..fd854a0bc 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -68,6 +68,10 @@ struct content_handler { nserror (*clone)(const struct content *old, struct content **newc); bool (*matches_quirks)(const struct content *c, bool quirks); content_type (*type)(lwc_string *mime_type); + + /** handler dependant content sensitive internal data interface. */ + void * (*get_internal)(const struct content *c, void *context); + /** There must be one content per user for this type. */ bool no_share; }; @@ -98,12 +102,9 @@ struct content { bool quirks; /**< Content is in quirks mode */ char *fallback_charset; /**< Fallback charset, or NULL */ - /**< URL for refresh request, in standard form as from url_join. */ + /** URL for refresh request, in standard form as from url_join. */ char *refresh; - /** Bitmap, for various image contents. */ - struct bitmap *bitmap; - unsigned int time; /**< Creation time, if LOADING or READY, otherwise total time. */ @@ -174,6 +175,7 @@ const char *content__get_source_data(struct content *c, unsigned long *size); void content__invalidate_reuse_data(struct content *c); const char *content__get_refresh_url(struct content *c); struct bitmap *content__get_bitmap(struct content *c); +bool content__get_opaque(struct content *c); bool content__is_locked(struct content *c); diff --git a/image/bmp.c b/image/bmp.c index 1a4152649..fdf64d9dc 100644 --- a/image/bmp.c +++ b/image/bmp.c @@ -43,6 +43,8 @@ typedef struct nsbmp_content { struct content base; bmp_image *bmp; /** BMP image data */ + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } nsbmp_content; static nserror nsbmp_create_bmp_data(nsbmp_content *bmp) @@ -165,8 +167,8 @@ static bool nsbmp_convert(struct content *c) c->size += (swidth * bmp->bmp->height) + 16 + 44; /* exit as a success */ - c->bitmap = bmp->bmp->bitmap; - bitmap_modified(c->bitmap); + bmp->bitmap = bmp->bmp->bitmap; + bitmap_modified(bmp->bitmap); content_set_ready(c); content_set_done(c); @@ -186,7 +188,7 @@ static bool nsbmp_redraw(struct content *c, struct content_redraw_data *data, if (bmp_decode(bmp->bmp) != BMP_OK) return false; - c->bitmap = bmp->bmp->bitmap; + bmp->bitmap = bmp->bmp->bitmap; if (data->repeat_x) flags |= BITMAPF_REPEAT_X; @@ -194,7 +196,7 @@ static bool nsbmp_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + bmp->bitmap, data->background_colour, flags); } @@ -242,6 +244,13 @@ static nserror nsbmp_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nsbmp_get_internal(const struct content *c, void *context) +{ + nsbmp_content *bmp = (nsbmp_content *)c; + + return bmp->bitmap; +} + static content_type nsbmp_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -254,6 +263,7 @@ static const content_handler nsbmp_content_handler = { .destroy = nsbmp_destroy, .redraw = nsbmp_redraw, .clone = nsbmp_clone, + .get_internal = nsbmp_get_internal, .type = nsbmp_content_type, .no_share = false, }; diff --git a/image/gif.c b/image/gif.c index 74d09f13d..88cc22147 100644 --- a/image/gif.c +++ b/image/gif.c @@ -51,6 +51,7 @@ typedef struct nsgif_content { struct gif_animation *gif; /**< GIF animation data */ int current_frame; /**< current frame to display [0...(max-1)] */ + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } nsgif_content; @@ -297,9 +298,11 @@ static bool nsgif_convert(struct content *c) nsgif_invalidate); /* Exit as a success */ - c->bitmap = gif->gif->frame_image; + gif->bitmap = gif->gif->frame_image; + content_set_ready(c); content_set_done(c); + /* Done: update status bar */ content_set_status(c, ""); return true; @@ -340,7 +343,7 @@ static bool nsgif_redraw(struct content *c, struct content_redraw_data *data, if (nsgif_get_frame(c) != GIF_OK) return false; - c->bitmap = gif->gif->frame_image; + gif->bitmap = gif->gif->frame_image; if ((data->width == -1) && (data->height == -1)) return true; @@ -351,7 +354,7 @@ static bool nsgif_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + gif->bitmap, data->background_colour, flags); } @@ -401,18 +404,25 @@ static nserror nsgif_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nsgif_get_internal(const struct content *c, void *context) +{ + nsgif_content *gif = (nsgif_content *) c; + + return gif->bitmap; +} + static content_type nsgif_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } - static const content_handler nsgif_content_handler = { .create = nsgif_create, .data_complete = nsgif_convert, .destroy = nsgif_destroy, .redraw = nsgif_redraw, .clone = nsgif_clone, + .get_internal = nsgif_get_internal, .type = nsgif_content_type, .no_share = false, }; diff --git a/image/ico.c b/image/ico.c index 35c59e2b4..f12e0cccb 100644 --- a/image/ico.c +++ b/image/ico.c @@ -41,6 +41,8 @@ typedef struct nsico_content { struct content base; struct ico_collection *ico; /** ICO collection data */ + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } nsico_content; @@ -132,8 +134,8 @@ static bool nsico_convert(struct content *c) /* exit as a success */ bmp = ico_find(ico->ico, 255, 255); assert(bmp); - c->bitmap = bmp->bitmap; - bitmap_modified(c->bitmap); + ico->bitmap = bmp->bitmap; + bitmap_modified(ico->bitmap); content_set_ready(c); content_set_done(c); @@ -155,7 +157,7 @@ static bool nsico_redraw(struct content *c, struct content_redraw_data *data, if (bmp_decode(bmp) != BMP_OK) return false; - c->bitmap = bmp->bitmap; + ico->bitmap = bmp->bitmap; if (data->repeat_x) flags |= BITMAPF_REPEAT_X; @@ -163,7 +165,7 @@ static bool nsico_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + ico->bitmap, data->background_colour, flags); } @@ -210,6 +212,13 @@ static nserror nsico_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nsico_get_internal(const struct content *c, void *context) +{ + nsico_content *ico = (nsico_content *) c; + + return ico->bitmap; +} + static content_type nsico_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -221,6 +230,7 @@ static const content_handler nsico_content_handler = { .destroy = nsico_destroy, .redraw = nsico_redraw, .clone = nsico_clone, + .get_internal = nsico_get_internal, .type = nsico_content_type, .no_share = false, }; diff --git a/image/jpeg.c b/image/jpeg.c index f2fb314af..29fd0bf5c 100644 --- a/image/jpeg.c +++ b/image/jpeg.c @@ -56,6 +56,8 @@ static char nsjpeg_error_buffer[JMSG_LENGTH_MAX]; typedef struct nsjpeg_content { struct content base; /**< base content */ + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } nsjpeg_content; struct nsjpeg_error_mgr { @@ -171,6 +173,7 @@ static void nsjpeg_error_exit(j_common_ptr cinfo) */ static bool nsjpeg_convert(struct content *c) { + struct nsjpeg_content *jpeg_content = (nsjpeg_content *)c; struct jpeg_decompress_struct cinfo; struct nsjpeg_error_mgr jerr; struct jpeg_source_mgr source_mgr = { 0, 0, @@ -257,7 +260,7 @@ static bool nsjpeg_convert(struct content *c) c->width = width; c->height = height; - c->bitmap = bitmap; + jpeg_content->bitmap = bitmap; snprintf(title, sizeof(title), messages_get("JPEGTitle"), width, height, size); content__set_title(c, title); @@ -275,8 +278,11 @@ static bool nsjpeg_convert(struct content *c) */ static void nsjpeg_destroy(struct content *c) { - if (c->bitmap) - bitmap_destroy(c->bitmap); + struct nsjpeg_content *jpeg_content = (nsjpeg_content *)c; + + if (jpeg_content->bitmap) { + bitmap_destroy(jpeg_content->bitmap); + } } @@ -286,6 +292,7 @@ static void nsjpeg_destroy(struct content *c) static bool nsjpeg_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + struct nsjpeg_content *jpeg_content = (nsjpeg_content *)c; bitmap_flags_t flags = BITMAPF_NONE; if (data->repeat_x) @@ -294,7 +301,7 @@ static bool nsjpeg_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + jpeg_content->bitmap, data->background_colour, flags); } @@ -331,6 +338,12 @@ static nserror nsjpeg_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nsjpeg_get_internal(const struct content *c, void *context) +{ + nsjpeg_content *jpeg_c = (nsjpeg_content *)c; + + return jpeg_c->bitmap; +} static content_type nsjpeg_content_type(lwc_string *mime_type) { @@ -343,6 +356,7 @@ static const content_handler nsjpeg_content_handler = { .destroy = nsjpeg_destroy, .redraw = nsjpeg_redraw, .clone = nsjpeg_clone, + .get_internal = nsjpeg_get_internal, .type = nsjpeg_content_type, .no_share = false, }; diff --git a/image/mng.c b/image/mng.c index eb4344bf8..f0eff4b69 100644 --- a/image/mng.c +++ b/image/mng.c @@ -53,6 +53,8 @@ typedef struct nsmng_content bool waiting; bool displayed; void *handle; + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } nsmng_content; @@ -166,8 +168,8 @@ static mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, c = (nsmng_content *) mng_get_userdata(mng); assert(c != NULL); - c->base.bitmap = bitmap_create(width, height, BITMAP_NEW); - if (c->base.bitmap == NULL) { + c->bitmap = bitmap_create(width, height, BITMAP_NEW); + if (c->bitmap == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); LOG(("Insufficient memory to create canvas.")); @@ -176,7 +178,7 @@ static mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, /* Get the buffer to ensure that it is allocated and the calls in * nsmng_getcanvasline() succeed. */ - buffer = bitmap_get_buffer(c->base.bitmap); + buffer = bitmap_get_buffer(c->bitmap); if (buffer == NULL) { msg_data.error = messages_get("NoMemory"); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data); @@ -254,8 +256,8 @@ static mng_ptr nsmng_getcanvasline(mng_handle mng, mng_uint32 line) /* Calculate the address */ - return bitmap_get_buffer(c->base.bitmap) + - bitmap_get_rowstride(c->base.bitmap) * line; + return bitmap_get_buffer(c->bitmap) + + bitmap_get_rowstride(c->bitmap) * line; } static mng_bool nsmng_refresh(mng_handle mng, mng_uint32 x, mng_uint32 y, @@ -329,8 +331,8 @@ static void nsmng_animate(void *p) c->waiting = false; mng_display_resume(c->handle); c->opaque_test_pending = true; - if (c->base.bitmap) - bitmap_modified(c->base.bitmap); + if (c->bitmap) + bitmap_modified(c->bitmap); } } @@ -549,7 +551,7 @@ static bool nsmng_convert(struct content *c) /* by this point, the png should have been parsed * and the bitmap created, so ensure that's the case */ - if (content__get_bitmap(c) == NULL) { + if (mng->bitmap == NULL) { return nsmng_broadcast_error(mng, -1) == NSERROR_OK; } @@ -585,7 +587,7 @@ static bool nsmng_convert(struct content *c) LOG(("Unable to start display (%i)", status)); return nsmng_broadcast_error(mng, status) == NSERROR_OK; } - bitmap_modified(c->bitmap); + bitmap_modified(mng->bitmap); /* Optimise the plotting of MNG */ mng->opaque_test_pending = false; @@ -607,7 +609,7 @@ static bool nsjpng_convert(struct content *c) /* by this point, the png should have been parsed * and the bitmap created, so ensure that's the case */ - if (content__get_bitmap(c) == NULL) { + if (mng->bitmap == NULL) { return nsmng_broadcast_error(mng, -1) == NSERROR_OK; } @@ -642,12 +644,12 @@ static bool nsjpng_convert(struct content *c) LOG(("Unable to start display (%i)", status)); return nsmng_broadcast_error(mng, status) == NSERROR_OK; } - bitmap_modified(c->bitmap); + bitmap_modified(mng->bitmap); /* Optimise the plotting of JNG/PNGs */ mng->opaque_test_pending = true; - bitmap_set_opaque(c->bitmap, false); + bitmap_set_opaque(mng->bitmap, false); /* free associated memory */ @@ -678,8 +680,9 @@ static void nsmng_destroy(struct content *c) mng->handle = NULL; } - if (c->bitmap) - bitmap_destroy(c->bitmap); + if (mng->bitmap) { + bitmap_destroy(mng->bitmap); + } } @@ -693,8 +696,9 @@ static bool nsmng_redraw(struct content *c, struct content_redraw_data *data, /* mark image as having been requested to display */ mng->displayed = true; - if ((c->bitmap) && (mng->opaque_test_pending)) { - bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap)); + if ((mng->bitmap) && + (mng->opaque_test_pending)) { + bitmap_set_opaque(mng->bitmap, bitmap_test_opaque(mng->bitmap)); mng->opaque_test_pending = false; } @@ -704,7 +708,7 @@ static bool nsmng_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; ret = ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + mng->bitmap, data->background_colour, flags); /* Check if we need to restart the animation */ if ((mng->waiting) && (option_animate_images)) @@ -759,6 +763,13 @@ static nserror nsmng_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nsmng_get_internal(const struct content *c, void *context) +{ + nsmng_content *mng = (nsmng_content *)c; + + return mng->bitmap; +} + static content_type nsmng_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -772,6 +783,7 @@ static const content_handler nsmng_content_handler = { .destroy = nsmng_destroy, .redraw = nsmng_redraw, .clone = nsmng_clone, + .get_internal = nsmng_get_internal, .type = nsmng_content_type, .no_share = false, }; @@ -794,6 +806,7 @@ static const content_handler nsjpng_content_handler = { .destroy = nsmng_destroy, .redraw = nsmng_redraw, .clone = nsmng_clone, + .get_internal = nsmng_get_internal, .type = nsmng_content_type, .no_share = false, }; diff --git a/image/nssprite.c b/image/nssprite.c index e64ef7d39..4e6b659e1 100644 --- a/image/nssprite.c +++ b/image/nssprite.c @@ -37,6 +37,7 @@ typedef struct nssprite_content { struct content base; + struct bitmap *bitmap; /**< Created NetSurf bitmap */ struct rosprite_area* sprite_area; } nssprite_content; @@ -112,19 +113,19 @@ static bool nssprite_convert(struct content *c) struct rosprite* sprite = sprite_area->sprites[0]; - c->bitmap = bitmap_create(sprite->width, sprite->height, BITMAP_NEW); - if (!c->bitmap) { + nssprite->bitmap = bitmap_create(sprite->width, sprite->height, BITMAP_NEW); + if (!nssprite->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - unsigned char* imagebuf = bitmap_get_buffer(c->bitmap); + unsigned char* imagebuf = bitmap_get_buffer(nssprite->bitmap); if (!imagebuf) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - unsigned int row_width = bitmap_get_rowstride(c->bitmap); + unsigned int row_width = bitmap_get_rowstride(nssprite->bitmap); memcpy(imagebuf, sprite->image, row_width * sprite->height); // TODO: avoid copying entire image buffer @@ -145,7 +146,7 @@ static bool nssprite_convert(struct content *c) c->width = sprite->width; c->height = sprite->height; - bitmap_modified(c->bitmap); + bitmap_modified(nssprite->bitmap); content_set_ready(c); content_set_done(c); @@ -160,12 +161,12 @@ static bool nssprite_convert(struct content *c) static void nssprite_destroy(struct content *c) { - nssprite_content *sprite = (nssprite_content *) c; + nssprite_content *nssprite = (nssprite_content *) c; - if (sprite->sprite_area != NULL) - rosprite_destroy_sprite_area(sprite->sprite_area); - if (c->bitmap != NULL) - bitmap_destroy(c->bitmap); + if (nssprite->sprite_area != NULL) + rosprite_destroy_sprite_area(nssprite->sprite_area); + if (nssprite->bitmap != NULL) + bitmap_destroy(nssprite->bitmap); } @@ -176,6 +177,7 @@ static void nssprite_destroy(struct content *c) static bool nssprite_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + nssprite_content *nssprite = (nssprite_content *) c; bitmap_flags_t flags = BITMAPF_NONE; if (data->repeat_x) @@ -184,7 +186,7 @@ static bool nssprite_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + nssprite->bitmap, data->background_colour, flags); } @@ -217,17 +219,26 @@ static nserror nssprite_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *nssprite_get_internal(const struct content *c, void *context) +{ + nssprite_content *nssprite = (nssprite_content *) c; + + return nssprite->bitmap; +} + static content_type nssprite_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; } + static const content_handler nssprite_content_handler = { .create = nssprite_create, .data_complete = nssprite_convert, .destroy = nssprite_destroy, .redraw = nssprite_redraw, .clone = nssprite_clone, + .get_internal = nssprite_get_internal, .type = nssprite_content_type, .no_share = false, }; diff --git a/image/png.c b/image/png.c index 4f1d18720..66826bb3d 100644 --- a/image/png.c +++ b/image/png.c @@ -331,8 +331,6 @@ static bool nspng_convert(struct content *c) bitmap_set_opaque(png_c->bitmap, bitmap_test_opaque(png_c->bitmap)); bitmap_modified(png_c->bitmap); - c->bitmap = png_c->bitmap; /* this needs to go */ - content_set_ready(c); content_set_done(c); content_set_status(c, ""); @@ -413,6 +411,13 @@ static nserror nspng_clone(const struct content *old_c, struct content **new_c) return NSERROR_OK; } +static void *nspng_get_internal(const struct content *c, void *context) +{ + nspng_content *png_c = (nspng_content *) c; + + return png_c->bitmap; +} + static content_type nspng_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -425,6 +430,7 @@ static const content_handler nspng_content_handler = { .destroy = nspng_destroy, .redraw = nspng_redraw, .clone = nspng_clone, + .get_internal = nspng_get_internal, .type = nspng_content_type, .no_share = false, }; diff --git a/image/rsvg.c b/image/rsvg.c index c322773c8..691e03370 100644 --- a/image/rsvg.c +++ b/image/rsvg.c @@ -207,8 +207,7 @@ static bool rsvg_convert(struct content *c) c->width, c->height, bitmap_get_rowstride(d->bitmap)); - c->bitmap = d->bitmap; - bitmap_modified(c->bitmap); + bitmap_modified(d->bitmap); content_set_ready(c); content_set_done(c); /* Done: update status bar */ @@ -220,9 +219,10 @@ static bool rsvg_convert(struct content *c) static bool rsvg_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + rsvg_content *rsvgcontent = (rsvg_content *) c; bitmap_flags_t flags = BITMAPF_NONE; - assert(c->bitmap != NULL); + assert(rsvgcontent->bitmap != NULL); if (data->repeat_x) flags |= BITMAPF_REPEAT_X; @@ -230,7 +230,7 @@ static bool rsvg_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + rsvgcontent->bitmap, data->background_colour, flags); } static void rsvg_destroy(struct content *c) @@ -290,6 +290,13 @@ static nserror rsvg_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *rsvg_get_internal(const struct content *c, void *context) +{ + rsvg_content *d = (rsvg_content *) c; + + return d->bitmap; +} + static content_type rsvg_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -302,6 +309,7 @@ static const content_handler rsvg_content_handler = { .destroy = rsvg_destroy, .redraw = rsvg_redraw, .clone = rsvg_clone, + .get_internal = rsvg_get_internal, .type = rsvg_content_type, .no_share = false, }; diff --git a/image/webp.c b/image/webp.c index 25a026271..714e44c5c 100644 --- a/image/webp.c +++ b/image/webp.c @@ -36,6 +36,8 @@ typedef struct webp_content { struct content base; + + struct bitmap *bitmap; /**< Created NetSurf bitmap */ } webp_content; @@ -71,6 +73,7 @@ static nserror webp_create(const content_handler *handler, static bool webp_convert(struct content *c) { + webp_content *webp = (webp_content *)c; union content_msg_data msg_data; const uint8_t *data; unsigned char *imagebuf = NULL; @@ -89,20 +92,20 @@ static bool webp_convert(struct content *c) return false; } - c->bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE); - if (!c->bitmap) { + webp->bitmap = bitmap_create(width, height, BITMAP_NEW | BITMAP_OPAQUE); + if (!webp->bitmap) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - imagebuf = bitmap_get_buffer(c->bitmap); + imagebuf = bitmap_get_buffer(webp->bitmap); if (!imagebuf) { msg_data.error = messages_get("NoMemory"); content_broadcast(c, CONTENT_MSG_ERROR, msg_data); return false; } - unsigned int row_width = bitmap_get_rowstride(c->bitmap); + unsigned int row_width = bitmap_get_rowstride(webp->bitmap); res_p = WebPDecodeRGBAInto(data, size, imagebuf, row_width * height, row_width); @@ -118,7 +121,7 @@ static bool webp_convert(struct content *c) width, height, size); content__set_title(c, title); - bitmap_modified(c->bitmap); + bitmap_modified(webp->bitmap); content_set_ready(c); content_set_done(c); @@ -134,8 +137,10 @@ static bool webp_convert(struct content *c) static void webp_destroy(struct content *c) { - if (c->bitmap != NULL) - bitmap_destroy(c->bitmap); + webp_content *webp = (webp_content *)c; + + if (webp->bitmap != NULL) + bitmap_destroy(webp->bitmap); } @@ -146,6 +151,7 @@ static void webp_destroy(struct content *c) static bool webp_redraw(struct content *c, struct content_redraw_data *data, const struct rect *clip, const struct redraw_context *ctx) { + webp_content *webp = (webp_content *)c; bitmap_flags_t flags = BITMAPF_NONE; if (data->repeat_x) @@ -154,7 +160,7 @@ static bool webp_redraw(struct content *c, struct content_redraw_data *data, flags |= BITMAPF_REPEAT_Y; return ctx->plot->bitmap(data->x, data->y, data->width, data->height, - c->bitmap, data->background_colour, flags); + webp->bitmap, data->background_colour, flags); } @@ -187,6 +193,13 @@ static nserror webp_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void *webp_get_internal(const struct content *c, void *context) +{ + webp_content *webp = (webp_content *)c; + + return webp->bitmap; +} + static content_type webp_content_type(lwc_string *mime_type) { return CONTENT_IMAGE; @@ -198,6 +211,7 @@ static const content_handler webp_content_handler = { .destroy = webp_destroy, .redraw = webp_redraw, .clone = webp_clone, + .get_internal = webp_get_internal, .type = webp_content_type, .no_share = false, }; diff --git a/render/html_redraw.c b/render/html_redraw.c index 5dd8bfd54..ef440f65d 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -2060,24 +2060,23 @@ bool html_redraw_background(int x, int y, struct box *box, float scale, /* handle background-repeat */ switch (css_computed_background_repeat(background->style)) { case CSS_BACKGROUND_REPEAT_REPEAT: - { - struct bitmap *bmp = content_get_bitmap( - background->background); repeat_x = repeat_y = true; /* optimisation: only plot the colour if * bitmap is not opaque */ - if (bmp != NULL) - plot_colour = !bitmap_get_opaque(bmp); - } + plot_colour = !content_get_opaque(background->background); break; + case CSS_BACKGROUND_REPEAT_REPEAT_X: repeat_x = true; break; + case CSS_BACKGROUND_REPEAT_REPEAT_Y: repeat_y = true; break; + case CSS_BACKGROUND_REPEAT_NO_REPEAT: break; + default: break; } @@ -2126,8 +2125,6 @@ bool html_redraw_background(int x, int y, struct box *box, float scale, for (; clip_box; clip_box = clip_box->next) { /* clip to child boxes if needed */ if (clip_to_children) { - struct bitmap *bmp = NULL; - assert(clip_box->type == BOX_TABLE_CELL); /* update clip.* to the child cell */ @@ -2145,16 +2142,17 @@ bool html_redraw_background(int x, int y, struct box *box, float scale, if (r.x1 > clip->x1) r.x1 = clip->x1; if (r.y1 > clip->y1) r.y1 = clip->y1; - if (clip_box->background != NULL) - bmp = content_get_bitmap(clip_box->background); - css_computed_background_color(clip_box->style, &bgcol); /* attributes override */ - if ((r.x0 >= r.x1) || (r.y0 >= r.y1) || - (nscss_color_is_transparent(bgcol) == - false) || - (bmp != NULL && bitmap_get_opaque(bmp))) + /* if the background content is opaque there + * is no need to plot underneath it. + */ + if ((r.x0 >= r.x1) || + (r.y0 >= r.y1) || + (nscss_color_is_transparent(bgcol) == false) || + ((clip_box->background != NULL) && + content_get_opaque(clip_box->background))) continue; } @@ -2259,24 +2257,24 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale, /* handle background-repeat */ switch (css_computed_background_repeat(box->style)) { case CSS_BACKGROUND_REPEAT_REPEAT: - { - struct bitmap *bmp = - content_get_bitmap(box->background); repeat_x = repeat_y = true; /* optimisation: only plot the colour if - * bitmap is not opaque */ - if (bmp != NULL) - plot_colour = !bitmap_get_opaque(bmp); - } + * bitmap is not opaque + */ + plot_colour = !content_get_opaque(box->background); break; + case CSS_BACKGROUND_REPEAT_REPEAT_X: repeat_x = true; break; + case CSS_BACKGROUND_REPEAT_REPEAT_Y: repeat_y = true; break; + case CSS_BACKGROUND_REPEAT_NO_REPEAT: break; + default: break; } -- cgit v1.2.3