From 6c8348a598cd79874007e233b6f0f409185093b1 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Tue, 1 Sep 2015 15:47:40 +0200 Subject: [PATCH] directwrite, coretext: implement substitutions This adds simple and sensible substitutions for generic font family names. A helper function is introduced to reduce code duplication. --- libass/ass_coretext.c | 14 ++++++++++++++ libass/ass_directwrite.c | 14 ++++++++++++++ libass/ass_fontselect.h | 31 +++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c index 3553324..877018d 100644 --- a/libass/ass_coretext.c +++ b/libass/ass_coretext.c @@ -25,6 +25,12 @@ #define SAFE_CFRelease(x) do { if (x) CFRelease(x); } while(0) +static const ASS_FontMapping font_substitutions[] = { + {"sans-serif", "Helvetica"}, + {"serif", "Times"}, + {"monospace", "Courier"} +}; + static char *cfstr2buf(CFStringRef string) { const int encoding = kCFStringEncodingUTF8; @@ -266,10 +272,18 @@ static char *get_fallback(void *priv, const char *family, uint32_t codepoint) return res_family; } +static void get_substitutions(void *priv, const char *name, + ASS_FontProviderMetaData *meta) +{ + const int n = sizeof(font_substitutions) / sizeof(font_substitutions[0]); + ass_map_font(font_substitutions, n, name, meta); +} + static ASS_FontProviderFuncs coretext_callbacks = { .check_glyph = check_glyph, .destroy_font = destroy_font, .match_fonts = match_fonts, + .get_substitutions = get_substitutions, .get_fallback = get_fallback, }; diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c index 86b0b4b..f11deb6 100644 --- a/libass/ass_directwrite.c +++ b/libass/ass_directwrite.c @@ -31,6 +31,12 @@ #define NAME_MAX_LENGTH 256 #define FALLBACK_DEFAULT_FONT L"Arial" +static const ASS_FontMapping font_substitutions[] = { + {"sans-serif", "Arial"}, + {"serif", "Times New Roman"}, + {"monospace", "Courier New"} +}; + /* * The private data stored for every font, detected by this backend. */ @@ -624,6 +630,13 @@ static void scan_fonts(IDWriteFactory *factory, } } +static void get_substitutions(void *priv, const char *name, + ASS_FontProviderMetaData *meta) +{ + const int n = sizeof(font_substitutions) / sizeof(font_substitutions[0]); + ass_map_font(font_substitutions, n, name, meta); +} + /* * Called by libass when the provider should perform the * specified task @@ -633,6 +646,7 @@ static ASS_FontProviderFuncs directwrite_callbacks = { .check_glyph = check_glyph, .destroy_font = destroy_font, .destroy_provider = destroy_provider, + .get_substitutions = get_substitutions, .get_fallback = get_fallback, }; diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h index c989e1a..1e0959e 100644 --- a/libass/ass_fontselect.h +++ b/libass/ass_fontselect.h @@ -177,6 +177,37 @@ struct ass_font_stream { void *priv; }; + +typedef struct ass_font_mapping ASS_FontMapping; + +struct ass_font_mapping { + const char *from; + const char *to; +}; + +/** + * Simple font substitution helper. This can be used to implement basic + * mappings from one name to another. This is useful for supporting + * generic font families in font providers. + * + * \param map list of mappings + * \param len length of list of mappings + * \param name font name to map from + * \param meta metadata struct, mapped fonts will be stored into this + */ +inline void ass_map_font(const ASS_FontMapping *map, int len, const char *name, + ASS_FontProviderMetaData *meta) +{ + for (int i = 0; i < len; i++) { + if (strcasecmp(map[i].from, name) == 0) { + meta->n_fullname = 1; + meta->fullnames = calloc(1, sizeof(char *)); + meta->fullnames[0] = strdup(map[i].to); + return; + } + } +} + ASS_FontSelector * ass_fontselect_init(ASS_Library *library, FT_Library ftlibrary, const char *family, -- 2.40.0