summaryrefslogtreecommitdiff
path: root/render
diff options
context:
space:
mode:
Diffstat (limited to 'render')
-rw-r--r--render/box.c11
-rw-r--r--render/css.c40
-rw-r--r--render/css.h8
-rw-r--r--render/css_enums2
-rw-r--r--render/layout.c72
-rw-r--r--render/render.c5
6 files changed, 99 insertions, 39 deletions
diff --git a/render/box.c b/render/box.c
index 79327602d..3fc6348d9 100644
--- a/render/box.c
+++ b/render/box.c
@@ -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;
diff --git a/render/css.c b/render/css.c
index 6e36bfeed..73af7fbb3 100644
--- a/render/css.c
+++ b/render/css.c
@@ -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;
diff --git a/render/css.h b/render/css.h
index b1429e33e..5869ad832 100644
--- a/render/css.h
+++ b/render/css.h
@@ -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;
diff --git a/render/css_enums b/render/css_enums
index 0f5b7a87e..8417e8d7e 100644
--- a/render/css_enums
+++ b/render/css_enums
@@ -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
diff --git a/render/layout.c b/render/layout.c
index d208fdd24..c47211879 100644
--- a/render/layout.c
+++ b/render/layout.c
@@ -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;
}
diff --git a/render/render.c b/render/render.c
index 66009fe65..7e31f4c65 100644
--- a/render/render.c
+++ b/render/render.c
@@ -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("\\\"");