From d79203b42621257aed8e4c02e4e6c95ec82d9243 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 22 Oct 2014 21:20:42 +0200 Subject: html: Don't compute full styles during box generation. Apply the style sheet rules and save the raw properties in each box. Only resolve the 'display' property that is needed for box generation. --- source/html/layout.c | 167 +++++++++++++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 85 deletions(-) (limited to 'source/html/layout.c') diff --git a/source/html/layout.c b/source/html/layout.c index c8ba17e2..1d92b502 100644 --- a/source/html/layout.c +++ b/source/html/layout.c @@ -40,159 +40,156 @@ enum struct box { int type; - float x, y, w, h; - float padding[4]; - float border[4]; - float margin[4]; - - int bold, italic; - - fz_xml *node; - const char *text; - struct box *up, *down, *last, *next; + fz_xml *node; + struct style style; }; -struct box *new_box(fz_context *ctx, struct box *root, int type, struct computed_style *cstyle, fz_xml *node) +struct box *new_box(fz_context *ctx, fz_xml *node, struct style *up_style) { struct box *box; - int i; box = fz_malloc_struct(ctx, struct box); - box->type = type; + + box->type = BOX_BLOCK; box->x = box->y = 0; box->w = box->h = 0; - for (i = 0; i < 4; ++i) - { - box->padding[i] = cstyle->padding[i]; - box->margin[i] = cstyle->margin[i]; - box->border[i] = cstyle->border_width[i]; - box->bold = cstyle->bold; - box->italic = cstyle->italic; - } - - box->node = node; - - box->up = root; + box->up = NULL; box->last = NULL; box->down = NULL; box->next = NULL; - if (root) + box->node = node; + + box->style.up = up_style; + box->style.count = 0; + + return box; +} + +void insert_box(fz_context *ctx, struct box *box, int type, struct box *top) +{ + box->type = type; + + box->up = top; + + if (top) { - if (!root->last) + if (!top->last) { - root->down = root->last = box; + top->down = top->last = box; } else { - root->last->next = box; - root->last = box; + top->last->next = box; + top->last = box; } } - - return box; } -static struct box *new_block_box(fz_context *ctx, struct box **topp, struct computed_style *cstyle, fz_xml *node) +static struct box *insert_block_box(fz_context *ctx, struct box *box, struct box *top) { - struct box *top = *topp; - struct box *box; - if (top->type == BOX_BLOCK) { - box = new_box(ctx, top, BOX_BLOCK, cstyle, node); + insert_box(ctx, box, BOX_BLOCK, top); } else if (top->type == BOX_ANONYMOUS) { while (top->type != BOX_BLOCK) top = top->up; - *topp = top; - box = new_box(ctx, top, BOX_BLOCK, cstyle, node); + insert_box(ctx, box, BOX_BLOCK, top); } else if (top->type == BOX_INLINE) { while (top->type != BOX_BLOCK) top = top->up; - *topp = top; - box = new_box(ctx, top, BOX_BLOCK, cstyle, node); + insert_box(ctx, box, BOX_BLOCK, top); } - return box; + return top; } -static struct box *new_inline_box(fz_context *ctx, struct box *box, struct computed_style *cstyle, fz_xml *node) +static void insert_inline_box(fz_context *ctx, struct box *box, struct box *top) { - if (box->type == BOX_BLOCK) + if (top->type == BOX_BLOCK) { - if (box->last && box->last->type == BOX_ANONYMOUS) - box = box->last; + if (top->last && top->last->type == BOX_ANONYMOUS) + { + insert_box(ctx, box, BOX_INLINE, top->last); + } else - box = new_box(ctx, box, BOX_ANONYMOUS, cstyle, NULL); - box = new_box(ctx, box, BOX_INLINE, cstyle, node); + { + struct box *anon = new_box(ctx, NULL, &top->style); + insert_box(ctx, anon, BOX_ANONYMOUS, top); + insert_box(ctx, box, BOX_INLINE, anon); + } } else if (box->type == BOX_ANONYMOUS) { - box = new_box(ctx, box, BOX_INLINE, cstyle, node); + insert_box(ctx, box, BOX_INLINE, top); } else if (box->type == BOX_INLINE) { - box = new_box(ctx, box, BOX_INLINE, cstyle, node); + insert_box(ctx, box, BOX_INLINE, top); } - return box; } -static void layout_tree(fz_context *ctx, fz_xml *node, struct box *top, struct style *up_style, struct rule *rule) +static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struct rule *rule) { - struct style style; - struct computed_style cstyle; + struct style *up_style; struct box *box; + int display; + + /* link styles separately because splitting inline blocks breaks the style/box tree symmetry */ + up_style = &top->style; while (node) { - style.up = up_style; - style.count = 0; + box = new_box(ctx, node, up_style); if (fz_xml_tag(node)) { - apply_styles(ctx, &style, rule, node); - compute_style(&cstyle, &style); - // print_style(&cstyle); + apply_styles(ctx, &box->style, rule, node); + + display = get_style_property_display(&box->style); // TOOD:
// TODO: - if (cstyle.display != NONE) + if (display != NONE) { - if (cstyle.display == BLOCK) + if (display == BLOCK) { - box = new_block_box(ctx, &top, &cstyle, node); + top = insert_block_box(ctx, box, top); } - else if (cstyle.display == INLINE) + else if (display == INLINE) { - box = new_inline_box(ctx, top, &cstyle, node); + insert_inline_box(ctx, box, top); } else { fz_warn(ctx, "unknown box display type"); - box = new_box(ctx, top, BOX_BLOCK, &cstyle, node); + insert_box(ctx, box, BOX_BLOCK, top); } if (fz_xml_down(node)) - layout_tree(ctx, fz_xml_down(node), box, &style, rule); + generate_boxes(ctx, fz_xml_down(node), box, rule); } } else { - compute_style(&cstyle, &style); - new_inline_box(ctx, top, &cstyle, node); + insert_inline_box(ctx, box, top); } node = fz_xml_next(node); } } +static void layout_boxes(fz_context *ctx, struct box *top, float w, float h) +{ +} + static void indent(int level) { while (level--) printf(" "); @@ -209,13 +206,12 @@ static void print_box(fz_context *ctx, struct box *box, int level) case BOX_ANONYMOUS: printf("anonymous"); break; case BOX_INLINE: printf("inline"); break; } - if (box->node) { + if (box->node) + { const char *tag = fz_xml_tag(box->node); const char *text = fz_xml_text(box->node); if (tag) printf(" <%s>", tag); if (text) printf(" \"%s\"", text); - if (box->bold) printf(" bold"); - if (box->italic) printf(" italic"); } printf("\n"); if (box->down) @@ -238,7 +234,8 @@ static char *concat_text(fz_context *ctx, fz_xml *root) for (node = fz_xml_down(root); node; node = fz_xml_next(node)) { const char *text = fz_xml_text(node); - if (text) { + if (text) + { n = strlen(text); memcpy(s+i, text, n); i += n; @@ -251,14 +248,18 @@ static char *concat_text(fz_context *ctx, fz_xml *root) static struct rule *load_css(fz_context *ctx, struct rule *css, fz_xml *root) { fz_xml *node; - for (node = root; node; node = fz_xml_next(node)) { + for (node = root; node; node = fz_xml_next(node)) + { const char *tag = fz_xml_tag(node); #if 0 - if (tag && !strcmp(tag, "link")) { + if (tag && !strcmp(tag, "link")) + { char *rel = fz_xml_att(node, "rel"); - if (rel && !strcasecmp(rel, "stylesheet")) { + if (rel && !strcasecmp(rel, "stylesheet")) + { char *type = fz_xml_att(node, "type"); - if ((type && !strcmp(type, "text/css")) || !type) { + if ((type && !strcmp(type, "text/css")) || !type) + { char *href = fz_xml_att(node, "href"); strcpy(filename, dirname); strcat(filename, href); @@ -267,7 +268,8 @@ static struct rule *load_css(fz_context *ctx, struct rule *css, fz_xml *root) } } #endif - if (tag && !strcmp(tag, "style")) { + if (tag && !strcmp(tag, "style")) + { char *s = concat_text(ctx, node); css = fz_parse_css(ctx, css, s); fz_free(ctx, s); @@ -283,8 +285,6 @@ html_layout_document(html_document *doc, float w, float h) { struct rule *css = NULL; struct box *root_box; - struct style style; - struct computed_style cstyle; #if 0 strcpy(dirname, argv[i]); @@ -299,11 +299,8 @@ html_layout_document(html_document *doc, float w, float h) // print_rules(css); - style.up = NULL; - style.count = 0; - compute_style(&cstyle, &style); - root_box = new_box(doc->ctx, NULL, BOX_BLOCK, &cstyle, NULL); - - layout_tree(doc->ctx, doc->root, root_box, NULL, css); + root_box = new_box(doc->ctx, NULL, NULL); + generate_boxes(doc->ctx, doc->root, root_box, css); + layout_boxes(doc->ctx, root_box, w, h); print_box(doc->ctx, root_box, 0); } -- cgit v1.2.3