mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-22 20:16:54 +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);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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 -
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
221
image/bmp.c
221
image/bmp.c
@ -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
|
||||||
|
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)] */
|
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
|
||||||
|
173
image/ico.c
173
image/ico.c
@ -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
|
||||||
|
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.
|
* 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,
|
||||||
|
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,
|
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,
|
||||||
|
182
image/rsvg.c
182
image/rsvg.c
@ -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 */
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user