From 16f1b4d913430975e1c52077a110c483cbf570cc Mon Sep 17 00:00:00 2001 From: James Bursa Date: Tue, 21 May 2002 21:32:35 +0000 Subject: [PATCH] [project @ 2002-05-21 21:32:35 by bursa] Start of float implementation. svn path=/import/netsurf/; revision=18 --- render/box.c | 91 ++++++++++++++++++++++++++++++++++++------------- render/layout.c | 14 +++++--- render/render.c | 23 +++++++++---- 3 files changed, 93 insertions(+), 35 deletions(-) diff --git a/render/box.c b/render/box.c index f857a3461..cb94fca36 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.3 2002/05/11 15:22:24 bursa Exp $ + * $Id: box.c,v 1.4 2002/05/21 21:32:35 bursa Exp $ */ #include @@ -18,6 +18,8 @@ */ void box_add_child(struct box * parent, struct box * child); +struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style, + xmlNode * n, struct css_selector * selector, unsigned int depth); /** @@ -60,7 +62,6 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css struct box * inline_container_c; struct css_style * style; xmlNode * c; - xmlChar * s; if (n->type == XML_ELEMENT_NODE) { /* work out the style for this element */ @@ -68,19 +69,34 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css (*selector)[depth].element = n->name; (*selector)[depth].class = (*selector)[depth].id = 0; - style = xcalloc(1, sizeof(struct css_style)); - memcpy(style, parent_style, sizeof(struct css_style)); - css_get_style(stylesheet, *selector, depth + 1, style); + style = box_get_style(stylesheet, parent_style, n, *selector, depth + 1); + } - if ((s = xmlGetProp(n, "style"))) { - struct css_style * astyle = xcalloc(1, sizeof(struct css_style)); - memcpy(astyle, &css_empty_style, sizeof(struct css_style)); - css_parse_property_list(astyle, s); - css_cascade(style, astyle); - free(astyle); - free(s); + if (n->type == XML_TEXT_NODE || + (n->type == XML_ELEMENT_NODE && (style->float_ == CSS_FLOAT_LEFT || + style->float_ == CSS_FLOAT_RIGHT))) { + /* text nodes are converted to inline boxes, wrapped in an inline container block */ + if (inline_container == 0) { /* this is the first inline node: make a container */ + inline_container = xcalloc(1, sizeof(struct box)); + inline_container->type = BOX_INLINE_CONTAINER; + box_add_child(parent, inline_container); + } + box = calloc(1, sizeof(struct box)); + box->node = n; + box_add_child(inline_container, box); + if (n->type == XML_TEXT_NODE) { + box->type = BOX_INLINE; + box->text = squash_whitespace(n->content); + } else { + box->type = BOX_FLOAT; + box->style = style; + inline_container_c = 0; + for (c = n->children; c != 0; c = c->next) + inline_container_c = xml_to_box(c, style, stylesheet, + selector, depth + 1, box, inline_container_c); } + } else if (n->type == XML_ELEMENT_NODE) { switch (style->display) { case CSS_DISPLAY_BLOCK: /* blocks get a node in the box tree */ box = xcalloc(1, sizeof(struct box)); @@ -111,6 +127,7 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css inline_container = 0; break; case CSS_DISPLAY_TABLE_ROW: + assert(parent->type == BOX_TABLE); box = xcalloc(1, sizeof(struct box)); box->node = n; box->type = BOX_TABLE_ROW; @@ -122,6 +139,7 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css inline_container = 0; break; case CSS_DISPLAY_TABLE_CELL: + assert(parent->type == BOX_TABLE_ROW); box = xcalloc(1, sizeof(struct box)); box->node = n; box->type = BOX_TABLE_CELL; @@ -136,24 +154,48 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css case CSS_DISPLAY_NONE: default: } - } else if (n->type == XML_TEXT_NODE) { - /* text nodes are converted to inline boxes, wrapped in an inline container block */ - if (inline_container == 0) { /* this is the first inline node: make a container */ - inline_container = xcalloc(1, sizeof(struct box)); - inline_container->type = BOX_INLINE_CONTAINER; - box_add_child(parent, inline_container); - } - box = calloc(1, sizeof(struct box)); - box->node = n; - box->type = BOX_INLINE; - box->text = n->content; - box_add_child(inline_container, box); } return inline_container; } +/* + * get the style for an element + */ + +struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_style * parent_style, + xmlNode * n, struct css_selector * selector, unsigned int depth) +{ + struct css_style * style = xcalloc(1, sizeof(struct css_style)); + xmlChar * s; + + memcpy(style, parent_style, sizeof(struct css_style)); + css_get_style(stylesheet, selector, depth, style); + + if ((s = xmlGetProp(n, "width"))) { + if (strrchr(s, '%')) + style->width.width = CSS_WIDTH_PERCENT, + style->width.value.percent = atof(s); + else + style->width.width = CSS_WIDTH_LENGTH, + style->width.value.length.unit = CSS_UNIT_PX, + style->width.value.length.value = atof(s); + } + + if ((s = xmlGetProp(n, "style"))) { + struct css_style * astyle = xcalloc(1, sizeof(struct css_style)); + memcpy(astyle, &css_empty_style, sizeof(struct css_style)); + css_parse_property_list(astyle, s); + css_cascade(style, astyle); + free(astyle); + free(s); + } + + return style; +} + + /* * print a box tree to standard output */ @@ -175,6 +217,7 @@ void box_dump(struct box * box, unsigned int depth) case BOX_TABLE: printf("BOX_TABLE <%s>\n", box->node->name); break; case BOX_TABLE_ROW: printf("BOX_TABLE_ROW <%s>\n", box->node->name); break; case BOX_TABLE_CELL: printf("BOX_TABLE_CELL <%s>\n", box->node->name); break; + case BOX_FLOAT: printf("BOX_FLOAT <%s>\n", box->node->name); break; default: printf("Unknown box type\n"); } diff --git a/render/layout.c b/render/layout.c index d02c44926..0070d6b95 100644 --- a/render/layout.c +++ b/render/layout.c @@ -1,5 +1,5 @@ /** - * $Id: layout.c,v 1.3 2002/05/18 08:23:39 bursa Exp $ + * $Id: layout.c,v 1.4 2002/05/21 21:32:35 bursa Exp $ */ #include @@ -118,6 +118,15 @@ void layout_inline_container(struct box * box, unsigned long width) struct font_split split; for (c = box->children; c != 0; ) { + if (c->type == BOX_FLOAT) { + layout_block(c, width); + c->x = 0; + c->y = y; + c = c->next; + continue; + } + + assert(c->type == BOX_INLINE); split = font_split(0, c->font, c->text, width - x, x == 0); if (*(split.end) == 0) { /* fits into this line */ @@ -132,9 +141,6 @@ void layout_inline_container(struct box * box, unsigned long width) /* doesn't fit at all: move down a line */ x = 0; y += 30; - /*c->width = font_split(0, c->font, c->text, (width-x)/20+1, &end)*20; - if (end == c->text) end = strchr(c->text, ' '); - if (end == 0) end = c->text + 1;*/ } else { /* split into two lines */ c->x = x; diff --git a/render/render.c b/render/render.c index e77a8c65f..6661b1ad2 100644 --- a/render/render.c +++ b/render/render.c @@ -1,5 +1,5 @@ /** - * $Id: render.c,v 1.10 2002/05/18 08:23:39 bursa Exp $ + * $Id: render.c,v 1.11 2002/05/21 21:32:35 bursa Exp $ */ #include @@ -97,6 +97,7 @@ void render_dump(struct box * box, unsigned long x, unsigned long y) case BOX_TABLE: case BOX_TABLE_ROW: case BOX_TABLE_CELL: + case BOX_FLOAT: case BOX_BLOCK: name = box->node->name; break; case BOX_INLINE: @@ -104,14 +105,22 @@ void render_dump(struct box * box, unsigned long x, unsigned long y) default: } - printf("rect %li %li %li %li \"%s\" \"%.*s\" ", x + box->x, y + box->y, - box->width, box->height, name, - box->type == BOX_INLINE ? box->length : 0, - box->type == BOX_INLINE ? box->text : ""); + printf("rect %li %li %li %li \"%s\" \"", x + box->x, y + box->y, + box->width, box->height, name); + if (box->type == BOX_INLINE) { + int i; + for (i = 0; i < box->length; i++) { + if (box->text[i] == '"') + printf("\\\""); + else + printf("%c", box->text[i]); + } + } + if (name == noname) - printf("\"\"\n"); + printf("\" \"\"\n"); else - printf("#%.6x\n", 0xffffff - ((name[0] << 16) | (name[1] << 8) | name[0])); + printf("\" #%.6x\n", 0xffffff - ((name[0] << 16) | (name[1] << 8) | name[0])); fflush(stdout); for (c = box->children; c != 0; c = c->next)