diff options
author | Simon Bünzli <zeniko@gmail.com> | 2013-12-20 00:21:53 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-01-13 17:22:03 +0000 |
commit | 056a8de560419eedaf097703893c798284ebb0a2 (patch) | |
tree | 8313aee783ea9aaa55baa8eaac147ff061a5191e | |
parent | 51d9a5673e367f03677d9ec684ec0e79fe445dd1 (diff) | |
download | mupdf-056a8de560419eedaf097703893c798284ebb0a2.tar.xz |
Bug 694851: enhance fz_load_system_font
For SumatraPDF, the following changes are required:
* fz_load_system_font is called from pdf_load_builtin_font as well so
that Arial, Courier New, etc. can be loaded from the system instead
of their Nimbus replacements. In order to distinguish between calls
from pdf_load_builtin_font and pdf_load_substitute_font, an
is_substitute argument is added.
* fz_load_system_cjk_font is added and called from
pdf_load_substitute_cjk_font so that a better replacement font can
be loaded instead of DroidSansFallback.
* Both fz_load_system_font and fz_load_system_cjk_font return fz_font*
instead of fz_buffer* so that implementers aren't required to load
fonts into memory (SumatraPDF uses fz_new_font_from_file for system
fonts).
In addition to that, fz_load_system_font_func is renamed to
fz_load_system_font_funcs since it now accepts two functions, and the
PDF_ROS_* constants are renamed to FZ_ADOBE_* (collection names aren't
passed as const char* so that implementers know which collections to
expect). For convenience, fz_load_*_font also never throws since
currently all callers have further fallbacks available.
-rw-r--r-- | include/mupdf/fitz/font.h | 12 | ||||
-rw-r--r-- | include/mupdf/pdf/font.h | 2 | ||||
-rw-r--r-- | source/fitz/font.c | 41 | ||||
-rw-r--r-- | source/pdf/pdf-font.c | 56 |
4 files changed, 75 insertions, 36 deletions
diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h index ffba996c..c5e72f05 100644 --- a/include/mupdf/fitz/font.h +++ b/include/mupdf/fitz/font.h @@ -61,13 +61,19 @@ struct fz_font_s int *width_table; /* in 1000 units */ }; +/* common CJK font collections */ +enum { FZ_ADOBE_CNS_1, FZ_ADOBE_GB_1, FZ_ADOBE_JAPAN_1, FZ_ADOBE_KOREA_1 }; + void fz_new_font_context(fz_context *ctx); fz_font_context *fz_keep_font_context(fz_context *ctx); void fz_drop_font_context(fz_context *ctx); -typedef fz_buffer *(*fz_load_system_font_func)(fz_context *ctx, const char *name); -void fz_install_load_system_font_func(fz_context *ctx, fz_load_system_font_func f); -fz_buffer *fz_load_system_font(fz_context *ctx, const char *name); +typedef fz_font *(*fz_load_system_font_func)(fz_context *ctx, const char *name, int is_substitute); +typedef fz_font *(*fz_load_system_cjk_font_func)(fz_context *ctx, const char *name, int ros, int serif); +void fz_install_load_system_font_funcs(fz_context *ctx, fz_load_system_font_func f, fz_load_system_cjk_font_func f_cjk); +/* fz_load_*_font returns NULL if no font could be loaded (also on error) */ +fz_font *fz_load_system_font(fz_context *ctx, const char *name, int is_substitute); +fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ros, int serif); fz_font *fz_new_type3_font(fz_context *ctx, const char *name, const fz_matrix *matrix); diff --git a/include/mupdf/pdf/font.h b/include/mupdf/pdf/font.h index 5b1cd8cd..73075a7c 100644 --- a/include/mupdf/pdf/font.h +++ b/include/mupdf/pdf/font.h @@ -18,8 +18,6 @@ enum PDF_FD_FORCE_BOLD = 1 << 18 }; -enum { PDF_ROS_CNS, PDF_ROS_GB, PDF_ROS_JAPAN, PDF_ROS_KOREA }; - void pdf_load_encoding(char **estrings, char *encoding); int pdf_lookup_agl(char *name); const char **pdf_lookup_agl_duplicates(int ucs); diff --git a/source/fitz/font.c b/source/fitz/font.c index b1ba1b02..6027164c 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -188,6 +188,7 @@ struct fz_font_context_s { FT_Library ftlib; int ftlib_refs; fz_load_system_font_func load_font; + fz_load_system_cjk_font_func load_cjk_font; }; #undef __FTERRORS_H__ @@ -233,16 +234,48 @@ void fz_drop_font_context(fz_context *ctx) fz_free(ctx, ctx->font); } -void fz_install_load_system_font_func(fz_context *ctx, fz_load_system_font_func f) +void fz_install_load_system_font_funcs(fz_context *ctx, fz_load_system_font_func f, fz_load_system_cjk_font_func f_cjk) { ctx->font->load_font = f; + ctx->font->load_cjk_font = f_cjk; } -fz_buffer *fz_load_system_font(fz_context *ctx, const char *name) +fz_font *fz_load_system_font(fz_context *ctx, const char *name, int is_substitute) { + fz_font *font = NULL; + if (ctx->font->load_font) - return ctx->font->load_font(ctx, name); - return NULL; + { + fz_try(ctx) + { + font = ctx->font->load_font(ctx, name, is_substitute); + } + fz_catch(ctx) + { + font = NULL; + } + } + + return font; +} + +fz_font *fz_load_system_cjk_font(fz_context *ctx, const char *name, int ros, int serif) +{ + fz_font *font = NULL; + + if (ctx->font->load_cjk_font) + { + fz_try(ctx) + { + font = ctx->font->load_cjk_font(ctx, name, ros, serif); + } + fz_catch(ctx) + { + font = NULL; + } + } + + return font; } static const struct ft_error ft_errors[] = diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c index efb1eee6..11b009b3 100644 --- a/source/pdf/pdf-font.c +++ b/source/pdf/pdf-font.c @@ -175,17 +175,22 @@ static int lookup_mre_code(char *name) static void pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname) { - unsigned char *data; - unsigned int len; FT_Face face; - fontname = clean_font_name(fontname); + fontdesc->font = fz_load_system_font(ctx, fontname, 0); + if (!fontdesc->font) + { + unsigned char *data; + unsigned int len; + + fontname = clean_font_name(fontname); - data = pdf_lookup_builtin_font(fontname, &len); - if (!data) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname); + data = pdf_lookup_builtin_font(fontname, &len); + if (!data) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname); - fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); + fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1); + } if (!strcmp(fontname, "Symbol") || !strcmp(fontname, "ZapfDingbats")) fontdesc->flags |= PDF_FD_SYMBOLIC; @@ -198,15 +203,8 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname) static void pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, int mono, int serif, int bold, int italic) { - fz_buffer *buffer; - - buffer = fz_load_system_font(ctx, fontname); - if (buffer) - { - fontdesc->font = fz_new_font_from_buffer(ctx, fontname, buffer, 0, 1); - fz_drop_buffer(ctx, buffer); - } - else + fontdesc->font = fz_load_system_font(ctx, fontname, 1); + if (!fontdesc->font) { unsigned char *data; unsigned int len; @@ -226,15 +224,19 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontnam static void pdf_load_substitute_cjk_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, int ros, int serif) { - unsigned char *data; - unsigned int len; + fontdesc->font = fz_load_system_cjk_font(ctx, fontname, ros, serif); + if (!fontdesc->font) + { + unsigned char *data; + unsigned int len; - data = pdf_lookup_substitute_cjk_font(ros, serif, &len); - if (!data) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font"); + data = pdf_lookup_substitute_cjk_font(ros, serif, &len); + if (!data) + fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin CJK font"); - /* a glyph bbox cache is too big for droid sans fallback (51k glyphs!) */ - fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 0); + /* a glyph bbox cache is too big for droid sans fallback (51k glyphs!) */ + fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 0); + } fontdesc->font->ft_substitute = 1; } @@ -266,13 +268,13 @@ pdf_load_system_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname, c if (collection) { if (!strcmp(collection, "Adobe-CNS1")) - pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, PDF_ROS_CNS, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_CNS_1, serif); else if (!strcmp(collection, "Adobe-GB1")) - pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, PDF_ROS_GB, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_GB_1, serif); else if (!strcmp(collection, "Adobe-Japan1")) - pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, PDF_ROS_JAPAN, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_JAPAN_1, serif); else if (!strcmp(collection, "Adobe-Korea1")) - pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, PDF_ROS_KOREA, serif); + pdf_load_substitute_cjk_font(ctx, fontdesc, fontname, FZ_ADOBE_KOREA_1, serif); else { if (strcmp(collection, "Adobe-Identity") != 0) |