diff options
-rw-r--r-- | include/mupdf/html.h | 16 | ||||
-rw-r--r-- | source/html/css-apply.c | 2 | ||||
-rw-r--r-- | source/html/css-parse.c | 74 | ||||
-rw-r--r-- | source/html/epub-doc.c | 17 | ||||
-rw-r--r-- | source/html/html-doc.c | 1 | ||||
-rw-r--r-- | source/html/html-layout.c | 29 |
6 files changed, 121 insertions, 18 deletions
diff --git a/include/mupdf/html.h b/include/mupdf/html.h index 0669966d..073145ed 100644 --- a/include/mupdf/html.h +++ b/include/mupdf/html.h @@ -43,7 +43,7 @@ struct fz_css_rule_s struct fz_css_selector_s { - const char *name; + char *name; int combine; fz_css_condition *cond; fz_css_selector *left; @@ -54,14 +54,14 @@ struct fz_css_selector_s struct fz_css_condition_s { int type; - const char *key; - const char *val; + char *key; + char *val; fz_css_condition *next; }; struct fz_css_property_s { - const char *name; + char *name; fz_css_value *value; int spec; fz_css_property *next; @@ -70,7 +70,7 @@ struct fz_css_property_s struct fz_css_value_s { int type; - const char *data; + char *data; fz_css_value *args; /* function arguments */ fz_css_value *next; }; @@ -80,8 +80,8 @@ struct fz_css_match_s fz_css_match *up; int count; struct { - const char *name; - fz_css_value *value; + const char *name; /* not owned */ + fz_css_value *value; /* not owned */ int spec; } prop[64]; }; @@ -164,6 +164,7 @@ struct fz_html_flow_s fz_css_rule *fz_parse_css(fz_context *ctx, fz_css_rule *old, const char *source); fz_css_property *fz_parse_css_properties(fz_context *ctx, const char *source); +void fz_free_css(fz_context *ctx, fz_css_rule *rule); void fz_match_css(fz_context *ctx, fz_css_match *match, fz_css_rule *rule, fz_xml *node); @@ -182,5 +183,6 @@ void fz_free_html_font_set(fz_context *ctx, fz_html_font_set *htx); fz_html_box *fz_generate_html(fz_context *ctx, fz_html_font_set *htx, fz_archive *zip, const char *base_uri, fz_buffer *buf); void fz_layout_html(fz_context *ctx, fz_html_box *box, float w, float h, float em); void fz_draw_html(fz_context *ctx, fz_html_box *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm); +void fz_free_html(fz_context *ctx, fz_html_box *box); #endif diff --git a/source/html/css-apply.c b/source/html/css-apply.c index eba9bbc0..81308c82 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -507,7 +507,7 @@ fz_match_css(fz_context *ctx, fz_css_match *match, fz_css_rule *rule, fz_xml *no add_property(match, prop->name, prop->value, INLINE_SPECIFICITY); prop = prop->next; } - // TODO: free props + // TODO: free props (hitch a ride with fz_css_rule?) } } diff --git a/source/html/css-parse.c b/source/html/css-parse.c index aaf0a623..0b12319f 100644 --- a/source/html/css-parse.c +++ b/source/html/css-parse.c @@ -62,6 +62,68 @@ static fz_css_value *fz_new_css_value(fz_context *ctx, int type, const char *dat return val; } +static void fz_free_css_value(fz_context *ctx, fz_css_value *val) +{ + while (val) + { + fz_css_value *next = val->next; + fz_free_css_value(ctx, val->args); + fz_free(ctx, val->data); + fz_free(ctx, val); + val = next; + } +} + +static void fz_free_css_condition(fz_context *ctx, fz_css_condition *cond) +{ + while (cond) + { + fz_css_condition *next = cond->next; + fz_free(ctx, cond->key); + fz_free(ctx, cond->val); + fz_free(ctx, cond); + cond = next; + } +} + +static void fz_free_css_selector(fz_context *ctx, fz_css_selector *sel) +{ + while (sel) + { + fz_css_selector *next = sel->next; + fz_free(ctx, sel->name); + fz_free_css_condition(ctx, sel->cond); + fz_free_css_selector(ctx, sel->left); + fz_free_css_selector(ctx, sel->right); + fz_free(ctx, sel); + sel = next; + } +} + +static void fz_free_css_property(fz_context *ctx, fz_css_property *prop) +{ + while (prop) + { + fz_css_property *next = prop->next; + fz_free(ctx, prop->name); + fz_free_css_value(ctx, prop->value); + fz_free(ctx, prop); + prop = next; + } +} + +void fz_free_css(fz_context *ctx, fz_css_rule *rule) +{ + while (rule) + { + fz_css_rule *next = rule->next; + fz_free_css_selector(ctx, rule->selector); + fz_free_css_property(ctx, rule->declaration); + fz_free(ctx, rule); + rule = next; + } +} + static void css_lex_next(struct lexbuf *buf) { // buf->s += fz_chartorune(&buf->c, buf->s); @@ -516,13 +578,13 @@ static fz_css_property *parse_declaration_list(struct lexbuf *buf) return head; } -static const char *parse_attrib_value(struct lexbuf *buf) +static char *parse_attrib_value(struct lexbuf *buf) { - const char *s; + char *s; if (buf->lookahead == CSS_KEYWORD || buf->lookahead == CSS_STRING) { - s = strdup(buf->string); + s = fz_strdup(buf->ctx, buf->string); next(buf); return s; } @@ -718,7 +780,7 @@ static void parse_media_list(struct lexbuf *buf) while (buf->lookahead != '}' && buf->lookahead != EOF) { r = parse_rule(buf); - // TODO: free_rule(r); + fz_free_css(buf->ctx, r); } } @@ -731,13 +793,13 @@ static void parse_at_rule(struct lexbuf *buf) if (accept(buf, '{')) /* @page */ { p = parse_declaration_list(buf); - // TODO: free_properties(p); + fz_free_css_property(buf->ctx, p); expect(buf, '}'); } else { v = parse_value_list(buf); - // TODO: free_value_list(v); + fz_free_css_value(buf->ctx, v); if (accept(buf, '{')) /* @media */ { parse_media_list(buf); diff --git a/source/html/epub-doc.c b/source/html/epub-doc.c index 3ad81d66..811e217e 100644 --- a/source/html/epub-doc.c +++ b/source/html/epub-doc.c @@ -95,10 +95,19 @@ epub_run_page(epub_document *doc, epub_page *page, fz_device *dev, const fz_matr static void epub_close_document(epub_document *doc) { - /* TODO:free all chapters */ - fz_close_archive(doc->ctx, doc->zip); - fz_free_html_font_set(doc->ctx, doc->set); - fz_free(doc->ctx, doc); + fz_context *ctx = doc->ctx; + epub_chapter *ch, *next; + ch = doc->spine; + while (ch) + { + next = ch->next; + fz_free_html(ctx, ch->box); + fz_free(ctx, ch); + ch = next; + } + fz_close_archive(ctx, doc->zip); + fz_free_html_font_set(ctx, doc->set); + fz_free(ctx, doc); } static const char * diff --git a/source/html/html-doc.c b/source/html/html-doc.c index 531e61c4..688a9f88 100644 --- a/source/html/html-doc.c +++ b/source/html/html-doc.c @@ -20,6 +20,7 @@ static void htdoc_close_document(html_document *doc) { fz_close_archive(doc->ctx, doc->zip); + fz_free_html(doc->ctx, doc->box); fz_free_html_font_set(doc->ctx, doc->set); fz_free(doc->ctx, doc); } diff --git a/source/html/html-layout.c b/source/html/html-layout.c index 412c4484..7e1662c3 100644 --- a/source/html/html-layout.c +++ b/source/html/html-layout.c @@ -39,6 +39,20 @@ static int iswhite(int c) return c == ' ' || c == '\t' || c == '\r' || c == '\n'; } +static void fz_free_html_flow(fz_context *ctx, fz_html_flow *flow) +{ + while (flow) + { + fz_html_flow *next = flow->next; + if (flow->type == FLOW_WORD) + fz_free(ctx, flow->text); + if (flow->type == FLOW_IMAGE) + fz_drop_image(ctx, flow->image); + fz_free(ctx, flow); + flow = next; + } +} + static fz_html_flow *add_flow(fz_context *ctx, fz_html_box *top, fz_css_style *style, int type) { fz_html_flow *flow = fz_malloc_struct(ctx, fz_html_flow); @@ -149,6 +163,18 @@ static void init_box(fz_context *ctx, fz_html_box *box) fz_default_css_style(ctx, &box->style); } +void fz_free_html(fz_context *ctx, fz_html_box *box) +{ + while (box) + { + fz_html_box *next = box->next; + fz_free_html_flow(ctx, box->flow_head); + fz_free_html(ctx, box->down); + fz_free(ctx, box); + box = next; + } +} + static fz_html_box *new_box(fz_context *ctx) { fz_html_box *box = fz_malloc_struct(ctx, fz_html_box); @@ -881,5 +907,8 @@ fz_generate_html(fz_context *ctx, fz_html_font_set *set, fz_archive *zip, const generate_boxes(ctx, set, zip, base_uri, xml, box, css, &match); + fz_free_css(ctx, css); + fz_free_xml(ctx, xml); + return box; } |