summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/box.c112
-rw-r--r--render/box.h18
-rw-r--r--render/html.c47
-rw-r--r--render/layout.c26
4 files changed, 143 insertions, 60 deletions
diff --git a/render/box.c b/render/box.c
index dca53b4e9..d71c1112b 100644
--- a/render/box.c
+++ b/render/box.c
@@ -84,6 +84,8 @@ static struct result box_applet(xmlNode *n, struct status *status,
static struct form* create_form(xmlNode* n);
static void add_form_element(struct page_elements* pe, struct form* f);
static void add_gadget_element(struct page_elements* pe, struct gui_gadget* g);
+static bool plugin_decode(struct content* content, char* url, struct box* box,
+ struct object_params* po);
/* element_table must be sorted by name */
struct element_entry {
@@ -156,6 +158,8 @@ struct box * box_create(struct css_style * style,
box->font = 0;
box->gadget = 0;
box->object = 0;
+ box->object_params = 0;
+ box->plugin_state = 0;
#endif
return box;
}
@@ -1344,6 +1348,8 @@ void box_free_box(struct box *box)
else if (box->parent->href != box->href)
xmlFree(box->href);
}
+
+ /* TODO: free object_params and plugin_state */
}
@@ -1394,7 +1400,7 @@ struct result box_object(xmlNode *n, struct status *status,
struct css_style *style)
{
struct box *box;
- struct plugin_object *po;
+ struct object_params *po;
char *s, *url;
box = box_create(style, status->href, 0);
@@ -1453,25 +1459,23 @@ struct result box_object(xmlNode *n, struct status *status,
}
/* object width */
- if ((s = (char *) xmlGetProp(n, (const xmlChar *) "width"))) {
-
- po->width = (unsigned int)atoi(s);
- LOG(("width: %u", (unsigned int)atoi(s)));
- xmlFree(s);
- }
+ if (style->width.width == CSS_WIDTH_LENGTH)
+ po->width = len(&style->width.value.length, style);
/* object height */
- if ((s = (char *) xmlGetProp(n, (const xmlChar *) "height"))) {
+ if (style->height.height == CSS_HEIGHT_LENGTH)
+ po->height = len(&style->height.length, style);
- po->height = (unsigned int)atoi(s);
- LOG(("height: %u", (unsigned int)atoi(s)));
- xmlFree(s);
- }
+ /* TODO: go through children looking for <param>, and add
+ * somewhere in po */
+
+ box->object_params = po;
/* start fetch */
- plugin_decode(status->content, url, box, po);
+ if (plugin_decode(status->content, url, box, po))
+ return (struct result) {box, 0};
- return (struct result) {box, 0};
+ return (struct result) {box, 1};
}
/**
@@ -1482,7 +1486,7 @@ struct result box_embed(xmlNode *n, struct status *status,
struct css_style *style)
{
struct box *box;
- struct plugin_object *po;
+ struct object_params *po;
char *s, *url;
box = box_create(style, status->href, 0);
@@ -1508,6 +1512,8 @@ struct result box_embed(xmlNode *n, struct status *status,
xmlFree(s);
}
+ box->object_params = po;
+
/* start fetch */
plugin_decode(status->content, url, box, po);
@@ -1540,3 +1546,79 @@ struct result box_applet(xmlNode *n, struct status *status,
return (struct result) {box,0};
}
+
+
+/**
+ * plugin_decode
+ * This function checks that the contents of the plugin_object struct
+ * are valid. If they are, it initiates the fetch process. If they are
+ * not, it exits, leaving the box structure as it was on entry. This is
+ * necessary as there are multiple ways of declaring an object's attributes.
+ *
+ * Returns false if the object could not be handled.
+ *
+ * TODO: alt html
+ * params - create parameters file and put the filename string
+ * somewhere such that it is accessible from plugin_create.
+ */
+bool plugin_decode(struct content* content, char* url, struct box* box,
+ struct object_params* po)
+{
+ os_error *e;
+ unsigned int *fv;
+
+ /* Check if the codebase attribute is defined.
+ * If it is not, set it to the codebase of the current document.
+ */
+ if(po->codebase == 0)
+ po->codebase = strdup(content->url);
+ else
+ po->codebase = url_join(po->codebase, content->url);
+
+ /* Check that we have some data specified.
+ * First, check the data attribute.
+ * Second, check the classid attribute.
+ * The data attribute takes precedence.
+ * If neither are specified or if classid begins "clsid:",
+ * we can't handle this object.
+ */
+ if(po->data == 0 && po->classid == 0) {
+ return false;
+ }
+ if(po->data == 0 && po->classid != 0) {
+ if(strnicmp(po->classid, "clsid:", 6) == 0) {
+ LOG(("ActiveX object - n0"));
+ return false;
+ }
+ else {
+ url = url_join(po->classid, po->codebase);
+ }
+ }
+ else {
+ url = url_join(po->data, po->codebase);
+ }
+
+ /* Check if the declared mime type is understandable.
+ * Checks type and codetype attributes.
+ */
+ if(po->type != 0) {
+ if (content_lookup(po->type) == CONTENT_OTHER)
+ return false;
+ }
+ if(po->codetype != 0) {
+ if (content_lookup(po->codetype) == CONTENT_OTHER)
+ return false;
+ }
+
+ /* If we've got to here, the object declaration has provided us with
+ * enough data to enable us to have a go at downloading and displaying it.
+ *
+ * We may still find that the object has a MIME type that we can't handle
+ * when we fetch it (if the type was not specified or is different to that
+ * given in the attributes).
+ */
+ html_fetch_object(content, url, box);
+
+ return true;
+}
+
diff --git a/render/box.h b/render/box.h
index 5a16ecd9c..b67d6e7b1 100644
--- a/render/box.h
+++ b/render/box.h
@@ -81,6 +81,23 @@ struct gui_gadget {
} data;
};
+/* state of a plugin handling this box, platform dependent */
+struct plugin_state;
+
+/* parameters for <object> and related elements */
+struct object_params {
+ char* data;
+ char* type;
+ char* codetype;
+ char* codebase;
+ char* classid;
+ char* paramds; /* very likely to change */
+ unsigned int* width;
+ unsigned int* height;
+ /* not a parameter, but stored here for convenience */
+ struct plugin_state *plugin_state;
+};
+
struct box {
box_type type;
struct css_style * style;
@@ -105,6 +122,7 @@ struct box {
struct font_data *font;
struct gui_gadget* gadget;
struct content* object; /* usually an image */
+ struct object_params *object_params;
};
struct form
diff --git a/render/html.c b/render/html.c
index 60d218121..b8db76ad1 100644
--- a/render/html.c
+++ b/render/html.c
@@ -96,6 +96,8 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
/* convert xml tree to box tree */
LOG(("XML to box"));
+ sprintf(c->status_message, "Processing document");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
xml_to_box(html, c);
/*box_dump(c->data.html.layout->children, 0);*/
@@ -103,18 +105,18 @@ int html_convert(struct content *c, unsigned int width, unsigned int height)
xmlFreeDoc(document);
content_remove_user(c->data.html.stylesheet_content[0],
- html_convert_css_callback, c, 0);
+ html_convert_css_callback, c, 0, 0);
if (c->data.html.stylesheet_content[1] != 0)
content_destroy(c->data.html.stylesheet_content[1]);
for (i = 2; i != c->data.html.stylesheet_count; i++)
if (c->data.html.stylesheet_content[i] != 0)
content_remove_user(c->data.html.stylesheet_content[i],
- html_convert_css_callback, c, i);
+ html_convert_css_callback, c, i, 0);
xfree(c->data.html.stylesheet_content);
/* layout the box tree */
- sprintf(c->status_message, "Formatting document");
- content_broadcast(c, CONTENT_MSG_STATUS, 0);
+ sprintf(c->status_message, "Formatting document");
+ content_broadcast(c, CONTENT_MSG_STATUS, 0);
LOG(("Layout document"));
layout_document(c->data.html.layout->children, width);
/*box_dump(c->data.html.layout->children, 0);*/
@@ -145,7 +147,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
c->error = 1;
sprintf(c->status_message, "Warning: stylesheet is not CSS");
content_broadcast(c, CONTENT_MSG_STATUS, 0);
- content_remove_user(css, html_convert_css_callback, c, i);
+ content_remove_user(css, html_convert_css_callback, c, i, 0);
}
break;
@@ -173,7 +175,7 @@ void html_convert_css_callback(content_msg msg, struct content *css,
c->active--;
c->data.html.stylesheet_content[i] = fetchcache(
error, c->url, html_convert_css_callback,
- c, i, css->width, css->height);
+ c, i, css->width, css->height, 0);
if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
break;
@@ -225,7 +227,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
#endif
c->url,
html_convert_css_callback,
- c, 0, c->width, c->height);
+ c, 0, c->width, c->height, 0);
if (c->data.html.stylesheet_content[0]->status != CONTENT_STATUS_DONE)
c->active++;
@@ -275,7 +277,7 @@ void html_find_stylesheets(struct content *c, xmlNode *head)
(i + 1) * sizeof(*c->data.html.stylesheet_content));
c->data.html.stylesheet_content[i] = fetchcache(url, c->url,
html_convert_css_callback, c, i,
- c->width, c->height);
+ c->width, c->height, 0);
if (c->data.html.stylesheet_content[i]->status != CONTENT_STATUS_DONE)
c->active++;
free(url);
@@ -356,7 +358,7 @@ void html_fetch_object(struct content *c, char *url, struct box *box)
/* start fetch */
c->data.html.object[i].content = fetchcache(url, c->url,
html_object_callback,
- c, i, 0, 0);
+ c, i, 0, 0, box->object_params);
c->active++;
if (c->data.html.object[i].content->status == CONTENT_STATUS_DONE)
html_object_callback(CONTENT_MSG_DONE,
@@ -379,7 +381,7 @@ void html_object_callback(content_msg msg, struct content *object,
c->error = 1;
sprintf(c->status_message, "Warning: bad object type");
content_broadcast(c, CONTENT_MSG_STATUS, 0);
- content_remove_user(object, html_object_callback, c, i);
+ content_remove_user(object, html_object_callback, c, i, 0);
}
break;
@@ -447,7 +449,8 @@ void html_object_callback(content_msg msg, struct content *object,
c->data.html.object[i].url = xstrdup(error);
c->data.html.object[i].content = fetchcache(
error, c->url, html_object_callback,
- c, i, 0, 0);
+ c, i, 0, 0,
+ c->data.html.object[i].box->object_params);
if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
c->active++;
break;
@@ -479,7 +482,8 @@ void html_revive(struct content *c, unsigned int width, unsigned int height)
c->data.html.object[i].content = fetchcache(
c->data.html.object[i].url, c->url,
html_object_callback,
- c, i, 0, 0);
+ c, i, 0, 0,
+ c->data.html.object[i].box->object_params);
if (c->data.html.object[i].content->status != CONTENT_STATUS_DONE)
c->active++;
}
@@ -507,6 +511,16 @@ void html_destroy(struct content *c)
unsigned int i;
LOG(("content %p", c));
+ for (i = 0; i != c->data.html.object_count; i++) {
+ LOG(("object %i %p", i, c->data.html.object[i].content));
+ if (c->data.html.object[i].content != 0)
+ content_remove_user(c->data.html.object[i].content,
+ html_object_callback, c, i,
+ c->data.html.object[i].box->object_params);
+ free(c->data.html.object[i].url);
+ }
+ free(c->data.html.object);
+
LOG(("layout %p", c->data.html.layout));
if (c->data.html.layout != 0)
box_free(c->data.html.layout);
@@ -516,14 +530,5 @@ void html_destroy(struct content *c)
LOG(("title %p", c->title));
if (c->title != 0)
xfree(c->title);
-
- for (i = 0; i != c->data.html.object_count; i++) {
- LOG(("object %i %p", i, c->data.html.object[i].content));
- if (c->data.html.object[i].content != 0)
- content_remove_user(c->data.html.object[i].content,
- html_object_callback, c, i);
- free(c->data.html.object[i].url);
- }
- free(c->data.html.object);
}
diff --git a/render/layout.c b/render/layout.c
index 14e9258f2..1fb27b77c 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -32,8 +32,6 @@
* internal functions
*/
-static signed long len(struct css_length * length, struct css_style * style);
-
static void layout_node(struct box * box, unsigned long width, struct box * cont,
unsigned long cx, unsigned long cy);
static void layout_block(struct box * box, unsigned long width, struct box * cont,
@@ -54,26 +52,6 @@ static void calculate_widths(struct box *box);
static void calculate_inline_container_widths(struct box *box);
static void calculate_table_widths(struct box *table);
-/**
- * convert a struct css_length to pixels
- */
-
-signed long len(struct css_length * length, struct css_style * style)
-{
- assert(!((length->unit == CSS_UNIT_EM || length->unit == CSS_UNIT_EX) && style == 0));
- switch (length->unit) {
- case CSS_UNIT_EM: return length->value * len(&style->font_size.value.length, 0);
- case CSS_UNIT_EX: return length->value * len(&style->font_size.value.length, 0) * 0.6;
- case CSS_UNIT_PX: return length->value;
- case CSS_UNIT_IN: return length->value * 90.0;
- case CSS_UNIT_CM: return length->value * 35.0;
- case CSS_UNIT_MM: return length->value * 3.5;
- case CSS_UNIT_PT: return length->value * 90.0 / 72.0;
- case CSS_UNIT_PC: return length->value * 90.0 / 6.0;
- default: break;
- }
- return 0;
-}
/**
* layout algorithm
@@ -196,7 +174,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont,
switch (style->width.width) {
case CSS_WIDTH_LENGTH:
- box->width = len(&style->width.value.length, box->style);
+ box->width = len(&style->width.value.length, style);
break;
case CSS_WIDTH_PERCENT:
box->width = width * style->width.value.percent / 100;
@@ -210,7 +188,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont,
box->height = layout_block_children(box, box->width, cont, cx, cy);
switch (style->height.height) {
case CSS_HEIGHT_LENGTH:
- box->height = len(&style->height.length, box->style);
+ box->height = len(&style->height.length, style);
break;
case CSS_HEIGHT_AUTO:
default: