consolidate content redraw

more cleanups ready for image content refactor

svn path=/trunk/netsurf/; revision=12317
This commit is contained in:
Vincent Sanders 2011-05-08 19:54:35 +00:00
parent 8f6c343309
commit 8be1e85e91
19 changed files with 549 additions and 758 deletions

View File

@ -463,60 +463,6 @@ void content_request_redraw(struct hlcache_handle *h,
content_broadcast(c, CONTENT_MSG_REDRAW, data); content_broadcast(c, CONTENT_MSG_REDRAW, data);
} }
/**
* Display content on screen.
*
* Calls the redraw function for the content, if it exists.
*
* \param h content
* \param x coordinate for top-left of redraw
* \param y coordinate for top-left of redraw
* \param width render width (not used for HTML redraw)
* \param height render height (not used for HTML redraw)
* \param clip clip rectangle
* \param scale scale for redraw
* \param background_colour the background colour
* \return true if successful, false otherwise
*
* x, y and clip are coordinates from the top left of the canvas area.
*
* The top left corner of the clip rectangle is (x0, y0) and
* the bottom right corner of the clip rectangle is (x1, y1).
* Units for x, y and clip are pixels.
*
* Content scaling is handled differently for contents with and without
* intrinsic dimensions.
*
* Content without intrinsic dimensions, e.g. HTML:
* The scale value is applied (the content having been reformatted
* appropriately beforehand). The width and height are not used.
*
* Content with intrinsic dimensions, e.g. images:
* The scale value is not used. The content is scaled from its own
* intrinsic dimensions to the passed render width and height.
*/
bool content_redraw(hlcache_handle *h, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
if (c->locked) {
/* not safe to attempt redraw */
return true;
}
if (c->handler->redraw == NULL) {
return true;
}
return c->handler->redraw(c, x, y, width, height,
clip, scale, background_colour);
}
/** /**
* Display content on screen with optional tiling. * Display content on screen with optional tiling.
* *
@ -524,59 +470,28 @@ bool content_redraw(hlcache_handle *h, int x, int y,
* redraw function if it doesn't exist. * redraw function if it doesn't exist.
*/ */
bool content_redraw_tiled(hlcache_handle *h, int x, int y, bool content_redraw(hlcache_handle *h, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y) bool repeat_x, bool repeat_y)
{ {
struct content *c = hlcache_handle_get_content(h); struct content *c = hlcache_handle_get_content(h);
int x0, y0, x1, y1;
assert(c != 0); assert(c != NULL);
// LOG(("%p %s", c, c->url)); if (c->locked) {
if (c->locked)
/* not safe to attempt redraw */ /* not safe to attempt redraw */
return true; return true;
}
if (c->handler->redraw_tiled != NULL) { /* ensure we have a redrawable content */
return c->handler->redraw_tiled(c, x, y, width, height, if (c->handler->redraw == NULL) {
return true;
}
return c->handler->redraw(c, x, y, width, height,
clip, scale, background_colour, clip, scale, background_colour,
repeat_x, repeat_y); repeat_x, repeat_y);
} else {
/* ensure we have a redrawable content */
if ((c->handler->redraw == NULL) || (width == 0) ||
(height == 0))
return true;
/* simple optimisation for no repeat (common for backgrounds) */
if ((!repeat_x) && (!repeat_y))
return c->handler->redraw(c, x, y, width,
height, clip, 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 (!c->handler->redraw(c, x, y,
width, height, clip,
scale, background_colour))
return false;
}
return true;
} }

View File

@ -125,9 +125,6 @@ void content_mouse_track(struct hlcache_handle *h, struct browser_window *bw,
void content_mouse_action(struct hlcache_handle *h, struct browser_window *bw, void content_mouse_action(struct hlcache_handle *h, struct browser_window *bw,
browser_mouse_state mouse, int x, int y); browser_mouse_state mouse, int x, int y);
bool content_redraw(struct hlcache_handle *h, int x, int y, bool content_redraw(struct hlcache_handle *h, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
bool content_redraw_tiled(struct hlcache_handle *h, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y); bool repeat_x, bool repeat_y);

View File

@ -55,9 +55,6 @@ struct content_handler {
void (*mouse_action)(struct content *c, struct browser_window *bw, void (*mouse_action)(struct content *c, struct browser_window *bw,
browser_mouse_state mouse, int x, int y); browser_mouse_state mouse, int x, int y);
bool (*redraw)(struct content *c, int x, int y, bool (*redraw)(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
bool (*redraw_tiled)(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y); bool repeat_x, bool repeat_y);

View File

@ -90,7 +90,6 @@ static const content_handler css_content_handler = {
NULL, NULL,
NULL, NULL,
NULL, NULL,
NULL,
nscss_clone, nscss_clone,
nscss_matches_quirks, nscss_matches_quirks,
nscss_content_type, nscss_content_type,

View File

@ -131,7 +131,7 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y,
/* Render the content */ /* Render the content */
plot_ok &= content_redraw(bw->current_content, x, y, width, height, plot_ok &= content_redraw(bw->current_content, x, y, width, height,
clip, bw->scale, 0xFFFFFF); clip, bw->scale, 0xFFFFFF, false, false);
if (plot.option_knockout) if (plot.option_knockout)
knockout_plot_end(); knockout_plot_end();

View File

@ -137,7 +137,7 @@ bool print_draw_next_page(const struct printer *printer,
printer->print_next_page(); printer->print_next_page();
if (!content_redraw(printed_content, 0, -done_height, if (!content_redraw(printed_content, 0, -done_height,
0, 0, 0, 0,
&clip, settings->scale, 0xffffff)) &clip, settings->scale, 0xffffff, false, false))
return false; return false;
done_height += page_content_height - done_height += page_content_height -

View File

@ -88,7 +88,7 @@ bool thumbnail_redraw(struct hlcache_handle *content,
/* Render the content */ /* Render the content */
plot_ok &= content_redraw(content, 0, 0, width, height, &clip, scale, plot_ok &= content_redraw(content, 0, 0, width, height, &clip, scale,
0xFFFFFF); 0xFFFFFF, false, false);
if (plot.option_knockout) if (plot.option_knockout)
knockout_plot_end(); knockout_plot_end();

View File

@ -1623,7 +1623,7 @@ static void tree_draw_node_element(struct tree *tree,
plot.clip(&c); plot.clip(&c);
content_redraw(icon , x, y + icon_inset, content_redraw(icon , x, y + icon_inset,
TREE_ICON_SIZE, TREE_ICON_SIZE, TREE_ICON_SIZE, TREE_ICON_SIZE,
&c, 1, 0); &c, 1, 0, false, false);
/* Restore previous clipping area */ /* Restore previous clipping area */
plot.clip(clip); plot.clip(clip);

View File

@ -39,6 +39,12 @@
$(shell $(PKG_CONFIG) --cflags openssl) \ $(shell $(PKG_CONFIG) --cflags openssl) \
$(shell xml2-config --cflags) $(shell xml2-config --cflags)
# The GTK build can also enable the following deprication flags
# -DG_DISABLE_SINGLE_INCLUDES -DG_DISABLE_DEPRECATED
# -DGTK_DISABLE_SINGLE_INCLUDES -DPANGO_DISABLE_DEPRECATED
# -DGDK_PIXBUF_DISABLE_DEPRECATED -DGDK_DISABLE_DEPRECATED
# -DGTK_DISABLE_DEPRECATED -DGTK_MULTIHEAD_SAFE
GTKLDFLAGS := $(shell $(PKG_CONFIG) --cflags --libs libglade-2.0 gtk+-2.0 gthread-2.0 gmodule-2.0 lcms) GTKLDFLAGS := $(shell $(PKG_CONFIG) --cflags --libs libglade-2.0 gtk+-2.0 gthread-2.0 gmodule-2.0 lcms)
CFLAGS += $(GTKCFLAGS) CFLAGS += $(GTKCFLAGS)

View File

@ -46,54 +46,8 @@ typedef struct nsbmp_content {
bmp_image *bmp; /** BMP image data */ bmp_image *bmp; /** BMP image data */
} nsbmp_content; } nsbmp_content;
static nserror nsbmp_create(const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static nserror nsbmp_create_bmp_data(nsbmp_content *bmp);
static bool nsbmp_convert(struct content *c);
static void nsbmp_destroy(struct content *c);
static bool nsbmp_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
static bool nsbmp_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y);
static nserror nsbmp_clone(const struct content *old, struct content **newc);
static content_type nsbmp_content_type(lwc_string *mime_type);
static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state);
/* The Bitmap callbacks function table;
* necessary for interaction with nsbmplib.
*/
bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
.bitmap_create = nsbmp_bitmap_create,
.bitmap_destroy = bitmap_destroy,
.bitmap_set_suspendable = bitmap_set_suspendable,
.bitmap_get_buffer = bitmap_get_buffer,
.bitmap_get_bpp = bitmap_get_bpp
};
static const content_handler nsbmp_content_handler = {
nsbmp_create,
NULL,
nsbmp_convert,
NULL,
nsbmp_destroy,
NULL,
NULL,
NULL,
nsbmp_redraw,
nsbmp_redraw_tiled,
NULL,
NULL,
nsbmp_clone,
NULL,
nsbmp_content_type,
false
};
static const char *nsbmp_types[] = { static const char *nsbmp_types[] = {
"application/bmp", "application/bmp",
@ -112,46 +66,24 @@ static const char *nsbmp_types[] = {
static lwc_string *nsbmp_mime_types[NOF_ELEMENTS(nsbmp_types)]; static lwc_string *nsbmp_mime_types[NOF_ELEMENTS(nsbmp_types)];
nserror nsbmp_init(void) static nserror nsbmp_create_bmp_data(nsbmp_content *bmp)
{ {
uint32_t i; union content_msg_data msg_data;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) { bmp->bmp = calloc(sizeof(struct bmp_image), 1);
lerror = lwc_intern_string(nsbmp_types[i], if (bmp->bmp == NULL) {
strlen(nsbmp_types[i]), msg_data.error = messages_get("NoMemory");
&nsbmp_mime_types[i]); content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data);
if (lerror != lwc_error_ok) { return NSERROR_NOMEM;
error = NSERROR_NOMEM;
goto error;
} }
error = content_factory_register_handler(nsbmp_mime_types[i], bmp_create(bmp->bmp, &bmp_bitmap_callbacks);
&nsbmp_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK; return NSERROR_OK;
error:
nsbmp_fini();
return error;
} }
void nsbmp_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) { static nserror nsbmp_create(const content_handler *handler,
if (nsbmp_mime_types[i] != NULL)
lwc_string_unref(nsbmp_mime_types[i]);
}
}
nserror nsbmp_create(const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params, lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset, llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c) bool quirks, struct content **c)
@ -181,23 +113,39 @@ nserror nsbmp_create(const content_handler *handler,
return NSERROR_OK; return NSERROR_OK;
} }
nserror nsbmp_create_bmp_data(nsbmp_content *bmp) /**
* Callback for libnsbmp; forwards the call to bitmap_create()
*
* \param width width of image in pixels
* \param height width of image in pixels
* \param state a flag word indicating the initial state
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
static void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state)
{ {
union content_msg_data msg_data; unsigned int bitmap_state = BITMAP_NEW;
bmp->bmp = calloc(sizeof(struct bmp_image), 1); /* set bitmap state based on bmp state */
if (bmp->bmp == NULL) { bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0;
msg_data.error = messages_get("NoMemory"); bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ?
content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data); BITMAP_CLEAR_MEMORY : 0;
return NSERROR_NOMEM;
}
bmp_create(bmp->bmp, &bmp_bitmap_callbacks); /* return the created bitmap */
return bitmap_create(width, height, bitmap_state);
return NSERROR_OK;
} }
bool nsbmp_convert(struct content *c) /* The Bitmap callbacks function table;
* necessary for interaction with nsbmplib.
*/
bmp_bitmap_callback_vt bmp_bitmap_callbacks = {
.bitmap_create = nsbmp_bitmap_create,
.bitmap_destroy = bitmap_destroy,
.bitmap_set_suspendable = bitmap_set_suspendable,
.bitmap_get_buffer = bitmap_get_buffer,
.bitmap_get_bpp = bitmap_get_bpp
};
static bool nsbmp_convert(struct content *c)
{ {
nsbmp_content *bmp = (nsbmp_content *) c; nsbmp_content *bmp = (nsbmp_content *) c;
bmp_result res; bmp_result res;
@ -249,25 +197,7 @@ bool nsbmp_convert(struct content *c)
return true; return true;
} }
static bool nsbmp_redraw(struct content *c, int x, int y,
bool nsbmp_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
nsbmp_content *bmp = (nsbmp_content *) c;
if (bmp->bmp->decoded == false)
if (bmp_decode(bmp->bmp) != BMP_OK)
return false;
c->bitmap = bmp->bmp->bitmap;
return plot.bitmap(x, y, width, height, c->bitmap,
background_colour, BITMAPF_NONE);
}
bool nsbmp_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y) bool repeat_x, bool repeat_y)
@ -291,7 +221,7 @@ bool nsbmp_redraw_tiled(struct content *c, int x, int y,
} }
void nsbmp_destroy(struct content *c) static void nsbmp_destroy(struct content *c)
{ {
nsbmp_content *bmp = (nsbmp_content *) c; nsbmp_content *bmp = (nsbmp_content *) c;
@ -300,7 +230,7 @@ void nsbmp_destroy(struct content *c)
} }
nserror nsbmp_clone(const struct content *old, struct content **newc) static nserror nsbmp_clone(const struct content *old, struct content **newc)
{ {
nsbmp_content *new_bmp; nsbmp_content *new_bmp;
nserror error; nserror error;
@ -335,30 +265,67 @@ nserror nsbmp_clone(const struct content *old, struct content **newc)
return NSERROR_OK; return NSERROR_OK;
} }
content_type nsbmp_content_type(lwc_string *mime_type) static content_type nsbmp_content_type(lwc_string *mime_type)
{ {
return CONTENT_IMAGE; return CONTENT_IMAGE;
} }
/**
* Callback for libnsbmp; forwards the call to bitmap_create() static const content_handler nsbmp_content_handler = {
* nsbmp_create,
* \param width width of image in pixels NULL,
* \param height width of image in pixels nsbmp_convert,
* \param state a flag word indicating the initial state NULL,
* \return an opaque struct bitmap, or NULL on memory exhaustion nsbmp_destroy,
*/ NULL,
void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state) NULL,
NULL,
nsbmp_redraw,
NULL,
NULL,
nsbmp_clone,
NULL,
nsbmp_content_type,
false
};
nserror nsbmp_init(void)
{ {
unsigned int bitmap_state = BITMAP_NEW; uint32_t i;
lwc_error lerror;
nserror error;
/* set bitmap state based on bmp state */ for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) {
bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0; lerror = lwc_intern_string(nsbmp_types[i],
bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ? strlen(nsbmp_types[i]),
BITMAP_CLEAR_MEMORY : 0; &nsbmp_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
/* return the created bitmap */ error = content_factory_register_handler(nsbmp_mime_types[i],
return bitmap_create(width, height, bitmap_state); &nsbmp_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsbmp_fini();
return error;
}
void nsbmp_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) {
if (nsbmp_mime_types[i] != NULL)
lwc_string_unref(nsbmp_mime_types[i]);
}
} }
#endif #endif

View File

@ -56,32 +56,28 @@ typedef struct nsgif_content {
int current_frame; /**< current frame to display [0...(max-1)] */ int current_frame; /**< current frame to display [0...(max-1)] */
} nsgif_content; } nsgif_content;
static nserror nsgif_create(const content_handler *handler, static const char *nsgif_types[] = {
lwc_string *imime_type, const struct http_parameter *params, "image/gif"
llcache_handle *llcache, const char *fallback_charset, };
bool quirks, struct content **c);
static nserror nsgif_create_gif_data(nsgif_content *c);
static bool nsgif_convert(struct content *c);
static void nsgif_destroy(struct content *c);
static bool nsgif_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
static bool nsgif_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y);
static nserror nsgif_clone(const struct content *old, struct content **newc);
static content_type nsgif_content_type(lwc_string *mime_type);
static void *nsgif_bitmap_create(int width, int height); static lwc_string *nsgif_mime_types[NOF_ELEMENTS(nsgif_types)];
static void nsgif_invalidate(void *bitmap, void *private_word);
static void nsgif_animate(void *p); /**
static gif_result nsgif_get_frame(struct content *c); * Callback for libnsgif; forwards the call to bitmap_create()
*
* \param width width of image in pixels
* \param height width of image in pixels
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/
static void *nsgif_bitmap_create(int width, int height)
{
return bitmap_create(width, height, BITMAP_NEW);
}
/* The Bitmap callbacks function table; /* The Bitmap callbacks function table;
* necessary for interaction with nsgiflib. * necessary for interaction with nsgiflib.
*/ */
gif_bitmap_callback_vt gif_bitmap_callbacks = { static gif_bitmap_callback_vt gif_bitmap_callbacks = {
.bitmap_create = nsgif_bitmap_create, .bitmap_create = nsgif_bitmap_create,
.bitmap_destroy = bitmap_destroy, .bitmap_destroy = bitmap_destroy,
.bitmap_get_buffer = bitmap_get_buffer, .bitmap_get_buffer = bitmap_get_buffer,
@ -90,71 +86,24 @@ gif_bitmap_callback_vt gif_bitmap_callbacks = {
.bitmap_modified = bitmap_modified .bitmap_modified = bitmap_modified
}; };
static const content_handler nsgif_content_handler = { static nserror nsgif_create_gif_data(nsgif_content *c)
nsgif_create,
NULL,
nsgif_convert,
NULL,
nsgif_destroy,
NULL,
NULL,
NULL,
nsgif_redraw,
nsgif_redraw_tiled,
NULL,
NULL,
nsgif_clone,
NULL,
nsgif_content_type,
false
};
static const char *nsgif_types[] = {
"image/gif"
};
static lwc_string *nsgif_mime_types[NOF_ELEMENTS(nsgif_types)];
nserror nsgif_init(void)
{ {
uint32_t i; union content_msg_data msg_data;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) { /* Initialise our data structure */
lerror = lwc_intern_string(nsgif_types[i], c->gif = calloc(sizeof(gif_animation), 1);
strlen(nsgif_types[i]), if (c->gif == NULL) {
&nsgif_mime_types[i]); msg_data.error = messages_get("NoMemory");
if (lerror != lwc_error_ok) { content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
error = NSERROR_NOMEM; return NSERROR_NOMEM;
goto error;
} }
gif_create(c->gif, &gif_bitmap_callbacks);
error = content_factory_register_handler(nsgif_mime_types[i],
&nsgif_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK; return NSERROR_OK;
error:
nsgif_fini();
return error;
} }
void nsgif_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) {
if (nsgif_mime_types[i] != NULL)
lwc_string_unref(nsgif_mime_types[i]);
}
}
nserror nsgif_create(const content_handler *handler, static nserror nsgif_create(const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params, lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset, llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c) bool quirks, struct content **c)
@ -184,216 +133,12 @@ nserror nsgif_create(const content_handler *handler,
return NSERROR_OK; return NSERROR_OK;
} }
nserror nsgif_create_gif_data(nsgif_content *c)
{
union content_msg_data msg_data;
/* Initialise our data structure */
c->gif = calloc(sizeof(gif_animation), 1);
if (c->gif == NULL) {
msg_data.error = messages_get("NoMemory");
content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
return NSERROR_NOMEM;
}
gif_create(c->gif, &gif_bitmap_callbacks);
return NSERROR_OK;
}
bool nsgif_convert(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
int res;
union content_msg_data msg_data;
const char *data;
unsigned long size;
char title[100];
/* Get the animation */
data = content__get_source_data(c, &size);
/* Initialise the GIF */
do {
res = gif_initialise(gif->gif, size, (unsigned char *) data);
if (res != GIF_OK && res != GIF_WORKING &&
res != GIF_INSUFFICIENT_FRAME_DATA) {
switch (res) {
case GIF_FRAME_DATA_ERROR:
case GIF_INSUFFICIENT_DATA:
case GIF_DATA_ERROR:
msg_data.error = messages_get("BadGIF");
break;
case GIF_INSUFFICIENT_MEMORY:
msg_data.error = messages_get("NoMemory");
break;
}
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
} while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA);
/* Abort on bad GIFs */
if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) ||
(gif->gif->height == 0)) {
msg_data.error = messages_get("BadGIF");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
/* Store our content width and description */
c->width = gif->gif->width;
c->height = gif->gif->height;
snprintf(title, sizeof(title), messages_get("GIFTitle"),
c->width, c->height, size);
content__set_title(c, title);
c->size += (gif->gif->width * gif->gif->height * 4) + 16 + 44;
/* Schedule the animation if we have one */
gif->current_frame = 0;
if (gif->gif->frame_count_partial > 1)
schedule(gif->gif->frames[0].frame_delay, nsgif_animate, c);
else
bitmap_set_suspendable(gif->gif->frame_image, gif->gif,
nsgif_invalidate);
/* Exit as a success */
c->bitmap = gif->gif->frame_image;
content_set_ready(c);
content_set_done(c);
/* Done: update status bar */
content_set_status(c, "");
return true;
}
void nsgif_invalidate(void *bitmap, void *private_word)
{
struct gif_animation *gif = (struct gif_animation *)private_word;
gif->decoded_frame = -1;
}
bool nsgif_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
nsgif_content *gif = (nsgif_content *) c;
if (gif->current_frame != gif->gif->decoded_frame)
if (nsgif_get_frame(c) != GIF_OK)
return false;
c->bitmap = gif->gif->frame_image;
if ((width == -1) && (height == -1))
return true;
return plot.bitmap(x, y, width, height, c->bitmap,
background_colour, BITMAPF_NONE);
}
bool nsgif_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{
nsgif_content *gif = (nsgif_content *) c;
bitmap_flags_t flags = BITMAPF_NONE;
if (gif->current_frame != gif->gif->decoded_frame)
if (nsgif_get_frame(c) != GIF_OK)
return false;
c->bitmap = gif->gif->frame_image;
if (repeat_x)
flags |= BITMAPF_REPEAT_X;
if (repeat_y)
flags |= BITMAPF_REPEAT_Y;
return plot.bitmap(x, y, width, height, c->bitmap, background_colour, flags);
}
void nsgif_destroy(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
/* Free all the associated memory buffers */
schedule_remove(nsgif_animate, c);
gif_finalise(gif->gif);
free(gif->gif);
}
nserror nsgif_clone(const struct content *old, struct content **newc)
{
nsgif_content *gif;
nserror error;
gif = talloc_zero(0, nsgif_content);
if (gif == NULL)
return NSERROR_NOMEM;
error = content__clone(old, &gif->base);
if (error != NSERROR_OK) {
content_destroy(&gif->base);
return error;
}
/* Simply replay creation and conversion of content */
error = nsgif_create_gif_data(gif);
if (error != NSERROR_OK) {
content_destroy(&gif->base);
return error;
}
if (old->status == CONTENT_STATUS_READY ||
old->status == CONTENT_STATUS_DONE) {
if (nsgif_convert(&gif->base) == false) {
content_destroy(&gif->base);
return NSERROR_CLONE_FAILED;
}
}
*newc = (struct content *) gif;
return NSERROR_OK;
}
content_type nsgif_content_type(lwc_string *mime_type)
{
return CONTENT_IMAGE;
}
/**
* Updates the GIF bitmap to display the current frame
*
* \param c the content to update
*/
gif_result nsgif_get_frame(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
int previous_frame, current_frame, frame;
gif_result res = GIF_OK;
current_frame = gif->current_frame;
if (!option_animate_images)
current_frame = 0;
if (current_frame < gif->gif->decoded_frame)
previous_frame = 0;
else
previous_frame = gif->gif->decoded_frame + 1;
for (frame = previous_frame; frame <= current_frame; frame++)
res = gif_decode_frame(gif->gif, frame);
return res;
}
/** /**
* Performs any necessary animation. * Performs any necessary animation.
* *
* \param p The content to animate * \param p The content to animate
*/ */
void nsgif_animate(void *p) static void nsgif_animate(void *p)
{ {
nsgif_content *gif = p; nsgif_content *gif = p;
union content_msg_data data; union content_msg_data data;
@ -496,17 +241,236 @@ void nsgif_animate(void *p)
content_broadcast(&gif->base, CONTENT_MSG_REDRAW, data); content_broadcast(&gif->base, CONTENT_MSG_REDRAW, data);
} }
static void nsgif_invalidate(void *bitmap, void *private_word)
{
struct gif_animation *gif = (struct gif_animation *)private_word;
gif->decoded_frame = -1;
}
static bool nsgif_convert(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
int res;
union content_msg_data msg_data;
const char *data;
unsigned long size;
char title[100];
/* Get the animation */
data = content__get_source_data(c, &size);
/* Initialise the GIF */
do {
res = gif_initialise(gif->gif, size, (unsigned char *) data);
if (res != GIF_OK && res != GIF_WORKING &&
res != GIF_INSUFFICIENT_FRAME_DATA) {
switch (res) {
case GIF_FRAME_DATA_ERROR:
case GIF_INSUFFICIENT_DATA:
case GIF_DATA_ERROR:
msg_data.error = messages_get("BadGIF");
break;
case GIF_INSUFFICIENT_MEMORY:
msg_data.error = messages_get("NoMemory");
break;
}
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
} while (res != GIF_OK && res != GIF_INSUFFICIENT_FRAME_DATA);
/* Abort on bad GIFs */
if ((gif->gif->frame_count_partial == 0) || (gif->gif->width == 0) ||
(gif->gif->height == 0)) {
msg_data.error = messages_get("BadGIF");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
/* Store our content width and description */
c->width = gif->gif->width;
c->height = gif->gif->height;
snprintf(title, sizeof(title), messages_get("GIFTitle"),
c->width, c->height, size);
content__set_title(c, title);
c->size += (gif->gif->width * gif->gif->height * 4) + 16 + 44;
/* Schedule the animation if we have one */
gif->current_frame = 0;
if (gif->gif->frame_count_partial > 1)
schedule(gif->gif->frames[0].frame_delay, nsgif_animate, c);
else
bitmap_set_suspendable(gif->gif->frame_image, gif->gif,
nsgif_invalidate);
/* Exit as a success */
c->bitmap = gif->gif->frame_image;
content_set_ready(c);
content_set_done(c);
/* Done: update status bar */
content_set_status(c, "");
return true;
}
/** /**
* Callback for libnsgif; forwards the call to bitmap_create() * Updates the GIF bitmap to display the current frame
* *
* \param width width of image in pixels * \param c the content to update
* \param height width of image in pixels
* \return an opaque struct bitmap, or NULL on memory exhaustion
*/ */
void *nsgif_bitmap_create(int width, int height) static gif_result nsgif_get_frame(struct content *c)
{ {
return bitmap_create(width, height, BITMAP_NEW); nsgif_content *gif = (nsgif_content *) c;
int previous_frame, current_frame, frame;
gif_result res = GIF_OK;
current_frame = gif->current_frame;
if (!option_animate_images)
current_frame = 0;
if (current_frame < gif->gif->decoded_frame)
previous_frame = 0;
else
previous_frame = gif->gif->decoded_frame + 1;
for (frame = previous_frame; frame <= current_frame; frame++)
res = gif_decode_frame(gif->gif, frame);
return res;
}
static bool nsgif_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{
nsgif_content *gif = (nsgif_content *) c;
bitmap_flags_t flags = BITMAPF_NONE;
if (gif->current_frame != gif->gif->decoded_frame)
if (nsgif_get_frame(c) != GIF_OK)
return false;
c->bitmap = gif->gif->frame_image;
if ((width == -1) && (height == -1))
return true;
if (repeat_x)
flags |= BITMAPF_REPEAT_X;
if (repeat_y)
flags |= BITMAPF_REPEAT_Y;
return plot.bitmap(x, y, width, height, c->bitmap, background_colour, flags);
}
static void nsgif_destroy(struct content *c)
{
nsgif_content *gif = (nsgif_content *) c;
/* Free all the associated memory buffers */
schedule_remove(nsgif_animate, c);
gif_finalise(gif->gif);
free(gif->gif);
}
static nserror nsgif_clone(const struct content *old, struct content **newc)
{
nsgif_content *gif;
nserror error;
gif = talloc_zero(0, nsgif_content);
if (gif == NULL)
return NSERROR_NOMEM;
error = content__clone(old, &gif->base);
if (error != NSERROR_OK) {
content_destroy(&gif->base);
return error;
}
/* Simply replay creation and conversion of content */
error = nsgif_create_gif_data(gif);
if (error != NSERROR_OK) {
content_destroy(&gif->base);
return error;
}
if (old->status == CONTENT_STATUS_READY ||
old->status == CONTENT_STATUS_DONE) {
if (nsgif_convert(&gif->base) == false) {
content_destroy(&gif->base);
return NSERROR_CLONE_FAILED;
}
}
*newc = (struct content *) gif;
return NSERROR_OK;
}
static content_type nsgif_content_type(lwc_string *mime_type)
{
return CONTENT_IMAGE;
}
static const content_handler nsgif_content_handler = {
nsgif_create,
NULL,
nsgif_convert,
NULL,
nsgif_destroy,
NULL,
NULL,
NULL,
nsgif_redraw,
NULL,
NULL,
nsgif_clone,
NULL,
nsgif_content_type,
false
};
nserror nsgif_init(void)
{
uint32_t i;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) {
lerror = lwc_intern_string(nsgif_types[i],
strlen(nsgif_types[i]),
&nsgif_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(nsgif_mime_types[i],
&nsgif_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsgif_fini();
return error;
}
void nsgif_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsgif_mime_types); i++) {
if (nsgif_mime_types[i] != NULL)
lwc_string_unref(nsgif_mime_types[i]);
}
} }
#endif #endif

View File

@ -46,42 +46,6 @@ typedef struct nsico_content {
struct ico_collection *ico; /** ICO collection data */ struct ico_collection *ico; /** ICO collection data */
} nsico_content; } nsico_content;
static nserror nsico_create(const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static nserror nsico_create_ico_data(nsico_content *c);
static bool nsico_convert(struct content *c);
static void nsico_destroy(struct content *c);
static bool nsico_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
static bool nsico_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour,
bool repeat_x, bool repeat_y);
static nserror nsico_clone(const struct content *old, struct content **newc);
static content_type nsico_content_type(lwc_string *mime_type);
static const content_handler nsico_content_handler = {
nsico_create,
NULL,
nsico_convert,
NULL,
nsico_destroy,
NULL,
NULL,
NULL,
nsico_redraw,
nsico_redraw_tiled,
NULL,
NULL,
nsico_clone,
NULL,
nsico_content_type,
false
};
static const char *nsico_types[] = { static const char *nsico_types[] = {
"application/ico", "application/ico",
"application/x-ico", "application/x-ico",
@ -92,46 +56,23 @@ static const char *nsico_types[] = {
static lwc_string *nsico_mime_types[NOF_ELEMENTS(nsico_types)]; static lwc_string *nsico_mime_types[NOF_ELEMENTS(nsico_types)];
nserror nsico_init(void)
static nserror nsico_create_ico_data(nsico_content *c)
{ {
uint32_t i; union content_msg_data msg_data;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) { c->ico = calloc(sizeof(ico_collection), 1);
lerror = lwc_intern_string(nsico_types[i], if (c->ico == NULL) {
strlen(nsico_types[i]), msg_data.error = messages_get("NoMemory");
&nsico_mime_types[i]); content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
if (lerror != lwc_error_ok) { return NSERROR_NOMEM;
error = NSERROR_NOMEM;
goto error;
} }
ico_collection_create(c->ico, &bmp_bitmap_callbacks);
error = content_factory_register_handler(nsico_mime_types[i],
&nsico_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK; return NSERROR_OK;
error:
nsico_fini();
return error;
} }
void nsico_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) { static nserror nsico_create(const content_handler *handler,
if (nsico_mime_types[i] != NULL)
lwc_string_unref(nsico_mime_types[i]);
}
}
nserror nsico_create(const content_handler *handler,
lwc_string *imime_type, const struct http_parameter *params, lwc_string *imime_type, const struct http_parameter *params,
llcache_handle *llcache, const char *fallback_charset, llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c) bool quirks, struct content **c)
@ -161,22 +102,9 @@ nserror nsico_create(const content_handler *handler,
return NSERROR_OK; return NSERROR_OK;
} }
nserror nsico_create_ico_data(nsico_content *c)
{
union content_msg_data msg_data;
c->ico = calloc(sizeof(ico_collection), 1);
if (c->ico == NULL) {
msg_data.error = messages_get("NoMemory");
content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
return NSERROR_NOMEM;
}
ico_collection_create(c->ico, &bmp_bitmap_callbacks);
return NSERROR_OK;
}
bool nsico_convert(struct content *c) static bool nsico_convert(struct content *c)
{ {
nsico_content *ico = (nsico_content *) c; nsico_content *ico = (nsico_content *) c;
struct bmp_image *bmp; struct bmp_image *bmp;
@ -228,21 +156,8 @@ bool nsico_convert(struct content *c)
return true; return true;
} }
bool nsico_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
nsico_content *ico = (nsico_content *) c;
struct bmp_image *bmp = ico_find(ico->ico, width, height);
if (!bmp->decoded)
if (bmp_decode(bmp) != BMP_OK)
return false;
c->bitmap = bmp->bitmap;
return plot.bitmap(x, y, width, height, c->bitmap,
background_colour, BITMAPF_NONE);
}
bool nsico_redraw_tiled(struct content *c, int x, int y, static bool nsico_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y) bool repeat_x, bool repeat_y)
@ -266,7 +181,7 @@ bool nsico_redraw_tiled(struct content *c, int x, int y,
} }
void nsico_destroy(struct content *c) static void nsico_destroy(struct content *c)
{ {
nsico_content *ico = (nsico_content *) c; nsico_content *ico = (nsico_content *) c;
@ -274,7 +189,7 @@ void nsico_destroy(struct content *c)
free(ico->ico); free(ico->ico);
} }
nserror nsico_clone(const struct content *old, struct content **newc) static nserror nsico_clone(const struct content *old, struct content **newc)
{ {
nsico_content *ico; nsico_content *ico;
nserror error; nserror error;
@ -309,9 +224,67 @@ nserror nsico_clone(const struct content *old, struct content **newc)
return NSERROR_OK; return NSERROR_OK;
} }
content_type nsico_content_type(lwc_string *mime_type) static content_type nsico_content_type(lwc_string *mime_type)
{ {
return CONTENT_IMAGE; return CONTENT_IMAGE;
} }
static const content_handler nsico_content_handler = {
nsico_create,
NULL,
nsico_convert,
NULL,
nsico_destroy,
NULL,
NULL,
NULL,
nsico_redraw,
NULL,
NULL,
nsico_clone,
NULL,
nsico_content_type,
false
};
nserror nsico_init(void)
{
uint32_t i;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) {
lerror = lwc_intern_string(nsico_types[i],
strlen(nsico_types[i]),
&nsico_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(nsico_mime_types[i],
&nsico_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsico_fini();
return error;
}
void nsico_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(nsico_mime_types); i++) {
if (nsico_mime_types[i] != NULL)
lwc_string_unref(nsico_mime_types[i]);
}
}
#endif #endif

View File

@ -274,22 +274,10 @@ static void nsjpeg_destroy(struct content *c)
} }
/**
* Redraw a CONTENT_JPEG.
*/
static bool nsjpeg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
return plot.bitmap(x, y, width, height,
c->bitmap, background_colour, BITMAPF_NONE);
}
/** /**
* Redraw a CONTENT_JPEG with appropriate tiling. * Redraw a CONTENT_JPEG with appropriate tiling.
*/ */
static bool nsjpeg_redraw_tiled(struct content *c, int x, int y, static bool nsjpeg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y) bool repeat_x, bool repeat_y)
@ -356,7 +344,6 @@ static const content_handler nsjpeg_content_handler = {
NULL, NULL,
NULL, NULL,
nsjpeg_redraw, nsjpeg_redraw,
nsjpeg_redraw_tiled,
NULL, NULL,
NULL, NULL,
nsjpeg_clone, nsjpeg_clone,

View File

@ -344,24 +344,12 @@ static void nspng_destroy(struct content *c)
static bool nspng_redraw(struct content *c, int x, int y, static bool nspng_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour)
{
nspng_content *png_c = (nspng_content *) c;
assert(png_c->bitmap != NULL);
return plot.bitmap(x, y, width, height, png_c->bitmap,
background_colour, BITMAPF_NONE);
}
static bool nspng_redraw_tiled(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour, float scale, colour background_colour,
bool repeat_x, bool repeat_y) bool repeat_x, bool repeat_y)
{ {
nspng_content *png_c = (nspng_content *) c; nspng_content *png_c = (nspng_content *) c;
bitmap_flags_t flags = 0; bitmap_flags_t flags = BITMAPF_NONE;
assert(png_c->bitmap != NULL); assert(png_c->bitmap != NULL);
@ -434,7 +422,6 @@ static const content_handler nspng_content_handler = {
NULL, NULL,
NULL, NULL,
nspng_redraw, nspng_redraw,
nspng_redraw_tiled,
NULL, NULL,
NULL, NULL,
nspng_clone, nspng_clone,

View File

@ -56,42 +56,7 @@ typedef struct rsvg_content {
struct bitmap *bitmap; /**< Created NetSurf bitmap */ struct bitmap *bitmap; /**< Created NetSurf bitmap */
} rsvg_content; } rsvg_content;
static nserror rsvg_create(const content_handler *handler,
lwc_string *imime_type, const http_parameter *params,
llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c);
static nserror rsvg_create_svg_data(rsvg_content *c);
static bool rsvg_process_data(struct content *c, const char *data,
unsigned int size);
static bool rsvg_convert(struct content *c);
static void rsvg_destroy(struct content *c);
static bool rsvg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip,
float scale, colour background_colour);
static nserror rsvg_clone(const struct content *old, struct content **newc);
static content_type rsvg_content_type(lwc_string *mime_type);
static inline void rsvg_argb_to_abgr(uint8_t *pixels,
int width, int height, size_t rowstride);
static const content_handler rsvg_content_handler = {
rsvg_create,
rsvg_process_data,
rsvg_convert,
NULL,
rsvg_destroy,
NULL,
NULL,
NULL,
rsvg_redraw,
NULL,
NULL,
NULL,
rsvg_clone,
NULL,
rsvg_content_type,
false
};
static const char *rsvg_types[] = { static const char *rsvg_types[] = {
"image/svg", "image/svg",
@ -100,46 +65,28 @@ static const char *rsvg_types[] = {
static lwc_string *rsvg_mime_types[NOF_ELEMENTS(rsvg_types)]; static lwc_string *rsvg_mime_types[NOF_ELEMENTS(rsvg_types)];
nserror nsrsvg_init(void)
static nserror rsvg_create_svg_data(rsvg_content *c)
{ {
uint32_t i; union content_msg_data msg_data;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) { c->rsvgh = NULL;
lerror = lwc_intern_string(rsvg_types[i], c->cs = NULL;
strlen(rsvg_types[i]), c->ct = NULL;
&rsvg_mime_types[i]); c->bitmap = NULL;
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(rsvg_mime_types[i], if ((c->rsvgh = rsvg_handle_new()) == NULL) {
&rsvg_content_handler); LOG(("rsvg_handle_new() returned NULL."));
if (error != NSERROR_OK) msg_data.error = messages_get("NoMemory");
goto error; content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
return NSERROR_NOMEM;
} }
return NSERROR_OK; return NSERROR_OK;
error:
nsrsvg_fini();
return error;
} }
void nsrsvg_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) { static nserror rsvg_create(const content_handler *handler,
if (rsvg_mime_types[i] != NULL)
lwc_string_unref(rsvg_mime_types[i]);
}
}
nserror rsvg_create(const content_handler *handler,
lwc_string *imime_type, const http_parameter *params, lwc_string *imime_type, const http_parameter *params,
llcache_handle *llcache, const char *fallback_charset, llcache_handle *llcache, const char *fallback_charset,
bool quirks, struct content **c) bool quirks, struct content **c)
@ -169,26 +116,8 @@ nserror rsvg_create(const content_handler *handler,
return NSERROR_OK; return NSERROR_OK;
} }
nserror rsvg_create_svg_data(rsvg_content *c)
{
union content_msg_data msg_data;
c->rsvgh = NULL; static bool rsvg_process_data(struct content *c, const char *data,
c->cs = NULL;
c->ct = NULL;
c->bitmap = NULL;
if ((c->rsvgh = rsvg_handle_new()) == NULL) {
LOG(("rsvg_handle_new() returned NULL."));
msg_data.error = messages_get("NoMemory");
content_broadcast(&c->base, CONTENT_MSG_ERROR, msg_data);
return NSERROR_NOMEM;
}
return NSERROR_OK;
}
bool rsvg_process_data(struct content *c, const char *data,
unsigned int size) unsigned int size)
{ {
rsvg_content *d = (rsvg_content *) c; rsvg_content *d = (rsvg_content *) c;
@ -235,7 +164,7 @@ static inline void rsvg_argb_to_abgr(uint8_t *pixels,
} }
} }
bool rsvg_convert(struct content *c) static bool rsvg_convert(struct content *c)
{ {
rsvg_content *d = (rsvg_content *) c; rsvg_content *d = (rsvg_content *) c;
union content_msg_data msg_data; union content_msg_data msg_data;
@ -300,15 +229,25 @@ bool rsvg_convert(struct content *c)
return true; return true;
} }
bool rsvg_redraw(struct content *c, int x, int y, static bool rsvg_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour) float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{ {
plot.bitmap(x, y, width, height, c->bitmap, background_colour, BITMAPF_NONE); bitmap_flags_t flags = BITMAPF_NONE;
return true;
assert(c->bitmap != NULL);
if (repeat_x)
flags |= BITMAPF_REPEAT_X;
if (repeat_y)
flags |= BITMAPF_REPEAT_Y;
return plot.bitmap(x, y, width, height,
c->bitmap, background_colour, flags);
} }
void rsvg_destroy(struct content *c) static void rsvg_destroy(struct content *c)
{ {
rsvg_content *d = (rsvg_content *) c; rsvg_content *d = (rsvg_content *) c;
@ -320,7 +259,7 @@ void rsvg_destroy(struct content *c)
return; return;
} }
nserror rsvg_clone(const struct content *old, struct content **newc) static nserror rsvg_clone(const struct content *old, struct content **newc)
{ {
rsvg_content *svg; rsvg_content *svg;
nserror error; nserror error;
@ -365,9 +304,66 @@ nserror rsvg_clone(const struct content *old, struct content **newc)
return NSERROR_OK; return NSERROR_OK;
} }
content_type rsvg_content_type(lwc_string *mime_type) static content_type rsvg_content_type(lwc_string *mime_type)
{ {
return CONTENT_IMAGE; return CONTENT_IMAGE;
} }
static const content_handler rsvg_content_handler = {
rsvg_create,
rsvg_process_data,
rsvg_convert,
NULL,
rsvg_destroy,
NULL,
NULL,
NULL,
rsvg_redraw,
NULL,
NULL,
rsvg_clone,
NULL,
rsvg_content_type,
false
};
nserror nsrsvg_init(void)
{
uint32_t i;
lwc_error lerror;
nserror error;
for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) {
lerror = lwc_intern_string(rsvg_types[i],
strlen(rsvg_types[i]),
&rsvg_mime_types[i]);
if (lerror != lwc_error_ok) {
error = NSERROR_NOMEM;
goto error;
}
error = content_factory_register_handler(rsvg_mime_types[i],
&rsvg_content_handler);
if (error != NSERROR_OK)
goto error;
}
return NSERROR_OK;
error:
nsrsvg_fini();
return error;
}
void nsrsvg_fini(void)
{
uint32_t i;
for (i = 0; i < NOF_ELEMENTS(rsvg_mime_types); i++) {
if (rsvg_mime_types[i] != NULL)
lwc_string_unref(rsvg_mime_types[i]);
}
}
#endif /* WITH_RSVG */ #endif /* WITH_RSVG */

View File

@ -111,7 +111,6 @@ static const content_handler html_content_handler = {
html_mouse_track, html_mouse_track,
html_mouse_action, html_mouse_action,
html_redraw, html_redraw,
NULL,
html_open, html_open,
html_close, html_close,
html_clone, html_clone,

View File

@ -97,7 +97,8 @@ void html_set_status(html_content *c, const char *extra);
/* in render/html_redraw.c */ /* in render/html_redraw.c */
bool html_redraw(struct content *c, int x, int y, bool html_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour); float scale, colour background_colour,
bool repeat_x, bool repeat_y);
/* in render/html_interaction.c */ /* in render/html_interaction.c */
void html_mouse_track(struct content *c, struct browser_window *bw, void html_mouse_track(struct content *c, struct browser_window *bw,

View File

@ -113,7 +113,8 @@ bool html_redraw_debug = false;
bool html_redraw(struct content *c, int x, int y, bool html_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour) float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{ {
html_content *html = (html_content *) c; html_content *html = (html_content *) c;
struct box *box; struct box *box;
@ -655,7 +656,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
x_scrolled + padding_left, x_scrolled + padding_left,
y_scrolled + padding_top, y_scrolled + padding_top,
width, height, &r, scale, width, height, &r, scale,
current_background_color)) current_background_color,
false, false))
return false; return false;
} else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) { } else if (box->gadget && box->gadget->type == GADGET_CHECKBOX) {
@ -2169,7 +2171,7 @@ bool html_redraw_background(int x, int y, struct box *box, float scale,
if ((r.x0 < r.x1) && (r.y0 < r.y1)) { if ((r.x0 < r.x1) && (r.y0 < r.y1)) {
if (!plot.clip(&r)) if (!plot.clip(&r))
return false; return false;
if (!content_redraw_tiled( if (!content_redraw(
background->background, x, y, background->background, x, y,
ceilf(width * scale), ceilf(width * scale),
ceilf(height * scale), &r, ceilf(height * scale), &r,
@ -2310,7 +2312,7 @@ bool html_redraw_inline_background(int x, int y, struct box *box, float scale,
if ((r.x0 < r.x1) && (r.y0 < r.y1)) { if ((r.x0 < r.x1) && (r.y0 < r.y1)) {
if (!plot.clip(&r)) if (!plot.clip(&r))
return false; return false;
if (!content_redraw_tiled(box->background, x, y, if (!content_redraw(box->background, x, y,
ceilf(width * scale), ceilf(width * scale),
ceilf(height * scale), &r, ceilf(height * scale), &r,
scale, *background_colour, scale, *background_colour,

View File

@ -104,7 +104,8 @@ static void textplain_reformat(struct content *c, int width, int height);
static void textplain_destroy(struct content *c); static void textplain_destroy(struct content *c);
static bool textplain_redraw(struct content *c, int x, int y, static bool textplain_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour); float scale, colour background_colour,
bool redraw_x, bool redraw_y);
static nserror textplain_clone(const struct content *old, static nserror textplain_clone(const struct content *old,
struct content **newc); struct content **newc);
static content_type textplain_content_type(lwc_string *mime_type); static content_type textplain_content_type(lwc_string *mime_type);
@ -131,7 +132,6 @@ static const content_handler textplain_content_handler = {
textplain_redraw, textplain_redraw,
NULL, NULL,
NULL, NULL,
NULL,
textplain_clone, textplain_clone,
NULL, NULL,
textplain_content_type, textplain_content_type,
@ -687,7 +687,8 @@ void textplain_mouse_action(struct content *c, struct browser_window *bw,
bool textplain_redraw(struct content *c, int x, int y, bool textplain_redraw(struct content *c, int x, int y,
int width, int height, const struct rect *clip, int width, int height, const struct rect *clip,
float scale, colour background_colour) float scale, colour background_colour,
bool repeat_x, bool repeat_y)
{ {
textplain_content *text = (textplain_content *) c; textplain_content *text = (textplain_content *) c;
struct browser_window *bw = current_redraw_browser; struct browser_window *bw = current_redraw_browser;