]> granicus.if.org Git - libass/commitdiff
coretext: replace CT attr reads with freetype lookups master
authorRodger Combs <rodger.combs@gmail.com>
Thu, 11 Oct 2018 07:32:50 +0000 (02:32 -0500)
committerOleg Oshmyan <chortos@inbox.lv>
Thu, 26 Sep 2019 13:51:09 +0000 (16:51 +0300)
This makes results much more consistent with other platforms,
particularly around cases where fonts have multiple conflicting names.

libass/ass_coretext.c

index 588547753ec20702a6d93b46ef6511d2f23be500..59a8a2d4ef7175646fa563107053f028d24c467b 100644 (file)
@@ -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);