[project @ 2002-06-21 18:16:24 by bursa]

Implemented clear, fixed inline / float bugs, eliminated many compiler warnings.

svn path=/import/netsurf/; revision=22
This commit is contained in:
James Bursa 2002-06-21 18:16:24 +00:00
parent 4bd5655408
commit 0a5d2d0daf
7 changed files with 102 additions and 42 deletions

View File

@ -1,5 +1,5 @@
/**
* $Id: box.c,v 1.5 2002/06/18 21:24:21 bursa Exp $
* $Id: box.c,v 1.6 2002/06/21 18:16:24 bursa Exp $
*/
#include <assert.h>
@ -176,6 +176,12 @@ struct css_style * box_get_style(struct css_stylesheet * stylesheet, struct css_
memcpy(style, parent_style, sizeof(struct css_style));
css_get_style(stylesheet, selector, depth, style);
if ((s = xmlGetProp(n, "clear"))) {
if (strcmp(s, "all") == 0) style->clear = CSS_CLEAR_BOTH;
else if (strcmp(s, "left") == 0) style->clear = CSS_CLEAR_LEFT;
else if (strcmp(s, "right") == 0) style->clear = CSS_CLEAR_RIGHT;
}
if ((s = xmlGetProp(n, "width"))) {
if (strrchr(s, '%'))
style->width.width = CSS_WIDTH_PERCENT,
@ -216,7 +222,8 @@ void box_dump(struct box * box, unsigned int depth)
switch (box->type) {
case BOX_BLOCK: fprintf(stderr, "BOX_BLOCK <%s> ", box->node->name); break;
case BOX_INLINE_CONTAINER: fprintf(stderr, "BOX_INLINE_CONTAINER "); break;
case BOX_INLINE: fprintf(stderr, "BOX_INLINE '%.*s' ", box->length, box->text); break;
case BOX_INLINE: fprintf(stderr, "BOX_INLINE '%.*s' ",
(int) box->length, box->text); break;
case BOX_TABLE: fprintf(stderr, "BOX_TABLE <%s> ", box->node->name); break;
case BOX_TABLE_ROW: fprintf(stderr, "BOX_TABLE_ROW <%s> ", box->node->name); break;
case BOX_TABLE_CELL: fprintf(stderr, "BOX_TABLE_CELL <%s> ", box->node->name); break;

View File

@ -1,5 +1,5 @@
/**
* $Id: css.c,v 1.5 2002/06/19 15:17:45 bursa Exp $
* $Id: css.c,v 1.6 2002/06/21 18:16:24 bursa Exp $
*/
#include <string.h>
@ -31,6 +31,7 @@ struct css_stylesheet {
};
static int parse_length(struct css_length * const length, const char *s);
static void parse_clear(struct css_style * const style, const char * const value);
static void parse_display(struct css_style * const style, const char * const value);
static void parse_float(struct css_style * const style, const char * const value);
static void parse_font_size(struct css_style * const style, const char * const value);
@ -51,33 +52,36 @@ static void dump_selector(const struct css_selector * const sel);
static void dump_rule(const struct rule * rule);
const struct css_style css_base_style = {
CSS_CLEAR_NONE,
CSS_DISPLAY_BLOCK,
CSS_FLOAT_NONE,
{ CSS_FONT_SIZE_LENGTH, {12, CSS_UNIT_PT} },
{ CSS_HEIGHT_AUTO },
{ CSS_LINE_HEIGHT_ABSOLUTE, 1.2 },
{ CSS_FONT_SIZE_LENGTH, { { 12, CSS_UNIT_PT } } },
{ CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } },
{ CSS_LINE_HEIGHT_ABSOLUTE, { 1.2 } },
CSS_TEXT_ALIGN_LEFT,
{ CSS_WIDTH_AUTO }
{ CSS_WIDTH_AUTO, { { 1, CSS_UNIT_EM } } }
};
const struct css_style css_empty_style = {
CSS_CLEAR_INHERIT,
CSS_DISPLAY_INHERIT,
CSS_FLOAT_INHERIT,
{ CSS_FONT_SIZE_INHERIT },
{ CSS_HEIGHT_AUTO },
{ CSS_LINE_HEIGHT_INHERIT },
{ CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_EM } } },
{ CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } },
{ CSS_LINE_HEIGHT_INHERIT, { 1.2 } },
CSS_TEXT_ALIGN_INHERIT,
{ CSS_WIDTH_INHERIT }
{ CSS_WIDTH_INHERIT, { { 1, CSS_UNIT_EM } } }
};
const struct css_style css_blank_style = {
CSS_CLEAR_NONE,
CSS_DISPLAY_BLOCK,
CSS_FLOAT_NONE,
{ CSS_FONT_SIZE_INHERIT },
{ CSS_HEIGHT_AUTO },
{ CSS_LINE_HEIGHT_INHERIT },
{ CSS_FONT_SIZE_INHERIT, { { 1, CSS_UNIT_EM } } },
{ CSS_HEIGHT_AUTO, { 1, CSS_UNIT_EM } },
{ CSS_LINE_HEIGHT_INHERIT, { 1.2 } },
CSS_TEXT_ALIGN_INHERIT,
{ CSS_WIDTH_AUTO }
{ CSS_WIDTH_AUTO, { { 1, CSS_UNIT_EM } } }
};
@ -94,6 +98,11 @@ static int parse_length(struct css_length * const length, const char *s)
return 0;
}
static void parse_clear(struct css_style * const style, const char * const value)
{
style->clear = css_clear_parse(value);
}
static void parse_display(struct css_style * const style, const char * const value)
{
style->display = css_display_parse(value);
@ -183,6 +192,7 @@ static struct property {
const char * const name;
void (*parse) (struct css_style * const s, const char * const value);
} const property[] = {
{ "clear", parse_clear },
{ "display", parse_display },
{ "float", parse_float },
{ "font-size", parse_font_size },
@ -464,6 +474,7 @@ static void dump_length(const struct css_length * const length)
void css_dump_style(const struct css_style * const style)
{
fprintf(stderr, "{ ");
fprintf(stderr, "clear: %s; ", css_clear_name[style->clear]);
fprintf(stderr, "display: %s; ", css_display_name[style->display]);
fprintf(stderr, "float: %s; ", css_float_name[style->float_]);
fprintf(stderr, "font-size: ");
@ -539,9 +550,10 @@ void css_dump_stylesheet(const struct css_stylesheet * stylesheet)
void css_cascade(struct css_style * const style, const struct css_style * const apply)
{
float f;
if (apply->clear != CSS_CLEAR_INHERIT) style->clear = apply->clear;
if (apply->display != CSS_DISPLAY_INHERIT) style->display = apply->display;
if (apply->float_ != CSS_FLOAT_INHERIT) style->float_ = apply->float_;
style->height = apply->height;
if (apply->height.height != CSS_HEIGHT_INHERIT) style->height = apply->height;
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;

View File

@ -1,5 +1,5 @@
/**
* $Id: css.h,v 1.4 2002/06/19 15:17:45 bursa Exp $
* $Id: css.h,v 1.5 2002/06/21 18:16:24 bursa Exp $
*/
#include "css_enum.h"
@ -17,6 +17,7 @@ struct css_length {
};
struct css_style {
css_clear clear;
css_display display;
css_float float_;
@ -26,14 +27,15 @@ struct css_style {
CSS_FONT_SIZE_LENGTH,
CSS_FONT_SIZE_PERCENT } size;
union {
float absolute;
struct css_length length;
float absolute;
float percent;
} value;
} font_size;
struct {
enum { CSS_HEIGHT_AUTO,
enum { CSS_HEIGHT_INHERIT,
CSS_HEIGHT_AUTO,
CSS_HEIGHT_LENGTH } height;
struct css_length length;
} height;

View File

@ -4,7 +4,7 @@ css_background_position inherit top center bottom left right length percent
css_background_repeat inherit repeat repeat_x repeat_y no_repeat
css_border_width inherit medium thin thick length
css_border_style inherit none dashed dotted double groove inset outset ridge solid
css_clear none both left right
css_clear inherit none both left right
css_display inherit inline block list-item run-in compact marker table inline-table table-row-group table-header-group table-footer-group table-row table-column-group table-column table-cell table-caption none
css_float inherit none left right
css_font_style normal italic oblique

View File

@ -1,5 +1,5 @@
/**
* $Id: layout.c,v 1.7 2002/06/19 15:17:45 bursa Exp $
* $Id: layout.c,v 1.8 2002/06/21 18:16:24 bursa Exp $
*/
#include <assert.h>
@ -91,16 +91,17 @@ void layout_block(struct box * box, unsigned long width, struct box * cont,
assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT);
switch (style->width.width) {
case CSS_WIDTH_AUTO:
/* take all available width */
box->width = width;
break;
case CSS_WIDTH_LENGTH:
box->width = len(&style->width.value.length, box->style);
break;
case CSS_WIDTH_PERCENT:
box->width = width * style->width.value.percent / 100;
break;
case CSS_WIDTH_AUTO:
default:
/* take all available width */
box->width = width;
break;
}
box->height = layout_block_children(box, box->width, cont, cx, cy);
switch (style->height.height) {
@ -129,6 +130,25 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc
assert(box->type == BOX_BLOCK || box->type == BOX_FLOAT || box->type == BOX_TABLE_CELL);
for (c = box->children; c != 0; c = c->next) {
if (c->style && c->style->clear != CSS_CLEAR_NONE) {
unsigned long x0, x1;
struct box * left, * right;
do {
x0 = cx;
x1 = cx + width;
find_sides(cont->float_children, cy + y, cy + y,
&x0, &x1, &left, &right);
if ((c->style->clear == CSS_CLEAR_LEFT || c->style->clear == CSS_CLEAR_BOTH)
&& left != 0)
y = left->y + left->height - cy + 1;
if ((c->style->clear == CSS_CLEAR_RIGHT || c->style->clear == CSS_CLEAR_BOTH)
&& right != 0)
if (cy + y < right->y + right->height + 1)
y = right->y + right->height - cy + 1;
} while ((c->style->clear == CSS_CLEAR_LEFT && left != 0) ||
(c->style->clear == CSS_CLEAR_RIGHT && right != 0) ||
(c->style->clear == CSS_CLEAR_BOTH && (left != 0 || right != 0)));
}
switch (c->type) {
case BOX_BLOCK:
layout_block(c, width, cont, cx, cy + y);
@ -172,6 +192,7 @@ unsigned long layout_block_children(struct box * box, unsigned long width, struc
void find_sides(struct box * fl, unsigned long y0, unsigned long y1,
unsigned long * x0, unsigned long * x1, struct box ** left, struct box ** right)
{
/* fprintf(stderr, "find_sides: y0 %li y1 %li x0 %li x1 %li => ", y0, y1, *x0, *x1); */
*left = *right = 0;
for (; fl; fl = fl->next_float) {
if (y0 <= fl->y + fl->height && fl->y <= y1) {
@ -184,7 +205,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, "x0 %li x1 %li left 0x%x right 0x%x\n", *x0, *x1, *left, *right); */
}
@ -238,6 +259,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
struct box * b;
struct box * c;
struct box * d;
int move_y = 0;
/* fprintf(stderr, "layout_line: '%.*s' %li %li %li\n", first->length, first->text, width, *y, cy); */
@ -259,20 +281,23 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
}
/* find new sides using this height */
x0 = 0;
x1 = width;
find_sides(cont->float_children, cy, cy + height, &x0, &x1, &left, &right);
/* pass 2: place boxes in line */
for (x = xp = 0, b = first; x < x1 - x0 && b != 0; b = b->next) {
for (x = xp = 0, b = first; x <= x1 - x0 && b != 0; b = b->next) {
if (b->type == BOX_INLINE) {
b->x = x;
xp = x;
b->width = font_width(b->style, b->text, b->length);
x += b->width;
c = b;
move_y = 1;
/* fprintf(stderr, "layout_line: '%.*s' %li %li\n", b->length, b->text, xp, x); */
} else {
b->float_children = 0;
css_dump_style(b->style);
/* css_dump_style(b->style); */
layout_block(b, width, b, 0, 0);
if (b->width < (x1 - x0) - x || (left == 0 && right == 0 && x == 0)) {
/* fits next to this line, or this line is empty with no floats */
@ -302,18 +327,27 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
/* the last box went over the end */
char * space = strchr(c->text, ' ');
char * space2 = space;
unsigned long w = font_width(c->style, c->text, space - c->text), wp = w;
unsigned long w, wp = w;
struct box * c2;
if (space == 0)
w = font_width(c->style, c->text, c->length);
else
w = font_width(c->style, c->text, space - c->text);
if (x1 - x0 < xp + w && left == 0 && right == 0 && c == first) {
/* first word doesn't fit, but no floats and first on line so force in */
c2 = memcpy(xcalloc(1, sizeof(struct box)), c, sizeof(struct box));
c2->text = space + 1;
c2->length = c->length - (c2->text - c->text);
c->length = space - c->text;
c2->next = c->next;
c->next = c2;
b = c2;
if (space == 0) {
b = c->next;
} else {
c2 = memcpy(xcalloc(1, sizeof(struct box)), c, sizeof(struct box));
c2->text = space + 1;
c2->length = c->length - (c2->text - c->text);
c->length = space - c->text;
c2->next = c->next;
c->next = c2;
b = c2;
}
/* 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 */
@ -321,6 +355,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
/* fprintf(stderr, "layout_line: overflow, leaving\n"); */
} else {
/* fit as many words as possible */
assert(space != 0);
while (xp + w < x1 - x0) {
/* fprintf(stderr, "%li + %li = %li < %li = %li - %li\n", */
/* xp, w, xp + w, x1 - x0, x1, x0); */
@ -340,6 +375,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
}
c->width = wp;
x = xp + wp;
move_y = 1;
}
/* set positions */
@ -355,7 +391,7 @@ struct box * layout_line(struct box * first, unsigned long width, unsigned long
}
}
*y += height + 1;
if (move_y) *y += height + 1;
return b;
}
@ -442,6 +478,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
used_width += table_width * c->style->width.value.percent / 100;
break;
case CSS_WIDTH_AUTO:
default:
auto_columns++;
break;
}
@ -467,6 +504,7 @@ void layout_table(struct box * table, unsigned long width, struct box * cont,
x += table_width * c->style->width.value.percent / 100 + extra_width;
break;
case CSS_WIDTH_AUTO:
default:
x += auto_width;
break;
}

View File

@ -1,5 +1,5 @@
/**
* $Id: render.c,v 1.13 2002/06/18 21:24:21 bursa Exp $
* $Id: render.c,v 1.14 2002/06/21 18:16:24 bursa Exp $
*/
#include <assert.h>
@ -20,6 +20,7 @@
void render_plain_element(char * g, struct box * box, unsigned long x, unsigned long y);
void render_plain(struct box * box);
void render_dump(struct box * box, unsigned long x, unsigned long y);
/**
@ -108,7 +109,7 @@ void render_dump(struct box * box, unsigned long x, unsigned long y)
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;
unsigned int i;
for (i = 0; i < box->length; i++) {
if (box->text[i] == '"')
printf("\\\"");

View File

@ -1,5 +1,5 @@
/**
* $Id: utils.c,v 1.3 2002/06/18 21:24:21 bursa Exp $
* $Id: utils.c,v 1.4 2002/06/21 18:16:24 bursa Exp $
*/
#include <ctype.h>
@ -63,10 +63,10 @@ char * load(const char * const path)
if (fp == 0) die("Failed to open file");
if (fseek(fp, 0, SEEK_END) != 0) die("fseek() failed");
if ((size = ftell(fp)) == -1) die("ftell() failed");
buf = xcalloc(size, 1);
buf = xcalloc((size_t) size, 1);
if (fseek(fp, 0, SEEK_SET) != 0) die("fseek() failed");
read = fread(buf, 1, size, fp);
read = fread(buf, 1, (size_t) size, fp);
if (read < size) die("fread() failed");
return buf;