mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 12:12:35 +03:00
consolidate content redraw
more cleanups ready for image content refactor svn path=/trunk/netsurf/; revision=12317
This commit is contained in:
parent
8f6c343309
commit
8be1e85e91
@ -463,60 +463,6 @@ void content_request_redraw(struct hlcache_handle *h,
|
||||
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.
|
||||
*
|
||||
@ -524,59 +470,28 @@ bool content_redraw(hlcache_handle *h, int x, int y,
|
||||
* 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,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
{
|
||||
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 */
|
||||
return true;
|
||||
|
||||
if (c->handler->redraw_tiled != NULL) {
|
||||
return c->handler->redraw_tiled(c, x, y, width, height,
|
||||
clip, scale, background_colour,
|
||||
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;
|
||||
|
||||
/* ensure we have a redrawable content */
|
||||
if (c->handler->redraw == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return c->handler->redraw(c, x, y, width, height,
|
||||
clip, scale, background_colour,
|
||||
repeat_x, repeat_y);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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,
|
||||
browser_mouse_state mouse, 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,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
|
@ -55,9 +55,6 @@ struct content_handler {
|
||||
void (*mouse_action)(struct content *c, struct browser_window *bw,
|
||||
browser_mouse_state mouse, 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,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y);
|
||||
|
@ -90,7 +90,6 @@ static const content_handler css_content_handler = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
nscss_clone,
|
||||
nscss_matches_quirks,
|
||||
nscss_content_type,
|
||||
|
@ -131,7 +131,7 @@ bool browser_window_redraw(struct browser_window *bw, int x, int y,
|
||||
|
||||
/* Render the content */
|
||||
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)
|
||||
knockout_plot_end();
|
||||
|
@ -137,7 +137,7 @@ bool print_draw_next_page(const struct printer *printer,
|
||||
printer->print_next_page();
|
||||
if (!content_redraw(printed_content, 0, -done_height,
|
||||
0, 0,
|
||||
&clip, settings->scale, 0xffffff))
|
||||
&clip, settings->scale, 0xffffff, false, false))
|
||||
return false;
|
||||
|
||||
done_height += page_content_height -
|
||||
|
@ -88,7 +88,7 @@ bool thumbnail_redraw(struct hlcache_handle *content,
|
||||
|
||||
/* Render the content */
|
||||
plot_ok &= content_redraw(content, 0, 0, width, height, &clip, scale,
|
||||
0xFFFFFF);
|
||||
0xFFFFFF, false, false);
|
||||
|
||||
if (plot.option_knockout)
|
||||
knockout_plot_end();
|
||||
|
@ -1623,7 +1623,7 @@ static void tree_draw_node_element(struct tree *tree,
|
||||
plot.clip(&c);
|
||||
content_redraw(icon , x, y + icon_inset,
|
||||
TREE_ICON_SIZE, TREE_ICON_SIZE,
|
||||
&c, 1, 0);
|
||||
&c, 1, 0, false, false);
|
||||
|
||||
/* Restore previous clipping area */
|
||||
plot.clip(clip);
|
||||
|
@ -39,6 +39,12 @@
|
||||
$(shell $(PKG_CONFIG) --cflags openssl) \
|
||||
$(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)
|
||||
|
||||
CFLAGS += $(GTKCFLAGS)
|
||||
|
223
image/bmp.c
223
image/bmp.c
@ -46,54 +46,8 @@ typedef struct nsbmp_content {
|
||||
bmp_image *bmp; /** BMP image data */
|
||||
} 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[] = {
|
||||
"application/bmp",
|
||||
@ -112,46 +66,24 @@ static const char *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;
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) {
|
||||
lerror = lwc_intern_string(nsbmp_types[i],
|
||||
strlen(nsbmp_types[i]),
|
||||
&nsbmp_mime_types[i]);
|
||||
if (lerror != lwc_error_ok) {
|
||||
error = NSERROR_NOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
error = content_factory_register_handler(nsbmp_mime_types[i],
|
||||
&nsbmp_content_handler);
|
||||
if (error != NSERROR_OK)
|
||||
goto error;
|
||||
bmp->bmp = calloc(sizeof(struct bmp_image), 1);
|
||||
if (bmp->bmp == NULL) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
|
||||
bmp_create(bmp->bmp, &bmp_bitmap_callbacks);
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
nserror nsbmp_create(const content_handler *handler,
|
||||
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)
|
||||
@ -181,23 +113,39 @@ nserror nsbmp_create(const content_handler *handler,
|
||||
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);
|
||||
if (bmp->bmp == NULL) {
|
||||
msg_data.error = messages_get("NoMemory");
|
||||
content_broadcast(&bmp->base, CONTENT_MSG_ERROR, msg_data);
|
||||
return NSERROR_NOMEM;
|
||||
}
|
||||
/* set bitmap state based on bmp state */
|
||||
bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0;
|
||||
bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ?
|
||||
BITMAP_CLEAR_MEMORY : 0;
|
||||
|
||||
bmp_create(bmp->bmp, &bmp_bitmap_callbacks);
|
||||
|
||||
return NSERROR_OK;
|
||||
/* return the created bitmap */
|
||||
return bitmap_create(width, height, bitmap_state);
|
||||
}
|
||||
|
||||
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;
|
||||
bmp_result res;
|
||||
@ -249,25 +197,7 @@ bool nsbmp_convert(struct content *c)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
static bool nsbmp_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)
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
nserror error;
|
||||
@ -335,30 +265,67 @@ nserror nsbmp_clone(const struct content *old, struct content **newc)
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void *nsbmp_bitmap_create(int width, int height, unsigned int bmp_state)
|
||||
|
||||
static const content_handler nsbmp_content_handler = {
|
||||
nsbmp_create,
|
||||
NULL,
|
||||
nsbmp_convert,
|
||||
NULL,
|
||||
nsbmp_destroy,
|
||||
NULL,
|
||||
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 */
|
||||
bitmap_state |= (bmp_state & BMP_OPAQUE) ? BITMAP_OPAQUE : 0;
|
||||
bitmap_state |= (bmp_state & BMP_CLEAR_MEMORY) ?
|
||||
BITMAP_CLEAR_MEMORY : 0;
|
||||
for (i = 0; i < NOF_ELEMENTS(nsbmp_mime_types); i++) {
|
||||
lerror = lwc_intern_string(nsbmp_types[i],
|
||||
strlen(nsbmp_types[i]),
|
||||
&nsbmp_mime_types[i]);
|
||||
if (lerror != lwc_error_ok) {
|
||||
error = NSERROR_NOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* return the created bitmap */
|
||||
return bitmap_create(width, height, bitmap_state);
|
||||
error = content_factory_register_handler(nsbmp_mime_types[i],
|
||||
&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
|
||||
|
542
image/gif.c
542
image/gif.c
@ -56,32 +56,28 @@ typedef struct nsgif_content {
|
||||
int current_frame; /**< current frame to display [0...(max-1)] */
|
||||
} nsgif_content;
|
||||
|
||||
static nserror nsgif_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 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 const char *nsgif_types[] = {
|
||||
"image/gif"
|
||||
};
|
||||
|
||||
static void *nsgif_bitmap_create(int width, int height);
|
||||
static void nsgif_invalidate(void *bitmap, void *private_word);
|
||||
static void nsgif_animate(void *p);
|
||||
static gif_result nsgif_get_frame(struct content *c);
|
||||
static lwc_string *nsgif_mime_types[NOF_ELEMENTS(nsgif_types)];
|
||||
|
||||
/**
|
||||
* 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;
|
||||
* 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_destroy = bitmap_destroy,
|
||||
.bitmap_get_buffer = bitmap_get_buffer,
|
||||
@ -90,71 +86,24 @@ gif_bitmap_callback_vt gif_bitmap_callbacks = {
|
||||
.bitmap_modified = bitmap_modified
|
||||
};
|
||||
|
||||
static const content_handler nsgif_content_handler = {
|
||||
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)
|
||||
static nserror nsgif_create_gif_data(nsgif_content *c)
|
||||
{
|
||||
uint32_t i;
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
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;
|
||||
/* 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;
|
||||
|
||||
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,
|
||||
llcache_handle *llcache, const char *fallback_charset,
|
||||
bool quirks, struct content **c)
|
||||
@ -184,216 +133,12 @@ nserror nsgif_create(const content_handler *handler,
|
||||
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.
|
||||
*
|
||||
* \param p The content to animate
|
||||
*/
|
||||
void nsgif_animate(void *p)
|
||||
static void nsgif_animate(void *p)
|
||||
{
|
||||
nsgif_content *gif = p;
|
||||
union content_msg_data data;
|
||||
@ -496,17 +241,236 @@ void nsgif_animate(void *p)
|
||||
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 height width of image in pixels
|
||||
* \return an opaque struct bitmap, or NULL on memory exhaustion
|
||||
* \param c the content to update
|
||||
*/
|
||||
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
|
||||
|
173
image/ico.c
173
image/ico.c
@ -46,42 +46,6 @@ typedef struct nsico_content {
|
||||
struct ico_collection *ico; /** ICO collection data */
|
||||
} 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[] = {
|
||||
"application/ico",
|
||||
"application/x-ico",
|
||||
@ -92,46 +56,23 @@ static const char *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;
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
nserror nsico_create(const content_handler *handler,
|
||||
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)
|
||||
@ -161,22 +102,9 @@ nserror nsico_create(const content_handler *handler,
|
||||
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;
|
||||
struct bmp_image *bmp;
|
||||
@ -228,21 +156,8 @@ bool nsico_convert(struct content *c)
|
||||
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,
|
||||
float scale, colour background_colour,
|
||||
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;
|
||||
|
||||
@ -274,7 +189,7 @@ void nsico_destroy(struct content *c)
|
||||
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;
|
||||
nserror error;
|
||||
@ -309,9 +224,67 @@ nserror nsico_clone(const struct content *old, struct content **newc)
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
|
15
image/jpeg.c
15
image/jpeg.c
@ -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.
|
||||
*/
|
||||
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,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
@ -356,7 +344,6 @@ static const content_handler nsjpeg_content_handler = {
|
||||
NULL,
|
||||
NULL,
|
||||
nsjpeg_redraw,
|
||||
nsjpeg_redraw_tiled,
|
||||
NULL,
|
||||
NULL,
|
||||
nsjpeg_clone,
|
||||
|
15
image/png.c
15
image/png.c
@ -344,24 +344,12 @@ static void nspng_destroy(struct content *c)
|
||||
|
||||
|
||||
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,
|
||||
float scale, colour background_colour,
|
||||
bool repeat_x, bool repeat_y)
|
||||
{
|
||||
nspng_content *png_c = (nspng_content *) c;
|
||||
bitmap_flags_t flags = 0;
|
||||
bitmap_flags_t flags = BITMAPF_NONE;
|
||||
|
||||
assert(png_c->bitmap != NULL);
|
||||
|
||||
@ -434,7 +422,6 @@ static const content_handler nspng_content_handler = {
|
||||
NULL,
|
||||
NULL,
|
||||
nspng_redraw,
|
||||
nspng_redraw_tiled,
|
||||
NULL,
|
||||
NULL,
|
||||
nspng_clone,
|
||||
|
184
image/rsvg.c
184
image/rsvg.c
@ -56,42 +56,7 @@ typedef struct rsvg_content {
|
||||
struct bitmap *bitmap; /**< Created NetSurf bitmap */
|
||||
} 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[] = {
|
||||
"image/svg",
|
||||
@ -100,46 +65,28 @@ static const char *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;
|
||||
lwc_error lerror;
|
||||
nserror error;
|
||||
union content_msg_data msg_data;
|
||||
|
||||
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;
|
||||
}
|
||||
c->rsvgh = NULL;
|
||||
c->cs = NULL;
|
||||
c->ct = NULL;
|
||||
c->bitmap = NULL;
|
||||
|
||||
error = content_factory_register_handler(rsvg_mime_types[i],
|
||||
&rsvg_content_handler);
|
||||
if (error != NSERROR_OK)
|
||||
goto error;
|
||||
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;
|
||||
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
nserror rsvg_create(const content_handler *handler,
|
||||
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)
|
||||
@ -169,26 +116,8 @@ nserror rsvg_create(const content_handler *handler,
|
||||
return NSERROR_OK;
|
||||
}
|
||||
|
||||
nserror rsvg_create_svg_data(rsvg_content *c)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
|
||||
c->rsvgh = NULL;
|
||||
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,
|
||||
static bool rsvg_process_data(struct content *c, const char *data,
|
||||
unsigned int size)
|
||||
{
|
||||
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;
|
||||
union content_msg_data msg_data;
|
||||
@ -300,15 +229,25 @@ bool rsvg_convert(struct content *c)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rsvg_redraw(struct content *c, int x, int y,
|
||||
int width, int height, const struct rect *clip,
|
||||
float scale, colour background_colour)
|
||||
static bool rsvg_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)
|
||||
{
|
||||
plot.bitmap(x, y, width, height, c->bitmap, background_colour, BITMAPF_NONE);
|
||||
return true;
|
||||
bitmap_flags_t flags = BITMAPF_NONE;
|
||||
|
||||
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;
|
||||
|
||||
@ -320,7 +259,7 @@ void rsvg_destroy(struct content *c)
|
||||
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;
|
||||
nserror error;
|
||||
@ -365,9 +304,66 @@ nserror rsvg_clone(const struct content *old, struct content **newc)
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
@ -111,7 +111,6 @@ static const content_handler html_content_handler = {
|
||||
html_mouse_track,
|
||||
html_mouse_action,
|
||||
html_redraw,
|
||||
NULL,
|
||||
html_open,
|
||||
html_close,
|
||||
html_clone,
|
||||
|
@ -97,7 +97,8 @@ void html_set_status(html_content *c, const char *extra);
|
||||
/* in render/html_redraw.c */
|
||||
bool html_redraw(struct content *c, int x, int y,
|
||||
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 */
|
||||
void html_mouse_track(struct content *c, struct browser_window *bw,
|
||||
|
@ -113,7 +113,8 @@ bool html_redraw_debug = false;
|
||||
|
||||
bool html_redraw(struct content *c, int x, int y,
|
||||
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;
|
||||
struct box *box;
|
||||
@ -655,7 +656,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent,
|
||||
x_scrolled + padding_left,
|
||||
y_scrolled + padding_top,
|
||||
width, height, &r, scale,
|
||||
current_background_color))
|
||||
current_background_color,
|
||||
false, false))
|
||||
return false;
|
||||
|
||||
} 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 (!plot.clip(&r))
|
||||
return false;
|
||||
if (!content_redraw_tiled(
|
||||
if (!content_redraw(
|
||||
background->background, x, y,
|
||||
ceilf(width * scale),
|
||||
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 (!plot.clip(&r))
|
||||
return false;
|
||||
if (!content_redraw_tiled(box->background, x, y,
|
||||
if (!content_redraw(box->background, x, y,
|
||||
ceilf(width * scale),
|
||||
ceilf(height * scale), &r,
|
||||
scale, *background_colour,
|
||||
|
@ -104,7 +104,8 @@ static void textplain_reformat(struct content *c, int width, int height);
|
||||
static void textplain_destroy(struct content *c);
|
||||
static bool textplain_redraw(struct content *c, int x, int y,
|
||||
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,
|
||||
struct content **newc);
|
||||
static content_type textplain_content_type(lwc_string *mime_type);
|
||||
@ -131,7 +132,6 @@ static const content_handler textplain_content_handler = {
|
||||
textplain_redraw,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
textplain_clone,
|
||||
NULL,
|
||||
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,
|
||||
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;
|
||||
struct browser_window *bw = current_redraw_browser;
|
||||
|
Loading…
Reference in New Issue
Block a user