mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-22 14:31:20 +03:00
[project @ 2006-02-21 20:49:11 by rjw]
Allow any content to be used as a background. Simplify bitmap code. svn path=/import/netsurf/; revision=2087
This commit is contained in:
parent
b6c6d77772
commit
4cc85469cb
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
||||
* Licensed under the GNU General Public License,
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* http://www.opensource.org/licenses/gpl-license
|
||||
* Copyright 2005 James Bursa <bursa@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
@ -174,6 +174,11 @@ struct handler_entry {
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
bool (*redraw_tiled)(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
void (*open)(struct content *c, struct browser_window *bw,
|
||||
struct content *page, unsigned int index,
|
||||
struct box *box,
|
||||
@ -186,51 +191,54 @@ struct handler_entry {
|
||||
* Must be ordered as enum ::content_type. */
|
||||
static const struct handler_entry handler_map[] = {
|
||||
{html_create, html_process_data, html_convert,
|
||||
html_reformat, html_destroy, html_stop, html_redraw,
|
||||
html_reformat, html_destroy, html_stop, html_redraw, 0,
|
||||
html_open, html_close,
|
||||
true},
|
||||
{textplain_create, textplain_process_data, textplain_convert,
|
||||
textplain_reformat, textplain_destroy, 0, textplain_redraw,
|
||||
textplain_reformat, textplain_destroy, 0, textplain_redraw, 0,
|
||||
0, 0, true},
|
||||
{0, 0, css_convert, 0, css_destroy, 0, 0, 0, 0, false},
|
||||
{0, 0, css_convert, 0, css_destroy, 0, 0, 0, 0, 0, false},
|
||||
#ifdef WITH_JPEG
|
||||
{0, 0, nsjpeg_convert,
|
||||
0, nsjpeg_destroy, 0, nsjpeg_redraw, 0, 0, false},
|
||||
{0, 0, nsjpeg_convert, 0, nsjpeg_destroy, 0,
|
||||
nsjpeg_redraw, nsjpeg_redraw_tiled, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_GIF
|
||||
{nsgif_create, 0, nsgif_convert,
|
||||
0, nsgif_destroy, 0, nsgif_redraw, 0, 0, false},
|
||||
{nsgif_create, 0, nsgif_convert, 0, nsgif_destroy, 0,
|
||||
nsgif_redraw, nsgif_redraw_tiled, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_MNG
|
||||
{nsmng_create, nsmng_process_data, nsmng_convert,
|
||||
0, nsmng_destroy, 0, nsmng_redraw, 0, 0, false},
|
||||
0, nsmng_destroy, 0, nsmng_redraw, nsmng_redraw_tiled,
|
||||
0, 0, false},
|
||||
{nsmng_create, nsmng_process_data, nsmng_convert,
|
||||
0, nsmng_destroy, 0, nsmng_redraw, 0, 0, false},
|
||||
0, nsmng_destroy, 0, nsmng_redraw, nsmng_redraw_tiled,
|
||||
0, 0, false},
|
||||
{nsmng_create, nsmng_process_data, nsmng_convert,
|
||||
0, nsmng_destroy, 0, nsmng_redraw, 0, 0, false},
|
||||
0, nsmng_destroy, 0, nsmng_redraw, nsmng_redraw_tiled,
|
||||
0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_SPRITE
|
||||
{0, 0, sprite_convert,
|
||||
0, sprite_destroy, 0, sprite_redraw, 0, 0, false},
|
||||
0, sprite_destroy, 0, sprite_redraw, 0, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_DRAW
|
||||
{0, 0, draw_convert,
|
||||
0, draw_destroy, 0, draw_redraw, 0, 0, false},
|
||||
0, draw_destroy, 0, draw_redraw, 0, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_PLUGIN
|
||||
{plugin_create, 0, plugin_convert,
|
||||
plugin_reformat, plugin_destroy, 0, plugin_redraw,
|
||||
plugin_reformat, plugin_destroy, 0, plugin_redraw, 0,
|
||||
plugin_open, plugin_close,
|
||||
true},
|
||||
#endif
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, false},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false},
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
{0, 0, artworks_convert,
|
||||
0, artworks_destroy, 0, artworks_redraw, 0, 0, false},
|
||||
0, artworks_destroy, 0, artworks_redraw, 0, 0, 0, false},
|
||||
#endif
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, false}
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false}
|
||||
};
|
||||
#define HANDLER_MAP_COUNT (sizeof(handler_map) / sizeof(handler_map[0]))
|
||||
|
||||
@ -415,8 +423,8 @@ struct content * content_get_ready(const char *url)
|
||||
/**
|
||||
* Initialise the content for the specified type.
|
||||
*
|
||||
* \param c content structure
|
||||
* \param type content_type to initialise to
|
||||
* \param c content structure
|
||||
* \param type content_type to initialise to
|
||||
* \param mime_type MIME-type string for this content
|
||||
* \param params array of strings, ordered attribute, value, attribute, ..., 0
|
||||
* \return true on success, false on error and error broadcast to users and
|
||||
@ -536,7 +544,7 @@ void content_set_status(struct content *c, const char *status_message, ...)
|
||||
*
|
||||
* Calls the process_data function for the content.
|
||||
*
|
||||
* \param c content structure
|
||||
* \param c content structure
|
||||
* \param data new data to process
|
||||
* \param size size of data
|
||||
* \return true on success, false on error and error broadcast to users and
|
||||
@ -822,8 +830,71 @@ bool content_redraw(struct content *c, int x, int y,
|
||||
return true;
|
||||
if (handler_map[c->type].redraw)
|
||||
return handler_map[c->type].redraw(c, x, y, width, height,
|
||||
clip_x0, clip_y0, clip_x1, clip_y1, scale,
|
||||
background_colour);
|
||||
clip_x0, clip_y0, clip_x1, clip_y1, scale,
|
||||
background_colour);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display content on screen with optional tiling.
|
||||
*
|
||||
* Calls the redraw_tile function for the content, or emulates it with the
|
||||
* redraw function if it doesn't exist.
|
||||
*/
|
||||
|
||||
bool content_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
{
|
||||
int x0, y0, x1, y1;
|
||||
|
||||
assert(c != 0);
|
||||
|
||||
if (c->locked)
|
||||
/* not safe to attempt redraw */
|
||||
return true;
|
||||
if (handler_map[c->type].redraw_tiled) {
|
||||
return handler_map[c->type].redraw_tiled(c, x, y, width, height,
|
||||
clip_x0, clip_y0, clip_x1, clip_y1, scale,
|
||||
background_colour, repeat_x, repeat_y);
|
||||
} else {
|
||||
/* ensure we have a redrawable content */
|
||||
if ((!handler_map[c->type].redraw) || (width == 0) ||
|
||||
(height == 0))
|
||||
return true;
|
||||
/* simple optimisation for no repeat (common for backgrounds) */
|
||||
if ((!repeat_x) || (!repeat_y))
|
||||
return handler_map[c->type].redraw(c, x, y, width,
|
||||
height, clip_x0, clip_y0, clip_x1, clip_y1,
|
||||
scale, background_colour);
|
||||
/* find the redraw boundaries to loop within*/
|
||||
x0 = x;
|
||||
if (repeat_x) {
|
||||
for (; x0 > clip_x0; x0 -= width);
|
||||
x1 = clip_x1;
|
||||
} else {
|
||||
x1 = x + 1;
|
||||
}
|
||||
y0 = y;
|
||||
if (repeat_y) {
|
||||
for (; y0 > clip_y0; y0 -= height);
|
||||
y1 = clip_y1;
|
||||
} else {
|
||||
y1 = y + 1;
|
||||
}
|
||||
/* repeatedly plot our content */
|
||||
for (y = y0; y < y1; y += height)
|
||||
for (x = x0; x < x1; x += width)
|
||||
if (!handler_map[c->type].redraw(c, x, y,
|
||||
width, height,
|
||||
clip_x0, clip_y0,
|
||||
clip_x1, clip_y1,
|
||||
scale, background_colour))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -831,7 +902,7 @@ bool content_redraw(struct content *c, int x, int y,
|
||||
/**
|
||||
* Register a user for callbacks.
|
||||
*
|
||||
* \param c the content to register
|
||||
* \param c the content to register
|
||||
* \param callback the callback function
|
||||
* \param p1, p2 callback private data
|
||||
* \return true on success, false otherwise on memory exhaustion
|
||||
@ -996,12 +1067,12 @@ void content_stop_check(struct content *c)
|
||||
/**
|
||||
* A window containing the content has been opened.
|
||||
*
|
||||
* \param c content that has been opened
|
||||
* \param bw browser window containing the content
|
||||
* \param page content of type CONTENT_HTML containing c, or 0 if not an
|
||||
* object within a page
|
||||
* \param c content that has been opened
|
||||
* \param bw browser window containing the content
|
||||
* \param page content of type CONTENT_HTML containing c, or 0 if not an
|
||||
* object within a page
|
||||
* \param index index in page->data.html.object, or 0 if not an object
|
||||
* \param box box containing c, or 0 if not an object
|
||||
* \param box box containing c, or 0 if not an object
|
||||
* \param params object parameters, or 0 if not an object
|
||||
*
|
||||
* Calls the open function for the content.
|
||||
|
@ -304,6 +304,11 @@ bool content_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
bool content_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
bool content_add_user(struct content *c,
|
||||
void (*callback)(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data),
|
||||
|
@ -32,7 +32,7 @@ struct bitmap {
|
||||
* \return an opaque struct bitmap, or NULL on memory exhaustion
|
||||
*/
|
||||
|
||||
struct bitmap *bitmap_create(int width, int height, bool clear)
|
||||
struct bitmap *bitmap_create(int width, int height, bitmap_state state)
|
||||
{
|
||||
struct bitmap *bitmap;
|
||||
bitmap = calloc(sizeof *bitmap + width * height * 4, 1);
|
||||
|
@ -33,7 +33,7 @@ struct bitmap;
|
||||
* \return an opaque struct bitmap, or NULL on memory exhaustion
|
||||
*/
|
||||
|
||||
struct bitmap *bitmap_create(int width, int height, bool clear)
|
||||
struct bitmap *bitmap_create(int width, int height, bitmap_state state)
|
||||
{
|
||||
GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, true, 8,
|
||||
width, height);
|
||||
|
@ -20,12 +20,18 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef enum {
|
||||
BITMAP_READY, /** Bitmap buffer is ready */
|
||||
BITMAP_ALLOCATE_MEMORY, /** Allocate memory */
|
||||
BITMAP_CLEAR_MEMORY, /** Clear the memory */
|
||||
} bitmap_state;
|
||||
|
||||
struct content;
|
||||
|
||||
/** An opaque image. */
|
||||
struct bitmap;
|
||||
|
||||
struct bitmap *bitmap_create(int width, int height, bool clear);
|
||||
struct bitmap *bitmap_create(int width, int height, bitmap_state state);
|
||||
void bitmap_set_opaque(struct bitmap *bitmap, bool opaque);
|
||||
bool bitmap_test_opaque(struct bitmap *bitmap);
|
||||
bool bitmap_get_opaque(struct bitmap *bitmap);
|
||||
|
14
image/gif.c
14
image/gif.c
@ -126,6 +126,20 @@ bool nsgif_redraw(struct content *c, int x, int y,
|
||||
}
|
||||
|
||||
|
||||
bool nsgif_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y) {
|
||||
|
||||
if (c->data.gif.current_frame != c->data.gif.gif->decoded_frame)
|
||||
nsgif_get_frame(c);
|
||||
c->bitmap = c->data.gif.gif->frame_image;
|
||||
return plot.bitmap_tile(x, y, width, height, c->bitmap, background_colour,
|
||||
repeat_x, repeat_y);
|
||||
}
|
||||
|
||||
|
||||
void nsgif_destroy(struct content *c)
|
||||
{
|
||||
/* Free all the associated memory buffers
|
||||
|
@ -25,5 +25,10 @@ bool nsgif_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
bool nsgif_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
|
||||
#endif
|
||||
|
@ -204,7 +204,7 @@ int gif_initialise(struct gif_animation *gif) {
|
||||
|
||||
/* Initialise the sprite header
|
||||
*/
|
||||
if ((gif->frame_image = bitmap_create(gif->width, gif->height, false)) == NULL) {
|
||||
if ((gif->frame_image = bitmap_create(gif->width, gif->height, BITMAP_ALLOCATE_MEMORY)) == NULL) {
|
||||
gif_finalise(gif);
|
||||
return GIF_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
@ -273,7 +273,8 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width,
|
||||
|
||||
/* Check if we've changed
|
||||
*/
|
||||
if ((width <= gif->width) && (height <= gif->height)) return 0;
|
||||
if ((width <= gif->width) && (height <= gif->height))
|
||||
return 0;
|
||||
|
||||
/* Get our maximum values
|
||||
*/
|
||||
@ -282,7 +283,7 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width,
|
||||
|
||||
/* Allocate some more memory
|
||||
*/
|
||||
if ((buffer = bitmap_create(max_width, max_height, false)) == NULL)
|
||||
if ((buffer = bitmap_create(max_width, max_height, BITMAP_ALLOCATE_MEMORY)) == NULL)
|
||||
return GIF_INSUFFICIENT_MEMORY;
|
||||
bitmap_destroy(gif->frame_image);
|
||||
gif->frame_image = buffer;
|
||||
|
18
image/jpeg.c
18
image/jpeg.c
@ -94,7 +94,7 @@ bool nsjpeg_convert(struct content *c, int w, int h)
|
||||
width = cinfo.output_width;
|
||||
height = cinfo.output_height;
|
||||
|
||||
bitmap = bitmap_create(width, height, false);
|
||||
bitmap = bitmap_create(width, height, BITMAP_ALLOCATE_MEMORY);
|
||||
if (bitmap)
|
||||
pixels = bitmap_get_buffer(bitmap);
|
||||
if ((!bitmap) || (!pixels)) {
|
||||
@ -226,6 +226,22 @@ bool nsjpeg_redraw(struct content *c, int x, int y,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Redraw a CONTENT_JPEG with appropriate tiling.
|
||||
*/
|
||||
|
||||
bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
{
|
||||
return plot.bitmap_tile(x, y, width, height,
|
||||
c->bitmap, background_colour,
|
||||
repeat_x, repeat_y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy a CONTENT_JPEG and free all resources it owns.
|
||||
*/
|
||||
|
@ -22,10 +22,15 @@ struct content_jpeg_data {
|
||||
};
|
||||
|
||||
bool nsjpeg_convert(struct content *c, int width, int height);
|
||||
void nsjpeg_destroy(struct content *c);
|
||||
bool nsjpeg_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
void nsjpeg_destroy(struct content *c);
|
||||
bool nsjpeg_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
|
||||
#endif
|
||||
|
25
image/mng.c
25
image/mng.c
@ -190,7 +190,7 @@ mng_bool nsmng_processheader(mng_handle mng, mng_uint32 width, mng_uint32 height
|
||||
|
||||
LOG(("processing header (%p) %d, %d", c, width, height));
|
||||
|
||||
c->bitmap = bitmap_create(width, height, false);
|
||||
c->bitmap = bitmap_create(width, height, BITMAP_ALLOCATE_MEMORY);
|
||||
if (!c->bitmap) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
@ -449,22 +449,33 @@ bool nsmng_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour)
|
||||
{
|
||||
return nsmng_redraw_tiled(c, x, y, width, height,
|
||||
clip_x0, clip_y0, clip_x1, clip_y1,
|
||||
scale, background_colour,
|
||||
false, false);
|
||||
}
|
||||
|
||||
|
||||
bool nsmng_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
{
|
||||
bool ret;
|
||||
|
||||
/* mark image as having been requested to display */
|
||||
if (!c->data.mng.displayed)
|
||||
c->data.mng.displayed = true;
|
||||
c->data.mng.displayed = true;
|
||||
|
||||
if ((c->bitmap) && (c->data.mng.opaque_test_pending)) {
|
||||
bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap));
|
||||
c->data.mng.opaque_test_pending = false;
|
||||
}
|
||||
|
||||
assert(c != NULL);
|
||||
|
||||
ret = plot.bitmap(x, y, width, height,
|
||||
c->bitmap, background_colour);
|
||||
ret = plot.bitmap_tile(x, y, width, height,
|
||||
c->bitmap, background_colour,
|
||||
repeat_x, repeat_y);
|
||||
|
||||
/* Check if we need to restart the animation
|
||||
*/
|
||||
|
@ -35,4 +35,9 @@ bool nsmng_redraw(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour);
|
||||
bool nsmng_redraw_tiled(struct content *c, int x, int y,
|
||||
int width, int height,
|
||||
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
|
||||
float scale, unsigned long background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
#endif
|
||||
|
@ -1000,21 +1000,23 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
bool repeat_x = false;
|
||||
bool repeat_y = false;
|
||||
bool plot_colour = true;
|
||||
bool plot_bitmap;
|
||||
bool plot_content;
|
||||
bool clip_to_children = false;
|
||||
struct box *clip_box = box;
|
||||
int px0 = clip_x0, py0 = clip_y0, px1 = clip_x1, py1 = clip_y1;
|
||||
int ox = x, oy = y;
|
||||
struct box *parent;
|
||||
|
||||
plot_bitmap = (box->background && box->background->bitmap);
|
||||
if (plot_bitmap) {
|
||||
plot_content = (box->background != NULL);
|
||||
if (plot_content) {
|
||||
/* handle background-repeat */
|
||||
switch (box->style->background_repeat) {
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT:
|
||||
repeat_x = repeat_y = true;
|
||||
/* optimisation: only plot the colour if bitmap is not opaque */
|
||||
plot_colour = !bitmap_get_opaque(box->background->bitmap);
|
||||
if (box->background->bitmap)
|
||||
plot_colour = !bitmap_get_opaque(
|
||||
box->background->bitmap);
|
||||
break;
|
||||
case CSS_BACKGROUND_REPEAT_REPEAT_X:
|
||||
repeat_x = true;
|
||||
@ -1109,19 +1111,13 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
|
||||
return false;
|
||||
}
|
||||
/* and plot the image */
|
||||
if (plot_bitmap) {
|
||||
if (plot_content) {
|
||||
if (!plot.clip(clip_x0, clip_y0, clip_x1, clip_y1))
|
||||
return false;
|
||||
/* SPECIAL CASE: As GIFs are normally decoded on the first call to
|
||||
* nsgif_redraw we may need to get the first frame manually. */
|
||||
if ((box->background->type == CONTENT_GIF) &&
|
||||
(box->background->data.gif.gif->decoded_frame < 0))
|
||||
gif_decode_frame(box->background->data.gif.gif,
|
||||
0);
|
||||
if (!plot.bitmap_tile(x, y,
|
||||
if (!content_redraw_tiled(box->background, x, y,
|
||||
ceilf(box->background->width * scale),
|
||||
ceilf(box->background->height * scale),
|
||||
box->background->bitmap,
|
||||
clip_x0, clip_y0, clip_x1, clip_y1, scale,
|
||||
*background_colour,
|
||||
repeat_x, repeat_y))
|
||||
return false;
|
||||
|
@ -74,7 +74,7 @@ struct bitmap_compressed_header {
|
||||
char bitmap_filename[256];
|
||||
|
||||
|
||||
static bool bitmap_initialise(struct bitmap *bitmap, bool clear);
|
||||
static bool bitmap_initialise(struct bitmap *bitmap);
|
||||
static void bitmap_decompress(struct bitmap *bitmap);
|
||||
static void bitmap_compress(struct bitmap *bitmap);
|
||||
static void bitmap_load_file(struct bitmap *bitmap);
|
||||
@ -145,7 +145,8 @@ void bitmap_quit(void)
|
||||
struct bitmap *bitmap;
|
||||
|
||||
for (bitmap = bitmap_head; bitmap; bitmap = bitmap->next)
|
||||
if ((bitmap->persistent) && (bitmap->filename[0] == '\0'))
|
||||
if ((bitmap->persistent) && ((bitmap->modified) ||
|
||||
(bitmap->filename[0] == '\0')))
|
||||
bitmap_save_file(bitmap);
|
||||
}
|
||||
|
||||
@ -159,7 +160,7 @@ void bitmap_quit(void)
|
||||
* \return an opaque struct bitmap, or NULL on memory exhaustion
|
||||
*/
|
||||
|
||||
struct bitmap *bitmap_create(int width, int height, bool clear)
|
||||
struct bitmap *bitmap_create(int width, int height, bitmap_state state)
|
||||
{
|
||||
struct bitmap *bitmap;
|
||||
|
||||
@ -172,10 +173,15 @@ struct bitmap *bitmap_create(int width, int height, bool clear)
|
||||
bitmap->width = width;
|
||||
bitmap->height = height;
|
||||
bitmap->opaque = false;
|
||||
if (clear)
|
||||
bitmap->init = BITMAP_INITIALISE_FULL;
|
||||
else
|
||||
bitmap->init = BITMAP_INITIALISE_QUICK;
|
||||
switch (state) {
|
||||
case BITMAP_CLEAR_MEMORY:
|
||||
case BITMAP_ALLOCATE_MEMORY:
|
||||
bitmap->state = state;
|
||||
break;
|
||||
default:
|
||||
LOG(("Invalid bitmap state"));
|
||||
assert(false);
|
||||
}
|
||||
|
||||
/* link into our list of bitmaps at the head */
|
||||
if (bitmap_head) {
|
||||
@ -207,7 +213,7 @@ struct bitmap *bitmap_create_file(char *file)
|
||||
return NULL;
|
||||
bitmap->opaque = true;
|
||||
bitmap->persistent = true;
|
||||
bitmap->init = BITMAP_INITIALISE_DONE;
|
||||
bitmap->state = BITMAP_READY;
|
||||
strcpy(bitmap->filename, file);
|
||||
|
||||
/* link in at the head */
|
||||
@ -227,21 +233,30 @@ struct bitmap *bitmap_create_file(char *file)
|
||||
* \param clear whether to clear the image ready for use
|
||||
*/
|
||||
|
||||
bool bitmap_initialise(struct bitmap *bitmap, bool clear)
|
||||
bool bitmap_initialise(struct bitmap *bitmap)
|
||||
{
|
||||
unsigned int area_size;
|
||||
osspriteop_area *sprite_area;
|
||||
osspriteop_header *sprite;
|
||||
|
||||
area_size = 16 + 44 + bitmap->width * bitmap->height * 4;
|
||||
if (clear)
|
||||
bitmap->sprite_area = calloc(1, area_size);
|
||||
else
|
||||
bitmap->sprite_area = malloc(area_size);
|
||||
if (!bitmap->sprite_area) {
|
||||
return false;
|
||||
switch (bitmap->state) {
|
||||
case BITMAP_CLEAR_MEMORY:
|
||||
bitmap->sprite_area = calloc(1, area_size);
|
||||
if (!bitmap->sprite_area)
|
||||
return false;
|
||||
bitmap->state = BITMAP_READY;
|
||||
break;
|
||||
case BITMAP_ALLOCATE_MEMORY:
|
||||
bitmap->sprite_area = malloc(area_size);
|
||||
if (!bitmap->sprite_area)
|
||||
return false;
|
||||
bitmap->state = BITMAP_READY;
|
||||
break;
|
||||
default:
|
||||
LOG(("Invalid bitmap state"));
|
||||
assert(false);
|
||||
}
|
||||
bitmap->init = BITMAP_INITIALISE_DONE;
|
||||
bitmap_direct_used += area_size;
|
||||
|
||||
/* area control block */
|
||||
@ -254,8 +269,7 @@ bool bitmap_initialise(struct bitmap *bitmap, bool clear)
|
||||
/* sprite control block */
|
||||
sprite = (osspriteop_header *) (sprite_area + 1);
|
||||
sprite->size = area_size - 16;
|
||||
if (!clear)
|
||||
memset(sprite->name, 0x00, 12);
|
||||
memset(sprite->name, 0x00, 12);
|
||||
strncpy(sprite->name, "bitmap", 12);
|
||||
sprite->width = bitmap->width - 1;
|
||||
sprite->height = bitmap->height - 1;
|
||||
@ -346,8 +360,6 @@ bool bitmap_get_opaque(struct bitmap *bitmap)
|
||||
|
||||
char *bitmap_get_buffer(struct bitmap *bitmap)
|
||||
{
|
||||
bool clear;
|
||||
|
||||
assert(bitmap);
|
||||
|
||||
/* move to the head of the list */
|
||||
@ -363,10 +375,14 @@ char *bitmap_get_buffer(struct bitmap *bitmap)
|
||||
}
|
||||
|
||||
/* dynamically create the buffer */
|
||||
if (bitmap->init != BITMAP_INITIALISE_DONE) {
|
||||
clear = (bitmap->init == BITMAP_INITIALISE_FULL);
|
||||
if (!bitmap_initialise(bitmap, clear))
|
||||
return NULL;
|
||||
switch (bitmap->state) {
|
||||
case BITMAP_ALLOCATE_MEMORY:
|
||||
case BITMAP_CLEAR_MEMORY:
|
||||
if (!bitmap_initialise(bitmap))
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* image is already decompressed, no change to image states */
|
||||
@ -591,7 +607,7 @@ void bitmap_decompress(struct bitmap *bitmap)
|
||||
}
|
||||
|
||||
/* create the image memory/header to decompress to */
|
||||
if (!bitmap_initialise(bitmap, false))
|
||||
if (!bitmap_initialise(bitmap))
|
||||
return;
|
||||
|
||||
/* decompress the data */
|
||||
|
@ -9,22 +9,17 @@
|
||||
#define _NETSURF_RISCOS_BITMAP_H_
|
||||
|
||||
#include "oslib/osspriteop.h"
|
||||
#include "netsurf/image/bitmap.h"
|
||||
|
||||
struct osspriteop_area;
|
||||
|
||||
typedef enum {
|
||||
BITMAP_INITIALISE_DONE, /** Initialisation has been done */
|
||||
BITMAP_INITIALISE_QUICK, /** Just allocate memory */
|
||||
BITMAP_INITIALISE_FULL /** Clear the sprite buffer */
|
||||
} bitmap_initialisation;
|
||||
|
||||
struct bitmap {
|
||||
int width;
|
||||
int height;
|
||||
bool opaque;
|
||||
bool modified;
|
||||
bool persistent;
|
||||
bitmap_initialisation init;
|
||||
bitmap_state state;
|
||||
|
||||
osspriteop_area *sprite_area; /** Uncompressed data, or NULL */
|
||||
char *compressed; /** Compressed data, or NULL */
|
||||
|
@ -178,7 +178,8 @@ void history_add(struct history *history, struct content *content, char *frag_id
|
||||
* loading */
|
||||
bitmap = url_store_get_thumbnail(url);
|
||||
if (!bitmap) {
|
||||
bitmap = bitmap_create(WIDTH / 2, HEIGHT / 2, false);
|
||||
bitmap = bitmap_create(WIDTH / 2, HEIGHT / 2,
|
||||
BITMAP_ALLOCATE_MEMORY);
|
||||
if (!bitmap) {
|
||||
LOG(("Thumbnail initialisation failed."));
|
||||
return;
|
||||
|
@ -1007,7 +1007,7 @@ bool ro_gui_save_create_thumbnail(struct content *c, const char *name)
|
||||
struct bitmap *bitmap;
|
||||
osspriteop_area *area;
|
||||
|
||||
bitmap = bitmap_create(34, 34, false);
|
||||
bitmap = bitmap_create(34, 34, BITMAP_CLEAR_MEMORY);
|
||||
if (!bitmap) {
|
||||
LOG(("Thumbnail initialisation failed."));
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user