summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-11-02 12:07:07 +0100
committerGrigori Goronzy <greg@chown.ath.cx>2015-07-10 10:42:40 +0200
commit9014b275e9e90d796bee95249a6059e4a55f3cf9 (patch)
treecb8972dc534a88fd4dc2bf3ee88a0735cdc53035 /libass
parentd9585a81add0a41f6a59f3c7f95bcc6182732059 (diff)
downloadlibass-9014b275e9e90d796bee95249a6059e4a55f3cf9.tar.bz2
libass-9014b275e9e90d796bee95249a6059e4a55f3cf9.tar.xz
fontselect: coretext: allow selection based on PostScript name
Up until now fontselect used the face index to identify which font to load from a font collection. While this pretty convenient when using something freetype based like fontconfig, it seems to be somewhat freetype specific. CoreText uses the PostScript name as the unique identifier of a font. This commit allows to use that instead of the index to decide which face to open with FT_New_Face. To use the PostScript name the provider must return a -1 index and the PostScript name.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass.h3
-rw-r--r--libass/ass_coretext.c15
-rw-r--r--libass/ass_font.c24
-rw-r--r--libass/ass_fontconfig.c3
-rw-r--r--libass/ass_fontselect.c50
-rw-r--r--libass/ass_fontselect.h4
6 files changed, 68 insertions, 31 deletions
diff --git a/libass/ass.h b/libass/ass.h
index d6728ed..1f8a506 100644
--- a/libass/ass.h
+++ b/libass/ass.h
@@ -453,6 +453,7 @@ ass_create_font_provider(ASS_Renderer *priv, ASS_FontProviderFuncs *funcs,
* \param meta font metadata. See struct definition for more information.
* \param path absolute path to font, or NULL for memory-based fonts
* \param index index inside a font collection file
+ * \param psname PostScript name of the face (overrides index if present)
* \param data private data for font callbacks
* \return success
*
@@ -460,7 +461,7 @@ ass_create_font_provider(ASS_Renderer *priv, ASS_FontProviderFuncs *funcs,
int
ass_font_provider_add_font(ASS_FontProvider *provider,
ASS_FontProviderMetaData *meta, const char *path,
- unsigned int index, void *data);
+ unsigned int index, const char *psname, void *data);
/**
* \brief Free font provider and associated fonts.
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index f970226..802b511 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -32,7 +32,7 @@ static char *cfstr2buf(CFStringRef string)
return strdup(buf_ptr);
} else {
size_t buf_len = CFStringGetLength(string) + 1;
- char *buf = calloc(buf_len, sizeof(char));
+ char *buf = malloc(buf_len);
CFStringGetCString(string, buf, buf_len, kCFStringEncodingUTF8);
return buf;
}
@@ -153,14 +153,15 @@ static void scan_fonts(ASS_Library *lib, ASS_FontProvider *provider)
{
ASS_FontProviderMetaData meta;
char *families[1];
- char *fullnames[2];
+ char *identifiers[1];
+ char *fullnames[1];
CTFontCollectionRef coll = CTFontCollectionCreateFromAvailableFonts(NULL);
CFArrayRef fontsd = CTFontCollectionCreateMatchingFontDescriptors(coll);
for (int i = 0; i < CFArrayGetCount(fontsd); i++) {
CTFontDescriptorRef fontd = CFArrayGetValueAtIndex(fontsd, i);
- int index = 0;
+ int index = -1;
char *path = get_font_file(fontd);
if (strcmp("", path) == 0) {
@@ -175,13 +176,15 @@ static void scan_fonts(ASS_Library *lib, ASS_FontProvider *provider)
get_name(fontd, kCTFontFamilyNameAttribute, families, &meta.n_family);
meta.families = families;
+ int zero = 0;
+ get_name(fontd, kCTFontNameAttribute, identifiers, &zero);
get_name(fontd, kCTFontDisplayNameAttribute, fullnames, &meta.n_fullname);
- get_name(fontd, kCTFontNameAttribute, fullnames, &meta.n_fullname);
meta.fullnames = fullnames;
CFCharacterSetRef chset =
CTFontDescriptorCopyAttribute(fontd, kCTFontCharacterSetAttribute);
- ass_font_provider_add_font(provider, &meta, path, index, (void*)chset);
+ ass_font_provider_add_font(provider, &meta, path, index,
+ identifiers[0], (void*)chset);
for (int j = 0; j < meta.n_family; j++)
free(meta.families[j]);
@@ -189,6 +192,8 @@ static void scan_fonts(ASS_Library *lib, ASS_FontProvider *provider)
for (int j = 0; j < meta.n_fullname; j++)
free(meta.fullnames[j]);
+ free(identifiers[0]);
+
free(path);
}
diff --git a/libass/ass_font.c b/libass/ass_font.c
index 0b6d24b..9a81dca 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -135,6 +135,7 @@ close_stream_font(FT_Stream stream)
static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
{
char *path;
+ char *postscript_name;
int i, index, uid, error;
ASS_FontStream stream = { NULL, NULL };
FT_Face face;
@@ -142,8 +143,8 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
if (font->n_faces == ASS_FONT_MAX_FACES)
return -1;
- path = ass_font_select(fontsel, font->library, font , &index, &uid,
- &stream, ch);
+ path = ass_font_select(fontsel, font->library, font , &index,
+ &postscript_name, &uid, &stream, ch);
if (!path)
return -1;
@@ -191,6 +192,25 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
free(path);
return -1;
}
+
+ if (postscript_name && index < 0 && face->num_faces > 0) {
+ // The font provider gave us a post_script name and is not sure
+ // about the face index.. so use the postscript name to find the
+ // correct face_index in the collection!
+ for (int i = 0; face->num_faces; i++) {
+ FT_Done_Face(face);
+ error = FT_New_Face(font->ftlibrary, path, i, &face);
+ if (error) {
+ ass_msg(font->library, MSGL_WARN,
+ "Error opening font: '%s', %d", path, i);
+ free(path);
+ return -1;
+ }
+
+ if (strcmp(FT_Get_Postscript_Name(face), postscript_name) == 0)
+ break;
+ }
+ }
}
charmap_magic(font->library, face);
diff --git a/libass/ass_fontconfig.c b/libass/ass_fontconfig.c
index 6080359..4fefa23 100644
--- a/libass/ass_fontconfig.c
+++ b/libass/ass_fontconfig.c
@@ -120,7 +120,8 @@ static void scan_fonts(FcConfig *config, ASS_FontProvider *provider)
meta.n_fullname++;
meta.fullnames = fullnames;
- ass_font_provider_add_font(provider, &meta, path, index, (void *)pat);
+ ass_font_provider_add_font(provider, &meta, path, index, NULL,
+ (void *)pat);
}
}
diff --git a/libass/ass_fontselect.c b/libass/ass_fontselect.c
index 9ef0ace..799ad02 100644
--- a/libass/ass_fontselect.c
+++ b/libass/ass_fontselect.c
@@ -68,8 +68,10 @@ struct font_info {
int width;
// how to access this face
- char *path; // absolute path
- int index; // font index inside font collections
+ 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
// similarity score
unsigned score;
@@ -219,13 +221,14 @@ ass_font_provider_new(ASS_FontSelector *selector, ASS_FontProviderFuncs *funcs,
* \param meta basic metadata of the font
* \param path path to the font file, or NULL
* \param index face index inside the file
+ * \param psname PostScript name of the face (overrides index if present)
* \param data private data for the font
* \return success
*/
int
ass_font_provider_add_font(ASS_FontProvider *provider,
ASS_FontProviderMetaData *meta, const char *path,
- unsigned int index, void *data)
+ unsigned int index, const char *psname, void *data)
{
int i;
int weight, slant, width;
@@ -275,6 +278,9 @@ ass_font_provider_add_font(ASS_FontProvider *provider,
if (path)
info->path = strdup(path);
+ if (psname)
+ info->postscript_name = strdup(psname);
+
info->index = index;
info->priv = data;
info->provider = provider;
@@ -331,6 +337,9 @@ void ass_font_provider_free(ASS_FontProvider *provider)
if (info->path)
free(info->path);
+ if (info->postscript_name)
+ free(info->postscript_name);
+
if (info->provider->funcs.destroy_font)
info->provider->funcs.destroy_font(info->priv);
@@ -451,8 +460,8 @@ static int font_info_compare(const void *av, const void *bv)
static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
const char *family, unsigned bold, unsigned italic,
- int *index, int *uid, ASS_FontStream *stream,
- uint32_t code)
+ int *index, char **postscript_name, int *uid,
+ ASS_FontStream *stream, uint32_t code)
{
int num_fonts = priv->n_font;
int idx = 0;
@@ -494,6 +503,7 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
free(req.fullnames[0]);
+ *postscript_name = font_infos[idx].postscript_name;
*index = font_infos[idx].index;
*uid = font_infos[idx].uid;
@@ -526,8 +536,8 @@ static char *select_font(ASS_FontSelector *priv, ASS_Library *library,
* \return font file path
*/
char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
- ASS_Font *font, int *index, int *uid,
- ASS_FontStream *data, uint32_t code)
+ ASS_Font *font, int *index, char **postscript_name,
+ int *uid, ASS_FontStream *data, uint32_t code)
{
char *res = 0;
const char *family = font->desc.family;
@@ -535,41 +545,41 @@ char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
unsigned italic = font->desc.italic;
if (family && *family)
- res = select_font(priv, library, family, bold, italic, index, uid,
- data, code);
+ res = select_font(priv, library, family, bold, italic, index,
+ postscript_name, uid, data, code);
if (!res && priv->family_default) {
res = select_font(priv, library, priv->family_default, bold,
- italic, index, uid, data, code);
+ italic, index, postscript_name, uid, data, code);
if (res)
ass_msg(library, MSGL_WARN, "fontselect: Using default "
- "font family: (%s, %d, %d) -> %s, %d",
- family, bold, italic, res, *index);
+ "font family: (%s, %d, %d) -> %s, %d, %s",
+ family, bold, italic, res, *index, *postscript_name);
}
if (!res && priv->path_default) {
res = strdup(priv->path_default);
*index = priv->index_default;
ass_msg(library, MSGL_WARN, "fontselect: Using default font: "
- "(%s, %d, %d) -> %s, %d", family, bold, italic,
- res, *index);
+ "(%s, %d, %d) -> %s, %d, %s", family, bold, italic,
+ res, *index, *postscript_name);
}
// FIXME: not sure if that is needed, we cannot reach this path at the
// moment, either select_font returns or a font or the default one is used
if (!res) {
res = select_font(priv, library, "Arial", bold, italic,
- index, uid, data, code);
+ index, postscript_name, uid, data, code);
if (res)
ass_msg(library, MSGL_WARN, "fontselect: Using 'Arial' "
- "font family: (%s, %d, %d) -> %s, %d", family, bold,
- italic, res, *index);
+ "font family: (%s, %d, %d) -> %s, %d, %s", family, bold,
+ italic, res, *index, *postscript_name);
}
if (res)
ass_msg(library, MSGL_V,
- "fontselect: (%s, %d, %d) -> %s, %d", family, bold,
- italic, res, *index);
+ "fontselect: (%s, %d, %d) -> %s, %d, %s", family, bold,
+ italic, res, *index, *postscript_name);
return res;
}
@@ -753,7 +763,7 @@ static void process_fontdata(ASS_FontProvider *priv, ASS_Library *library,
ft->name = strdup(name);
ft->idx = -1;
- ass_font_provider_add_font(priv, &info, NULL, face_index, ft);
+ ass_font_provider_add_font(priv, &info, NULL, face_index, NULL, ft);
free_font_info(&info);
FT_Done_Face(face);
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index e080ab0..c1371dd 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -36,8 +36,8 @@ ass_fontselect_init(ASS_Library *library,
FT_Library ftlibrary, const char *family,
const char *path, const char *config, int fc);
char *ass_font_select(ASS_FontSelector *priv, ASS_Library *library,
- ASS_Font *font, int *index, int *uid,
- ASS_FontStream *data, uint32_t code);
+ ASS_Font *font, int *index, char **postscript_name,
+ int *uid, ASS_FontStream *data, uint32_t code);
void ass_fontselect_free(ASS_FontSelector *priv);
// Font provider functions