From 000b8df004b175781af5b071590cf3867ae16f3a Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 21 Jan 2016 12:34:56 +0100 Subject: epub: Put font fallback chain in fz_font. fz_encode_character_with_fallback finds the first font in the fallback chain that has the glyph encoded, and if none do then try to encode a bullet character. --- source/fitz/font.c | 36 ++++++++++++++++-- source/html/css-apply.c | 1 - source/html/html-font.c | 35 ++++++++--------- source/html/html-layout.c | 97 ++++++++--------------------------------------- 4 files changed, 67 insertions(+), 102 deletions(-) (limited to 'source') diff --git a/source/fitz/font.c b/source/fitz/font.c index 0350674f..bdfee584 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -120,14 +120,14 @@ fz_drop_font(fz_context *ctx, fz_font *font) if (!fz_drop_imp(ctx, font, &font->refs)) return; - free_resources(ctx, font); + fz_drop_font(ctx, font->fallback); + if (font->t3lists) { + free_resources(ctx, font); for (i = 0; i < 256; i++) - { if (font->t3lists[i]) fz_drop_display_list(ctx, font->t3lists[i]); - } fz_free(ctx, font->t3procs); fz_free(ctx, font->t3lists); fz_free(ctx, font->t3widths); @@ -1366,3 +1366,33 @@ fz_encode_character(fz_context *ctx, fz_font *font, int ucs) } return ucs; } + +int +fz_encode_character_with_fallback(fz_context *ctx, fz_font *first_font, int ucs, fz_font **out_font) +{ + fz_font *font; + + for (font = first_font; font; font = font->fallback) + { + int gid = fz_encode_character(ctx, font, ucs); + if (gid > 0) + { + *out_font = font; + return gid; + } + } + + ucs = 0x25CF; /* bullet */ + for (font = first_font; font; font = font->fallback) + { + int gid = fz_encode_character(ctx, font, ucs); + if (gid > 0) + { + *out_font = font; + return gid; + } + } + + *out_font = first_font; + return 0; +} diff --git a/source/html/css-apply.c b/source/html/css-apply.c index f7884504..45fa7713 100644 --- a/source/html/css-apply.c +++ b/source/html/css-apply.c @@ -1161,7 +1161,6 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style, const char *font_style = string_from_property(match, "font-style", "normal"); const char *font_weight = string_from_property(match, "font-weight", "normal"); style->font = fz_load_html_font(ctx, set, font_family, font_variant, font_style, font_weight); - style->fallback = fz_load_html_fallback_font(ctx, set); } } diff --git a/source/html/html-font.c b/source/html/html-font.c index e9c17719..4b138162 100644 --- a/source/html/html-font.c +++ b/source/html/html-font.c @@ -11,6 +11,23 @@ static const char *font_names[16] = "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique", }; +fz_font * +fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set) +{ + if (!set->fallback) + { + unsigned char *data; + unsigned int size; + int index; + + data = pdf_lookup_substitute_cjk_font(ctx, FZ_ADOBE_GB_1, 0, 0, &size, &index); + if (!data) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load fallback font"); + set->fallback = fz_new_font_from_memory(ctx, "fallback", data, size, index, 0); + } + return set->fallback; +} + fz_font * fz_load_html_font(fz_context *ctx, fz_html_font_set *set, const char *family, const char *variant, const char *style, const char *weight) @@ -30,28 +47,12 @@ fz_load_html_font(fz_context *ctx, fz_html_font_set *set, if (!data) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load html font: %s", font_names[idx]); set->fonts[idx] = fz_new_font_from_memory(ctx, font_names[idx], data, size, 0, 1); + set->fonts[idx]->fallback = fz_load_html_fallback_font(ctx, set); } return set->fonts[idx]; } -fz_font * -fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set) -{ - if (!set->fallback) - { - unsigned char *data; - unsigned int size; - int index; - - data = pdf_lookup_substitute_cjk_font(ctx, FZ_ADOBE_GB_1, 0, 0, &size, &index); - if (!data) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load fallback font"); - set->fallback = fz_new_font_from_memory(ctx, "fallback", data, size, index, 0); - } - return set->fallback; -} - fz_html_font_set *fz_new_html_font_set(fz_context *ctx) { return fz_malloc_struct(ctx, fz_html_font_set); diff --git a/source/html/html-layout.c b/source/html/html-layout.c index 6366f5cc..36995c34 100644 --- a/source/html/html-layout.c +++ b/source/html/html-layout.c @@ -538,6 +538,7 @@ static void measure_image(fz_context *ctx, fz_html_flow *node, float max_w, floa static void measure_word(fz_context *ctx, fz_html_flow *node, float em) { + fz_font *font; const char *s; int c, g; float w; @@ -552,16 +553,8 @@ static void measure_word(fz_context *ctx, fz_html_flow *node, float em) while (*s) { s += fz_chartorune(&c, s); - g = fz_encode_character(ctx, node->style->font, c); - if (g) - { - w += fz_advance_glyph(ctx, node->style->font, g) * em; - } - else - { - g = fz_encode_character(ctx, node->style->fallback, c); - w += fz_advance_glyph(ctx, node->style->fallback, g) * em; - } + g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font); + w += fz_advance_glyph(ctx, font, g) * em; } node->w = w; node->em = em; @@ -906,6 +899,7 @@ static float layout_block(fz_context *ctx, fz_html *box, fz_html *top, float em, static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm) { + fz_font *font; fz_html_flow *node; fz_text *text; fz_matrix trm; @@ -949,27 +943,9 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p { t += fz_chartorune(&c, t); if (node->mirror) - { c = ucdn_mirror(c); - } - g = fz_encode_character(ctx, node->style->font, c); - if (g) - { - w += fz_advance_glyph(ctx, node->style->font, g) * node->em; - } - else - { - g = fz_encode_character(ctx, node->style->fallback, c); - if (g) - { - w += fz_advance_glyph(ctx, node->style->fallback, g) * node->em; - } - else - { - g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */ - w += fz_advance_glyph(ctx, node->style->font, g) * node->em; - } - } + g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font); + w += fz_advance_glyph(ctx, font, g) * node->em; } trm.e += w; @@ -977,33 +953,11 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p { s += fz_chartorune(&c, s); if (node->mirror) - { c = ucdn_mirror(c); - } - g = fz_encode_character(ctx, node->style->font, c); - if (g) - { - trm.e -= fz_advance_glyph(ctx, node->style->font, g) * node->em; - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->font, 0, &trm, g, c); - } - else - { - g = fz_encode_character(ctx, node->style->fallback, c); - if (g) - { - trm.e -= fz_advance_glyph(ctx, node->style->fallback, g) * node->em; - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->fallback, 0, &trm, g, c); - } - else - { - trm.e -= fz_advance_glyph(ctx, node->style->font, g) * node->em; - g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */ - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->font, 0, &trm, g, c); - } - } + g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font); + trm.e -= fz_advance_glyph(ctx, font, g) * node->em; + if (node->style->visibility == V_VISIBLE) + fz_add_text(ctx, text, font, 0, &trm, g, c); } trm.e += w; } @@ -1012,30 +966,10 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p while (*s) { s += fz_chartorune(&c, s); - g = fz_encode_character(ctx, node->style->font, c); - if (g) - { - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->font, 0, &trm, g, c); - trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em; - } - else - { - g = fz_encode_character(ctx, node->style->fallback, c); - if (g) - { - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->fallback, 0, &trm, g, c); - trm.e += fz_advance_glyph(ctx, node->style->fallback, g) * node->em; - } - else - { - g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */ - if (node->style->visibility == V_VISIBLE) - fz_add_text(ctx, text, node->style->font, 0, &trm, g, c); - trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em; - } - } + g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font); + if (node->style->visibility == V_VISIBLE) + fz_add_text(ctx, text, font, 0, &trm, g, c); + trm.e += fz_advance_glyph(ctx, font, g) * node->em; } } @@ -1181,6 +1115,7 @@ static fz_html_flow *find_list_mark_anchor(fz_context *ctx, fz_html *box) static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm, int n) { + fz_font *font; fz_text *text; fz_matrix trm; fz_html_flow *line; @@ -1219,7 +1154,7 @@ static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float while (*s) { s += fz_chartorune(&c, s); - g = fz_encode_character(ctx, box->style.font, c); + g = fz_encode_character_with_fallback(ctx, box->style.font, c, &font); w += fz_advance_glyph(ctx, box->style.font, g) * box->em; } -- cgit v1.2.3