summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2021-06-17 19:42:25 +0300
committerOleg Oshmyan <chortos@inbox.lv>2021-07-10 02:36:31 +0300
commit887e6cc50bfbe8fc354993682edc03c51203e2fc (patch)
tree5fccc501b40b24192d2573e88fe240703b7d9d98
parent72c4eaadb42c7692ebdd828b0903a907acad5d16 (diff)
downloadlibass-887e6cc50bfbe8fc354993682edc03c51203e2fc.tar.bz2
libass-887e6cc50bfbe8fc354993682edc03c51203e2fc.tar.xz
fontselect: automatically read metadata from font file if needed
-rw-r--r--libass/ass_coretext.c40
-rw-r--r--libass/ass_font.c9
-rw-r--r--libass/ass_fontselect.c85
-rw-r--r--libass/ass_fontselect.h19
4 files changed, 76 insertions, 77 deletions
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index 42259bb..8002d8b 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -126,8 +126,7 @@ static char *get_name(CTFontDescriptorRef fontd, CFStringRef attr)
return ret;
}
-static bool get_font_info_ct(ASS_Library *lib, FT_Library ftlib,
- CTFontDescriptorRef fontd,
+static bool get_font_info_ct(CTFontDescriptorRef fontd,
char **path_out,
ASS_FontProviderMetaData *info)
{
@@ -139,29 +138,19 @@ static bool get_font_info_ct(ASS_Library *lib, FT_Library ftlib,
}
char *ps_name = get_name(fontd, kCTFontNameAttribute);
+ info->postscript_name = ps_name;
if (!ps_name)
return false;
char *family_name = get_name(fontd, kCTFontFamilyNameAttribute);
- if (!family_name) {
- free(ps_name);
+ info->extended_family = family_name;
+ if (!family_name)
return false;
- }
-
- bool got_info =
- ass_get_font_info(lib, ftlib, path, ps_name, -1, family_name, info);
- free(ps_name);
- if (got_info)
- info->extended_family = family_name;
- else
- free(family_name);
-
- return got_info;
+ return true;
}
-static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
- ASS_FontProvider *provider, CFArrayRef fontsd)
+static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd)
{
if (!fontsd)
return;
@@ -172,20 +161,11 @@ static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
int index = -1;
char *path = NULL;
- if (get_font_info_ct(lib, ftlib, fontd, &path, &meta)) {
+ if (get_font_info_ct(fontd, &path, &meta)) {
CFRetain(fontd);
ass_font_provider_add_font(provider, &meta, path, index, (void*)fontd);
}
- for (int j = 0; j < meta.n_family; j++)
- free(meta.families[j]);
-
- for (int j = 0; j < meta.n_fullname; j++)
- free(meta.fullnames[j]);
-
- free(meta.families);
- free(meta.fullnames);
-
free(meta.postscript_name);
free(meta.extended_family);
@@ -196,8 +176,6 @@ static void process_descriptors(ASS_Library *lib, FT_Library ftlib,
static void match_fonts(void *priv, ASS_Library *lib, ASS_FontProvider *provider,
char *name)
{
- FT_Library ftlib = priv;
-
CFStringRef cfname =
CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
if (!cfname)
@@ -256,7 +234,7 @@ static void match_fonts(void *priv, ASS_Library *lib, ASS_FontProvider *provider
if (!fontsd)
goto cleanup;
- process_descriptors(lib, ftlib, provider, fontsd);
+ process_descriptors(provider, fontsd);
cleanup:
SAFE_CFRelease(fontsd);
@@ -329,5 +307,5 @@ ASS_FontProvider *
ass_coretext_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
const char *config, FT_Library ftlib)
{
- return ass_font_provider_new(selector, &coretext_callbacks, ftlib);
+ return ass_font_provider_new(selector, &coretext_callbacks, NULL);
}
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 9dc8772..a7ee576 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -203,8 +203,13 @@ FT_Face ass_face_stream(ASS_Library *lib, FT_Library ftlib, const char *name,
FT_Face face;
int error = FT_Open_Face(ftlib, &args, index, &face);
if (error) {
- ass_msg(lib, MSGL_WARN,
- "Error opening memory font: '%s'", name);
+ if (name) {
+ ass_msg(lib, MSGL_WARN,
+ "Error opening memory font: '%s'", name);
+ } else {
+ ass_msg(lib, MSGL_WARN,
+ "Error opening memory font");
+ }
return NULL;
}
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 670156e..68a4407 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -358,23 +358,6 @@ error:
return false;
}
-bool ass_get_font_info(ASS_Library *lib, FT_Library ftlib, const char *path,
- const char *postscript_name, int index,
- const char *fallback_family_name,
- ASS_FontProviderMetaData *info)
-{
- FT_Face face = ass_face_open(lib, ftlib, path, postscript_name, index);
- if (!face)
- return false;
-
- bool ret = get_font_info(ftlib, face, fallback_family_name, info);
- if (ret)
- info->postscript_name = strdup(info->postscript_name);
- FT_Done_Face(face);
-
- return ret;
-}
-
/**
* \brief Free the dynamically allocated fields of metadata
* created by get_font_info.
@@ -382,16 +365,17 @@ bool ass_get_font_info(ASS_Library *lib, FT_Library ftlib, const char *path,
*/
static void free_font_info(ASS_FontProviderMetaData *meta)
{
- int i;
-
- for (i = 0; i < meta->n_family; i++)
- free(meta->families[i]);
-
- for (i = 0; i < meta->n_fullname; i++)
- free(meta->fullnames[i]);
+ if (meta->families) {
+ for (int i = 0; i < meta->n_family; i++)
+ free(meta->families[i]);
+ free(meta->families);
+ }
- free(meta->families);
- free(meta->fullnames);
+ if (meta->fullnames) {
+ for (int i = 0; i < meta->n_fullname; i++)
+ free(meta->fullnames[i]);
+ free(meta->fullnames);
+ }
}
/**
@@ -411,7 +395,48 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
int i;
int weight, slant, width;
ASS_FontSelector *selector = provider->parent;
- ASS_FontInfo *info;
+ ASS_FontInfo *info = NULL;
+ ASS_FontProviderMetaData implicit_meta = {0};
+
+ if (!meta->n_family) {
+ FT_Face face;
+ if (provider->funcs.get_font_index)
+ index = provider->funcs.get_font_index(data);
+ if (!path) {
+ ASS_FontStream stream = {
+ .func = provider->funcs.get_data,
+ .priv = data,
+ };
+ // This name is only used in an error message, so use
+ // our best name but don't panic if we don't have any.
+ // Prefer PostScript name because it is unique.
+ const char *name = meta->postscript_name ?
+ meta->postscript_name : meta->extended_family;
+ face = ass_face_stream(selector->library, selector->ftlibrary,
+ name, &stream, index);
+ } else {
+ face = ass_face_open(selector->library, selector->ftlibrary,
+ path, meta->postscript_name, index);
+ }
+ if (!face)
+ goto error;
+ if (!get_font_info(selector->ftlibrary, face, meta->extended_family,
+ &implicit_meta)) {
+ FT_Done_Face(face);
+ goto error;
+ }
+ if (implicit_meta.postscript_name) {
+ implicit_meta.postscript_name =
+ strdup(implicit_meta.postscript_name);
+ if (!implicit_meta.postscript_name) {
+ FT_Done_Face(face);
+ goto error;
+ }
+ }
+ FT_Done_Face(face);
+ implicit_meta.extended_family = meta->extended_family;
+ meta = &implicit_meta;
+ }
#if 0
int j;
@@ -511,7 +536,11 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
return true;
error:
- ass_font_provider_free_fontinfo(info);
+ if (info)
+ ass_font_provider_free_fontinfo(info);
+
+ free_font_info(&implicit_meta);
+ free(implicit_meta.postscript_name);
if (provider->funcs.destroy_font)
provider->funcs.destroy_font(data);
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 50c1968..522c729 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -171,6 +171,9 @@ typedef struct font_provider_funcs {
/*
* Basic font metadata. All strings must be encoded with UTF-8.
* At minimum one family is required.
+ * If no family names are present, ass_font_provider_add_font
+ * will open the font file and read metadata from there,
+ * replacing everything but extended_family.
*/
struct ass_font_provider_meta_data {
/**
@@ -280,22 +283,6 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
int index, void *data);
/**
- * \brief Read a font's parameters
- * \param lib a FT_Library to use (need not be the global one)
- * \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 fallback_family_name family name from outside source, used as last resort
- * \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,
- const char *fallback_family_name,
- ASS_FontProviderMetaData *info);
-
-/**
* \brief Free font provider and associated fonts.
* \param provider the font provider
*