summaryrefslogtreecommitdiff
path: root/source/html
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2014-10-22 21:20:42 +0200
committerTor Andersson <tor.andersson@artifex.com>2014-12-03 12:25:51 +0100
commitd79203b42621257aed8e4c02e4e6c95ec82d9243 (patch)
tree4ebd4fc7a39f55ad1a4ec7cad157f0d9a90a64e3 /source/html
parent9890cc2bd3c6b81ebaf5f7ce236117dc08c03cee (diff)
downloadmupdf-d79203b42621257aed8e4c02e4e6c95ec82d9243.tar.xz
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.
Diffstat (limited to 'source/html')
-rw-r--r--source/html/css-apply.c33
-rw-r--r--source/html/layout.c167
2 files changed, 100 insertions, 100 deletions
diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index 53a46f50..1a93e3e4 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -699,6 +699,24 @@ get_style_property_string(struct style *node, const char *name, const char *init
return value->data;
}
+int
+get_style_property_display(struct style *node)
+{
+ struct value *value = get_style_property(node, "display");
+ if (value)
+ {
+ if (!strcmp(value->data, "none"))
+ return NONE;
+ if (!strcmp(value->data, "inline"))
+ return INLINE;
+ if (!strcmp(value->data, "block"))
+ return BLOCK;
+ if (!strcmp(value->data, "list-item"))
+ return LIST_ITEM;
+ }
+ return INLINE;
+}
+
static float
compute_number(struct value *value, float em, float hundred, float scale, float initial)
{
@@ -751,24 +769,10 @@ compute_style(struct computed_style *style, struct style *node)
memset(style, 0, sizeof *style);
- style->display = INLINE;
style->position = STATIC;
style->text_align = LEFT;
style->font_size = 12;
- value = get_style_property(node, "display");
- if (value)
- {
- if (!strcmp(value->data, "none"))
- style->display = NONE;
- if (!strcmp(value->data, "inline"))
- style->display = INLINE;
- if (!strcmp(value->data, "block"))
- style->display = BLOCK;
- if (!strcmp(value->data, "list-item"))
- style->display = LIST_ITEM;
- }
-
value = get_style_property(node, "position");
if (value)
{
@@ -871,7 +875,6 @@ void
print_style(struct computed_style *style)
{
printf("style {\n");
- printf("\tdisplay = %d;\n", style->display);
printf("\tposition = %d;\n", style->position);
printf("\ttext-align = %d;\n", style->text_align);
printf("\tfont-family = %s;\n", style->font_family);
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: <br>
// TODO: <img>
- 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);
}