diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2014-11-05 16:02:19 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2014-12-03 12:25:51 +0100 |
commit | 36667a0003cc5ac230d94f3483bcc77e8cfc600e (patch) | |
tree | f70c4daeaa4bd27a28f306f2515ae9f7e5b258e3 /source/html | |
parent | 24d9a0f9720f7faade99f34c478bb24225174e91 (diff) | |
download | mupdf-36667a0003cc5ac230d94f3483bcc77e8cfc600e.tar.xz |
html: Generate flow nodes during box generation.
Diffstat (limited to 'source/html')
-rw-r--r-- | source/html/css-apply.c | 13 | ||||
-rw-r--r-- | source/html/layout.c | 174 |
2 files changed, 88 insertions, 99 deletions
diff --git a/source/html/css-apply.c b/source/html/css-apply.c index 0e451ce0..d5ceb24d 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -801,16 +801,21 @@ get_style_property_white_space(struct style *node) } void -compute_style(struct computed_style *style, struct style *node) +default_computed_style(struct computed_style *style) { - struct value *value; - memset(style, 0, sizeof *style); - style->text_align = TA_LEFT; style->vertical_align = 0; style->white_space = WS_NORMAL; style->font_size = make_number(1, N_SCALE); +} + +void +compute_style(struct computed_style *style, struct style *node) +{ + struct value *value; + + default_computed_style(style); style->white_space = get_style_property_white_space(node); diff --git a/source/html/layout.c b/source/html/layout.c index 3bdb26af..b8627e34 100644 --- a/source/html/layout.c +++ b/source/html/layout.c @@ -56,9 +56,9 @@ enum struct flow { int type; + float x, y, w, h; struct computed_style *style; char *text, *broken_text; - float width, broken_width; struct flow *next; }; @@ -67,6 +67,62 @@ static int iswhite(int c) return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } +static struct flow *add_flow(fz_context *ctx, struct box *top, struct computed_style *style, int type) +{ + struct flow *flow = fz_malloc_struct(ctx, struct flow); + flow->type = type; + flow->style = style; + *top->flow_tail = flow; + top->flow_tail = &flow->next; + return flow; +} + +static void add_flow_space(fz_context *ctx, struct box *top, struct computed_style *style) +{ + struct flow *flow; + + /* delete space at the beginning of the line */ + if (!top->flow_head) + return; + + flow = add_flow(ctx, top, style, FLOW_GLUE); + flow->text = " "; + flow->broken_text = ""; +} + +static void add_flow_word(fz_context *ctx, struct box *top, struct computed_style *style, const char *a, const char *b) +{ + struct flow *flow = add_flow(ctx, top, style, FLOW_WORD); + flow->text = fz_malloc(ctx, b - a + 1); + memcpy(flow->text, a, b - a); + flow->text[b - a] = 0; +} + +static void generate_text(fz_context *ctx, struct box *box, const char *text) +{ + struct box *flow = box; + while (flow->type != BOX_FLOW) + flow = flow->up; + + while (*text) + { + if (iswhite(*text)) + { + ++text; + while (iswhite(*text)) + ++text; + add_flow_space(ctx, flow, &box->style); + } + if (*text) + { + const char *mark = text++; + while (*text && !iswhite(*text)) + ++text; + add_flow_word(ctx, flow, &box->style, mark, text); + } + } +} + struct box *new_box(fz_context *ctx, fz_xml *node) { struct box *box; @@ -87,6 +143,8 @@ struct box *new_box(fz_context *ctx, fz_xml *node) box->flow_head = NULL; box->flow_tail = &box->flow_head; + default_computed_style(&box->style); + return box; } @@ -175,7 +233,7 @@ static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struc display = get_style_property_display(&style); - // TOOD: <br> + // TODO: <br> // TODO: <img> if (display != DIS_NONE) @@ -196,11 +254,14 @@ static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struc if (fz_xml_down(node)) generate_boxes(ctx, fz_xml_down(node), box, rule, &style); + + // TODO: remove empty flow boxes } } else { insert_inline_box(ctx, box, top); + generate_text(ctx, box, fz_xml_text(node)); } compute_style(&box->style, &style); @@ -209,93 +270,18 @@ static void generate_boxes(fz_context *ctx, fz_xml *node, struct box *top, struc } } -static struct flow *add_flow(fz_context *ctx, struct box *top, struct computed_style *style, int type) -{ - struct flow *flow = fz_malloc_struct(ctx, struct flow); - flow->type = type; - flow->style = style; - *top->flow_tail = flow; - top->flow_tail = &flow->next; - return flow; -} - -static void add_flow_space(fz_context *ctx, struct box *top, struct computed_style *style, float em) -{ - struct flow *flow; - - /* delete space at the beginning of the line */ - if (!top->flow_head) - return; - - flow = add_flow(ctx, top, style, FLOW_GLUE); - flow->text = " "; - flow->width = 0.5 * em; - flow->broken_text = ""; - flow->broken_width = 0; -} - -static void add_flow_word(fz_context *ctx, struct box *top, struct computed_style *style, float em, const char *a, const char *b) -{ - struct flow *flow = add_flow(ctx, top, style, FLOW_WORD); - flow->text = fz_malloc(ctx, b - a + 1); - memcpy(flow->text, a, b - a); - flow->text[b - a] = 0; - flow->width = (b - a) * 0.5 * em; -} - -static void layout_text(fz_context *ctx, struct box *top, const char *text, struct computed_style *style, float em) -{ - while (*text) - { - if (iswhite(*text)) - { - ++text; - while (iswhite(*text)) - ++text; - add_flow_space(ctx, top, style, em); - } - if (*text) - { - const char *mark = text++; - while (*text && !iswhite(*text)) - ++text; - add_flow_word(ctx, top, style, em, mark, text); - } - } -} - -static void layout_inline(fz_context *ctx, struct box *box, struct box *top, float em) +static void layout_text(fz_context *ctx, struct flow *node, struct box *top, float em) { - struct box *child; - const char *s; - - em = from_number(box->style.font_size, em, em); - - box->x = top->x + top->w; - box->y = top->y; - box->h = em; - box->w = 0; - - s = fz_xml_text(box->node); - if (s) - { - layout_text(ctx, top, s, &box->style, em); - - box->w += strlen(s) * 0.5 * em; - } - - for (child = box->down; child; child = child->next) - { - layout_inline(ctx, child, top, em); - if (child->h > box->h) - box->h = child->h; - top->w += child->w; - } + em = from_number(node->style->font_size, em, em); + node->x = top->x + top->w; + node->y = top->y; + node->h = em; + node->w = strlen(node->text) * 0.5 * em; } static void layout_flow(fz_context *ctx, struct box *box, struct box *top, float em) { - struct box *child; + struct flow *node; em = from_number(box->style.font_size, em, em); @@ -304,12 +290,12 @@ static void layout_flow(fz_context *ctx, struct box *box, struct box *top, float box->h = 0; box->w = 0; - for (child = box->down; child; child = child->next) + for (node = box->flow_head; node; node = node->next) { - layout_inline(ctx, child, box, em); - if (child->h > box->h) - box->h = child->h; - box->w += child->w; + layout_text(ctx, node, box, em); + if (node->h > box->h) + box->h = node->h; + box->w += node->w; } } @@ -335,10 +321,7 @@ static void layout_block(fz_context *ctx, struct box *box, struct box *top, floa if (child->type == BOX_BLOCK) layout_block(ctx, child, box, em); else if (child->type == BOX_FLOW) - { layout_flow(ctx, child, box, em); - // TOOD: remove flow box if no flow content - } box->h += child->h; } @@ -354,7 +337,7 @@ static void print_flow(fz_context *ctx, struct flow *flow, int level) { while (flow) { - printf(" "); + printf("%-5d %-5d", (int)flow->x, (int)flow->y); indent(level); switch (flow->type) { @@ -482,14 +465,15 @@ html_layout_document(html_document *doc, float w, float h) style.up = NULL; style.count = 0; - root_box = new_box(doc->ctx, NULL); - generate_boxes(doc->ctx, doc->xml, root_box, css, &style); + root_box = new_box(doc->ctx, NULL); win_box = new_box(doc->ctx, NULL); win_box->w = w; win_box->h = 0; + generate_boxes(doc->ctx, doc->xml, root_box, css, &style); + layout_block(doc->ctx, root_box, win_box, 12); print_box(doc->ctx, root_box, 0); |