The convert stage of a content's state progression no longer reflows the content to the provided dimensions.

It is now defined as converting the content into a state in which it is ready for use.
The user of the content is now responsible for performing an initial reformat (sic) of the content before it can be redrawn.

Purge width/height parameters from hlcache_handle_retrieve/content_convert/*_convert APIs.
Fix up content handlers affected by the above change in semantics.
Ensure that browser_window_callback performs an initial reformat of its content.

svn path=/trunk/netsurf/; revision=10207
This commit is contained in:
John Mark Bell 2010-03-29 22:33:21 +00:00
parent 2a53c4c811
commit 9aca901eb1
32 changed files with 87 additions and 104 deletions

View File

@ -248,7 +248,7 @@ const char * const content_status_name[] = {
struct handler_entry {
bool (*create)(struct content *c, const http_parameter *params);
bool (*process_data)(struct content *c, char *data, unsigned int size);
bool (*convert)(struct content *c, int width, int height);
bool (*convert)(struct content *c);
void (*reformat)(struct content *c, int width, int height);
void (*destroy)(struct content *c);
void (*stop)(struct content *c);
@ -344,7 +344,7 @@ static const struct handler_entry handler_map[] = {
#endif
#ifdef WITH_NS_SVG
{svg_create, 0, svg_convert,
0, svg_destroy, 0, svg_redraw, 0, 0, 0, true},
svn_reformat, svg_destroy, 0, svg_redraw, 0, 0, 0, true},
#endif
#ifdef WITH_RSVG
{rsvg_create, rsvg_process_data, rsvg_convert,
@ -356,7 +356,7 @@ static const struct handler_entry handler_map[] = {
static nserror content_llcache_callback(llcache_handle *llcache,
const llcache_event *event, void *pw);
static void content_convert(struct content *c, int width, int height);
static void content_convert(struct content *c);
static void content_update_status(struct content *c);
@ -537,7 +537,7 @@ nserror content_llcache_callback(llcache_handle *llcache,
content_set_status(c, messages_get("Converting"), source_size);
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
content_convert(c, c->width, c->height);
content_convert(c);
}
break;
case LLCACHE_EVENT_ERROR:
@ -635,7 +635,7 @@ void content_update_status(struct content *c)
* be destroyed and must no longer be used.
*/
void content_convert(struct content *c, int width, int height)
void content_convert(struct content *c)
{
union content_msg_data msg_data;
@ -649,9 +649,8 @@ void content_convert(struct content *c, int width, int height)
LOG(("content %s (%p)", llcache_handle_get_url(c->llcache), c));
c->locked = true;
c->available_width = width;
if (handler_map[c->type].convert) {
if (!handler_map[c->type].convert(c, width, height)) {
if (!handler_map[c->type].convert(c)) {
c->status = CONTENT_STATUS_ERROR;
c->locked = false;
return;

View File

@ -73,7 +73,6 @@ static void hlcache_content_callback(struct content *c,
/* See hlcache.h for documentation */
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
const char *referer, llcache_post_data *post,
uint32_t width, uint32_t height,
hlcache_handle_callback cb, void *pw,
hlcache_child_context *child, hlcache_handle **result)
{
@ -98,8 +97,6 @@ nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
ctx->child.quirks = child->quirks;
}
/** \todo What happens with width/height? */
ctx->handle->cb = cb;
ctx->handle->pw = pw;
@ -275,11 +272,6 @@ nserror hlcache_find_content(hlcache_retrieval_ctx *ctx)
event.type = CONTENT_MSG_LOADING;
ctx->handle->cb(ctx->handle, &event, ctx->handle->pw);
/** \todo Reflow content to new width
if (content_get_available_width(ctx->handle) != width)
content_reformat(ctx->handle, width, height);
*/
if (ctx->handle->cb != NULL) {
event.type = CONTENT_MSG_READY;
ctx->handle->cb(ctx->handle, &event,

View File

@ -60,8 +60,6 @@ typedef nserror (*hlcache_handle_callback)(hlcache_handle *handle,
* \param flags Object retrieval flags
* \param referer Referring URL, or NULL if none
* \param post POST data, or NULL for a GET request
* \param width Available width for content
* \param height Available height for content
* \param cb Callback to handle object events
* \param pw Pointer to client-specific data for callback
* \param child Child retrieval context, or NULL for top-level content
@ -78,7 +76,6 @@ typedef nserror (*hlcache_handle_callback)(hlcache_handle *handle,
*/
nserror hlcache_handle_retrieve(const char *url, uint32_t flags,
const char *referer, llcache_post_data *post,
uint32_t width, uint32_t height,
hlcache_handle_callback cb, void *pw,
hlcache_child_context *child, hlcache_handle **result);

View File

@ -150,18 +150,16 @@ css_error nscss_process_css_data(struct content_css_data *c, char *data,
* Convert a CSS content ready for use
*
* \param c Content to convert
* \param w Width of area content will be displayed in
* \param h Height of area content will be displayed in
* \return true on success, false on failure
*/
bool nscss_convert(struct content *c, int w, int h)
bool nscss_convert(struct content *c)
{
union content_msg_data msg_data;
uint32_t i;
size_t size;
css_error error;
error = nscss_convert_css_data(&c->data.css, w, h);
error = nscss_convert_css_data(&c->data.css);
if (error != CSS_OK) {
msg_data.error = "?";
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
@ -198,11 +196,9 @@ bool nscss_convert(struct content *c, int w, int h)
* Convert CSS data ready for use
*
* \param c CSS data to convert
* \param w Width of area content will be displayed in
* \param h Height of area content will be displayed in
* \return CSS error
*/
css_error nscss_convert_css_data(struct content_css_data *c, int w, int h)
css_error nscss_convert_css_data(struct content_css_data *c)
{
const char *referer;
uint32_t i = 0;
@ -255,7 +251,7 @@ css_error nscss_convert_css_data(struct content_css_data *c, int w, int h)
i = c->import_count;
c->imports[c->import_count].media = media;
nerror = hlcache_handle_retrieve(lwc_string_data(uri),
0, referer, NULL, w, h, nscss_import, c,
0, referer, NULL, nscss_import, c,
&child, &c->imports[c->import_count++].c);
if (error != NSERROR_OK) {
return CSS_NOMEM;

View File

@ -53,7 +53,7 @@ bool nscss_create(struct content *c, const struct http_parameter *params);
bool nscss_process_data(struct content *c, char *data, unsigned int size);
bool nscss_convert(struct content *c, int w, int h);
bool nscss_convert(struct content *c);
void nscss_destroy(struct content *c);
@ -61,7 +61,7 @@ nserror nscss_create_css_data(struct content_css_data *c,
const char *url, const char *charset, bool quirks);
css_error nscss_process_css_data(struct content_css_data *c, char *data,
unsigned int size);
css_error nscss_convert_css_data(struct content_css_data *c, int w, int h);
css_error nscss_convert_css_data(struct content_css_data *c);
void nscss_destroy_css_data(struct content_css_data *c);
struct nscss_import *nscss_get_imports(struct hlcache_handle *h, uint32_t *n);

View File

@ -291,7 +291,6 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
url_func_result res;
int depth = 0;
struct browser_window *cur;
int width, height;
uint32_t fetch_flags = 0;
bool fetch_is_post = (post_urlenc != NULL || post_multipart != NULL);
llcache_post_data post;
@ -402,14 +401,13 @@ void browser_window_go_post(struct browser_window *bw, const char *url,
browser_window_remove_caret(bw);
browser_window_destroy_children(bw);
gui_window_get_dimensions(bw->window, &width, &height, true);
LOG(("Loading '%s' width %i, height %i", url2, width, height));
LOG(("Loading '%s'", url2));
browser_window_set_status(bw, messages_get("Loading"));
bw->history_add = add_to_history;
error = hlcache_handle_retrieve(url2, 0, referer,
fetch_is_post ? &post : NULL, width, height,
fetch_is_post ? &post : NULL,
browser_window_callback, bw,
parent != NULL ? &child : NULL, &c);
if (error == NSERROR_NO_FETCH_HANDLER) {
@ -462,6 +460,9 @@ nserror browser_window_callback(hlcache_handle *c,
break;
case CONTENT_MSG_READY:
{
int width, height;
assert(bw->loading_content == c);
if (bw->current_content != NULL) {
@ -475,6 +476,10 @@ nserror browser_window_callback(hlcache_handle *c,
hlcache_handle_release(bw->current_content);
}
/* Format the new content to the correct dimensions */
gui_window_get_dimensions(bw->window, &width, &height, true);
content_reformat(c, width, height);
bw->current_content = c;
bw->loading_content = NULL;
@ -523,7 +528,7 @@ nserror browser_window_callback(hlcache_handle *c,
if (content_get_type(c) == CONTENT_HTML &&
html_get_iframe(c) != NULL)
browser_window_create_iframes(bw, html_get_iframe(c));
}
break;
case CONTENT_MSG_DONE:

View File

@ -229,7 +229,7 @@ void search_web_retrieve_ico(bool localdefault)
return;
}
error = hlcache_handle_retrieve(url, 0, NULL, NULL, 20, 20,
error = hlcache_handle_retrieve(url, 0, NULL, NULL,
search_web_ico_callback, NULL, NULL, &search_ico);
if (error != NSERROR_OK)
search_ico = NULL;

View File

@ -64,7 +64,7 @@ bool nsbmp_create(struct content *c, const struct http_parameter *params)
}
bool nsbmp_convert(struct content *c, int iwidth, int iheight)
bool nsbmp_convert(struct content *c)
{
bmp_result res;
bmp_image *bmp;

View File

@ -42,7 +42,7 @@ struct content_bmp_data {
extern bmp_bitmap_callback_vt bmp_bitmap_callbacks; /** Only to be used by ICO code. */
bool nsbmp_create(struct content *c, const struct http_parameter *params);
bool nsbmp_convert(struct content *c, int width, int height);
bool nsbmp_convert(struct content *c);
void nsbmp_destroy(struct content *c);
bool nsbmp_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -79,7 +79,7 @@ bool nsgif_create(struct content *c, const struct http_parameter *params)
}
bool nsgif_convert(struct content *c, int iwidth, int iheight)
bool nsgif_convert(struct content *c)
{
int res;
struct gif_animation *gif;

View File

@ -39,7 +39,7 @@ struct content_gif_data {
};
bool nsgif_create(struct content *c, const struct http_parameter *params);
bool nsgif_convert(struct content *c, int width, int height);
bool nsgif_convert(struct content *c);
void nsgif_destroy(struct content *c);
bool nsgif_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -52,7 +52,7 @@ bool nsico_create(struct content *c, const struct http_parameter *params)
}
bool nsico_convert(struct content *c, int iwidth, int iheight)
bool nsico_convert(struct content *c)
{
struct bmp_image *bmp;
bmp_result res;

View File

@ -38,7 +38,7 @@ struct content_ico_data {
};
bool nsico_create(struct content *c, const struct http_parameter *params);
bool nsico_convert(struct content *c, int width, int height);
bool nsico_convert(struct content *c);
void nsico_destroy(struct content *c);
bool nsico_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -75,7 +75,7 @@ static void nsjpeg_term_source(j_decompress_ptr cinfo);
* Convert a CONTENT_JPEG for display.
*/
bool nsjpeg_convert(struct content *c, int w, int h)
bool nsjpeg_convert(struct content *c)
{
struct jpeg_decompress_struct cinfo;
struct nsjpeg_error_mgr jerr;

View File

@ -35,7 +35,7 @@ struct content_jpeg_data {
int dummy; /* NOT USED but to satisfy Norcroft */
};
bool nsjpeg_convert(struct content *c, int width, int height);
bool nsjpeg_convert(struct content *c);
void nsjpeg_destroy(struct content *c);
bool nsjpeg_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -299,7 +299,7 @@ bool nsmng_process_data(struct content *c, char *data, unsigned int size)
}
bool nsmng_convert(struct content *c, int width, int height)
bool nsmng_convert(struct content *c)
{
mng_retcode status;

View File

@ -43,7 +43,7 @@ struct content_mng_data {
bool nsmng_create(struct content *c, const struct http_parameter *params);
bool nsmng_process_data(struct content *c, char *data, unsigned int size);
bool nsmng_convert(struct content *c, int width, int height);
bool nsmng_convert(struct content *c);
void nsmng_destroy(struct content *c);
bool nsmng_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -56,7 +56,7 @@
* No conversion is necessary. We merely read the sprite dimensions.
*/
bool nssprite_convert(struct content *c, int width, int height)
bool nssprite_convert(struct content *c)
{
union content_msg_data msg_data;

View File

@ -34,7 +34,7 @@ struct content_nssprite_data {
struct rosprite_area* sprite_area;
};
bool nssprite_convert(struct content *c, int width, int height);
bool nssprite_convert(struct content *c);
void nssprite_destroy(struct content *c);
bool nssprite_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -261,7 +261,7 @@ void end_callback(png_structp png, png_infop info)
bool nspng_convert(struct content *c, int width, int height)
bool nspng_convert(struct content *c)
{
const char *data;
unsigned long size;

View File

@ -44,7 +44,7 @@ struct content_png_data {
bool nspng_create(struct content *c, const struct http_parameter *params);
bool nspng_process_data(struct content *c, char *data, unsigned int size);
bool nspng_convert(struct content *c, int width, int height);
bool nspng_convert(struct content *c);
void nspng_destroy(struct content *c);
bool nspng_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -115,7 +115,7 @@ static inline void rsvg_argb_to_abgr(uint32_t pixels[], int width, int height,
}
}
bool rsvg_convert(struct content *c, int iwidth, int iheight)
bool rsvg_convert(struct content *c)
{
struct content_rsvg_data *d = &c->data.rsvg;
union content_msg_data msg_data;

View File

@ -44,7 +44,7 @@ struct content_rsvg_data {
bool rsvg_create(struct content *c, const struct http_parameter *params);
bool rsvg_process_data(struct content *c, char *data, unsigned int size);
bool rsvg_convert(struct content *c, int width, int height);
bool rsvg_convert(struct content *c);
void rsvg_destroy(struct content *c);
bool rsvg_redraw(struct content *c, int x, int y,
int width, int height,

View File

@ -48,6 +48,8 @@ bool svg_create(struct content *c, const struct http_parameter *params)
if (!c->data.svg.diagram)
goto no_memory;
c->data.svg.done_parse = false;
return true;
no_memory:
@ -61,21 +63,8 @@ no_memory:
* Convert a CONTENT_SVG for display.
*/
bool svg_convert(struct content *c, int w, int h)
bool svg_convert(struct content *c)
{
const char *source_data;
unsigned long source_size;
assert(c->data.svg.diagram);
source_data = content__get_source_data(c, &source_size);
svgtiny_parse(c->data.svg.diagram, source_data, source_size,
content__get_url(c), w, h);
c->width = c->data.svg.diagram->width;
c->height = c->data.svg.diagram->height;
/*c->title = malloc(100);
if (c->title)
snprintf(c->title, 100, messages_get("svgTitle"),
@ -88,6 +77,28 @@ bool svg_convert(struct content *c, int w, int h)
return true;
}
/**
* Reformat a CONTENT_SVG.
*/
void svg_reformat(struct content *c, int width, int height)
{
const char *source_data;
unsigned long source_size;
assert(c->data.svg.diagram);
if (c->data.svg.done_parse == false) {
source_data = content__get_source_data(c, &source_size);
svgtiny_parse(c->data.svg.diagram, source_data, source_size,
content__get_url(c), w, h);
}
c->width = c->data.svg.diagram->width;
c->height = c->data.svg.diagram->height;
}
/**
* Redraw a CONTENT_SVG.

View File

@ -31,11 +31,13 @@ struct svgtiny_diagram;
struct content_svg_data {
struct svgtiny_diagram *diagram;
bool done_parse;
};
bool svg_create(struct content *c, const struct http_parameter *params);
bool svg_convert(struct content *c, int width, int height);
bool svg_convert(struct content *c);
void svg_destroy(struct content *c);
void svg_reformat(struct content *c, int width, int height);
bool svg_redraw(struct content *c, int x, int y,
int width, int height,
int clip_x0, int clip_y0, int clip_x1, int clip_y1,

View File

@ -52,7 +52,7 @@ bool directory_create(struct content *c, const struct http_parameter *params) {
return true;
}
bool directory_convert(struct content *c, int width, int height) {
bool directory_convert(struct content *c) {
char *path;
DIR *parent;
struct dirent *entry;
@ -135,7 +135,7 @@ bool directory_convert(struct content *c, int width, int height) {
(uint8_t *) footer, sizeof(footer) - 1);
c->type = CONTENT_HTML;
return html_convert(c, width, height);
return html_convert(c);
}
void directory_destroy(struct content *c)

View File

@ -31,7 +31,7 @@
struct http_parameter;
bool directory_create(struct content *c, const struct http_parameter *params);
bool directory_convert(struct content *c, int width, int height);
bool directory_convert(struct content *c);
void directory_destroy(struct content *c);
#endif

View File

@ -155,7 +155,7 @@ bool favicon_get_icon(struct content *c, xmlNode *html)
if (url == NULL)
return false;
error = hlcache_handle_retrieve(url, 0, NULL, NULL, c->width, c->height,
error = hlcache_handle_retrieve(url, 0, NULL, NULL,
favicon_callback, c, NULL, &c->data.html.favicon);
free(url);

View File

@ -307,20 +307,18 @@ encoding_change:
* - stylesheets are fetched
* - favicon is retrieved
* - the XML tree is converted to a box tree and object fetches are started
* - the box tree is laid out
*
* On exit, the content status will be either CONTENT_STATUS_DONE if the
* document is completely loaded or CONTENT_STATUS_READY if objects are still
* being fetched.
*/
bool html_convert(struct content *c, int width, int height)
bool html_convert(struct content *c)
{
binding_error err;
xmlNode *html, *head;
union content_msg_data msg_data;
unsigned long size;
unsigned int time_before, time_taken;
struct form *f;
/* finish parsing */
@ -483,21 +481,6 @@ bool html_convert(struct content *c, int width, int height)
}
/*imagemap_dump(c);*/
/* layout the box tree */
html_set_status(c, messages_get("Formatting"));
content_broadcast(c, CONTENT_MSG_STATUS, msg_data);
LOG(("Layout document"));
time_before = wallclock();
html_reformat(c, width, height);
time_taken = wallclock() - time_before;
LOG(("Layout took %dcs", time_taken));
c->reformat_time = wallclock() +
((time_taken < option_min_reflow_period ?
option_min_reflow_period : time_taken * 1.25));
LOG(("Scheduling relayout no sooner than %dcs",
c->reformat_time - wallclock()));
/*box_dump(stderr, c->data.html.layout->children, 0);*/
/* Destroy the parser binding */
binding_destroy_tree(c->data.html.parser_binding);
c->data.html.parser_binding = NULL;
@ -835,7 +818,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
c->active = 0;
ns_error = hlcache_handle_retrieve(default_stylesheet_url, 0,
content__get_url(c), NULL, c->width, c->height,
content__get_url(c), NULL,
html_convert_css_callback, c, &child,
&c->data.html.stylesheets[
STYLESHEET_BASE].data.external);
@ -846,7 +829,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
if (c->data.html.quirks == BINDING_QUIRKS_MODE_FULL) {
ns_error = hlcache_handle_retrieve(quirks_stylesheet_url, 0,
content__get_url(c), NULL, c->width, c->height,
content__get_url(c), NULL,
html_convert_css_callback, c, &child,
&c->data.html.stylesheets[
STYLESHEET_QUIRKS].data.external);
@ -858,7 +841,7 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
if (option_block_ads) {
ns_error = hlcache_handle_retrieve(adblock_stylesheet_url, 0,
content__get_url(c), NULL, c->width, c->height,
content__get_url(c), NULL,
html_convert_css_callback, c, &child,
&c->data.html.stylesheets[
STYLESHEET_ADBLOCK].data.external);
@ -967,7 +950,6 @@ bool html_find_stylesheets(struct content *c, xmlNode *html)
HTML_STYLESHEET_EXTERNAL;
ns_error = hlcache_handle_retrieve(url2, 0,
content__get_url(c), NULL,
c->width, c->height,
html_convert_css_callback, c, &child,
&c->data.html.stylesheets[i].
data.external);
@ -1135,7 +1117,7 @@ bool html_process_style_element(struct content *c, unsigned int *index,
}
/* Convert the content -- manually, as we want the result */
if (nscss_convert_css_data(sheet, c->width, c->height) != CSS_OK) {
if (nscss_convert_css_data(sheet) != CSS_OK) {
/* conversion failed */
nscss_destroy_css_data(sheet);
talloc_free(sheet);
@ -1264,7 +1246,6 @@ bool html_fetch_object(struct content *c, const char *url, struct box *box,
}
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
available_width, available_height,
html_object_callback, c, &child,
&c_fetch);
@ -1331,8 +1312,6 @@ bool html_replace_object(struct content *c, unsigned int i, const char *url)
/* initialise fetch */
error = hlcache_handle_retrieve(url2, 0, content__get_url(c), NULL,
c->data.html.object[i].box->width,
c->data.html.object[i].box->height,
html_object_callback, c, &child,
&c_fetch);
@ -1509,12 +1488,7 @@ nserror html_object_callback(hlcache_handle *object,
(c->status == CONTENT_STATUS_READY ||
c->status == CONTENT_STATUS_DONE) &&
(wallclock() > c->reformat_time)) {
unsigned int time_before = wallclock(), time_taken;
content__reformat(c, c->available_width, c->height);
time_taken = wallclock() - time_before;
c->reformat_time = wallclock() +
((time_taken < option_min_reflow_period ?
option_min_reflow_period : time_taken * 1.25));
}
return NSERROR_OK;
@ -1724,6 +1698,9 @@ void html_stop(struct content *c)
void html_reformat(struct content *c, int width, int height)
{
struct box *layout;
unsigned int time_before, time_taken;
time_before = wallclock();
layout_document(c, width, height);
layout = c->data.html.layout;
@ -1741,6 +1718,11 @@ void html_reformat(struct content *c, int width, int height)
c->width = layout->x + layout->descendant_x1;
if (c->height < layout->y + layout->descendant_y1)
c->height = layout->y + layout->descendant_y1;
time_taken = wallclock() - time_before;
c->reformat_time = wallclock() +
((time_taken < option_min_reflow_period ?
option_min_reflow_period : time_taken * 1.25));
}

View File

@ -187,7 +187,7 @@ extern bool html_redraw_debug;
bool html_create(struct content *c, const struct http_parameter *params);
bool html_process_data(struct content *c, char *data, unsigned int size);
bool html_convert(struct content *c, int width, int height);
bool html_convert(struct content *c);
void html_reformat(struct content *c, int width, int height);
void html_destroy(struct content *c);
bool html_fetch_object(struct content *c, const char *url, struct box *box,

View File

@ -197,12 +197,11 @@ no_memory:
* Convert a CONTENT_TEXTPLAIN for display.
*/
bool textplain_convert(struct content *c, int width, int height)
bool textplain_convert(struct content *c)
{
iconv_close(c->data.textplain.iconv_cd);
c->data.textplain.iconv_cd = 0;
textplain_reformat(c, width, height);
c->status = CONTENT_STATUS_DONE;
content_set_status(c, messages_get("Done"));

View File

@ -50,7 +50,7 @@ struct content_textplain_data {
bool textplain_create(struct content *c, const struct http_parameter *params);
bool textplain_process_data(struct content *c, char *data, unsigned int size);
bool textplain_convert(struct content *c, int width, int height);
bool textplain_convert(struct content *c);
void textplain_reformat(struct content *c, int width, int height);
void textplain_destroy(struct content *c);
bool textplain_redraw(struct content *c, int x, int y,