[project @ 2004-06-10 20:41:26 by bursa]

Add global content list. Better error handling in content code. Improved code documentation. Remove some obsolete functions. Implement debug window listing contents.

svn path=/import/netsurf/; revision=951
This commit is contained in:
James Bursa 2004-06-10 20:41:26 +00:00
parent ff5e70f865
commit 08177fa581
36 changed files with 743 additions and 436 deletions

View File

@ -117,6 +117,9 @@ FetchStyle2:Loading %u stylesheets: %s
NotCSS:Warning: stylesheet is not CSS
BadObject:Warning: bad object type
ObjError:Error loading object: %s
ParsingFail:Parsing the document failed.
BadGIF:Reading GIF failed.
PNGError:PNG library error.
DrawTitle:Draw image (%lux%lu, %lu bytes)
GIFTitle:GIF image (%lux%lu)

Binary file not shown.

View File

@ -115,6 +115,9 @@ FetchStyle2:Chargement de %u feuilles de styles: %s
NotCSS:Attention: feuille de style non CSS
BadObject:Attention: mauvais type d'objet
ObjError:Erreur lors du chargement de: %s
ParsingFail:Parsing the document failed.
BadGIF:Reading GIF failed.
PNGError:PNG library error.
DrawTitle:Image Draw (%lux%lu, %lu octets)
GIFTitle:Image GIF (%lux%lu)

Binary file not shown.

View File

@ -45,6 +45,10 @@
#include "netsurf/utils/utils.h"
/** Linked list of all content structures. May include more than one content
* per URL. Doubly-linked. */
struct content *content_list = 0;
/** An entry in mime_map. */
struct mime_entry {
char mime_type[40];
@ -79,17 +83,50 @@ static const struct mime_entry mime_map[] = {
};
#define MIME_MAP_COUNT (sizeof(mime_map) / sizeof(mime_map[0]))
const char *content_type_name[] = {
"HTML",
"TEXTPLAIN",
"CSS",
#ifdef WITH_JPEG
"JPEG",
#endif
#ifdef WITH_GIF
"GIF",
#endif
#ifdef WITH_PNG
"PNG",
#endif
#ifdef WITH_SPRITE
"SPRITE",
#endif
#ifdef WITH_DRAW
"DRAW",
#endif
#ifdef WITH_PLUGIN
"PLUGIN",
#endif
"OTHER",
"UNKNOWN"
};
const char *content_status_name[] = {
"TYPE_UNKNOWN",
"LOADING",
"READY",
"DONE",
"ERROR"
};
/** An entry in handler_map. */
struct handler_entry {
void (*create)(struct content *c, const char *params[]);
void (*process_data)(struct content *c, char *data, unsigned long size);
int (*convert)(struct content *c, unsigned int width, unsigned int height);
void (*revive)(struct content *c, unsigned int width, unsigned int height);
void (*reformat)(struct content *c, unsigned int width, unsigned int height);
bool (*create)(struct content *c, const char *params[]);
bool (*process_data)(struct content *c, char *data, unsigned int size);
bool (*convert)(struct content *c, int width, int height);
void (*reformat)(struct content *c, int width, int height);
void (*destroy)(struct content *c);
void (*redraw)(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void (*redraw)(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
void (*add_instance)(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,
@ -104,39 +141,39 @@ struct handler_entry {
/** A table of handler functions, indexed by ::content_type.
* Must be ordered as enum ::content_type. */
static const struct handler_entry handler_map[] = {
{html_create, html_process_data, html_convert, html_revive,
{html_create, html_process_data, html_convert,
html_reformat, html_destroy, html_redraw,
html_add_instance, html_remove_instance, html_reshape_instance},
{textplain_create, html_process_data, textplain_convert,
0, 0, 0, 0, 0, 0, 0},
{0, 0, css_convert, css_revive, 0, css_destroy, 0, 0, 0, 0},
0, 0, 0, 0, 0, 0},
{0, 0, css_convert, 0, css_destroy, 0, 0, 0, 0},
#ifdef WITH_JPEG
{nsjpeg_create, 0, nsjpeg_convert, 0,
{nsjpeg_create, 0, nsjpeg_convert,
0, nsjpeg_destroy, nsjpeg_redraw, 0, 0, 0},
#endif
#ifdef WITH_GIF
{nsgif_create, 0, nsgif_convert, 0,
{nsgif_create, 0, nsgif_convert,
0, nsgif_destroy, nsgif_redraw, 0, 0, 0},
#endif
#ifdef WITH_PNG
{nspng_create, nspng_process_data, nspng_convert, 0,
{nspng_create, nspng_process_data, nspng_convert,
0, nspng_destroy, nspng_redraw, 0, 0, 0},
#endif
#ifdef WITH_SPRITE
{sprite_create, sprite_process_data, sprite_convert, sprite_revive,
sprite_reformat, sprite_destroy, sprite_redraw, 0, 0, 0},
{sprite_create, sprite_process_data, sprite_convert,
0, sprite_destroy, sprite_redraw, 0, 0, 0},
#endif
#ifdef WITH_DRAW
{0, 0, draw_convert, 0,
{0, 0, draw_convert,
0, draw_destroy, draw_redraw, 0, 0, 0},
#endif
#ifdef WITH_PLUGIN
{plugin_create, plugin_process_data, plugin_convert, plugin_revive,
{plugin_create, plugin_process_data, plugin_convert,
plugin_reformat, plugin_destroy, plugin_redraw,
plugin_add_instance, plugin_remove_instance,
plugin_reshape_instance},
#endif
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
{0, 0, 0, 0, 0, 0, 0, 0, 0}
};
#define HANDLER_MAP_COUNT (sizeof(handler_map) / sizeof(handler_map[0]))
@ -166,33 +203,62 @@ content_type content_lookup(const char *mime_type)
/**
* Create a new content structure.
*
* \param url URL of content, copied
* \return the new content structure, or 0 on memory exhaustion
*
* The type is initialised to CONTENT_UNKNOWN, and the status to
* CONTENT_STATUS_TYPE_UNKNOWN.
*/
struct content * content_create(char *url)
struct content * content_create(const char *url)
{
struct content *c;
struct content_user *user_sentinel;
LOG(("url %s", url));
c = xcalloc(1, sizeof(struct content));
c->url = xstrdup(url);
c = malloc(sizeof(struct content));
if (!c)
return 0;
user_sentinel = malloc(sizeof *user_sentinel);
if (!user_sentinel) {
free(c);
return 0;
}
c->url = strdup(url);
if (!c->url) {
free(c);
free(user_sentinel);
return 0;
}
c->type = CONTENT_UNKNOWN;
c->mime_type = 0;
c->status = CONTENT_STATUS_TYPE_UNKNOWN;
c->width = 0;
c->height = 0;
c->available_width = 0;
c->cache = 0;
c->size = sizeof(struct content);
c->fetch = 0;
c->source_data = 0;
c->source_size = 0;
c->mime_type = 0;
content_set_status(c, messages_get("Loading"));
user_sentinel = xcalloc(1, sizeof(*user_sentinel));
c->title = 0;
c->active = 0;
user_sentinel->callback = 0;
user_sentinel->p1 = user_sentinel->p2 = 0;
user_sentinel->next = 0;
c->user_list = user_sentinel;
content_set_status(c, messages_get("Loading"));
c->fetch = 0;
c->source_data = 0;
c->source_size = 0;
c->total_size = 0;
c->lock = 0;
c->destroy_pending = false;
c->no_error_pages = false;
c->error_count = 0;
c->prev = 0;
c->next = content_list;
if (content_list)
content_list->prev = c;
content_list = c;
return c;
}
@ -200,34 +266,51 @@ struct content * content_create(char *url)
/**
* Initialise the content for the specified type.
*
* \param c content structure
* \param type content_type to initialise to
* \param mime_type MIME-type string for this content
* \param params array of strings, ordered attribute, value, attribute, ..., 0
* \return true on success, false on error and error broadcast to users and
* possibly reported
*
* The type is updated to the given type, and a copy of mime_type is taken. The
* status is changed to CONTENT_STATUS_LOADING. CONTENT_MSG_LOADING is sent to
* all users. The create function for the type is called to initialise the type
* specific parts of the content structure.
*
* \param c content structure
* \param type content_type to initialise to
* \param mime_type MIME-type string for this content
* \param params array of strings, ordered attribute, value, attribute, ..., 0
*/
void content_set_type(struct content *c, content_type type,
bool content_set_type(struct content *c, content_type type,
const char *mime_type, const char *params[])
{
union content_msg_data data;
union content_msg_data msg_data;
assert(c != 0);
assert(c->status == CONTENT_STATUS_TYPE_UNKNOWN);
assert(type < CONTENT_UNKNOWN);
LOG(("content %s, type %i", c->url, type));
c->mime_type = strdup(mime_type);
if (!c->mime_type) {
c->status = CONTENT_STATUS_ERROR;
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->type = type;
c->mime_type = xstrdup(mime_type);
c->status = CONTENT_STATUS_LOADING;
c->source_data = xcalloc(0, 1);
if (handler_map[type].create)
handler_map[type].create(c, params);
content_broadcast(c, CONTENT_MSG_LOADING, data);
/* c may be destroyed at this point as a result of
* CONTENT_MSG_LOADING, so must not be accessed */
if (handler_map[type].create) {
if (!handler_map[type].create(c, params)) {
c->status = CONTENT_STATUS_ERROR;
return false;
}
}
content_broadcast(c, CONTENT_MSG_LOADING, msg_data);
return true;
}
@ -255,19 +338,44 @@ void content_set_status(struct content *c, const char *status_message, ...)
* Process a block of source data.
*
* Calls the process_data function for the content.
*
* \param c content structure
* \param data new data to process
* \param size size of data
* \return true on success, false on error and error broadcast to users and
* possibly reported
*/
void content_process_data(struct content *c, char *data, unsigned long size)
bool content_process_data(struct content *c, char *data, unsigned int size)
{
assert(c != 0);
char *source_data;
union content_msg_data msg_data;
assert(c);
assert(c->type < HANDLER_MAP_COUNT);
assert(c->status == CONTENT_STATUS_LOADING);
LOG(("content %s, size %lu", c->url, size));
c->source_data = xrealloc(c->source_data, c->source_size + size);
LOG(("content %s, size %u", c->url, size));
source_data = realloc(c->source_data, c->source_size + size);
if (!source_data) {
c->status = CONTENT_STATUS_ERROR;
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->source_data = source_data;
memcpy(c->source_data + c->source_size, data, size);
c->source_size += size;
c->size += size;
if (handler_map[c->type].process_data)
handler_map[c->type].process_data(c, data, size);
if (handler_map[c->type].process_data) {
if (!handler_map[c->type].process_data(c, data, size)) {
c->status = CONTENT_STATUS_ERROR;
return false;
}
}
return true;
}
@ -281,54 +389,34 @@ void content_process_data(struct content *c, char *data, unsigned long size)
* CONTENT_MSG_READY is sent to all users.
* - If the conversion succeeds and is complete, the content gets status
* CONTENT_STATUS_DONE, and CONTENT_MSG_READY then CONTENT_MSG_DONE are sent.
* - If the conversion fails, CONTENT_MSG_ERROR is sent. The content is then
* destroyed and must no longer be used.
* - If the conversion fails, CONTENT_MSG_ERROR is sent. The content will soon
* be destroyed and must no longer be used.
*/
void content_convert(struct content *c, unsigned long width, unsigned long height)
void content_convert(struct content *c, int width, int height)
{
union content_msg_data data;
assert(c != 0);
union content_msg_data msg_data;
assert(c);
assert(c->type < HANDLER_MAP_COUNT);
assert(c->status == CONTENT_STATUS_LOADING);
LOG(("content %s", c->url));
c->available_width = width;
if (handler_map[c->type].convert) {
if (handler_map[c->type].convert(c, width, height)) {
/* convert failed, destroy content */
data.error = "Conversion failed";
content_broadcast(c, CONTENT_MSG_ERROR, data);
if (c->cache)
cache_destroy(c);
content_destroy(c);
if (!handler_map[c->type].convert(c, width, height)) {
c->status = CONTENT_STATUS_ERROR;
return;
}
} else {
c->status = CONTENT_STATUS_DONE;
}
assert(c->status == CONTENT_STATUS_READY ||
c->status == CONTENT_STATUS_DONE);
content_broadcast(c, CONTENT_MSG_READY, data);
content_broadcast(c, CONTENT_MSG_READY, msg_data);
if (c->status == CONTENT_STATUS_DONE)
content_broadcast(c, CONTENT_MSG_DONE, data);
}
/**
* Fix content that has been loaded from the cache.
*
* Calls the revive function for the content. The content will be processed for
* display, for example dependencies loaded or reformated to current width.
*/
void content_revive(struct content *c, unsigned long width, unsigned long height)
{
assert(0); /* unmaintained */
assert(c != 0);
if (c->status != CONTENT_STATUS_DONE)
return;
c->available_width = width;
handler_map[c->type].revive(c, width, height);
content_broadcast(c, CONTENT_MSG_DONE, msg_data);
}
@ -338,7 +426,7 @@ void content_revive(struct content *c, unsigned long width, unsigned long height
* Calls the reformat function for the content.
*/
void content_reformat(struct content *c, unsigned long width, unsigned long height)
void content_reformat(struct content *c, int width, int height)
{
union content_msg_data data;
assert(c != 0);
@ -352,6 +440,29 @@ void content_reformat(struct content *c, unsigned long width, unsigned long heig
}
/**
* Destroys any contents in the content_list with no users or in
* CONTENT_STATUS_ERROR, and not with an active fetch or cached.
*/
void content_clean(void)
{
struct content *c, *next;
for (c = content_list; c; c = next) {
next = c->next;
if (((!c->user_list->next && !c->cache) ||
c->status == CONTENT_STATUS_ERROR) &&
!c->fetch) {
LOG(("%p %s", c, c->url));
if (c->cache)
cache_destroy(c);
content_destroy(c);
}
}
}
/**
* Destroy and free a content.
*
@ -371,6 +482,13 @@ void content_destroy(struct content *c)
return;
}
if (c->next)
c->next->prev = c->prev;
if (c->prev)
c->prev->next = c->next;
else
content_list = c->next;
if (c->type < HANDLER_MAP_COUNT && handler_map[c->type].destroy)
handler_map[c->type].destroy(c);
for (user = c->user_list; user != 0; user = next) {
@ -411,9 +529,9 @@ void content_reset(struct content *c)
* Calls the redraw function for the content, if it exists.
*/
void content_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void content_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
assert(c != 0);
@ -570,3 +688,9 @@ void content_reshape_instance(struct content *c, struct browser_window *bw,
handler_map[c->type].reshape_instance(c, bw, page, box, params, state);
}
void content_add_error(struct content *c, const char *token,
unsigned int line)
{
}

View File

@ -14,12 +14,73 @@
* Each content has a type. The type is used to call a specific implementation
* of functions such as content_process_data().
*
* The source data fetched from the URL is placed in the source_data buffer as
* it arrives.
*
* Contents have an associated set of users, which are informed by a callback
* when the state of the content changes or something interesting happens.
*
* Optionally, contents may have instances (depending on type). Instances
* represent copies of the same URL, for example if a page is open in two
* windows, or a page contains the same image twice.
*
* The status of a content follows a fixed order. Certain content functions
* change the state, and each change of state results in a message to all users
* of the content. The diagram below shows this:
* \dot
* digraph status {
* node [shape=plaintext, fontname=Helvetica, fontsize=9];
* edge [fontname=Helvetica, fontsize=9];
*
* content_create -> TYPE_UNKNOWN [style=bold];
* TYPE_UNKNOWN -> content_set_type [style=bold];
* content_set_type -> LOADING [label=MSG_LOADING, style=bold];
* content_set_type -> ERROR [label=MSG_ERROR];
* LOADING -> content_process_data [style=bold];
* content_process_data -> LOADING [style=bold];
* content_process_data -> ERROR [label=MSG_ERROR];
* LOADING -> content_convert [style=bold];
* content_convert -> READY [label=MSG_READY, style=bold];
* content_convert -> DONE [label="MSG_READY\nMSG_DONE", style=bold];
* content_convert -> ERROR [label=MSG_ERROR];
* READY -> READY [style=bold];
* READY -> DONE [label=MSG_DONE, style=bold];
*
* TYPE_UNKNOWN [shape=ellipse];
* LOADING [shape=ellipse];
* READY [shape=ellipse];
* DONE [shape=ellipse];
* ERROR [shape=ellipse];
* }
* \enddot
*
* To implement a new content type, implement the following functions:
*
* - <i>type</i>_create(): called to initialise type-specific fields in the
* content structure. Optional.
*
* - <i>type</i>_process_data(): called when some data arrives. Optional.
*
* - <i>type</i>_convert(): called when data has finished arriving. The
* content needs to be converted for display. Must set the status to one of
* CONTENT_STATUS_READY or CONTENT_STATUS_DONE if no error occurs. Optional,
* but probably required for non-trivial types.
*
* - <i>type</i>_reformat(): called when, for example, the window has been
* resized, and the content needs reformatting for the new size. Optional.
*
* - <i>type</i>_destroy(): called when the content is being destroyed. Free all
* resources. Optional.
*
* - <i>type</i>_redraw(): called to plot the content to screen.
*
* - <i>type</i>_(add|remove|reshape)_instance: ask James, this will probably
* be redesigned sometime.
*
* - <i>type</i>_create(), <i>type</i>_process_data(), <i>type</i>_convert():
* if an error occurs, must broadcast CONTENT_MSG_ERROR and return false.
* Optionally use warn_user() for serious errors. The _destroy function will
* be called soon after.
*/
#ifndef _NETSURF_DESKTOP_CONTENT_H_
@ -111,7 +172,9 @@ struct content {
converted and is not safe to display. */
CONTENT_STATUS_READY, /**< Some parts of content still being
loaded, but can be displayed. */
CONTENT_STATUS_DONE /**< All finished. */
CONTENT_STATUS_DONE, /**< All finished. */
CONTENT_STATUS_ERROR /**< Error occurred, content will be
destroyed imminently. */
} status; /**< Current status. */
int width, height; /**< Dimensions, if applicable. */
@ -147,7 +210,6 @@ struct content {
char *title; /**< Title for browser window. */
unsigned int active; /**< Number of child fetches or
conversions currently in progress. */
int error; /**< Non-0 if an error has occurred. */
struct content_user *user_list; /**< List of users. */
char status_message[80]; /**< Text for status bar. */
@ -159,26 +221,40 @@ struct content {
int lock; /**< Content in use, do not destroy. */
bool destroy_pending; /**< Destroy when lock returns to 0. */
bool no_error_pages; /**< Used by fetchcache(). */
/** Array of first n rendering errors or warnings. */
struct {
const char *token;
unsigned int line; /**< Line no, 0 if not applicable. */
} error_list[40];
unsigned int error_count; /**< Number of valid error entries. */
struct content *prev; /**< Previous in global content list. */
struct content *next; /**< Next in global content list. */
};
extern struct content *content_list;
extern const char *content_type_name[];
extern const char *content_status_name[];
struct browser_window;
content_type content_lookup(const char *mime_type);
struct content * content_create(char *url);
void content_set_type(struct content *c, content_type type,
struct content * content_create(const char *url);
bool content_set_type(struct content *c, content_type type,
const char *mime_type, const char *params[]);
void content_set_status(struct content *c, const char *status_message, ...);
void content_process_data(struct content *c, char *data, unsigned long size);
void content_convert(struct content *c, unsigned long width, unsigned long height);
void content_revive(struct content *c, unsigned long width, unsigned long height);
void content_reformat(struct content *c, unsigned long width, unsigned long height);
bool content_process_data(struct content *c, char *data, unsigned int size);
void content_convert(struct content *c, int width, int height);
void content_reformat(struct content *c, int width, int height);
void content_clean(void);
void content_destroy(struct content *c);
void content_reset(struct content *c);
void content_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void content_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
void content_add_user(struct content *c,
void (*callback)(content_msg msg, struct content *c, void *p1,
@ -199,5 +275,7 @@ void content_remove_instance(struct content *c, struct browser_window *bw,
void content_reshape_instance(struct content *c, struct browser_window *bw,
struct content *page, struct box *box,
struct object_params *params, void **state);
void content_add_error(struct content *c, const char *token,
unsigned int line);
#endif

View File

@ -31,9 +31,6 @@
#include "curl/curl.h"
#include "netsurf/utils/config.h"
#include "netsurf/content/fetch.h"
#ifdef riscos
#include "netsurf/desktop/gui.h"
#endif
#include "netsurf/desktop/options.h"
#ifdef WITH_AUTH
#include "netsurf/desktop/401login.h"
@ -587,6 +584,11 @@ size_t fetch_curl_data(void * data, size_t size, size_t nmemb, struct fetch *f)
/* send data to the caller */
LOG(("FETCH_DATA"));
f->callback(FETCH_DATA, f->p, data, size * nmemb);
if (f->aborting) {
f->locked--;
f->stopped = true;
return 0;
}
f->locked--;
return size * nmemb;

View File

@ -59,7 +59,7 @@ static void fetchcache_error_page(struct content *c, const char *error);
* \param post_urlenc url encoded post data, or 0 if none
* \param post_multipart multipart post data, or 0 if none
* \param cookies send and accept cookies
* \return a new content, or 0 if an error occurred and no_error_pages is true
* \return a new content, or 0 if an error occurred
*/
struct content * fetchcache(const char *url, char *referer,
@ -77,12 +77,16 @@ struct content * fetchcache(const char *url, char *referer,
)
{
struct content *c;
char *url1 = xstrdup(url);
char *hash = strchr(url1, '#');
char *url1;
char *hash;
char error_message[500];
url1 = strdup(url);
if (!url1)
return 0;
/* strip fragment identifier */
if (hash != 0)
if ((hash = strchr(url1, '#')))
*hash = 0;
LOG(("url %s", url1));
@ -100,6 +104,10 @@ struct content * fetchcache(const char *url, char *referer,
}
c = content_create(url1);
if (!c) {
free(url1);
return 0;
}
content_add_user(c, callback, p1, p2);
#ifdef WITH_POST
@ -118,12 +126,10 @@ struct content * fetchcache(const char *url, char *referer,
,cookies
#endif
);
if (c->fetch == 0) {
if (!c->fetch) {
LOG(("warning: fetch_start failed"));
if (c->cache)
cache_destroy(c);
c->status = CONTENT_STATUS_ERROR;
if (no_error_pages) {
content_destroy(c);
free(url1);
return 0;
}
@ -144,6 +150,7 @@ struct content * fetchcache(const char *url, char *referer,
void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
{
bool res;
struct content *c = p;
content_type type;
char *mime_type, *url;
@ -159,11 +166,13 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
mime_type = fetchcache_parse_type(data, &params);
type = content_lookup(mime_type);
LOG(("FETCH_TYPE, type %u", type));
content_set_type(c, type, mime_type, (const char**)params);
res = content_set_type(c, type, mime_type, params);
free(mime_type);
for (i = 0; params[i]; i++)
free(params[i]);
free(params);
if (!res)
fetch_abort(c->fetch);
if (c->cache && c->type == CONTENT_OTHER)
cache_destroy(c);
break;
@ -181,7 +190,8 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
messages_get("Received"),
human_friendly_bytesize(c->source_size + size));
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
content_process_data(c, data, size);
if (!content_process_data(c, data, size))
fetch_abort(c->fetch);
break;
case FETCH_FINISHED:
@ -199,9 +209,10 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
if (c->cache)
cache_destroy(c);
if (c->no_error_pages) {
c->status = CONTENT_STATUS_ERROR;
msg_data.error = data;
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
content_destroy(c);
content_broadcast(c, CONTENT_MSG_ERROR,
msg_data);
} else {
content_reset(c);
fetchcache_error_page(c, data);
@ -233,15 +244,15 @@ void fetchcache_callback(fetch_msg msg, void *p, char *data, unsigned long size)
c->fetch = 0;
msg_data.auth_realm = data;
content_broadcast(c, CONTENT_MSG_AUTH, msg_data);
cache_destroy(c);
if (c->cache)
cache_destroy(c);
break;
#endif
default:
assert(0);
}
if (--(c->lock) == 0 && c->destroy_pending)
content_destroy(c);
c->lock--;
}

119
css/css.c
View File

@ -87,6 +87,7 @@
#include "netsurf/desktop/gui.h"
#endif
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
#include "netsurf/utils/url.h"
#include "netsurf/utils/utils.h"
@ -241,7 +242,7 @@ const struct css_style css_blank_style = {
* Convert a CONTENT_CSS for use.
*/
int css_convert(struct content *c, unsigned int width, unsigned int height)
bool css_convert(struct content *c, int width, int height)
{
unsigned char *source_data;
unsigned char *current, *end, *token_text;
@ -250,6 +251,7 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
void *parser;
struct css_parser_params param = {false, c, 0, false, false};
struct css_parser_token token_data;
union content_msg_data msg_data;
c->data.css.css = malloc(sizeof *c->data.css.css);
parser = css_parser_Alloc(malloc);
@ -258,7 +260,11 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
if (!c->data.css.css || !parser || !source_data) {
free(c->data.css.css);
css_parser_Free(parser, free);
return 1;
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
for (i = 0; i != HASH_SIZE; i++)
@ -292,8 +298,12 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
css_parser_(parser, 0, token_data, &param);
css_parser_Free(parser, free);
if (param.memory_error)
return 1;
if (param.memory_error) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
/*css_dump_stylesheet(c->data.css.css);*/
@ -305,35 +315,7 @@ int css_convert(struct content *c, unsigned int width, unsigned int height)
}
c->status = CONTENT_STATUS_DONE;
return 0;
}
void css_revive(struct content *c, unsigned int width, unsigned int height)
{
unsigned int i;
/* imported stylesheets */
for (i = 0; i != c->data.css.import_count; i++) {
c->data.css.import_content[i] = fetchcache(
c->data.css.import_url[i], c->url,
css_atimport_callback, c, (void*)i,
c->width, c->height, true
#ifdef WITH_POST
, 0, 0
#endif
#ifdef WITH_COOKIES
, false
#endif
);
if (c->data.css.import_content[i] == 0)
continue;
if (c->data.css.import_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
}
while (c->active != 0) {
fetch_poll();
gui_multitask();
}
return true;
}
@ -371,6 +353,7 @@ void css_destroy(struct content *c)
/**
* Create a new struct css_node.
*
* \param stylesheet content of type CONTENT_CSS
* \param type type of node
* \param data string for data, not copied
* \param data_length length of data
@ -610,7 +593,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
content_remove_user(css, css_atimport_callback, c, (void*)i);
c->data.css.import_content[i] = 0;
c->active--;
c->error = 1;
content_add_error(c, "NotCSS", 0);
}
break;
@ -626,7 +609,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
case CONTENT_MSG_ERROR:
c->data.css.import_content[i] = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
break;
case CONTENT_MSG_STATUS:
@ -638,7 +621,7 @@ void css_atimport_callback(content_msg msg, struct content *css,
c->data.css.import_url[i] = strdup(data.redirect);
if (!c->data.css.import_url[i]) {
/** \todo report to user */
c->error = 1;
/* c->error = 1; */
return;
}
c->data.css.import_content[i] = fetchcache(
@ -996,9 +979,41 @@ void css_dump_style(const struct css_style * const style)
if (style->z != css_empty_style.z) \
fprintf(stderr, s ": %s; ", n[style->z]);
DUMP_KEYWORD(background_attachment, "background-attachment", css_background_attachment_name);
DUMP_COLOR(background_color, "background-color");
DUMP_KEYWORD(background_repeat, "background-repeat", css_background_repeat_name);
if (style->background_attachment !=
css_empty_style.background_attachment ||
style->background_image.type !=
css_empty_style.background_image.type ||
style->background_position.horz.pos !=
css_empty_style.background_position.horz.pos ||
style->background_position.vert.pos !=
css_empty_style.background_position.vert.pos ||
style->background_repeat !=
css_empty_style.background_repeat) {
fprintf(stderr, "background: ");
switch (style->background_image.type) {
case CSS_BACKGROUND_IMAGE_NONE:
fprintf(stderr, "none");
break;
case CSS_BACKGROUND_IMAGE_INHERIT:
fprintf(stderr, "inherit");
break;
case CSS_BACKGROUND_IMAGE_URI:
fprintf(stderr, "(%p) \"%s\"",
style->background_image.uri,
style->background_image.uri);
break;
default:
fprintf(stderr, "UNKNOWN");
break;
}
fprintf(stderr, " %s %s ",
css_background_attachment_name[
style->background_attachment],
css_background_repeat_name[
style->background_repeat]);
fprintf(stderr, "; ");
}
DUMP_KEYWORD(clear, "clear", css_clear_name);
DUMP_COLOR(color, "color");
DUMP_KEYWORD(cursor, "cursor", css_cursor_name);
@ -1078,7 +1093,7 @@ void css_dump_style(const struct css_style * const style)
if (style->margin[0].margin != css_empty_style.margin[0].margin ||
style->margin[1].margin != css_empty_style.margin[1].margin ||
style->margin[2].margin != css_empty_style.margin[2].margin ||
style->margin[3].margin != css_empty_style.margin[3].margin) {
style->margin[3].margin != css_empty_style.margin[3].margin) {
fprintf(stderr, "margin:");
for (i = 0; i != 4; i++) {
switch (style->margin[i].margin) {
@ -1152,19 +1167,19 @@ void css_dump_style(const struct css_style * const style)
if (style->text_indent.size != css_empty_style.text_indent.size) {
fprintf(stderr, "text-indent: ");
switch (style->text_indent.size) {
case CSS_TEXT_INDENT_LENGTH:
css_dump_length(&style->text_indent.value.length);
break;
case CSS_TEXT_INDENT_PERCENT:
fprintf(stderr, "%g%%",
style->text_indent.value.percent);
break;
case CSS_TEXT_INDENT_INHERIT:
fprintf(stderr, "inherit");
break;
default:
fprintf(stderr, "UNKNOWN");
break;
case CSS_TEXT_INDENT_LENGTH:
css_dump_length(&style->text_indent.value.length);
break;
case CSS_TEXT_INDENT_PERCENT:
fprintf(stderr, "%g%%",
style->text_indent.value.percent);
break;
case CSS_TEXT_INDENT_INHERIT:
fprintf(stderr, "inherit");
break;
default:
fprintf(stderr, "UNKNOWN");
break;
}
fprintf(stderr, "; ");
}

View File

@ -311,8 +311,7 @@ struct css_parser_token {
struct content;
int css_convert(struct content *c, unsigned int width, unsigned int height);
void css_revive(struct content *c, unsigned int width, unsigned int height);
bool css_convert(struct content *c, int width, int height);
void css_destroy(struct content *c);
#ifdef CSS_INTERNALS
@ -340,6 +339,7 @@ void *css_parser_Alloc(void *(*mallocProc)(/*size_t*/ int));
void css_parser_Free(void *p, void (*freeProc)(void*));
void css_parser_(void *yyp, int yymajor, struct css_parser_token yyminor,
struct css_parser_params *param);
const char *css_parser_TokenName(int tokenType);
#endif

View File

@ -119,9 +119,9 @@ void plugin_decode(void *a, void *b, void *c, void *d)
}
#endif
void html_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long x0, long y0, long x1, long y1,
void html_redraw(struct content *c, int x, int y,
int width, int height,
int x0, int y0, int x1, int y1,
float scale)
{
}
@ -262,9 +262,9 @@ extern os_t os_read_monotonic_time(void)
}
#endif
void warn_user(const char *warn)
void warn_user(const char *warning, const char *detail)
{
printf("WARNING: %s\n", warn);
printf("WARNING: %s %s\n", warning, detail);
}
void *ro_gui_current_redraw_gui = 0;

View File

@ -260,6 +260,7 @@ void browser_window_callback(content_msg msg, struct content *c,
case CONTENT_MSG_ERROR:
browser_window_set_status(bw, data.error);
warn_user(data.error, 0);
if (c == bw->loading_content)
bw->loading_content = 0;
else if (c == bw->current_content)

View File

@ -62,6 +62,4 @@ void gui_window_place_caret(gui_window *g, int x, int y, int height);
void gui_launch_url(const char *url);
void warn_user(const char *warning, const char *detail);
#endif

View File

@ -54,6 +54,7 @@ void netsurf_init(int argc, char** argv)
struct utsname utsname;
stdout = stderr;
curl_memdebug("memdump");
if (uname(&utsname) != 0)
LOG(("Failed to extract machine information\n"));
else
@ -63,12 +64,6 @@ void netsurf_init(int argc, char** argv)
fetch_init();
cache_init();
fetchcache_init();
#ifdef WITH_PNG
nspng_init();
#endif
#ifdef WITH_GIF
nsgif_init();
#endif
url_init();
}
@ -79,8 +74,9 @@ void netsurf_init(int argc, char** argv)
void netsurf_poll(void)
{
gui_poll(fetch_active);
fetch_poll();
content_clean();
gui_poll(fetch_active);
fetch_poll();
}

View File

@ -24,13 +24,13 @@ OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/
OBJECTS_RISCOS = $(OBJECTS_COMMON)
OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/
OBJECTS_RISCOS += 401login.o about.o constdata.o dialog.o download.o \
draw.o filetype.o font.o gif.o gifread.o gui.o help.o \
history.o htmlinstance.o htmlredraw.o jpeg.o menus.o \
mouseactions.o plugin.o png.o save.o save_complete.o \
save_draw.o save_text.o schedule.o sprite.o \
textselection.o theme.o thumbnail.o toolbar.o uri.o \
url_protocol.o wimp.o window.o # riscos/
OBJECTS_RISCOS += 401login.o about.o constdata.o debugwin.o \
dialog.o download.o draw.o filetype.o font.o gif.o \
gifread.o gui.o help.o history.o htmlinstance.o \
htmlredraw.o jpeg.o menus.o mouseactions.o plugin.o \
png.o save.o save_complete.o save_draw.o save_text.o \
schedule.o sprite.o textselection.o theme.o thumbnail.o \
toolbar.o uri.o url_protocol.o wimp.o window.o # riscos/
OBJECTS_DEBUG = $(OBJECTS_COMMON)
OBJECTS_DEBUG += filetyped.o fontd.o netsurfd.o # debug/

View File

@ -51,10 +51,11 @@ static bool html_object_type_permitted(const content_type type,
* created.
*/
void html_create(struct content *c, const char *params[])
bool html_create(struct content *c, const char *params[])
{
unsigned int i;
struct content_html_data *html = &c->data.html;
union content_msg_data msg_data;
xmlCharEncoding encoding = XML_CHAR_ENCODING_NONE;
html->encoding = NULL;
@ -74,7 +75,7 @@ void html_create(struct content *c, const char *params[])
}
html->parser = htmlCreatePushParserCtxt(0, 0, "", 0, 0, encoding);
html->base_url = xstrdup(c->url);
html->base_url = strdup(c->url);
html->layout = 0;
html->background_colour = TRANSPARENT;
html->stylesheet_count = 0;
@ -85,9 +86,24 @@ void html_create(struct content *c, const char *params[])
html->object = 0;
html->imagemaps = 0;
html->string_pool = pool_create(8000);
assert(html->string_pool);
html->box_pool = pool_create(sizeof (struct box) * 100);
assert(html->box_pool);
if (!html->parser || !html->base_url || !html->string_pool ||
!html->box_pool) {
htmlFreeParserCtxt(html->parser);
free(html->base_url);
if (html->string_pool)
pool_destroy(html->string_pool);
if (html->box_pool)
pool_destroy(html->box_pool);
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
return true;
}
@ -97,7 +113,7 @@ void html_create(struct content *c, const char *params[])
* The data is parsed in chunks of size CHUNK, multitasking in between.
*/
void html_process_data(struct content *c, char *data, unsigned long size)
bool html_process_data(struct content *c, char *data, unsigned int size)
{
unsigned long x;
@ -120,6 +136,8 @@ void html_process_data(struct content *c, char *data, unsigned long size)
gui_multitask();
}
htmlParseChunk(c->data.html.parser, data + x, (int) (size - x), 0);
return true;
}
@ -138,11 +156,11 @@ void html_process_data(struct content *c, char *data, unsigned long size)
* being fetched.
*/
int html_convert(struct content *c, unsigned int width, unsigned int height)
bool html_convert(struct content *c, int width, int height)
{
xmlDoc *document;
xmlNode *html, *head;
union content_msg_data data;
union content_msg_data msg_data;
/* finish parsing */
htmlParseChunk(c->data.html.parser, "", 0, 1);
@ -150,9 +168,12 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/*xmlDebugDumpDocument(stderr, c->data.html.parser->myDoc);*/
htmlFreeParserCtxt(c->data.html.parser);
c->data.html.parser = 0;
if (document == NULL) {
if (!document) {
LOG(("Parsing failed"));
return 1;
msg_data.error = messages_get("ParsingFail");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("ParsingFail", 0);
return false;
}
/* Last change to pick the Content-Type charset information if the
* server didn't send it (or we're reading the HTML from disk)
@ -168,7 +189,10 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
if (html == 0 || strcmp((const char *) html->name, "html") != 0) {
LOG(("html element not found"));
xmlFreeDoc(document);
return 1;
msg_data.error = messages_get("ParsingFail");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("ParsingFail", 0);
return false;
}
for (head = html->children;
head != 0 && head->type != XML_ELEMENT_NODE;
@ -188,7 +212,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* convert xml tree to box tree */
LOG(("XML to box"));
content_set_status(c, messages_get("Processing"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
xml_to_box(html, c);
/*box_dump(c->data.html.layout->children, 0);*/
@ -201,7 +225,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* layout the box tree */
content_set_status(c, messages_get("Formatting"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
LOG(("Layout document"));
layout_document(c->data.html.layout->children, width,
c->data.html.box_pool);
@ -218,7 +242,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
content_set_status(c, messages_get("FetchObjs"), c->active);
}
return 0;
return true;
}
@ -281,7 +305,6 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
c->data.html.stylesheet_content[1] = 0;
c->data.html.stylesheet_count = 2;
c->error = 0;
c->active = 0;
c->data.html.stylesheet_content[0] = fetchcache(
@ -396,6 +419,8 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
const char *params[] = { 0 };
c->data.html.stylesheet_content[1] =
content_create(c->data.html.base_url);
if (!c->data.html.stylesheet_content[1])
return false;
content_set_type(c->data.html.stylesheet_content[1],
CONTENT_CSS, "text/css", params);
}
@ -434,10 +459,10 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
gui_multitask();
}
if (c->error) {
content_set_status(c, "Warning: some stylesheets failed to load");
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
}
/* if (c->error) { */
/* content_set_status(c, "Warning: some stylesheets failed to load"); */
/* content_broadcast(c, CONTENT_MSG_STATUS, msg_data); */
/* } */
}
@ -457,7 +482,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
if (css->type != CONTENT_CSS) {
c->data.html.stylesheet_content[i] = 0;
c->active--;
c->error = 1;
content_add_error(c, "NotCSS", 0);
content_set_status(c, messages_get("NotCSS"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(css, html_convert_css_callback, c, (void*)i);
@ -475,7 +500,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
case CONTENT_MSG_ERROR:
c->data.html.stylesheet_content[i] = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
break;
case CONTENT_MSG_STATUS:
@ -506,7 +531,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
case CONTENT_MSG_AUTH:
c->data.html.stylesheet_content[i] = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
break;
#endif
@ -590,7 +615,7 @@ void html_object_callback(content_msg msg, struct content *object,
/* not acceptable */
c->data.html.object[i].content = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
content_set_status(c, messages_get("BadObject"));
content_broadcast(c, CONTENT_MSG_STATUS, data);
content_remove_user(object, html_object_callback, c, (void*)i);
@ -611,7 +636,7 @@ void html_object_callback(content_msg msg, struct content *object,
case CONTENT_MSG_ERROR:
c->data.html.object[i].content = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
content_set_status(c, messages_get("ObjError"),
data.error);
content_broadcast(c, CONTENT_MSG_STATUS, data);
@ -674,7 +699,7 @@ void html_object_callback(content_msg msg, struct content *object,
case CONTENT_MSG_AUTH:
c->data.html.object[i].content = 0;
c->active--;
c->error = 1;
content_add_error(c, "?", 0);
break;
#endif
@ -754,47 +779,11 @@ bool html_object_type_permitted(const content_type type,
}
void html_revive(struct content *c, unsigned int width, unsigned int height)
{
unsigned int i;
assert(0); /* dead code, do not use as is */
/* reload objects and fix pointers */
for (i = 0; i != c->data.html.object_count; i++) {
if (c->data.html.object[i].content != 0) {
c->data.html.object[i].content = fetchcache(
c->data.html.object[i].url, c->url,
html_object_callback,
c, (void*)i, 0, 0, true
#ifdef WITH_POST
, 0, 0
#endif
#ifdef WITH_COOKIES
, false
#endif
);
if (c->data.html.object[i].content &&
c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
c->active++;
}
}
layout_document(c->data.html.layout->children, width,
c->data.html.box_pool);
c->width = c->data.html.layout->children->width;
c->height = c->data.html.layout->children->height;
if (c->active != 0)
c->status = CONTENT_STATUS_READY;
}
/**
* Reformat a CONTENT_HTML to a new width.
*/
void html_reformat(struct content *c, unsigned int width, unsigned int height)
void html_reformat(struct content *c, int width, int height)
{
layout_document(c->data.html.layout->children, width,
c->data.html.box_pool);

View File

@ -83,11 +83,10 @@ struct content_html_data {
};
void html_create(struct content *c, const char *params[]);
void html_process_data(struct content *c, char *data, unsigned long size);
int html_convert(struct content *c, unsigned int width, unsigned int height);
void html_revive(struct content *c, unsigned int width, unsigned int height);
void html_reformat(struct content *c, unsigned int width, unsigned int height);
bool html_create(struct content *c, const char *params[]);
bool html_process_data(struct content *c, char *data, unsigned int size);
bool html_convert(struct content *c, int width, int height);
void html_reformat(struct content *c, int width, int height);
void html_destroy(struct content *c);
void html_fetch_object(struct content *c, char *url, struct box *box,
const content_type *permitted_types,
@ -106,9 +105,9 @@ void html_remove_instance(struct content *c, struct browser_window *bw,
struct object_params *params, void **state);
/* in riscos/htmlredraw.c */
void html_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void html_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -15,14 +15,18 @@ static const char header[] = "<html><body><pre>";
static const char footer[] = "</pre></body></html>";
void textplain_create(struct content *c, const char *params[])
bool textplain_create(struct content *c, const char *params[])
{
html_create(c, params);
if (!html_create(c, params))
/* html_create() must have broadcast MSG_ERROR already, so we
* don't need to. */
return false;
htmlParseChunk(c->data.html.parser, header, sizeof(header) - 1, 0);
return true;
}
int textplain_convert(struct content *c, unsigned int width, unsigned int height)
bool textplain_convert(struct content *c, int width, int height)
{
htmlParseChunk(c->data.html.parser, footer, sizeof(footer) - 1, 0);
c->type = CONTENT_HTML;

View File

@ -10,7 +10,7 @@
struct content;
void textplain_create(struct content *c, const char *params[]);
int textplain_convert(struct content *c, unsigned int width, unsigned int height);
bool textplain_create(struct content *c, const char *params[]);
bool textplain_convert(struct content *c, int width, int height);
#endif

View File

@ -33,7 +33,7 @@ wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_401li,
#endif
dialog_zoom, dialog_pageinfo, dialog_objinfo, dialog_tooltip,
dialog_warning, dialog_config_th_pane;
dialog_warning, dialog_config_th_pane, dialog_debug;
static int font_size;
static int font_min_size;
@ -83,6 +83,7 @@ void ro_gui_dialog_init(void)
dialog_objinfo = ro_gui_dialog_create("objectinfo");
dialog_tooltip = ro_gui_dialog_create("tooltip");
dialog_warning = ro_gui_dialog_create("warning");
dialog_debug = ro_gui_dialog_create("debug");
set_browser_choices();
set_proxy_choices();

View File

@ -18,56 +18,47 @@
#ifdef WITH_DRAW
int draw_convert(struct content *c, unsigned int width, unsigned int height)
bool draw_convert(struct content *c, int width, int height)
{
union content_msg_data msg_data;
os_box bbox;
os_error *error;
os_trfm *matrix = xcalloc(1, sizeof(os_trfm));
os_box *bbox = xcalloc(1, sizeof(os_box));
/* Full size image (1:1) */
matrix->entries[0][0] = 1 << 16;
matrix->entries[0][1] = 0;
matrix->entries[1][0] = 0;
matrix->entries[1][1] = 1 << 16;
matrix->entries[2][0] = 0;
matrix->entries[2][1] = 0;
/* BBox contents in Draw units (256*OS unit) */
error = xdrawfile_bbox(0, (drawfile_diagram*)(c->source_data),
(int)c->source_size, matrix, bbox);
(int) c->source_size, 0, &bbox);
if (error) {
LOG(("error: %s", error->errmess));
xfree(matrix);
xfree(bbox);
return 1;
LOG(("xdrawfile_bbox: 0x%x: %s",
error->errnum, error->errmess));
msg_data.error = error->errmess;
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
/* c->width & c->height stored as (OS units/2)
=> divide by 512 to convert from draw units */
c->width = ((bbox->x1 - bbox->x0) / 512);
c->height = ((bbox->y1 - bbox->y0) / 512);
c->data.draw.x0 = bbox->x0 / 2;
c->data.draw.y0 = bbox->y0 / 2;
c->title = xcalloc(100, 1);
sprintf(c->title, messages_get("DrawTitle"), c->width,
c->width = ((bbox.x1 - bbox.x0) / 512);
c->height = ((bbox.y1 - bbox.y0) / 512);
c->data.draw.x0 = bbox.x0 / 2;
c->data.draw.y0 = bbox.y0 / 2;
c->title = malloc(100);
if (c->title)
snprintf(c->title, 100, messages_get("DrawTitle"), c->width,
c->height, c->source_size);
c->status = CONTENT_STATUS_DONE;
xfree(matrix);
xfree(bbox);
return 0;
return true;
}
void draw_destroy(struct content *c)
{
xfree(c->title);
free(c->title);
}
void draw_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void draw_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
os_trfm matrix;

View File

@ -14,10 +14,10 @@ struct content_draw_data {
int x0, y0;
};
int draw_convert(struct content *c, unsigned int width, unsigned int height);
bool draw_convert(struct content *c, int width, int height);
void draw_destroy(struct content *c);
void draw_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void draw_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -21,6 +21,7 @@
#include "netsurf/riscos/options.h"
#include "netsurf/riscos/tinct.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h"
@ -38,19 +39,27 @@
static void nsgif_animate(void *p);
void nsgif_init(void) {
}
void nsgif_create(struct content *c, const char *params[]) {
bool nsgif_create(struct content *c, const char *params[]) {
union content_msg_data msg_data;
/* Initialise our data structure
*/
c->data.gif.gif = (gif_animation *)xcalloc(sizeof(gif_animation), 1);
c->data.gif.gif = calloc(sizeof(gif_animation), 1);
if (!c->data.gif.gif) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->data.gif.current_frame = 0;
return true;
}
int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight) {
bool nsgif_convert(struct content *c, int iwidth, int iheight) {
int res;
struct gif_animation *gif;
union content_msg_data msg_data;
/* Create our animation
*/
@ -61,38 +70,59 @@ int nsgif_convert(struct content *c, unsigned int iwidth, unsigned int iheight)
/* Initialise the GIF
*/
gif_initialise(gif);
res = gif_initialise(gif);
if (res < 0) {
if (res == GIF_INSUFFICIENT_MEMORY) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
} else {
msg_data.error = messages_get("BadGIF");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
}
return false;
}
/* Abort on bad GIFs
*/
if ((gif->frame_count_partial == 0) || (gif->width == 0) || (gif->height == 0)) return 1;
if ((gif->frame_count_partial == 0) || (gif->width == 0) ||
(gif->height == 0)) {
msg_data.error = messages_get("BadGIF");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
/* Store our content width
*/
c->width = gif->width;
c->height = gif->height;
/* Initialise the first frame so if we try to use the image data directly prior to
a plot we get some sensible data
*/
res = gif_decode_frame(c->data.gif.gif, 0);
if (res < 0 && res != GIF_INSUFFICIENT_FRAME_DATA) {
msg_data.error = messages_get("BadGIF");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
/* Schedule the animation if we have one
*/
if (gif->frame_count > 1) {
schedule(gif->frames[0].frame_delay, nsgif_animate, c);
}
/* Initialise the first frame so if we try to use the image data directly prior to
a plot we get some sensible data
*/
gif_decode_frame(c->data.gif.gif, 0);
/* Exit as a success
*/
c->status = CONTENT_STATUS_DONE;
return 0;
return true;
}
void nsgif_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nsgif_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale) {
int previous_frame;
@ -152,7 +182,7 @@ void nsgif_destroy(struct content *c)
*/
schedule_remove(nsgif_animate, c);
gif_finalise(c->data.gif.gif);
xfree(c->data.gif.gif);
free(c->data.gif.gif);
}

View File

@ -25,13 +25,12 @@ struct content_gif_data {
unsigned int current_frame;
};
void nsgif_init(void);
void nsgif_create(struct content *c, const char *params[]);
int nsgif_convert(struct content *c, unsigned int width, unsigned int height);
bool nsgif_create(struct content *c, const char *params[]);
bool nsgif_convert(struct content *c, int width, int height);
void nsgif_destroy(struct content *c);
void nsgif_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nsgif_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -96,11 +96,12 @@ static int clear_image = FALSE;
any information that hasn't already been decoded.
If an error occurs, all previously decoded frames are retained.
@return -5 for GIF frame data error
-4 for insufficient data to process any more frames
-3 for memory error
-2 for GIF error
-1 for insufficient data to do anything
@return GIF_FRAME_DATA_ERROR for GIF frame data error
GIF_INSUFFICIENT_FRAME_DATA for insufficient data to process
any more frames
GIF_INSUFFICIENT_MEMORY for memory error
GIF_DATA_ERROR for GIF error
GIF_INSUFFICIENT_DATA for insufficient data to do anything
0 for successful decoding
1 for successful decoding (all frames completely read)
*/
@ -112,7 +113,7 @@ int gif_initialise(struct gif_animation *gif) {
/* Check for sufficient data to be a GIF
*/
if (gif->buffer_size < 13) return -1;
if (gif->buffer_size < 13) return GIF_INSUFFICIENT_DATA;
/* Get our current processing position
*/
@ -244,12 +245,12 @@ int gif_initialise(struct gif_animation *gif) {
if (gif->frame_count_partial > 0) {
/* Set the redraw for the first frame to the maximum frame size
*/
gif->frames[0].redraw_required = 0;
gif->frames[0].redraw_required = 0;
gif->frames[0].redraw_x = 0;
gif->frames[0].redraw_y = 0;
gif->frames[0].redraw_width = gif->width;
gif->frames[0].redraw_height = gif->height;
/* We now work backwards to update the redraw characteristics of frames
with clear codes to stop a snowball effect of the redraw areas. It doesn't
really make much difference for most images, and will not work as well
@ -282,7 +283,7 @@ int gif_initialise(struct gif_animation *gif) {
}
}
}
}
/* If there was a memory error tell the caller
@ -512,7 +513,7 @@ int gif_initialise_frame(struct gif_animation *gif) {
gif->frames[frame].redraw_width = width;
gif->frames[frame].redraw_height = height;
}
/* if we are clearing the background then we need to redraw enough to cover the previous
frame too
*/
@ -584,10 +585,10 @@ int gif_initialise_frame(struct gif_animation *gif) {
/** Decodes a GIF frame.
@return -5 for GIF frame data error
-4 for insufficient data to complete the frame
-2 for GIF error (invalid frame header)
-1 for insufficient data to do anything
@return GIF_FRAME_DATA_ERROR for GIF frame data error
GIF_INSUFFICIENT_FRAME_DATA for insufficient data to complete the frame
GIF_DATA_ERROR for GIF error (invalid frame header)
GIF_INSUFFICIENT_DATA for insufficient data to do anything
0 for successful decoding
*/
int gif_decode_frame(struct gif_animation *gif, unsigned int frame) {

View File

@ -374,7 +374,7 @@ void ro_gui_check_resolvers(void)
if (resolvers) {
LOG(("Inet$Resolvers '%s'", resolvers));
} else {
LOG(("Inet$Resolvers not set", resolvers));
LOG(("Inet$Resolvers not set"));
warn_user("Resolvers", 0);
}
}
@ -613,6 +613,8 @@ void ro_gui_redraw_window_request(wimp_draw *redraw)
ro_gui_redraw_config_th_pane(redraw);
else if (redraw->w == history_window)
ro_gui_history_redraw(redraw);
else if (redraw->w == dialog_debug)
ro_gui_debugwin_redraw(redraw);
else {
g = ro_lookup_gui_from_w(redraw->w);
if (g != NULL)
@ -660,6 +662,11 @@ void ro_gui_close_window_request(wimp_close *close)
{
gui_window *g;
if (close->w == dialog_debug) {
ro_gui_debugwin_close();
return;
}
g = ro_lookup_gui_from_w(close->w);
if (g) {
@ -719,6 +726,8 @@ void ro_gui_icon_bar_click(wimp_pointer *pointer)
"file:///%%3CNetSurf$Dir%%3E/Docs/intro_%s",
option_language)) >= 0 && length < sizeof(url))
browser_window_create(url, NULL);
} else if (pointer->buttons == wimp_CLICK_ADJUST) {
ro_gui_debugwin_open();
}
}

View File

@ -23,7 +23,8 @@
extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
dialog_config_prox, dialog_config_th, dialog_zoom, dialog_pageinfo,
dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane;
dialog_objinfo, dialog_tooltip, dialog_warning, dialog_config_th_pane,
dialog_debug;
extern wimp_w history_window;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu;
extern int iconbar_menu_height;
@ -195,6 +196,11 @@ void schedule(int t, void (*callback)(void *p), void *p);
void schedule_remove(void (*callback)(void *p), void *p);
void schedule_run(void);
/* in debugwin.c */
void ro_gui_debugwin_open(void);
void ro_gui_debugwin_close(void);
void ro_gui_debugwin_redraw(wimp_draw *redraw);
/* icon numbers */
#define ICON_TOOLBAR_BACK 0
#define ICON_TOOLBAR_FORWARD 1

View File

@ -60,9 +60,9 @@ static os_trfm trfm = { {
{ 0, 0 } } };
void html_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void html_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
bool select_on = false;

View File

@ -40,6 +40,9 @@
#endif
static char nsjpeg_error_buffer[JMSG_LENGTH_MAX];
struct nsjpeg_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
@ -57,9 +60,10 @@ static void nsjpeg_term_source(j_decompress_ptr cinfo);
* Create a CONTENT_JPEG.
*/
void nsjpeg_create(struct content *c, const char *params[])
bool nsjpeg_create(struct content *c, const char *params[])
{
c->data.jpeg.sprite_area = 0;
return true;
}
@ -67,7 +71,7 @@ void nsjpeg_create(struct content *c, const char *params[])
* Convert a CONTENT_JPEG for display.
*/
int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
bool nsjpeg_convert(struct content *c, int w, int h)
{
struct jpeg_decompress_struct cinfo;
struct nsjpeg_error_mgr jerr;
@ -80,13 +84,17 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
unsigned int area_size;
osspriteop_area *sprite_area = 0;
osspriteop_header *sprite;
union content_msg_data msg_data;
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = nsjpeg_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
free(sprite_area);
return 1;
msg_data.error = nsjpeg_error_buffer;
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
jpeg_create_decompress(&cinfo);
source_mgr.next_input_byte = c->source_data;
@ -104,7 +112,12 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
sprite_area = malloc(area_size);
if (!sprite_area) {
LOG(("malloc failed"));
return 1;
jpeg_destroy_decompress(&cinfo);
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
/* area control block */
@ -142,10 +155,10 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
c->data.jpeg.sprite_area = sprite_area;
c->title = malloc(100);
if (c->title)
sprintf(c->title, messages_get("JPEGTitle"),
snprintf(c->title, 100, messages_get("JPEGTitle"),
width, height, c->source_size);
c->status = CONTENT_STATUS_DONE;
return 0;
return true;
}
@ -158,7 +171,7 @@ int nsjpeg_convert(struct content *c, unsigned int w, unsigned int h)
void nsjpeg_error_exit(j_common_ptr cinfo)
{
struct nsjpeg_error_mgr *err = (struct nsjpeg_error_mgr *) cinfo->err;
(*cinfo->err->output_message) (cinfo);
err->pub.format_message(cinfo, nsjpeg_error_buffer);
longjmp(err->setjmp_buffer, 1);
}
@ -229,9 +242,9 @@ void nsjpeg_destroy(struct content *c)
* Redraw a CONTENT_JPEG.
*/
void nsjpeg_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nsjpeg_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
unsigned int tinct_options;
@ -255,7 +268,7 @@ void nsjpeg_redraw(struct content *c, long x, long y,
_IN(2) | _IN(3) | _IN(4) | _IN(5) | _IN(6) | _IN(7),
(char *) c->data.jpeg.sprite_area +
c->data.jpeg.sprite_area->first,
x, (int) (y - height),
x, y - height,
width, height,
tinct_options);
}

View File

@ -16,12 +16,12 @@ struct content_jpeg_data {
osspriteop_area *sprite_area;
};
void nsjpeg_create(struct content *c, const char *params[]);
int nsjpeg_convert(struct content *c, unsigned int width, unsigned int height);
bool nsjpeg_create(struct content *c, const char *params[]);
bool nsjpeg_convert(struct content *c, int width, int height);
void nsjpeg_destroy(struct content *c);
void nsjpeg_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nsjpeg_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -32,19 +32,29 @@ static void row_callback(png_structp png, png_bytep new_row,
static void end_callback(png_structp png, png_infop info);
void nspng_init(void)
bool nspng_create(struct content *c, const char *params[])
{
}
union content_msg_data msg_data;
void nspng_create(struct content *c, const char *params[])
{
c->data.png.sprite_area = 0;
c->data.png.png = png_create_read_struct(PNG_LIBPNG_VER_STRING,
0, 0, 0);
assert(c->data.png.png != 0);
if (!c->data.png.png) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->data.png.info = png_create_info_struct(c->data.png.png);
assert(c->data.png.info != 0);
if (!c->data.png.info) {
png_destroy_read_struct(&c->data.png.png,
&c->data.png.info, 0);
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
if (setjmp(png_jmpbuf(c->data.png.png))) {
png_destroy_read_struct(&c->data.png.png,
@ -52,30 +62,38 @@ void nspng_create(struct content *c, const char *params[])
LOG(("Failed to set callbacks"));
c->data.png.png = NULL;
c->data.png.info = NULL;
return;
msg_data.error = messages_get("PNGError");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
png_set_progressive_read_fn(c->data.png.png, c,
info_callback, row_callback, end_callback);
return true;
}
void nspng_process_data(struct content *c, char *data, unsigned long size)
bool nspng_process_data(struct content *c, char *data, unsigned int size)
{
union content_msg_data msg_data;
if (setjmp(png_jmpbuf(c->data.png.png))) {
png_destroy_read_struct(&c->data.png.png,
&c->data.png.info, 0);
LOG(("Failed to process data"));
c->data.png.png = NULL;
c->data.png.info = NULL;
return;
msg_data.error = messages_get("PNGError");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
LOG(("data %p, size %li", data, size));
png_process_data(c->data.png.png, c->data.png.info,
data, size);
png_process_data(c->data.png.png, c->data.png.info, data, size);
c->size += size;
return true;
}
@ -224,30 +242,32 @@ void end_callback(png_structp png, png_infop info)
int nspng_convert(struct content *c, unsigned int width, unsigned int height)
bool nspng_convert(struct content *c, int width, int height)
{
if (c->data.png.png == NULL || c->data.png.info == NULL)
return 1;
assert(c->data.png.png);
assert(c->data.png.info);
png_destroy_read_struct(&c->data.png.png, &c->data.png.info, 0);
c->title = xcalloc(100, 1);
sprintf(c->title, messages_get("PNGTitle"), c->width, c->height);
c->title = malloc(100);
if (c->title)
snprintf(c->title, 100, messages_get("PNGTitle"),
c->width, c->height);
c->status = CONTENT_STATUS_DONE;
return 0;
return true;
}
void nspng_destroy(struct content *c)
{
xfree(c->title);
xfree(c->data.png.sprite_area);
free(c->title);
free(c->data.png.sprite_area);
}
void nspng_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nspng_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
unsigned int tinct_options;
@ -269,7 +289,7 @@ void nspng_redraw(struct content *c, long x, long y,
*/
_swix(Tinct_PlotScaledAlpha, _IN(2) | _IN(3) | _IN(4) | _IN(5) | _IN(6) | _IN(7),
((char *) c->data.png.sprite_area + c->data.png.sprite_area->first),
x, (int)(y - height),
x, y - height,
width, height,
tinct_options);
}

View File

@ -22,13 +22,12 @@ struct content_png_data {
char *sprite_image;
};
void nspng_init(void);
void nspng_create(struct content *c, const char *params[]);
void nspng_process_data(struct content *c, char *data, unsigned long size);
int nspng_convert(struct content *c, unsigned int width, unsigned int height);
bool nspng_create(struct content *c, const char *params[]);
bool nspng_process_data(struct content *c, char *data, unsigned int size);
bool nspng_convert(struct content *c, int width, int height);
void nspng_destroy(struct content *c);
void nspng_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void nspng_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -19,74 +19,90 @@
#ifdef WITH_SPRITE
void sprite_create(struct content *c, const char *params[])
bool sprite_create(struct content *c, const char *params[])
{
c->data.sprite.data = xcalloc(4, 1);
union content_msg_data msg_data;
c->data.sprite.data = malloc(4);
if (!c->data.sprite.data) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->data.sprite.length = 4;
return true;
}
void sprite_process_data(struct content *c, char *data, unsigned long size)
bool sprite_process_data(struct content *c, char *data, unsigned int size)
{
c->data.sprite.data = xrealloc(c->data.sprite.data, c->data.sprite.length + size);
memcpy((char*)(c->data.sprite.data) + c->data.sprite.length, data, size);
char *sprite_data;
union content_msg_data msg_data;
sprite_data = realloc(c->data.sprite.data,
c->data.sprite.length + size);
if (!sprite_data) {
msg_data.error = messages_get("NoMemory");
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
warn_user("NoMemory", 0);
return false;
}
c->data.sprite.data = sprite_data;
memcpy((char*)(c->data.sprite.data) + c->data.sprite.length,
data, size);
c->data.sprite.length += size;
c->size += size;
return true;
}
int sprite_convert(struct content *c, unsigned int width, unsigned int height)
bool sprite_convert(struct content *c, int width, int height)
{
os_error *error;
int w, h;
union content_msg_data msg_data;
osspriteop_area *area = (osspriteop_area*)c->data.sprite.data;
/* fill in the size (first word) of the area */
/* fill in the size (first word) of the area */
area->size = c->data.sprite.length;
error = xosspriteop_read_sprite_info(osspriteop_PTR,
area,
(osspriteop_id)((char*)(c->data.sprite.data) + area->first),
&w, &h, NULL, NULL);
if (error) {
LOG(("error: %s", error->errmess));
return 1;
}
area,
(osspriteop_id)((char*)(c->data.sprite.data) + area->first),
&w, &h, NULL, NULL);
if (error) {
LOG(("xosspriteop_read_sprite_info: 0x%x: %s",
error->errnum, error->errmess));
msg_data.error = error->errmess;
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
return false;
}
c->width = w;
c->height = h;
c->title = xcalloc(100, 1);
sprintf(c->title, messages_get("SpriteTitle"), c->width,
c->height, c->data.sprite.length);
c->title = malloc(100);
if (c->title)
snprintf(c->title, 100, messages_get("SpriteTitle"), c->width,
c->height, c->data.sprite.length);
c->status = CONTENT_STATUS_DONE;
return 0;
}
void sprite_revive(struct content *c, unsigned int width, unsigned int height)
{
}
void sprite_reformat(struct content *c, unsigned int width, unsigned int height)
{
return true;
}
void sprite_destroy(struct content *c)
{
xfree(c->data.sprite.data);
xfree(c->title);
free(c->data.sprite.data);
free(c->title);
}
void sprite_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void sprite_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale)
{
unsigned int size;
unsigned int size;
osspriteop_area *area = (osspriteop_area*)c->data.sprite.data;
osspriteop_trans_tab *table;
os_factors factors;
@ -94,14 +110,14 @@ void sprite_redraw(struct content *c, long x, long y,
xcolourtrans_generate_table_for_sprite(
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
area->first),
area->first),
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
0, colourtrans_GIVEN_SPRITE, 0, 0, &size);
table = xcalloc(size, 1);
xcolourtrans_generate_table_for_sprite(
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
area->first),
area->first),
colourtrans_CURRENT_MODE, colourtrans_CURRENT_PALETTE,
table, colourtrans_GIVEN_SPRITE, 0, 0, 0);
@ -113,7 +129,7 @@ void sprite_redraw(struct content *c, long x, long y,
xosspriteop_put_sprite_scaled(osspriteop_PTR,
area,
(osspriteop_id)((char*)(c->data.sprite.data) +
area->first),
area->first),
x, (int)(y - height),
osspriteop_USE_MASK | osspriteop_USE_PALETTE, &factors, table);

View File

@ -17,15 +17,12 @@ struct content_sprite_data {
unsigned long length;
};
void sprite_init(void);
void sprite_create(struct content *c, const char *params[]);
void sprite_process_data(struct content *c, char *data, unsigned long size);
int sprite_convert(struct content *c, unsigned int width, unsigned int height);
void sprite_revive(struct content *c, unsigned int width, unsigned int height);
void sprite_reformat(struct content *c, unsigned int width, unsigned int height);
bool sprite_create(struct content *c, const char *params[]);
bool sprite_process_data(struct content *c, char *data, unsigned int size);
bool sprite_convert(struct content *c, int width, int height);
void sprite_destroy(struct content *c);
void sprite_redraw(struct content *c, long x, long y,
unsigned long width, unsigned long height,
long clip_x0, long clip_y0, long clip_x1, long clip_y1,
void sprite_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,
float scale);
#endif

View File

@ -21,6 +21,7 @@
#include "netsurf/desktop/gui.h"
#include "netsurf/riscos/wimp.h"
#include "netsurf/utils/log.h"
#include "netsurf/utils/utils.h"
/* Wimp_Extend,11 block
*/

View File

@ -31,5 +31,6 @@ void regcomp_wrapper(regex_t *preg, const char *regex, int cflags);
void clean_cookiejar(void);
void unicode_transliterate(unsigned int c, char **r);
char *human_friendly_bytesize(unsigned long bytesize);
void warn_user(const char *warning, const char *detail);
#endif