[gs-commits] mupdf 1.16.1.69 Optimise CSS style usage in HTML.
[email protected] (Robin Watts) Thu, 3 Oct 2019 15:19:02 +0000 (UTC)
| Newsgroups | gmane.comp.printing.ghostscript.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 9ec9f4ddda06790a773a9b7903157b955723ec2f Author: Robin Watts <[email protected]> Date: Tue Oct 1 10:29:07 2019 +0100 Optimise CSS style usage in HTML. diff --git a/source/html/css-apply.c b/source/html/css-apply.c index 7ff6e58..e54bd67 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -4,6 +4,7 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <assert.h> static const char *inherit_list[] = { "color", @@ -1335,6 +1336,192 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, } } +#ifdef DEBUG_CSS_SPLAY +static void +do_verify_splay(const fz_css_style_splay *x) +{ + printf("%x<", x); + if (x->lt) + { + assert(memcmp(&x->lt->style, &x->style, sizeof(x->style)) < 0); + assert(x->lt->up == x); + do_verify_splay(x->lt); + } + printf(","); + if (x->gt) + { + assert(memcmp(&x->gt->style, &x->style, sizeof(x->style)) > 0); + assert(x->gt->up == x); + do_verify_splay(x->gt); + } + printf(">\n"); +} + +static void +verify_splay(const fz_css_style_splay *x) +{ + if (x == NULL) + return; + assert(x->up == NULL); + do_verify_splay(x); + printf("-----\n"); +} +#endif + +/* Lookup style in the splay tree, returning a pointer to the found instance + * if there is one, creating and inserting (and moving to root) one if there + * is not. */ +const fz_css_style * +fz_css_enlist(fz_context *ctx, const fz_css_style *style, fz_css_style_splay **tree, fz_pool *pool) +{ + fz_css_style_splay **current = tree; + fz_css_style_splay *x; + fz_css_style_splay *y = NULL; + + /* Search for a match in the tree, if there is one, or for + * the insertion point, if there is not. */ + while (*current != NULL) + { + int cmp = memcmp(style, &(*current)->style, sizeof(*style)); + if (cmp == 0) + { + /* We have a match - break out and do move to root. */ + break; + } + y = (*current); + if (cmp < 0) + current = &y->lt; + else + current = &y->gt; + } + /* Create one if needed */ + if (*current == NULL) + { + x = *current = fz_pool_alloc(ctx, pool, sizeof(*y)); + x->style = *style; + x->up = y; + x->lt = NULL; + x->gt = NULL; + } + else + x = *current; + /* Now move to root */ + /* + The splaying steps used: + + Case 1: |a) z x b) z x + | y D => A y A y y D + | x C B z B x => z C + | A B C D C D A B + + Case 2: |a) z x b) z x + | y D => y z A y => z y + | A x A B C D x D A B C D + | B C B C + + Case 3: |a) y x b) y x + | x C => A y A x => y C + | A B B C B C A B + */ +#ifdef DEBUG_CSS_SPLAY + printf("BEFORE\n"); + verify_splay(*tree); +#endif + while ((y = x->up) != NULL ) /* While we're not at the root */ + { + fz_css_style_splay *z = y->up; + y->up = x; + if (z == NULL) + { + if (y->lt == x) /* Case 3a */ + { + y->lt = x->gt; + if (y->lt) + y->lt->up = y; + x->gt = y; + } + else /* Case 3b */ + { + y->gt = x->lt; + if (y->gt) + y->gt->up = y; + x->lt = y; + } + x->up = NULL; + break; + } + x->up = z->up; + if (z->up) + { + if (z->up->lt == z) + z->up->lt = x; + else + z->up->gt = x; + } + if (z->lt == y) + { + if (y->lt == x) /* Case 1a */ + { + z->lt = y->gt; + if (z->lt) + z->lt->up = z; + y->lt = x->gt; + if (y->lt) + y->lt->up = y; + y->gt = z; + z->up = y; + x->gt = y; + } + else /* Case 2a */ + { + y->gt = x->lt; + if (y->gt) + y->gt->up = y; + z->lt = x->gt; + if (z->lt) + z->lt->up = z; + x->lt = y; + x->gt = z; + z->up = x; + } + } + else + { + if (y->gt == x) /* Case 1b */ + { + z->gt = y->lt; + if (z->gt) + z->gt->up = z; + y->gt = x->lt; + if (y->gt) + y->gt->up = y; + y->lt = z; + z->up = y; + x->lt = y; + } + else /* Case 2b */ + { + z->gt = x->lt; + if (z->gt) + z->gt->up = z; + y->lt = x->gt; + if (y->lt) + y->lt->up = y; + x->gt = y; + x->lt = z; + z->up = x; + } + } + } + + *tree = x; +#ifdef DEBUG_CSS_SPLAY + printf("AFTER\n"); + verify_splay(x); +#endif + + return &x->style; +} /* * Pretty printing */ diff --git a/source/html/html-imp.h b/source/html/html-imp.h index bd2f60f..08e2fd0 100644 --- a/source/html/html-imp.h +++ b/source/html/html-imp.h @@ -6,6 +6,7 @@ typedef struct fz_html_font_set_s fz_html_font_set; typedef struct fz_html_s fz_html; typedef struct fz_html_box_s fz_html_box; typedef struct fz_html_flow_s fz_html_flow; +typedef struct fz_css_style_splay_s fz_css_style_splay; typedef struct fz_css_s fz_css; typedef struct fz_css_rule_s fz_css_rule; @@ -181,6 +182,13 @@ struct fz_css_style_s fz_font *font; }; +struct fz_css_style_splay_s { + fz_css_style style; + fz_css_style_splay *lt; + fz_css_style_splay *gt; + fz_css_style_splay *up; +}; + enum { BOX_BLOCK, /* block-level: contains block, break, flow, and table boxes */ @@ -217,7 +225,7 @@ struct fz_html_box_s fz_html_box *up, *down, *next; fz_html_flow *flow_head, **flow_tail; char *id, *href; - fz_css_style style; + const fz_css_style *style; /* Only BOX_{BLOCK,TABLE,TABLE_ROW,TABLE_CELL} actually use the following */ float padding[4]; float margin[4]; @@ -282,6 +290,7 @@ void fz_match_css_at_page(fz_context *ctx, fz_css_match *match, fz_css *css); int fz_get_css_match_display(fz_css_match *node); void fz_default_css_style(fz_context *ctx, fz_css_style *style); void fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, fz_css_match *match); +const fz_css_style *fz_css_enlist(fz_context *ctx, const fz_css_style *style, fz_css_style_splay **tree, fz_pool *pool); float fz_from_css_number(fz_css_number number, float em, float percent_value, float auto_value); float fz_from_css_number_scale(fz_css_number number, float scale); diff --git a/source/html/html-layout.c b/source/html/html-layout.c index a74cdc6..b65ecbd 100644 --- a/source/html/html-layout.c +++ b/source/html/html-layout.c @@ -244,10 +244,10 @@ static void measure_string(fz_context *ctx, fz_html_flow *node, hb_buffer_t *hb_ node->x = 0; node->y = 0; node->w = 0; - node->h = fz_from_css_number_scale(node->box->style.line_height, em); + node->h = fz_from_css_number_scale(node->box->style->line_height, em); s = get_node_text(ctx, node); - init_string_walker(ctx, &walker, hb_buf, node->bidi_level & 1, node->box->style.font, node->script, node->markup_lang, node->box->style.small_caps, s); + init_string_walker(ctx, &walker, hb_buf, node->bidi_level & 1, node->box->style->font, node->script, node->markup_lang, node->box->style->small_caps, s); while (walk_string(&walker)) { int x = 0; @@ -382,7 +382,7 @@ static void layout_line(fz_context *ctx, float indent, float page_w, float line_ node->x = x; x += w; - switch (node->box->style.vertical_align) + switch (node->box->style->vertical_align) { default: case VA_BASELINE: @@ -450,7 +450,7 @@ static void layout_flow_inline(fz_context *ctx, fz_html_box *box, fz_html_box *t while (box) { box->y = top->y; - box->em = fz_from_css_number(box->style.font_size, top->em, top->em, top->em); + box->em = fz_from_css_number(box->style->font_size, top->em, top->em, top->em); if (box->down) layout_flow_inline(ctx, box->down, box); box = box->next; @@ -463,9 +463,9 @@ static void layout_flow(fz_context *ctx, fz_html_box *box, fz_html_box *top, flo float line_w, candidate_w, indent, break_w, nonbreak_w; int line_align, align; - float em = box->em = fz_from_css_number(box->style.font_size, top->em, top->em, top->em); - indent = box->is_first_flow ? fz_from_css_number(top->style.text_indent, em, top->w, 0) : 0; - align = top->style.text_align; + float em = box->em = fz_from_css_number(box->style->font_size, top->em, top->em, top->em); + indent = box->is_first_flow ? fz_from_css_number(top->style->text_indent, em, top->w, 0) : 0; + align = top->style->text_align; if (box->markup_dir == FZ_BIDI_RTL) { @@ -503,8 +503,8 @@ static void layout_flow(fz_context *ctx, fz_html_box *box, fz_html_box *top, flo node->w = node->content.image->w * 72 / 96; node->h = node->content.image->h * 72 / 96; - node->w = fz_from_css_number(node->box->style.width, top->em, top->w - margin_w, node->w); - node->h = fz_from_css_number(node->box->style.height, top->em, page_h - margin_h, node->h); + node->w = fz_from_css_number(node->box->style->width, top->em, top->w - margin_w, node->w); + node->h = fz_from_css_number(node->box->style->height, top->em, page_h - margin_h, node->h); /* Shrink image to fit on one page if needed */ if (max_w > 0 && node->w > max_w) @@ -627,9 +627,9 @@ static void layout_table(fz_context *ctx, fz_html_box *box, fz_html_box *top, fl fz_html_box *row, *cell, *child; int col, ncol = 0; - box->em = fz_from_css_number(box->style.font_size, top->em, top->em, top->em); + box->em = fz_from_css_number(box->style->font_size, top->em, top->em, top->em); box->x = top->x; - box->w = fz_from_css_number(box->style.width, box->em, top->w, top->w); + box->w = fz_from_css_number(box->style->width, box->em, top->w, top->w); box->y = box->b = top->b; for (row = box->down; row; row = row->next) @@ -645,7 +645,7 @@ static void layout_table(fz_context *ctx, fz_html_box *box, fz_html_box *top, fl { col = 0; - row->em = fz_from_css_number(row->style.font_size, box->em, box->em, box->em); + row->em = fz_from_css_number(row->style->font_size, box->em, box->em, box->em); row->x = box->x; row->w = box->w; row->y = row->b = box->b; @@ -654,7 +654,7 @@ static void layout_table(fz_context *ctx, fz_html_box *box, fz_html_box *top, fl { float colw = row->w / ncol; // TODO: proper calculation - cell->em = fz_from_css_number(cell->style.font_size, row->em, row->em, row->em); + cell->em = fz_from_css_number(cell->style->font_size, row->em, row->em, row->em); cell->y = cell->b = row->y; cell->x = row->x + col * colw; cell->w = colw; @@ -685,7 +685,7 @@ static float layout_block(fz_context *ctx, fz_html_box *box, float em, float top float auto_width; int first; - fz_css_style *style = &box->style; + const fz_css_style *style = box->style; float *margin = box->margin; float *border = box->border; float *padding = box->padding; @@ -811,10 +811,10 @@ fz_layout_html(fz_context *ctx, fz_html *html, float w, float h, float em) fz_var(hb_buf); fz_var(unlocked); - html->page_margin[T] = fz_from_css_number(html->root->style.margin[T], em, em, 0); - html->page_margin[B] = fz_from_css_number(html->root->style.margin[B], em, em, 0); - html->page_margin[L] = fz_from_css_number(html->root->style.margin[L], em, em, 0); - html->page_margin[R] = fz_from_css_number(html->root->style.margin[R], em, em, 0); + html->page_margin[T] = fz_from_css_number(html->root->style->margin[T], em, em, 0); + html->page_margin[B] = fz_from_css_number(html->root->style->margin[B], em, em, 0); + html->page_margin[L] = fz_from_css_number(html->root->style->margin[L], em, em, 0); + html->page_margin[R] = fz_from_css_number(html->root->style->margin[R], em, em, 0); html->page_w = w - html->page_margin[L] - html->page_margin[R]; if (html->page_w <= 72) @@ -889,7 +889,7 @@ static void draw_flow_box(fz_context *ctx, fz_html_box *box, float page_top, flo for (node = box->flow_head; node; node = node->next) { - fz_css_style *style = &node->box->style; + const fz_css_style *style = node->box->style; if (node->type == FLOW_IMAGE) { @@ -1169,7 +1169,7 @@ static void draw_list_mark(fz_context *ctx, fz_html_box *box, float page_top, fl } else { - float h = fz_from_css_number_scale(box->style.line_height, box->em); + float h = fz_from_css_number_scale(box->style->line_height, box->em); float a = box->em * 0.8f; float d = box->em * 0.2f; if (a + d > h) @@ -1180,14 +1180,14 @@ static void draw_list_mark(fz_context *ctx, fz_html_box *box, float page_top, fl if (y > page_bot || y < page_top) return; - format_list_number(ctx, box->style.list_style_type, n, buf, sizeof buf); + format_list_number(ctx, box->style->list_style_type, n, buf, sizeof buf); s = buf; w = 0; while (*s) { s += fz_chartorune(&c, s); - g = fz_encode_character_with_fallback(ctx, box->style.font, c, UCDN_SCRIPT_LATIN, FZ_LANG_UNSET, &font); + g = fz_encode_character_with_fallback(ctx, box->style->font, c, UCDN_SCRIPT_LATIN, FZ_LANG_UNSET, &font); w += fz_advance_glyph(ctx, font, g, 0) * box->em; } @@ -1201,14 +1201,14 @@ static void draw_list_mark(fz_context *ctx, fz_html_box *box, float page_top, fl while (*s) { s += fz_chartorune(&c, s); - g = fz_encode_character_with_fallback(ctx, box->style.font, c, UCDN_SCRIPT_LATIN, FZ_LANG_UNSET, &font); + g = fz_encode_character_with_fallback(ctx, box->style->font, c, UCDN_SCRIPT_LATIN, FZ_LANG_UNSET, &font); fz_show_glyph(ctx, text, font, trm, g, c, 0, 0, FZ_BIDI_NEUTRAL, FZ_LANG_UNSET); trm.e += fz_advance_glyph(ctx, font, g, 0) * box->em; } - color[0] = box->style.color.r / 255.0f; - color[1] = box->style.color.g / 255.0f; - color[2] = box->style.color.b / 255.0f; + color[0] = box->style->color.r / 255.0f; + color[1] = box->style->color.g / 255.0f; + color[2] = box->style->color.b / 255.0f; fz_fill_text(ctx, dev, text, ctm, fz_device_rgb(ctx), color, 1, fz_default_color_params); } @@ -1234,18 +1234,18 @@ static void draw_block_box(fz_context *ctx, fz_html_box *box, float page_top, fl if (y0 > page_bot || y1 < page_top) return; - if (box->style.visibility == V_VISIBLE) + if (box->style->visibility == V_VISIBLE) { - draw_rect(ctx, dev, ctm, page_top, box->style.background_color, x0, y0, x1, y1); + draw_rect(ctx, dev, ctm, page_top, box->style->background_color, x0, y0, x1, y1); if (border[T] > 0) - draw_rect(ctx, dev, ctm, page_top, box->style.border_color[T], x0 - border[L], y0 - border[T], x1 + border[R], y0); + draw_rect(ctx, dev, ctm, page_top, box->style->border_color[T], x0 - border[L], y0 - border[T], x1 + border[R], y0); if (border[B] > 0) - draw_rect(ctx, dev, ctm, page_top, box->style.border_color[B], x0 - border[L], y1, x1 + border[R], y1 + border[B]); + draw_rect(ctx, dev, ctm, page_top, box->style->border_color[B], x0 - border[L], y1, x1 + border[R], y1 + border[B]); if (border[L] > 0) - draw_rect(ctx, dev, ctm, page_top, box->style.border_color[L], x0 - border[L], y0 - border[T], x0, y1 + border[B]); + draw_rect(ctx, dev, ctm, page_top, box->style->border_color[L], x0 - border[L], y0 - border[T], x0, y1 + border[B]); if (border[R] > 0) - draw_rect(ctx, dev, ctm, page_top, box->style.border_color[R], x1, y0 - border[T], x1 + border[R], y1 + border[B]); + draw_rect(ctx, dev, ctm, page_top, box->style->border_color[R], x1, y0 - border[T], x1 + border[R], y1 + border[B]); if (box->list_item) draw_list_mark(ctx, box, page_top, page_bot, dev, ctm, box->list_item); @@ -1276,7 +1276,7 @@ fz_draw_html(fz_context *ctx, fz_device *dev, fz_matrix ctm, fz_html *html, int fz_var(hb_buf); fz_var(unlocked); - draw_rect(ctx, dev, ctm, 0, html->root->style.background_color, + draw_rect(ctx, dev, ctm, 0, html->root->style->background_color, 0, 0, html->page_w + html->page_margin[L] + html->page_margin[R], html->page_h + html->page_margin[T] + html->page_margin[B]); diff --git a/source/html/html-parse.c b/source/html/html-parse.c index 686992e..5adbd85 100644 --- a/source/html/html-parse.c +++ b/source/html/html-parse.c @@ -109,6 +109,7 @@ struct genstate int at_bol; int emit_white; int last_brk_cls; + fz_css_style_splay *styles; }; static int iswhite(int c) @@ -226,7 +227,7 @@ static fz_html_flow *split_flow(fz_context *ctx, fz_pool *pool, fz_html_flow *fl static void flush_space(fz_context *ctx, fz_html_box *flow, fz_html_box *inline_box, int lang, struct genstate *g) { static const char *space = " "; - int bsp = inline_box->style.white_space & WS_ALLOW_BREAK_SPACE; + int bsp = inline_box->style->white_space & WS_ALLOW_BREAK_SPACE; fz_pool *pool = g->pool; if (g->emit_white) { @@ -281,9 +282,9 @@ static void generate_text(fz_context *ctx, fz_html_box *box, const char *text, i { fz_html_box *flow; fz_pool *pool = g->pool; - int collapse = box->style.white_space & WS_COLLAPSE; - int bsp = box->style.white_space & WS_ALLOW_BREAK_SPACE; - int bnl = box->style.white_space & WS_FORCE_BREAK_NEWLINE; + int collapse = box->style->white_space & WS_COLLAPSE; + int bsp = box->style->white_space & WS_ALLOW_BREAK_SPACE; + int bnl = box->style->white_space & WS_FORCE_BREAK_NEWLINE; static const char *space = " "; @@ -483,8 +484,7 @@ static void init_box(fz_context *ctx, fz_html_box *box, fz_bidi_direction markup box->flow_head = NULL; box->flow_tail = &box->flow_head; box->markup_dir = markup_dir; - - fz_default_css_style(ctx, &box->style); + box->style = NULL; } static void fz_drop_html_box(fz_context *ctx, fz_html_box *box) @@ -641,8 +641,11 @@ static void insert_inline_box(fz_context *ctx, fz_html_box *box, fz_html_box *to } else { + fz_css_style style; fz_html_box *flow = new_short_box(ctx, g->pool, markup_dir); flow->is_first_flow = !top->next; + fz_default_css_style(ctx, &style); + flow->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_box(ctx, flow, BOX_FLOW, top); insert_box(ctx, box, BOX_INLINE, flow); g->at_bol = 1; @@ -665,6 +668,7 @@ generate_boxes(fz_context *ctx, fz_html_box *box, *last_top; const char *tag; int display; + fz_css_style style; while (node) { @@ -690,7 +694,8 @@ generate_boxes(fz_context *ctx, else { box = new_short_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_apply_css_style(ctx, g->set, &style, &match); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); top = insert_break_box(ctx, box, top); } g->at_bol = 1; @@ -705,17 +710,18 @@ generate_boxes(fz_context *ctx, const char *w_att = fz_xml_att(node, "width"); const char *h_att = fz_xml_att(node, "height"); box = new_short_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_apply_css_style(ctx, g->set, &style, &match); if (w_att && (w = fz_atoi(w_att)) > 0) { - box->style.width.value = w; - box->style.width.unit = strchr(w_att, '%') ? N_PERCENT : N_LENGTH; + style.width.value = w; + style.width.unit = strchr(w_att, '%') ? N_PERCENT : N_LENGTH; } if (h_att && (h = fz_atoi(h_att)) > 0) { - box->style.height.value = h; - box->style.height.unit = strchr(h_att, '%') ? N_PERCENT : N_LENGTH; + style.height.value = h; + style.height.unit = strchr(h_att, '%') ? N_PERCENT : N_LENGTH; } + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_inline_box(ctx, box, top, markup_dir, g); generate_image(ctx, box, load_html_image(ctx, g->zip, g->base_uri, src), g); } @@ -724,7 +730,8 @@ generate_boxes(fz_context *ctx, else if (tag[0]=='s' && tag[1]=='v' && tag[2]=='g' && tag[3]==0) { box = new_short_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_apply_css_style(ctx, g->set, &style, &match); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_inline_box(ctx, box, top, markup_dir, g); generate_image(ctx, box, load_svg_image(ctx, g->zip, g->base_uri, node), g); } @@ -741,17 +748,21 @@ generate_boxes(fz_context *ctx, { fz_html_box *imgbox; box = new_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_default_css_style(ctx, &style); + fz_apply_css_style(ctx, g->set, &style, &match); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); top = insert_block_box(ctx, box, top); imgbox = new_short_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &imgbox->style, &match); + fz_apply_css_style(ctx, g->set, &style, &match); + imgbox->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_inline_box(ctx, imgbox, box, markup_dir, g); generate_image(ctx, imgbox, fz_keep_image(ctx, img), g); } else if (display == DIS_INLINE) { box = new_short_box(ctx, g->pool, markup_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_apply_css_style(ctx, g->set, &style, &match); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_inline_box(ctx, box, top, markup_dir, g); generate_image(ctx, box, fz_keep_image(ctx, img), g); } @@ -785,7 +796,9 @@ generate_boxes(fz_context *ctx, box = new_short_box(ctx, g->pool, child_dir); else box = new_box(ctx, g->pool, child_dir); - fz_apply_css_style(ctx, g->set, &box->style, &match); + fz_default_css_style(ctx, &style); + fz_apply_css_style(ctx, g->set, &style, &match); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); id = fz_xml_att(node, "id"); if (id) @@ -872,7 +885,7 @@ generate_boxes(fz_context *ctx, else { const char *text = fz_xml_text(node); - int collapse = top->style.white_space & WS_COLLAPSE; + int collapse = top->style->white_space & WS_COLLAPSE; if (collapse && is_all_white(text)) { g->emit_white = 1; @@ -882,12 +895,16 @@ generate_boxes(fz_context *ctx, if (top->type != BOX_INLINE) { /* Create anonymous inline box, with the same style as the top block box. */ + fz_css_style style; box = new_short_box(ctx, g->pool, markup_dir); + fz_default_css_style(ctx, &style); + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); insert_inline_box(ctx, box, top, markup_dir, g); - box->style = top->style; + style = *top->style; /* Make sure not to recursively multiply font sizes. */ - box->style.font_size.value = 1; - box->style.font_size.unit = N_SCALE; + style.font_size.value = 1; + style.font_size.unit = N_SCALE; + box->style = fz_css_enlist(ctx, &style, &g->styles, g->pool); generate_text(ctx, box, text, markup_lang, g); } else @@ -1253,6 +1270,7 @@ fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const cha g.at_bol = 0; g.emit_white = 0; g.last_brk_cls = UCDN_LINEBREAK_CLASS_OP; + g.styles = NULL; xml = fz_parse_xml(ctx, buf, 1); root = fz_xml_root(xml); @@ -1308,15 +1326,19 @@ fz_parse_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const cha fz_try(ctx) { + fz_css_style style; + g.pool = fz_new_pool(ctx); html = fz_pool_alloc(ctx, g.pool, sizeof *html); html->pool = g.pool; html->root = new_box(ctx, g.pool, DEFAULT_DIR); + fz_default_css_style(ctx, &style); match.up = NULL; match.count = 0; fz_match_css_at_page(ctx, &match, g.css); - fz_apply_css_style(ctx, g.set, &html->root->style, &match); + fz_apply_css_style(ctx, g.set, &style, &match); + html->root->style = fz_css_enlist(ctx, &style, &g.styles, g.pool); // TODO: transfer page margins out of this hacky box generate_boxes(ctx, root, html->root, &match, 0, 0, DEFAULT_DIR, FZ_LANG_UNSET, &g); @@ -1378,18 +1400,18 @@ fz_debug_html_flow(fz_context *ctx, fz_html_flow *flow, int level) } sbox = flow->box; indent(level); - printf("span em=%g font='%s'", sbox->em, fz_font_name(ctx, sbox->style.font)); - if (fz_font_is_serif(ctx, sbox->style.font)) + printf("span em=%g font='%s'", sbox->em, fz_font_name(ctx, sbox->style->font)); + if (fz_font_is_serif(ctx, sbox->style->font)) printf(" serif"); else printf(" sans"); - if (fz_font_is_monospaced(ctx, sbox->style.font)) + if (fz_font_is_monospaced(ctx, sbox->style->font)) printf(" monospaced"); - if (fz_font_is_bold(ctx, sbox->style.font)) + if (fz_font_is_bold(ctx, sbox->style->font)) printf(" bold"); - if (fz_font_is_italic(ctx, sbox->style.font)) + if (fz_font_is_italic(ctx, sbox->style->font)) printf(" italic"); - if (sbox->style.small_caps) + if (sbox->style->small_caps) printf(" small-caps"); printf("\n"); indent(level); http://git.ghostscript.com/?p=mupdf.git;a=commit;h=9ec9f4ddda06790a773a9b7903157b955723ec2f -- MuPDF library Artifex Software, Inc.