diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2014-11-25 23:50:27 +0100 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2014-12-03 12:25:52 +0100 |
commit | cf42f2f4d5e95b7254479e80614d1814e74e2387 (patch) | |
tree | 9d0452350d479c0222002c5969a4b0d8ce104925 /source/html/layout.c | |
parent | bb238db8919162c8976980b8aa48f70664f2f29d (diff) | |
download | mupdf-cf42f2f4d5e95b7254479e80614d1814e74e2387.tar.xz |
html: Split html parsing cache and state into html_context.
html_document is now a simple client of html_context.
Diffstat (limited to 'source/html/layout.c')
-rw-r--r-- | source/html/layout.c | 135 |
1 files changed, 84 insertions, 51 deletions
diff --git a/source/html/layout.c b/source/html/layout.c index 822e2937..f07108b5 100644 --- a/source/html/layout.c +++ b/source/html/layout.c @@ -100,33 +100,30 @@ static void generate_text(fz_context *ctx, struct box *box, const char *text) } } -static void generate_image(html_document *doc, struct box *box, const char *src) +static void generate_image(fz_context *ctx, html_context *htx, const char *base_uri, struct box *box, const char *src) { - fz_context *ctx = doc->ctx; fz_image *img; fz_buffer *buf; - char filename[2048]; + char path[2048]; struct box *flow = box; while (flow->type != BOX_FLOW) flow = flow->up; - fz_strlcpy(filename, doc->dirname, sizeof filename); - fz_strlcat(filename, src, sizeof filename); + fz_strlcpy(path, base_uri, sizeof path); + fz_strlcat(path, "/", sizeof path); + fz_strlcat(path, src, sizeof path); + fz_cleanname(path); - buf = fz_read_file(ctx, filename); + buf = fz_read_archive_entry(ctx, htx->zip, path); img = fz_new_image_from_buffer(ctx, buf); fz_drop_buffer(ctx, buf); add_flow_image(ctx, flow, &box->style, img); } -struct box *new_box(fz_context *ctx, fz_xml *node) +static void init_box(fz_context *ctx, struct box *box, fz_xml *node) { - struct box *box; - - box = fz_malloc_struct(ctx, struct box); - box->type = BOX_BLOCK; box->x = box->y = 0; box->w = box->h = 0; @@ -142,11 +139,16 @@ struct box *new_box(fz_context *ctx, fz_xml *node) box->flow_tail = &box->flow_head; default_computed_style(&box->style); +} +static struct box *new_box(fz_context *ctx, fz_xml *node) +{ + struct box *box = fz_malloc_struct(ctx, struct box); + init_box(ctx, box, node); return box; } -void insert_box(fz_context *ctx, struct box *box, int type, struct box *top) +static void insert_box(fz_context *ctx, struct box *box, int type, struct box *top) { box->type = type; @@ -234,9 +236,9 @@ static void insert_inline_box(fz_context *ctx, struct box *box, struct box *top) } } -static void generate_boxes(html_document *doc, fz_xml *node, struct box *top, struct rule *rule, struct style *up_style) +static void generate_boxes(fz_context *ctx, html_context *htx, const char *base_uri, + fz_xml *node, struct box *top, struct rule *rule, struct style *up_style) { - fz_context *ctx = doc->ctx; struct style style; struct box *box; const char *tag; @@ -257,7 +259,7 @@ static void generate_boxes(html_document *doc, fz_xml *node, struct box *top, st if (!strcmp(tag, "br")) { box = new_box(ctx, node); - compute_style(doc, &box->style, &style); + compute_style(ctx, htx, &box->style, &style); top = insert_break_box(ctx, box, top); } @@ -267,16 +269,16 @@ static void generate_boxes(html_document *doc, fz_xml *node, struct box *top, st if (src) { box = new_box(ctx, node); - compute_style(doc, &box->style, &style); + compute_style(ctx, htx, &box->style, &style); insert_inline_box(ctx, box, top); - generate_image(doc, box, src); + generate_image(ctx, htx, base_uri, box, src); } } else if (display != DIS_NONE) { box = new_box(ctx, node); - compute_style(doc, &box->style, &style); + compute_style(ctx, htx, &box->style, &style); if (display == DIS_BLOCK) { @@ -297,7 +299,7 @@ static void generate_boxes(html_document *doc, fz_xml *node, struct box *top, st } if (fz_xml_down(node)) - generate_boxes(doc, fz_xml_down(node), box, rule, &style); + generate_boxes(ctx, htx, base_uri, fz_xml_down(node), box, rule, &style); // TODO: remove empty flow boxes } @@ -804,7 +806,7 @@ draw_block_box(fz_context *ctx, struct box *box, float page_top, float page_bot, } void -html_run_box(fz_context *ctx, struct box *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *inctm) +html_draw(fz_context *ctx, html_context *htx, struct box *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *inctm) { fz_matrix ctm = *inctm; fz_pre_translate(&ctm, 0, -page_top); @@ -836,16 +838,15 @@ static char *concat_text(fz_context *ctx, fz_xml *root) return s; } -static struct rule *load_css(html_document *doc, struct rule *css, fz_xml *root) +static struct rule *html_load_css(fz_context *ctx, html_context *htx, const char *base_uri, struct rule *css, fz_xml *root) { - fz_context *ctx = doc->ctx; fz_xml *node; - char filename[2048]; + fz_buffer *buf; + char path[2048]; for (node = root; node; node = fz_xml_next(node)) { const char *tag = fz_xml_tag(node); -#if 1 if (tag && !strcmp(tag, "link")) { char *rel = fz_xml_att(node, "rel"); @@ -855,13 +856,21 @@ static struct rule *load_css(html_document *doc, struct rule *css, fz_xml *root) if ((type && !strcmp(type, "text/css")) || !type) { char *href = fz_xml_att(node, "href"); - fz_strlcpy(filename, doc->dirname, sizeof filename); - fz_strlcat(filename, href, sizeof filename); - css = fz_parse_css_file(ctx, css, filename); + if (href) + { + fz_strlcpy(path, base_uri, sizeof path); + fz_strlcat(path, "/", sizeof path); + fz_strlcat(path, href, sizeof path); + fz_cleanname(path); + + buf = fz_read_archive_entry(ctx, htx->zip, path); + fz_write_buffer_byte(ctx, buf, 0); + css = fz_parse_css(ctx, css, (char*)buf->data); + fz_drop_buffer(ctx, buf); + } } } } -#endif if (tag && !strcmp(tag, "style")) { char *s = concat_text(ctx, node); @@ -869,46 +878,70 @@ static struct rule *load_css(html_document *doc, struct rule *css, fz_xml *root) fz_free(ctx, s); } if (fz_xml_down(node)) - css = load_css(doc, css, fz_xml_down(node)); + css = html_load_css(ctx, htx, base_uri, css, fz_xml_down(node)); } return css; } void -html_layout_document(html_document *doc, float page_w, float page_h, float em) +html_layout(fz_context *ctx, html_context *htx, struct box *box, float w, float h, float em) +{ + struct box page_box; + + htx->page_w = w; + htx->page_h = h; + + printf("html: laying out text.\n"); + + init_box(ctx, &page_box, NULL); + page_box.w = w; + page_box.h = 0; + + layout_block(ctx, box, &page_box, em, 0, h); + + printf("html: finished.\n"); +} + +struct box * +html_generate(fz_context *ctx, html_context *htx, const char *base_uri, fz_buffer *buf) { - struct rule *css = NULL; - struct box *root_box; - struct box *page_box; + fz_xml *xml; + struct rule *css; + struct box *box; struct style style; - doc->page_w = page_w; - doc->page_h = page_h; + printf("html: parsing XHTML.\n"); + xml = fz_parse_xml(ctx, buf->data, buf->len, 1); -printf("html: parsing style sheets.\n"); - css = fz_parse_css(doc->ctx, NULL, default_css); - css = load_css(doc, css, doc->xml); + printf("html: parsing style sheets.\n"); + css = fz_parse_css(ctx, NULL, default_css); + css = html_load_css(ctx, htx, base_uri, css, xml); // print_rules(css); + printf("html: applying styles and generating boxes.\n"); + box = new_box(ctx, NULL); + style.up = NULL; style.count = 0; - root_box = new_box(doc->ctx, NULL); - - page_box = new_box(doc->ctx, NULL); - page_box->w = page_w; - page_box->h = 0; + generate_boxes(ctx, htx, base_uri, xml, box, css, &style); - // TODO: split generate and layout + return box; +} -printf("html: applying styles and generating boxes.\n"); - generate_boxes(doc, doc->xml, root_box, css, &style); -printf("html: laying out text.\n"); - layout_block(doc->ctx, root_box, page_box, em, 0, page_h); -printf("html: finished.\n"); +void html_init(fz_context *ctx, html_context *html, fz_archive *zip) +{ + memset(html, 0, sizeof *html); + html->zip = zip; +} - // print_box(doc->ctx, root_box, 0); +void html_rebind(html_context *html, fz_context *ctx) +{ + fz_rebind_archive(html->zip, ctx); +} - doc->box = root_box; +void html_fini(fz_context *ctx, html_context *html) +{ + fz_close_archive(ctx, html->zip); } |