From 09b1ede5a3fe5c37e34fe1c13780536f30297806 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Tue, 15 Apr 2003 17:53:00 +0000 Subject: [project @ 2003-04-15 17:53:00 by bursa] Inline images and related. svn path=/import/netsurf/; revision=125 --- render/html.c | 207 +++++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 162 insertions(+), 45 deletions(-) (limited to 'render/html.c') diff --git a/render/html.c b/render/html.c index 9b38b7378..0c60acdb5 100644 --- a/render/html.c +++ b/render/html.c @@ -1,5 +1,5 @@ /** - * $Id: html.c,v 1.14 2003/04/13 12:50:10 bursa Exp $ + * $Id: html.c,v 1.15 2003/04/15 17:53:00 bursa Exp $ */ #include @@ -25,6 +25,8 @@ static void html_convert_css_callback(fetchcache_msg msg, struct content *css, void *p, const char *error); static void html_title(struct content *c, xmlNode *head); static void html_find_stylesheets(struct content *c, xmlNode *head); +static void html_image_callback(fetchcache_msg msg, struct content *image, + void *p, const char *error); void html_create(struct content *c) @@ -51,10 +53,7 @@ void html_process_data(struct content *c, char *data, unsigned long size) int html_convert(struct content *c, unsigned int width, unsigned int height) { - struct css_selector* selector = xcalloc(1, sizeof(struct css_selector)); - struct fetch_data *fetch_data; unsigned int i; - char status[80]; xmlDoc *document; xmlNode *html, *head; @@ -91,39 +90,11 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) html_title(c, head); /* get stylesheets */ - c->error = 0; - c->active = 0; - html_find_stylesheets(c, head); - while (c->active != 0) { - if (c->status_callback != 0) { - sprintf(status, "Loading %u stylesheets", c->active); - c->status_callback(c->status_p, status); - } - fetch_poll(); - gui_multitask(); - } - - if (c->error) { - c->status_callback(c->status_p, "Warning: some stylesheets failed to load"); - } - - LOG(("Copying base style")); - c->data.html.style = xcalloc(1, sizeof(struct css_style)); - memcpy(c->data.html.style, &css_base_style, sizeof(struct css_style)); - - LOG(("Creating box")); - c->data.html.layout = xcalloc(1, sizeof(struct box)); - c->data.html.layout->type = BOX_BLOCK; - - c->data.html.fonts = font_new_set(); - + /* convert xml tree to box tree */ LOG(("XML to box")); - xml_to_box(html, c->data.html.style, - c->data.html.stylesheet_content, c->data.html.stylesheet_count, - &selector, 0, c->data.html.layout, 0, 0, c->data.html.fonts, - 0, 0, 0, 0, &c->data.html.elements); + xml_to_box(html, c); /*box_dump(c->data.html.layout->children, 0);*/ /* XML tree and stylesheets not required past this point */ @@ -137,6 +108,7 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) cache_free(c->data.html.stylesheet_content[i]); xfree(c->data.html.stylesheet_content); + /* layout the box tree */ c->status_callback(c->status_p, "Formatting document"); LOG(("Layout document")); layout_document(c->data.html.layout->children, width); @@ -144,6 +116,9 @@ int html_convert(struct content *c, unsigned int width, unsigned int height) c->width = c->data.html.layout->children->width; c->height = c->data.html.layout->children->height; + + if (c->active != 0) + c->status = CONTENT_PENDING; return 0; } @@ -200,8 +175,9 @@ void html_title(struct content *c, xmlNode *head) void html_find_stylesheets(struct content *c, xmlNode *head) { - xmlNode *node; + xmlNode *node, *node2; char *rel, *type, *media, *href, *data, *url; + char status[80]; unsigned int i = 2; struct fetch_data *fetch_data; @@ -210,6 +186,9 @@ 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; + fetch_data = xcalloc(1, sizeof(*fetch_data)); fetch_data->c = c; fetch_data->i = 0; @@ -218,10 +197,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head) html_convert_css_callback, fetch_data, c->width, c->height, 1 << CONTENT_CSS); - if (head == 0) - return; - - for (node = head->children; node != 0; node = node->next) { + for (node = head == 0 ? 0 : head->children; node != 0; node = node->next) { if (strcmp(node->name, "link") == 0) { /* rel='stylesheet' */ if (!(rel = (char *) xmlGetProp(node, (const xmlChar *) "rel"))) @@ -294,11 +270,16 @@ void html_find_stylesheets(struct content *c, xmlNode *head) /* create stylesheet */ LOG(("style element")); if (c->data.html.stylesheet_content[1] == 0) - c->data.html.stylesheet_content[1] = content_create(CONTENT_CSS, ""); - - data = xmlNodeGetContent(node); - content_process_data(c->data.html.stylesheet_content[1], data, strlen(data)); - free(data); + c->data.html.stylesheet_content[1] = content_create(CONTENT_CSS, c->url); + + /* can't just use xmlNodeGetContent(node), because that won't give + * the content of comments which may be used to 'hide' the content */ + for (node2 = node->children; node2 != 0; node2 = node2->next) { + data = xmlNodeGetContent(node2); + content_process_data(c->data.html.stylesheet_content[1], + data, strlen(data)); + free(data); + } } } @@ -306,15 +287,142 @@ void html_find_stylesheets(struct content *c, xmlNode *head) if (c->data.html.stylesheet_content[1] != 0) content_convert(c->data.html.stylesheet_content[1], c->width, c->height); + + /* complete the fetches */ + while (c->active != 0) { + if (c->status_callback != 0) { + sprintf(status, "Loading %u stylesheets", c->active); + c->status_callback(c->status_p, status); + } + fetch_poll(); + gui_multitask(); + } + + if (c->error) { + c->status_callback(c->status_p, "Warning: some stylesheets failed to load"); + } +} + + +void html_fetch_image(struct content *c, char *url, struct box *box) +{ + struct fetch_data *fetch_data; + + /* add to object list */ + c->data.html.object = xrealloc(c->data.html.object, + (c->data.html.object_count + 1) * + sizeof(*c->data.html.object)); + c->data.html.object[c->data.html.object_count].url = url; + c->data.html.object[c->data.html.object_count].content = 0; + c->data.html.object[c->data.html.object_count].box = box; + + /* start fetch */ + fetch_data = xcalloc(1, sizeof(*fetch_data)); + fetch_data->c = c; + fetch_data->i = c->data.html.object_count; + c->data.html.object_count++; + c->active++; + fetchcache(url, c->url, + html_image_callback, + fetch_data, 0, 0, 1 << CONTENT_JPEG); +} + + +void html_image_callback(fetchcache_msg msg, struct content *image, + void *p, const char *error) +{ + struct fetch_data *data = p; + struct content *c = data->c; + unsigned int i = data->i; + struct box *box = c->data.html.object[i].box; + switch (msg) { + case FETCHCACHE_OK: + LOG(("got image '%s'", image->url)); + box->object = image; + c->data.html.object[i].content = image; + /* set dimensions to object dimensions if auto */ + if (box->style->width.width == CSS_WIDTH_AUTO) { + box->style->width.width = CSS_WIDTH_LENGTH; + box->style->width.value.length.unit = CSS_UNIT_PX; + box->style->width.value.length.value = image->width; + box->min_width = box->max_width = image->width; + /* invalidate parent min, max widths */ + if (box->parent->max_width != UNKNOWN_MAX_WIDTH) { + struct box *b = box->parent; + if (b->min_width < image->width) + b->min_width = image->width; + if (b->max_width < image->width) + b->max_width = image->width; + for (b = b->parent; + b != 0 && b->max_width != UNKNOWN_MAX_WIDTH; + b = b->parent) + b->max_width = UNKNOWN_MAX_WIDTH; + } + } + if (box->style->height.height == CSS_HEIGHT_AUTO) { + box->style->height.height = CSS_HEIGHT_LENGTH; + box->style->height.length.unit = CSS_UNIT_PX; + box->style->height.length.value = image->height; + } + /* remove alt text */ + if (box->text != 0) { + free(box->text); + box->text = 0; + box->length = 0; + } + /*if (box->children != 0) { + box_free(box->children); + box->children = 0; + }*/ + /* TODO: recalculate min, max width */ + /* drop through */ + case FETCHCACHE_BADTYPE: + case FETCHCACHE_ERROR: + if (c->active == 1 && c->status == CONTENT_PENDING) { + /* all images have arrived */ + content_reformat(c, c->available_width, 0); + } + c->active--; + if (c->active == 0) + sprintf(c->status_message, "Document done"); + else + sprintf(c->status_message, "Loading %i images", c->active); + free(data); + break; + case FETCHCACHE_STATUS: + /* TODO: need to add a way of sending status to the + * owning window */ + break; + default: + assert(0); + } } void html_revive(struct content *c, unsigned int width, unsigned int height) { - /* TODO: reload images and fix any pointers to them */ + unsigned int i; + struct fetch_data *fetch_data; + + /* reload images and fix pointers */ + for (i = 0; i != c->data.html.object_count; i++) { + if (c->data.html.object[i].content != 0) { + fetch_data = xcalloc(1, sizeof(*fetch_data)); + fetch_data->c = c; + fetch_data->i = i; + c->active++; + fetchcache(c->data.html.object[i].url, c->url, + html_image_callback, + fetch_data, 0, 0, 1 << CONTENT_JPEG); + } + } + layout_document(c->data.html.layout->children, width); c->width = c->data.html.layout->children->width; c->height = c->data.html.layout->children->height; + + if (c->active != 0) + c->status = CONTENT_PENDING; } @@ -328,6 +436,7 @@ void html_reformat(struct content *c, unsigned int width, unsigned int height) void html_destroy(struct content *c) { + unsigned int i; LOG(("content %p", c)); if (c->data.html.layout != 0) @@ -336,4 +445,12 @@ void html_destroy(struct content *c) font_free_set(c->data.html.fonts); if (c->title != 0) xfree(c->title); + + for (i = 0; i != c->data.html.object_count; i++) { + if (c->data.html.object[i].content != 0) + cache_free(c->data.html.object[i].content); + free(c->data.html.object[i].url); + } + free(c->data.html.object); } + -- cgit v1.2.3