diff options
author | James Bursa <james@netsurf-browser.org> | 2002-05-11 15:22:24 +0000 |
---|---|---|
committer | James Bursa <james@netsurf-browser.org> | 2002-05-11 15:22:24 +0000 |
commit | 600f3ad557dd0ac4e1fea316fe36251363988401 (patch) | |
tree | 72160c08f0313eac0ceb505c68d38a3e9ee63ff5 /render | |
parent | 91300f840ff90b108658a63bb8fdfe21a8f45c4b (diff) | |
download | netsurf-600f3ad557dd0ac4e1fea316fe36251363988401.tar.gz netsurf-600f3ad557dd0ac4e1fea316fe36251363988401.tar.bz2 |
[project @ 2002-05-11 15:22:24 by bursa]
Better inline layout algorithm, simple tcl/tk gui.
svn path=/import/netsurf/; revision=15
Diffstat (limited to 'render')
-rw-r--r-- | render/box.c | 4 | ||||
-rw-r--r-- | render/font.c | 34 | ||||
-rw-r--r-- | render/font.h | 11 | ||||
-rw-r--r-- | render/layout.c | 96 | ||||
-rw-r--r-- | render/render.c | 44 | ||||
-rw-r--r-- | render/show.tcl | 19 | ||||
-rw-r--r-- | render/test/test1.html | 2 |
7 files changed, 141 insertions, 69 deletions
diff --git a/render/box.c b/render/box.c index 2966e70af..f857a3461 100644 --- a/render/box.c +++ b/render/box.c @@ -1,5 +1,5 @@ /** - * $Id: box.c,v 1.2 2002/05/04 21:17:06 bursa Exp $ + * $Id: box.c,v 1.3 2002/05/11 15:22:24 bursa Exp $ */ #include <assert.h> @@ -72,7 +72,7 @@ struct box * xml_to_box(xmlNode * n, struct css_style * parent_style, struct css memcpy(style, parent_style, sizeof(struct css_style)); css_get_style(stylesheet, *selector, depth + 1, style); - if (s = xmlGetProp(n, "style")) { + 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); diff --git a/render/font.c b/render/font.c index 068687431..6ac3a656a 100644 --- a/render/font.c +++ b/render/font.c @@ -1,5 +1,5 @@ /** - * $Id: font.c,v 1.1 2002/04/25 15:52:26 bursa Exp $ + * $Id: font.c,v 1.2 2002/05/11 15:22:24 bursa Exp $ */ #include <assert.h> @@ -39,21 +39,31 @@ void font_set_free(struct font_set * font_set) * find where to split some text to fit it in width */ -unsigned long font_split(struct font_set * font_set, font_id id, const char * text, - unsigned long width, const char ** end) +struct font_split font_split(struct font_set * font_set, font_id id, const char * text, + unsigned long width, int force) { size_t len = strlen(text); unsigned int i; - assert(width >= 1); - if (len <= width) { - *end = text + len; - return len; + struct font_split split; + + split.height = 30; + + if (len * 20 <= width) { + split.width = len * 20; + split.end = text + len; + } else { + for (i = width / 20; i != 0 && text[i] != ' '; i--) + ; + if (force && i == 0) { + i = width / 20; + if (i == 0) i = 1; + } + split.width = i * 20; + if (text[i] == ' ') i++; + split.end = text + i; } - /* invariant: no space in text[i+1..width) */ - for (i = width - 1; i != 0 && text[i] != ' '; i--) - ; - *end = text + i; - return i; + + return split; } diff --git a/render/font.h b/render/font.h index db10b20b2..4d789a208 100644 --- a/render/font.h +++ b/render/font.h @@ -1,5 +1,5 @@ /** - * $Id: font.h,v 1.1 2002/04/25 15:52:26 bursa Exp $ + * $Id: font.h,v 1.2 2002/05/11 15:22:24 bursa Exp $ */ /** @@ -8,6 +8,11 @@ struct font_set; typedef unsigned int font_id; +struct font_split { + unsigned long width; + unsigned long height; + const char * end; +}; /** * interface @@ -17,6 +22,6 @@ struct font_set * font_set_create(void); font_id font_add(struct font_set * font_set, const char * name, unsigned int weight, unsigned int size); void font_set_free(struct font_set * font_set); -unsigned long font_split(struct font_set * font_set, font_id id, const char * text, - unsigned long width, const char ** end); +struct font_split font_split(struct font_set * font_set, font_id id, const char * text, + unsigned long width, int force); diff --git a/render/layout.c b/render/layout.c index af0760362..8e386736f 100644 --- a/render/layout.c +++ b/render/layout.c @@ -1,5 +1,5 @@ /** - * $Id: layout.c,v 1.1 2002/05/04 19:57:18 bursa Exp $ + * $Id: layout.c,v 1.2 2002/05/11 15:22:24 bursa Exp $ */ #include <assert.h> @@ -56,7 +56,7 @@ void layout_block(struct box * box, unsigned long width) box->width = width; break; case CSS_WIDTH_LENGTH: - box->width = len(&style->width.value.length, 10); + box->width = len(&style->width.value.length, 20); break; case CSS_WIDTH_PERCENT: box->width = width * style->width.value.percent / 100; @@ -67,7 +67,7 @@ void layout_block(struct box * box, unsigned long width) case CSS_HEIGHT_AUTO: break; case CSS_HEIGHT_LENGTH: - box->height = len(&style->height.length, 10); + box->height = len(&style->height.length, 20); break; } } @@ -75,27 +75,27 @@ void layout_block(struct box * box, unsigned long width) unsigned long layout_block_children(struct box * box, unsigned long width) { struct box * c; - unsigned long y = 1; + unsigned long y = 0; for (c = box->children; c != 0; c = c->next) { switch (c->type) { case BOX_BLOCK: - layout_block(c, width-4); - c->x = 2; + layout_block(c, width); + c->x = 0; c->y = y; - y += c->height + 1; + y += c->height; break; case BOX_INLINE_CONTAINER: - layout_inline_container(c, width-4); - c->x = 2; + layout_inline_container(c, width); + c->x = 0; c->y = y; - y += c->height + 1; + y += c->height; break; case BOX_TABLE: - layout_table(c, width-4); - c->x = 2; + layout_table(c, width); + c->x = 0; c->y = y; - y += c->height + 1; + y += c->height; break; default: die("block child not block, table, or inline container"); @@ -108,45 +108,49 @@ void layout_inline_container(struct box * box, unsigned long width) { /* TODO: write this */ struct box * c; - unsigned long y = 1; - unsigned long x = 2; + unsigned long y = 0; + unsigned long x = 0; const char * end; - struct box * new; + struct box * c2; + struct font_split split; for (c = box->children; c != 0; ) { - c->width = font_split(0, c->font, c->text, width-2-x, &end)+1; - if (*end == 0) { + split = font_split(0, c->font, c->text, width - x, x == 0); + if (*(split.end) == 0) { /* fits into this line */ c->x = x; c->y = y; - c->height = 2; + c->width = split.width; + c->height = split.height; + c->length = split.end - c->text; x += c->width; c = c->next; - continue; - } - if (end == c->text) { + } else if (split.end == c->text) { /* doesn't fit at all: move down a line */ - x = 2; - y += 3; - c->width = font_split(0, c->font, c->text, width-2-x, &end)+1; + 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; + if (end == 0) end = c->text + 1;*/ + } else { + /* split into two lines */ + c->x = x; + c->y = y; + c->width = split.width; + c->height = split.height; + c->length = split.end - c->text; + x = 0; + y += 30; + c2 = memcpy(xcalloc(1, sizeof(struct box)), c, sizeof(struct box)); + c2->text = split.end; + c2->next = c->next; + c->next = c2; + c = c2; } - /* split into two lines */ - c->x = x; - c->y = y; - c->height = 2; - x = 2; - y += 3; - new = memcpy(xcalloc(1, sizeof(struct box)), c, sizeof(struct box)); - new->text = end + 1; - new->next = c->next; - c->next = new; - c = new; } box->width = width; - box->height = y + 3; + box->height = y + 30; } /** @@ -165,7 +169,7 @@ void layout_table(struct box * table, unsigned long width) unsigned long auto_width; /* width of each auto column (all equal) */ unsigned long extra_width = 0; /* extra width for each column if table is wider than columns */ unsigned long x; - unsigned long y = 1; + unsigned long y = 0; unsigned long * xs; unsigned int i; struct box * c; @@ -176,7 +180,7 @@ void layout_table(struct box * table, unsigned long width) /* find table width */ switch (table->style->width.width) { case CSS_WIDTH_LENGTH: - table_width = len(&table->style->width.value.length, 10); + table_width = len(&table->style->width.value.length, 20); break; case CSS_WIDTH_PERCENT: table_width = width * table->style->width.value.percent / 100; @@ -193,7 +197,7 @@ void layout_table(struct box * table, unsigned long width) assert(c->type == BOX_TABLE_CELL); switch (c->style->width.width) { case CSS_WIDTH_LENGTH: - used_width += len(&c->style->width.value.length, 10); + used_width += len(&c->style->width.value.length, 20); break; case CSS_WIDTH_PERCENT: used_width += table_width * c->style->width.value.percent / 100; @@ -228,9 +232,9 @@ void layout_table(struct box * table, unsigned long width) break; } xs[i] = x; - printf("%i ", x); + /*printf("%i ", x);*/ } - printf("\n"); + /*printf("\n");*/ if (auto_columns == 0 && table->style->width.width == CSS_WIDTH_AUTO) table_width = used_width; @@ -249,14 +253,14 @@ void layout_table(struct box * table, unsigned long width) break; } c->x = xs[i]; - c->y = 1; + c->y = 0; if (c->height > height) height = c->height; } r->x = 0; r->y = y; r->width = table_width; - r->height = height + 2; - y += height + 3; + r->height = height; + y += height; } free(xs); diff --git a/render/render.c b/render/render.c index 6ada1da3e..2e3eb9c12 100644 --- a/render/render.c +++ b/render/render.c @@ -1,5 +1,5 @@ /** - * $Id: render.c,v 1.8 2002/05/04 21:17:06 bursa Exp $ + * $Id: render.c,v 1.9 2002/05/11 15:22:24 bursa Exp $ */ #include <assert.h> @@ -87,6 +87,38 @@ void render_plain(struct box * box) } +void render_dump(struct box * box, unsigned long x, unsigned long y) +{ + struct box * c; + const char * const noname = ""; + const char * name = noname; + + switch (box->type) { + case BOX_TABLE: + case BOX_TABLE_ROW: + case BOX_TABLE_CELL: + case BOX_BLOCK: name = box->node->name; + break; + case BOX_INLINE: + case BOX_INLINE_CONTAINER: + 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 : ""); + if (name == noname) + printf("\"\"\n"); + else + printf("#%.6x\n", 0xffffff - ((name[0] << 16) | (name[1] << 8) | name[0])); + fflush(stdout); + + for (c = box->children; c != 0; c = c->next) + render_dump(c, x + box->x, y + box->y); +} + + int main(int argc, char *argv[]) { struct css_stylesheet * stylesheet; @@ -115,11 +147,13 @@ int main(int argc, char *argv[]) doc_box->node = c; xml_to_box(c, style, stylesheet, &selector, 0, doc_box, 0); html_box = doc_box->children; - box_dump(html_box, 0); +/* box_dump(html_box, 0);*/ - layout_block(html_box, 79); - box_dump(html_box, 0); - render_plain(html_box); + layout_block(html_box, 600); +/* box_dump(html_box, 0);*/ +/* render_plain(html_box);*/ + printf("%li %li\n", html_box->width, html_box->height); + render_dump(html_box, 0, 0); return 0; } diff --git a/render/show.tcl b/render/show.tcl new file mode 100644 index 000000000..4adc48287 --- /dev/null +++ b/render/show.tcl @@ -0,0 +1,19 @@ +#!/usr/bin/wish + +gets stdin size +scan $size "%i %i" x y +canvas .can -width [expr $x+16] -height [expr $y+16] -borderwidth 0 -highlightthickness 0 -bg white +pack .can + +proc rect {x y w h n t c} { + set x [expr $x+8] + set y [expr $y+8] + .can create rectangle $x $y [expr $x+$w] [expr $y+$h] -fill $c + .can create text $x $y -anchor nw -text $n -fill red -font "arial 18 bold" + .can create text $x [expr $y+$h] -anchor sw -text $t -font "courier 32" +} + +while {-1 != [gets stdin line]} { + eval $line +} + diff --git a/render/test/test1.html b/render/test/test1.html index 757c51cb6..901d13c67 100644 --- a/render/test/test1.html +++ b/render/test/test1.html @@ -9,7 +9,7 @@ <p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque <b>habitant <i>Morbi</i></b> tristique Senectus et Metus et malesuada Fames ac turpis Egestas. (This paragraph has no closing tag.)<p>Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; <b>Pellentesque</b> habitant Morbi tristique Senectus et Metus et malesuada Fames ac turpis Egestas.</p> -<table><tr><td style="width: 30%; height: 1em">Cell 1</td><td style="width: 50%;">Cell 2<p>More cell 2</p></td></tr> +<table><tr><td style="width: 30%; height: 4em">Cell 1</td><td style="width: 50%;">Cell 2<p>More cell 2</p></td></tr> <tr><td>Cell 3</td><td>Cell 4</td></tr></table> <p>Inline text <div>containing a block</div> and more text.</p> |