From 4bd56554081f454ca8a7798032360d060f3aaf3b Mon Sep 17 00:00:00 2001 From: James Bursa Date: Wed, 19 Jun 2002 15:17:45 +0000 Subject: [PATCH] [project @ 2002-06-19 15:17:45 by bursa] CSS fixes, text-align property implemented (except justify). svn path=/import/netsurf/; revision=21 --- render/css.c | 30 +++++++++++++++++------- render/css.h | 5 ++-- render/layout.c | 52 +++++++++++++++++++++++------------------- render/test/test1.css | 3 +-- render/test/test1.html | 12 +++++++--- 5 files changed, 64 insertions(+), 38 deletions(-) diff --git a/render/css.c b/render/css.c index 2e59027c8..6e36bfeed 100644 --- a/render/css.c +++ b/render/css.c @@ -1,5 +1,5 @@ /** - * $Id: css.c,v 1.4 2002/06/18 21:24:21 bursa Exp $ + * $Id: css.c,v 1.5 2002/06/19 15:17:45 bursa Exp $ */ #include @@ -24,7 +24,7 @@ struct decl { struct rule * rule; }; -#define HASH_SIZE 13 +#define HASH_SIZE 1 struct css_stylesheet { struct rule * hash[HASH_SIZE]; @@ -67,7 +67,7 @@ const struct css_style css_empty_style = { { CSS_HEIGHT_AUTO }, { CSS_LINE_HEIGHT_INHERIT }, CSS_TEXT_ALIGN_INHERIT, - { CSS_WIDTH_AUTO } + { CSS_WIDTH_INHERIT } }; const struct css_style css_blank_style = { @@ -269,7 +269,7 @@ static int seleq(const struct css_selector * const s1, const struct css_selector static unsigned long selmatch(const struct css_selector * const s, const struct css_selector * const sr) { unsigned int c; - if (strcmp(s->element, sr->element) != 0) return 0; + if (sr->element[0] != 0 && strcmp(s->element, sr->element) != 0) return 0; c = s->element[0] == 0 ? 0 : 1; if (sr->class != 0) { if (s->class != 0 && strcmp(s->class, sr->class) == 0) return 0x100 + c; @@ -320,16 +320,26 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel struct decl * decl = xcalloc(0, sizeof(struct decl)); unsigned int d, decls = 0; +/* fprintf(stderr, "css_get_style: "); */ +/* for (d = 0; d < selectors; d++) dump_selector(&selector[d]); */ +/* fprintf(stderr, "\n"); */ + for (rule = stylesheet->hash[hash_str(selector[selectors - 1].element)]; rule != 0; rule = rule->next) { unsigned int i = selectors - 1; unsigned int j; unsigned int score, s; - if ((score = selmatch(&selector[i], &rule->selector[rule->selectors - 1])) == 0) +/* for (d = 0; d < rule->selectors; d++) dump_selector(&rule->selector[d]); */ + + if ((score = selmatch(&selector[i], &rule->selector[rule->selectors - 1])) == 0) { +/* fprintf(stderr, " last selector match fails\n"); */ continue; - if (selectors < rule->selectors) + } + if (selectors < rule->selectors) { +/* fprintf(stderr, " less selectors than in rule\n"); */ continue; + } for (j = rule->selectors - 1; j != 0; j--) { for (; i != 0 && (s = selmatch(&selector[i - 1], &rule->selector[j - 1])) == 0; i--) @@ -339,10 +349,13 @@ void css_get_style(struct css_stylesheet * stylesheet, struct css_selector * sel score += s; } if (j == 0) { +/* fprintf(stderr, " match\n"); */ decl = xrealloc(decl, (decls + 1) * sizeof(struct decl)); decl[decls].score = score; decl[decls].rule = rule; decls++; + } else { +/* fprintf(stderr, " some selector match fails\n"); */ } } @@ -371,7 +384,7 @@ static void update_style(struct css_stylesheet * stylesheet, struct css_selector rule->selector = selector; rule->selectors = selectors; rule->style = xcalloc(1, sizeof(struct css_style)); - memcpy(rule->style, &css_empty_style, sizeof(struct css_style)); + memcpy(rule->style, &css_blank_style, sizeof(struct css_style)); css_parse_property_list(rule->style, str); rule->next = stylesheet->hash[h]; stylesheet->hash[h] = rule; @@ -529,7 +542,8 @@ void css_cascade(struct css_style * const style, const struct css_style * const if (apply->display != CSS_DISPLAY_INHERIT) style->display = apply->display; if (apply->float_ != CSS_FLOAT_INHERIT) style->float_ = apply->float_; style->height = apply->height; - style->width = apply->width; + if (apply->text_align != CSS_TEXT_ALIGN_INHERIT) style->text_align = apply->text_align; + if (apply->width.width != CSS_WIDTH_INHERIT) style->width = apply->width; /* font-size */ f = apply->font_size.value.percent / 100; diff --git a/render/css.h b/render/css.h index 2a963f4f3..b1429e33e 100644 --- a/render/css.h +++ b/render/css.h @@ -1,5 +1,5 @@ /** - * $Id: css.h,v 1.3 2002/06/18 21:24:21 bursa Exp $ + * $Id: css.h,v 1.4 2002/06/19 15:17:45 bursa Exp $ */ #include "css_enum.h" @@ -53,7 +53,8 @@ struct css_style { css_text_align text_align; struct { - enum { CSS_WIDTH_AUTO, + enum { CSS_WIDTH_INHERIT, + CSS_WIDTH_AUTO, CSS_WIDTH_LENGTH, CSS_WIDTH_PERCENT } width; union { diff --git a/render/layout.c b/render/layout.c index 36c018a9e..d208fdd24 100644 --- a/render/layout.c +++ b/render/layout.c @@ -1,5 +1,5 @@ /** - * $Id: layout.c,v 1.6 2002/06/18 21:24:21 bursa Exp $ + * $Id: layout.c,v 1.7 2002/06/19 15:17:45 bursa Exp $ */ #include @@ -88,7 +88,7 @@ void layout_block(struct box * box, unsigned long width, struct box * cont, { struct css_style * style = box->style; - assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT); + assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT); switch (style->width.width) { case CSS_WIDTH_AUTO: @@ -126,7 +126,7 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc struct box * c; unsigned long y = 0; - assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT || box->type == BOX_TABLE_CELL); + assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT || box->type == BOX_TABLE_CELL); for (c = box->children; c != 0; c = c->next) { switch (c->type) { @@ -149,7 +149,7 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc y += c->height; break; default: - printf("%s -> %s\n", + fprintf(stderr, "%s -> %s\n", box->node ? box->node->name : "()", c->node ? c->node->name : "()"); die("block child not block, table, or inline container"); @@ -184,7 +184,7 @@ void find_sides(struct box * fl, unsigned long y0, unsigned long y1, } } } - fprintf(stderr, "find_sides: y0 %li y1 %li => x0 %li x1 %li\n", y0, y1, *x0, *x1); +/* fprintf(stderr, "find_sides: y0 %li y1 %li => x0 %li x1 %li\n", y0, y1, *x0, *x1); */ } @@ -239,8 +239,8 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long struct box * c; struct box * d; - fprintf(stderr, "layout_line: '%.*s' %li %li %li\n", first->length, first->text, width, *y, cy); - +/* fprintf(stderr, "layout_line: '%.*s' %li %li %li\n", first->length, first->text, width, *y, cy); */ + /* find sides at top of line */ find_sides(cont->float_children, cy, cy, &x0, &x1, &left, &right); @@ -257,7 +257,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long x += font_width(b->style, b->text, b->length); } } - + /* find new sides using this height */ find_sides(cont->float_children, cy, cy + height, &x0, &x1, &left, &right); @@ -269,7 +269,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long b->width = font_width(b->style, b->text, b->length); x += b->width; c = b; - fprintf(stderr, "layout_line: '%.*s' %li %li\n", b->length, b->text, xp, x); +/* fprintf(stderr, "layout_line: '%.*s' %li %li\n", b->length, b->text, xp, x); */ } else { b->float_children = 0; css_dump_style(b->style); @@ -286,12 +286,12 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long right = b; } b->y = cy; - fprintf(stderr, "layout_line: float fits %li %li, edges %li %li\n", - b->x, b->y, x0, x1); +/* fprintf(stderr, "layout_line: float fits %li %li, edges %li %li\n", */ +/* b->x, b->y, x0, x1); */ } else { /* doesn't fit: place below */ place_float_below(b, width, cy + height + 1, cont); - fprintf(stderr, "layout_line: float doesn't fit %li %li\n", b->x, b->y); +/* fprintf(stderr, "layout_line: float doesn't fit %li %li\n", b->x, b->y); */ } b->next_float = cont->float_children; cont->float_children = b; @@ -314,16 +314,16 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long c2->next = c->next; c->next = c2; b = c2; - fprintf(stderr, "layout_line: overflow, forcing\n"); +/* fprintf(stderr, "layout_line: overflow, forcing\n"); */ } else if (x1 - x0 < xp + w) { /* first word doesn't fit, but full width not available so leave for later */ b = c; - fprintf(stderr, "layout_line: overflow, leaving\n"); +/* fprintf(stderr, "layout_line: overflow, leaving\n"); */ } else { /* fit as many words as possible */ while (xp + w < x1 - x0) { - fprintf(stderr, "%li + %li = %li < %li = %li - %li\n", - xp, w, xp + w, x1 - x0, x1, x0); +/* fprintf(stderr, "%li + %li = %li < %li = %li - %li\n", */ +/* xp, w, xp + w, x1 - x0, x1, x0); */ space = space2; wp = w; space2 = strchr(space + 1, ' '); @@ -336,25 +336,31 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long c2->next = c->next; c->next = c2; b = c2; - fprintf(stderr, "layout_line: overflow, fit\n"); +/* fprintf(stderr, "layout_line: overflow, fit\n"); */ } c->width = wp; + x = xp + wp; } /* set positions */ + switch (first->parent->parent->style->text_align) { + case CSS_TEXT_ALIGN_RIGHT: x0 = x1 - x; break; + case CSS_TEXT_ALIGN_CENTER: x0 = (x0 + (x1 - x)) / 2; break; + default: /* leave on left */ + } for (d = first; d != b; d = d->next) { if (d->type == BOX_INLINE) { d->x += x0; d->y = *y; } } - + *y += height + 1; return b; } - + void place_float_below(struct box * c, unsigned long width, unsigned long y, struct box * cont) { unsigned long x0, x1, yy = y; @@ -374,7 +380,7 @@ void place_float_below(struct box * c, unsigned long width, unsigned long y, str yy = left->y + left->height + 1; } } while (!((left == 0 && right == 0) || (c->width < x1 - x0))); - + if (c->style->float_ == CSS_FLOAT_LEFT) { c->x = x0; } else { @@ -448,7 +454,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont, auto_width = (table_width - used_width) / auto_columns; /*printf("%i %i %i %i %i\n", table_width, columns, auto_columns, used_width, auto_width);*/ - + /* find column widths */ xs = xcalloc(columns + 1, sizeof(*xs)); xs[0] = x = 0; @@ -471,7 +477,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont, if (auto_columns == 0 && table->style->width.width == CSS_WIDTH_AUTO) table_width = used_width; - + /* position cells */ for (r = table->children; r != 0; r = r->next) { unsigned long height = 0; @@ -498,7 +504,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont, } free(xs); - + table->width = table_width; table->height = y; } diff --git a/render/test/test1.css b/render/test/test1.css index dbff4a8b9..2158e3a7a 100644 --- a/render/test/test1.css +++ b/render/test/test1.css @@ -20,5 +20,4 @@ colgroup { display: table-column-group } td, th { display: table-cell } caption { display: table-caption } -div { float: left; width: 90%; } - +h1 { font-size: xx-large; text-align: center } diff --git a/render/test/test1.html b/render/test/test1.html index 901d13c67..6ec2a780a 100644 --- a/render/test/test1.html +++ b/render/test/test1.html @@ -7,12 +7,18 @@

Heading

-

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque habitant Morbi tristique Senectus et Metus et malesuada Fames ac turpis Egestas. (This paragraph has no closing tag.)

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque habitant Morbi tristique Senectus et Metus et malesuada Fames ac turpis Egestas.

+

Left aligned paragraph. Integer felis. Suspendisse placerat enim et sem viverra aliquet. Nam sodales. Donec arcu velit, tincidunt eget, suscipit et, suscipit at, purus. Nullam tristique libero quis wisi. Integer diam nulla, nonummy sed, faucibus at, porta sed, tortor. Vivamus sem. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Donec ante. Ut pellentesque. Phasellus vulputate placerat lacus. Aliquam a risus a mauris luctus tempor. Maecenas volutpat. Nam mollis convallis sapien. Nulla molestie tincidunt dui. Donec adipiscing, quam vitae mattis suscipit, justo elit bibendum wisi, ac viverra ligula turpis ac tortor. Quisque molestie luctus ante. Pellentesque ac velit quis orci dignissim consequat.

- +

Centered paragraph. Aliquam ligula risus, pharetra non, dapibus eu, vestibulum et, pede. Donec diam orci, consequat ut, scelerisque ut, vestibulum sed, felis. Quisque ipsum. Donec vestibulum, nisl et porttitor feugiat, lacus velit sodales elit, non interdum leo sem ac sapien. Donec risus tellus, convallis sit amet, congue pellentesque, vestibulum sagittis, risus. Curabitur elementum. Suspendisse gravida sem. Donec condimentum. Donec et erat. Cras nonummy. Donec ut mi. In pharetra. Curabitur egestas volutpat ligula. Vestibulum fermentum purus at diam. Ut ornare quam ut pede. Praesent ultrices tincidunt quam. In sed enim quis enim mollis malesuada. Suspendisse accumsan, velit nec molestie adipiscing, erat lorem consectetuer tellus, quis vulputate ipsum ante at eros. Donec laoreet mi eu felis.

+ +

Right-aligned paragraph. Suspendisse at sem. Sed nec quam ut sapien aliquet fermentum. Curabitur lacus nibh, congue id, lobortis ac, ultricies at, felis. Proin ipsum ipsum, ultrices eu, porttitor ut, condimentum ac, quam. Mauris sodales dignissim purus. Aenean et nibh. Vestibulum sagittis scelerisque ante. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Cras pede odio, mollis nec, hendrerit quis, dapibus at, urna. Aliquam eget nisl. Integer augue. Morbi et orci ac nunc volutpat gravida. Integer laoreet. Quisque fringilla. Nulla tristique libero at sapien. Nam auctor.

+ +

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque habitant Morbi tristique Senectus Left floated span et Metus et malesuada Fames ac turpis Egestas. (This paragraph has no closing tag.)

Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Pellentesque habitant Morbi tristique Senectus et Metus et malesuada Fames ac turpis Egestas.

+ +
Cell 1Cell 2

More cell 2

Cell 1Cell 2

More cell 2

Cell 3Cell 4
-

Inline text

containing a block
and more text.

+

Inline text containing a float and more text. Vestibulum ante ipsum primis in faucibus orci luctus.