From f501211e904d2c01e47b03e774ffc6f93faeae25 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 22 Jan 2016 12:00:55 +0100 Subject: epub: Implement @font-face rules. Note: font->fallback is not reference counted here. The fallback mechanism is probably going to have to change when we add text shaping. --- source/html/html-font.c | 71 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 10 deletions(-) (limited to 'source/html/html-font.c') diff --git a/source/html/html-font.c b/source/html/html-font.c index 4b138162..d595b582 100644 --- a/source/html/html-font.c +++ b/source/html/html-font.c @@ -11,7 +11,7 @@ static const char *font_names[16] = "Courier", "Courier-Oblique", "Courier-Bold", "Courier-BoldOblique", }; -fz_font * +static fz_font * fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set) { if (!set->fallback) @@ -29,30 +29,67 @@ fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set) } 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) +fz_load_html_builtin_font(fz_context *ctx, fz_html_font_set *set, const char *family, int is_bold, int is_italic) { - unsigned char *data; - unsigned int size; - int is_mono = !strcmp(family, "monospace"); int is_sans = !strcmp(family, "sans-serif"); - int is_bold = !strcmp(weight, "bold") || !strcmp(weight, "bolder") || atoi(weight) > 400; - int is_italic = !strcmp(style, "italic") || !strcmp(style, "oblique"); - int idx = is_mono * 8 + is_sans * 4 + is_bold * 2 + is_italic; if (!set->fonts[idx]) { + unsigned char *data; + unsigned int size; + data = pdf_lookup_builtin_font(ctx, font_names[idx], &size); 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_font(fz_context *ctx, fz_html_font_set *set, const char *family, int is_bold, int is_italic) +{ + fz_html_font_face *custom; + + for (custom = set->custom; custom; custom = custom->next) + { + if (!strcmp(family, custom->family) && + is_bold == custom->is_bold && + is_italic == custom->is_italic) + { + return custom->font; + } + } + + if (!strcmp(family, "monospace") || + !strcmp(family, "sans-serif") || + !strcmp(family, "serif")) + return fz_load_html_builtin_font(ctx, set, family, is_bold, is_italic); + + return NULL; +} + +void +fz_add_html_font_face(fz_context *ctx, fz_html_font_set *set, + const char *family, int is_bold, int is_italic, const char *src, + fz_font *font) +{ + fz_html_font_face *custom; + + custom = fz_malloc_struct(ctx, fz_html_font_face); + custom->font = fz_keep_font(ctx, font); + custom->src = fz_strdup(ctx, src); + custom->family = fz_strdup(ctx, family); + custom->is_bold = is_bold; + custom->is_italic = is_italic; + custom->next = set->custom; + set->custom = custom; + + font->fallback = fz_load_html_builtin_font(ctx, set, family, is_bold, is_italic); +} + fz_html_font_set *fz_new_html_font_set(fz_context *ctx) { return fz_malloc_struct(ctx, fz_html_font_set); @@ -60,9 +97,23 @@ fz_html_font_set *fz_new_html_font_set(fz_context *ctx) void fz_drop_html_font_set(fz_context *ctx, fz_html_font_set *set) { + fz_html_font_face *font, *next; int i; + + font = set->custom; + while (font) + { + next = font->next; + fz_drop_font(ctx, font->font); + fz_free(ctx, font->src); + fz_free(ctx, font->family); + fz_free(ctx, font); + font = next; + } + for (i = 0; i < nelem(set->fonts); ++i) fz_drop_font(ctx, set->fonts[i]); fz_drop_font(ctx, set->fallback); + fz_free(ctx, set); } -- cgit v1.2.3