summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2021-03-27 04:11:07 +0200
committerOleg Oshmyan <chortos@inbox.lv>2021-04-29 03:18:15 +0300
commit2d2be3237d3422cd9ef7beebd1134b7cc5b3b474 (patch)
tree5882683751c0df0018fca57a551810ed02b3cb2a
parentb4b744244799d9c3c81df809313e6a85347f1bd0 (diff)
downloadlibass-2d2be3237d3422cd9ef7beebd1134b7cc5b3b474.tar.bz2
libass-2d2be3237d3422cd9ef7beebd1134b7cc5b3b474.tar.xz
fontselect: coretext: ask Core Text for family name as last resort
If a font contains no recognized Microsoft-platform family names, use the family name reported by Core Text. Skip FreeType's face->family_name because it is an ASCII bastardization of a family name and may not exist at all.
-rw-r--r--libass/ass_coretext.c56
-rw-r--r--libass/ass_fontselect.c40
-rw-r--r--libass/ass_fontselect.h2
3 files changed, 70 insertions, 28 deletions
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index b6870a6..49a96ff 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -125,6 +125,49 @@ static char *get_name(CTFontDescriptorRef fontd, CFStringRef attr)
return ret;
}
+static bool fill_family_name(CTFontDescriptorRef fontd,
+ ASS_FontProviderMetaData *info)
+{
+ if (info->n_family)
+ return true;
+
+ char *family_name = get_name(fontd, kCTFontFamilyNameAttribute);
+ if (!family_name)
+ return false;
+
+ info->families = malloc(sizeof(char *));
+ if (!info->families) {
+ free(family_name);
+ return false;
+ }
+
+ info->families[0] = family_name;
+ info->n_family++;
+ return true;
+}
+
+static bool get_font_info_ct(ASS_Library *lib, FT_Library ftlib,
+ CTFontDescriptorRef fontd,
+ char **path_out,
+ ASS_FontProviderMetaData *info)
+{
+ char *path = get_font_file(fontd);
+ *path_out = path;
+ if (!path || !*path) {
+ // skip the font if the URL field in the font descriptor is empty
+ return false;
+ }
+
+ char *ps_name = get_name(fontd, kCTFontNameAttribute);
+ if (!ps_name)
+ return false;
+
+ bool got_info = ass_get_font_info(lib, ftlib, path, ps_name, -1, false, info);
+ free(ps_name);
+
+ return got_info && fill_family_name(fontd, info);
+}
+
static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
ASS_FontProvider *provider, CFArrayRef fontsd)
{
@@ -136,16 +179,8 @@ static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
CTFontDescriptorRef fontd = CFArrayGetValueAtIndex(fontsd, i);
int index = -1;
- char *path = get_font_file(fontd);
- if (!path || !*path) {
- // skip the font if the URL field in the font descriptor is empty
- free(path);
- continue;
- }
-
- char *ps_name = get_name(fontd, kCTFontNameAttribute);
-
- if (ass_get_font_info(lib, ftlib, path, ps_name, -1, &meta)) {
+ char *path = NULL;
+ if (get_font_info_ct(lib, ftlib, fontd, &path, &meta)) {
CFRetain(fontd);
ass_font_provider_add_font(provider, &meta, path, index, (void*)fontd);
}
@@ -161,7 +196,6 @@ static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
free(meta.postscript_name);
- free(ps_name);
free(path);
}
}
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index b75920f..6b62511 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -756,7 +756,8 @@ char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
* \return success
*/
static bool
-get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info)
+get_font_info(FT_Library lib, FT_Face face, bool require_family_name,
+ ASS_FontProviderMetaData *info)
{
int i;
int num_fullname = 0;
@@ -800,18 +801,20 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info)
}
- // check if we got a valid family - if not use whatever FreeType gives us
- if (num_family == 0 && face->family_name) {
- families[0] = strdup(face->family_name);
- if (families[0] == NULL)
+ if (require_family_name) {
+ // check if we got a valid family - if not use whatever FreeType gives us
+ if (num_family == 0 && face->family_name) {
+ families[0] = strdup(face->family_name);
+ if (families[0] == NULL)
+ goto error;
+ num_family++;
+ }
+
+ // we absolutely need a name
+ if (num_family == 0)
goto error;
- num_family++;
}
- // we absolutely need a name
- if (num_family == 0)
- goto error;
-
// calculate sensible slant and weight from style attributes
slant = 110 * !!(face->style_flags & FT_STYLE_FLAG_ITALIC);
weight = ass_face_get_weight(face);
@@ -823,11 +826,13 @@ get_font_info(FT_Library lib, FT_Face face, ASS_FontProviderMetaData *info)
info->postscript_name = (char *)FT_Get_Postscript_Name(face);
- 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;
+ if (num_family) {
+ 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;
+ }
if (num_fullname) {
info->fullnames = calloc(sizeof(char *), num_fullname);
@@ -857,6 +862,7 @@ error:
bool ass_get_font_info(ASS_Library *lib, FT_Library ftlib, const char *path,
const char *postscript_name, int index,
+ bool require_family_name,
ASS_FontProviderMetaData *info)
{
bool ret = false;
@@ -887,7 +893,7 @@ bool ass_get_font_info(ASS_Library *lib, FT_Library ftlib, const char *path,
}
if (face) {
- ret = get_font_info(ftlib, face, info);
+ ret = get_font_info(ftlib, face, require_family_name, info);
if (ret)
info->postscript_name = strdup(info->postscript_name);
FT_Done_Face(face);
@@ -952,7 +958,7 @@ static void process_fontdata(ASS_FontProvider *priv, ASS_Library *library,
charmap_magic(library, face);
memset(&info, 0, sizeof(ASS_FontProviderMetaData));
- if (!get_font_info(ftlibrary, face, &info)) {
+ if (!get_font_info(ftlibrary, face, true, &info)) {
ass_msg(library, MSGL_WARN,
"Error getting metadata for embedded font '%s'", name);
FT_Done_Face(face);
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 2cb5672..d029b0b 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -273,12 +273,14 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
* \param path the path to the font file to read
* \param postscript_name the PS name of the specific face to read (set either this or index)
* \param index the face index to read, or -1 if not applicable
+ * \param require_family_name whether to try a fallback family name and fail if none found
* \param info the struct to store results into
* \return success
*
*/
bool ass_get_font_info(ASS_Library *lib, FT_Library ftlib, const char *path,
const char *postscript_name, int index,
+ bool require_family_name,
ASS_FontProviderMetaData *info);
/**