summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
authorRodger Combs <rodger.combs@gmail.com>2018-10-11 02:32:50 -0500
committerOleg Oshmyan <chortos@inbox.lv>2019-09-26 16:51:09 +0300
commitbe0d1613f79a95073d18d96a60e1394abf9316a2 (patch)
treec1f10b448b21cde468f50c5f923e4c1260c87cfd /libass
parentf62f5f0d05480ea5d8f8dd50bae55243b1cfb90b (diff)
downloadlibass-be0d1613f79a95073d18d96a60e1394abf9316a2.tar.bz2
libass-be0d1613f79a95073d18d96a60e1394abf9316a2.tar.xz
coretext: replace CT attr reads with freetype lookups
This makes results much more consistent with other platforms, particularly around cases where fonts have multiple conflicting names.
Diffstat (limited to 'libass')
-rw-r--r--libass/ass_coretext.c136
1 files changed, 24 insertions, 112 deletions
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index 5885477..59a8a2d 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -103,118 +103,31 @@ static char *get_font_file(CTFontDescriptorRef fontd)
return buffer;
}
-static void get_name(CTFontDescriptorRef fontd, CFStringRef attr,
- char **array, int *idx)
+static char *get_name(CTFontDescriptorRef fontd, CFStringRef attr)
{
-
+ char *ret = NULL;
CFStringRef name = CTFontDescriptorCopyAttribute(fontd, attr);
if (name) {
- array[*idx] = cfstr2buf(name);
+ ret = cfstr2buf(name);
SAFE_CFRelease(name);
- *idx += 1;
}
+ return ret;
}
-static void get_trait(CFDictionaryRef traits, CFStringRef attribute,
- double *trait)
-{
- CFNumberRef cftrait = CFDictionaryGetValue(traits, attribute);
- *trait = 0.0;
- CFNumberGetValue(cftrait, kCFNumberDoubleType, trait);
-}
-
-// These are available as kCTFontWeightUltraLight, etc. in newer SDKs.
-// For some reason they switched the terms "ultra light" and "thin"
-#define FontWeightUltraLight -0.8
-#define FontWeightThin -0.6
-#define FontWeightLight -0.4
-#define FontWeightRegular 0
-#define FontWeightMedium 0.23
-#define FontWeightSemibold 0.3
-#define FontWeightBold 0.4
-#define FontWeightHeavy 0.56
-#define FontWeightBlack 0.62
-
-#define AVG(x, y) ((x + y) / 2.)
-
-static void get_font_traits(CTFontDescriptorRef fontd,
- ASS_FontProviderMetaData *meta)
-{
- double weight, slant, width;
-
- CFDictionaryRef traits =
- CTFontDescriptorCopyAttribute(fontd, kCTFontTraitsAttribute);
-
- get_trait(traits, kCTFontWeightTrait, &weight);
- get_trait(traits, kCTFontSlantTrait, &slant);
- get_trait(traits, kCTFontWidthTrait, &width);
-
- SAFE_CFRelease(traits);
-
- // Printed all of my system fonts (see if'deffed code below). Here is how
- // CoreText 'normalized' weights maps to CSS/libass:
-
- // opentype: 0 100 200 300 400 500 600 700 800 900
- // css: LIGHT REG MED SBOLD BOLD BLACK EXTRABL
- // libass: LIGHT MEDIUM BOLD
- // coretext: -0.4 0.0 0.23 0.3 0.4 0.62
-
- if (weight >= AVG(FontWeightHeavy, FontWeightBlack))
- meta->weight = 900;
- else if (weight >= AVG(FontWeightBold, FontWeightHeavy))
- meta->weight = 800;
- else if (weight >= AVG(FontWeightSemibold, FontWeightBold))
- meta->weight = 700;
- else if (weight >= AVG(FontWeightMedium, FontWeightSemibold))
- meta->weight = 600;
- else if (weight >= AVG(FontWeightRegular, FontWeightMedium))
- meta->weight = 500;
- else if (weight >= AVG(FontWeightLight, FontWeightMedium))
- meta->weight = 400;
- else if (weight >= AVG(FontWeightThin, FontWeightLight))
- meta->weight = 300;
- else if (weight >= AVG(FontWeightUltraLight, FontWeightThin))
- meta->weight = 200;
- else
- meta->weight = 100;
-
- if (slant > 0.03)
- meta->slant = FONT_SLANT_ITALIC;
- else
- meta->slant = FONT_SLANT_NONE;
-
- if (width <= -0.2)
- meta->width = FONT_WIDTH_CONDENSED;
- else if (width >= 0.2)
- meta->width = FONT_WIDTH_EXPANDED;
- else
- meta->width = FONT_WIDTH_NORMAL;
-
-#if 0
- char *name[1];
- int idx = 0;
- get_name(fontd, kCTFontDisplayNameAttribute, name, &idx);
- char *file = get_font_file(fontd);
- printf(
- "Font traits for: %-40s [%-50s] "
- "<slant: %f, %03d>, <weight: (%f, %03d)>, <width: %f, %03d>\n",
- name[0], file,
- slant, meta->slant, weight, meta->weight, width, meta->width);
- free(name[0]);
- free(file);
-#endif
-}
-
-static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd)
+static void process_descriptors(ASS_Library *lib, ASS_FontProvider *provider,
+ CFArrayRef fontsd)
{
ASS_FontProviderMetaData meta;
- char *families[1];
- char *identifiers[1];
- char *fullnames[1];
if (!fontsd)
return;
+ FT_Library ftlib;
+ if (FT_Init_FreeType(&ftlib)) {
+ ass_msg(lib, MSGL_WARN, "Failed to create FT lib");
+ return;
+ }
+
for (int i = 0; i < CFArrayGetCount(fontsd); i++) {
CTFontDescriptorRef fontd = CFArrayGetValueAtIndex(fontsd, i);
int index = -1;
@@ -227,20 +140,13 @@ static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd)
}
memset(&meta, 0, sizeof(meta));
- get_font_traits(fontd, &meta);
-
- get_name(fontd, kCTFontFamilyNameAttribute, families, &meta.n_family);
- meta.families = families;
- get_name(fontd, kCTFontDisplayNameAttribute, fullnames, &meta.n_fullname);
- meta.fullnames = fullnames;
+ char *ps_name = get_name(fontd, kCTFontNameAttribute);
- int zero = 0;
- get_name(fontd, kCTFontNameAttribute, identifiers, &zero);
- meta.postscript_name = identifiers[0];
-
- CFRetain(fontd);
- ass_font_provider_add_font(provider, &meta, path, index, (void*)fontd);
+ if (ass_get_font_info(lib, ftlib, path, ps_name, -1, &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]);
@@ -248,10 +154,16 @@ static void process_descriptors(ASS_FontProvider *provider, CFArrayRef fontsd)
for (int j = 0; j < meta.n_fullname; j++)
free(meta.fullnames[j]);
+ free(meta.families);
+ free(meta.fullnames);
+
free(meta.postscript_name);
+ free(ps_name);
free(path);
}
+
+ FT_Done_FreeType(ftlib);
}
static void match_fonts(ASS_Library *lib, ASS_FontProvider *provider,
@@ -284,7 +196,7 @@ static void match_fonts(ASS_Library *lib, ASS_FontProvider *provider,
CFArrayRef fontsd =
CTFontCollectionCreateMatchingFontDescriptors(ctcoll);
- process_descriptors(provider, fontsd);
+ process_descriptors(lib, provider, fontsd);
SAFE_CFRelease(fontsd);
SAFE_CFRelease(ctcoll);