diff options
-rw-r--r-- | libass/ass_coretext.c | 15 | ||||
-rw-r--r-- | libass/ass_directwrite.c | 20 | ||||
-rw-r--r-- | libass/ass_fontconfig.c | 8 | ||||
-rw-r--r-- | libass/ass_fontselect.c | 44 | ||||
-rw-r--r-- | libass/ass_fontselect.h | 3 | ||||
-rw-r--r-- | libass/dwrite_c.h | 11 |
6 files changed, 88 insertions, 13 deletions
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c index a2cd77f..006547b 100644 --- a/libass/ass_coretext.c +++ b/libass/ass_coretext.c @@ -88,6 +88,19 @@ static void get_name(CTFontDescriptorRef fontd, CFStringRef attr, } } +static bool is_postscript(CTFontDescriptorRef fontd) +{ + int format; + CFNumberRef cfformat = + CTFontDescriptorCopyAttribute(fontd, kCTFontFormatAttribute); + + if (!CFNumberGetValue(cfformat, kCFNumberIntType, &format)) + return false; + + return format == kCTFontFormatOpenTypePostScript || + format == kCTFontFormatPostScript; +} + static void get_trait(CFDictionaryRef traits, CFStringRef attribute, float *trait) { @@ -192,6 +205,8 @@ static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd) get_name(fontd, kCTFontNameAttribute, identifiers, &zero); meta.postscript_name = identifiers[0]; + meta.is_postscript = is_postscript(fontd); + CFCharacterSetRef chset = CTFontDescriptorCopyAttribute(fontd, kCTFontCharacterSetAttribute); ass_font_provider_add_font(provider, &meta, path, index, (void*)chset); diff --git a/libass/ass_directwrite.c b/libass/ass_directwrite.c index 6b6b623..8388f1c 100644 --- a/libass/ass_directwrite.c +++ b/libass/ass_directwrite.c @@ -483,6 +483,24 @@ static int map_width(enum DWRITE_FONT_STRETCH stretch) } } +static bool is_postscript(IDWriteFont *font) +{ + HRESULT hr = S_OK; + IDWriteFontFace *face = NULL; + DWRITE_FONT_FACE_TYPE type; + + hr = IDWriteFont_CreateFontFace(font, &face); + if (FAILED(hr) || !face) + return false; + + type = IDWriteFontFace_GetType(face); + IDWriteFontFace_Release(face); + + return type == DWRITE_FONT_FACE_TYPE_CFF || + type == DWRITE_FONT_FACE_TYPE_RAW_CFF || + type == DWRITE_FONT_FACE_TYPE_TYPE1; +} + /* * Scan every system font on the current machine and add it * to the libass lookup. Stores the FontPrivate as private data @@ -616,6 +634,8 @@ static void scan_fonts(IDWriteFactory *factory, } IDWriteLocalizedStrings_Release(familyNames); + meta.is_postscript = is_postscript(font); + FontPrivate *font_priv = (FontPrivate *) calloc(1, sizeof(*font_priv)); font_priv->font = font; diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c index c9bb2f9..8b0824b 100644 --- a/libass/ass_fontconfig.c +++ b/libass/ass_fontconfig.c @@ -86,6 +86,7 @@ static void scan_fonts(FcConfig *config, ASS_FontProvider *provider) FcBool outline; int index, weight; char *path; + char *format; char *fullnames[MAX_NAME]; char *families[MAX_NAME]; @@ -138,6 +139,13 @@ static void scan_fonts(FcConfig *config, ASS_FontProvider *provider) FcPatternGetString(pat, FC_POSTSCRIPT_NAME, 0, (FcChar8 **)&meta.postscript_name); + meta.is_postscript = false; + if (FcPatternGetString(pat, FC_FONTFORMAT, 0, + (FcChar8 **)&format) == FcResultMatch) + meta.is_postscript = + !strcmp(format, "Type 1") || !strcmp(format, "Type 42") || + !strcmp(format, "CID Type 1") || !strcmp(format, "CFF"); + ass_font_provider_add_font(provider, &meta, path, index, (void *)pat); } } diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c index 39d4d5d..2f577f1 100644 --- a/libass/ass_fontselect.c +++ b/libass/ass_fontselect.c @@ -35,6 +35,7 @@ #include FT_FREETYPE_H #include FT_SFNT_NAMES_H #include FT_TRUETYPE_IDS_H +#include FT_TYPE1_TABLES_H #include "ass_utils.h" #include "ass.h" @@ -66,8 +67,10 @@ struct font_info { // how to access this face char *path; // absolute path int index; // font index inside font collections + char *postscript_name; // can be used as an alternative to index to // identify a font inside a collection + bool is_postscript; // font source ASS_FontProvider *provider; @@ -294,21 +297,23 @@ ass_font_provider_add_font(ASS_FontProvider *provider, // set uid info->uid = selector->uid++; - info->slant = slant; - info->weight = weight; - info->width = width; - info->n_fullname = meta->n_fullname; - info->n_family = meta->n_family; - info->families = calloc(meta->n_family, sizeof(char *)); + info->slant = slant; + info->weight = weight; + info->width = width; + info->n_fullname = meta->n_fullname; + info->n_family = meta->n_family; + info->is_postscript = meta->is_postscript; + + info->families = calloc(meta->n_family, sizeof(char *)); + if (info->families == NULL) + goto error; + if (meta->n_fullname) { info->fullnames = calloc(meta->n_fullname, sizeof(char *)); if (info->fullnames == NULL) goto error; } - if (info->families == NULL) - goto error; - for (i = 0; i < info->n_family; i++) { info->families[i] = strdup(meta->families[i]); if (info->families[i] == NULL) @@ -426,6 +431,18 @@ static bool matches_fullname(ASS_FontInfo *f, const char *fullname) } /** + * \brief Return whether the given font has the given PostScript name. + */ +static bool matches_postscript_name(ASS_FontInfo *f, const char *name) +{ + if (f->is_postscript && f->postscript_name) { + if (ass_strcasecmp(f->postscript_name, name) == 0) + return true; + } + return false; +} + +/** * \brief Compare attributes of font (a) against a font request (req). Returns * a matching score - the lower the better. * Ignores font names/families! @@ -510,7 +527,8 @@ find_font(ASS_FontSelector *priv, ASS_Library *library, // to determine best match in that particular family score = font_attributes_similarity(font, &req); *name_match = true; - } else if (matches_fullname(font, fullname)) { + } else if (matches_fullname(font, fullname) || + matches_postscript_name(font, fullname)) { // If we don't have any match, compare fullnames against request // if there is a match now, assign lowest score possible. This means // the font should be chosen instantly, without further search. @@ -720,6 +738,7 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) char *fullnames[MAX_FULLNAME]; char *families[MAX_FULLNAME]; char *postscript_name = NULL; + PS_FontInfoRec postscript_info; // we're only interested in outlines if (!(face->face_flags & FT_FACE_FLAG_SCALABLE)) @@ -779,12 +798,13 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info) info->slant = slant; info->weight = weight; info->width = 100; // FIXME, should probably query the OS/2 table + info->postscript_name = postscript_name; - info->families = calloc(sizeof(char *), num_family); + info->is_postscript = !FT_Get_PS_Font_Info(face, &postscript_info); + info->families = calloc(sizeof(char *), num_family); if (info->families == NULL) goto error; - memcpy(info->families, &families, sizeof(char *) * num_family); info->n_family = num_family; diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h index f1e2933..09749ad 100644 --- a/libass/ass_fontselect.h +++ b/libass/ass_fontselect.h @@ -19,6 +19,7 @@ #ifndef LIBASS_FONTCONFIG_H #define LIBASS_FONTCONFIG_H +#include <stdbool.h> #include <stdint.h> #include <ft2build.h> #include FT_FREETYPE_H @@ -171,6 +172,8 @@ struct ass_font_provider_meta_data { // See FONT_WEIGHT_* int width; // Font weight in percent, normally 100 // See FONT_WIDTH_* + + bool is_postscript; // Whether the font contains PostScript outlines }; typedef struct ass_font_stream ASS_FontStream; diff --git a/libass/dwrite_c.h b/libass/dwrite_c.h index ac7f4a2..ffdf110 100644 --- a/libass/dwrite_c.h +++ b/libass/dwrite_c.h @@ -59,6 +59,15 @@ typedef enum DWRITE_FACTORY_TYPE { DWRITE_FACTORY_TYPE_ISOLATED } DWRITE_FACTORY_TYPE; +typedef enum DWRITE_FONT_FACE_TYPE { + DWRITE_FONT_FACE_TYPE_CFF = 0, + DWRITE_FONT_FACE_TYPE_TRUETYPE, + DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION, + DWRITE_FONT_FACE_TYPE_TYPE1, + DWRITE_FONT_FACE_TYPE_VECTOR, + DWRITE_FONT_FACE_TYPE_BITMAP, + DWRITE_FONT_FACE_TYPE_UNKNOWN +} DWRITE_FONT_FACE_TYPE; typedef enum DWRITE_FONT_SIMULATIONS { DWRITE_FONT_SIMULATIONS_NONE = 0x0000, @@ -319,7 +328,7 @@ DECLARE_INTERFACE_(IDWriteFontFace,IUnknown) #endif /* IDWriteFontFace methods */ - STDMETHOD(dummy1)(THIS); + STDMETHOD_(DWRITE_FONT_FACE_TYPE, GetType)(THIS) PURE; STDMETHOD(GetFiles)(THIS_ UINT32 *numberOfFiles, |