[vlc-commits] freetype: replace legacy Mac selector with a re-write based on CoreText

Felix Paul Kühne git at videolan.org
Sun Nov 22 19:54:01 CET 2015


vlc | branch: master | Felix Paul Kühne <fkuehne at videolan.org> | Sun Nov 22 19:12:44 2015 +0100| [8fba7c5840e8270cbe0e0a9f54684114cb4fd929] | committer: Felix Paul Kühne

freetype: replace legacy Mac selector with a re-write based on CoreText

This removes a Carbon dependency and adds support for tvOS and iOS

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=8fba7c5840e8270cbe0e0a9f54684114cb4fd929
---

 modules/text_renderer/Makefile.am      |    2 +-
 modules/text_renderer/fonts/darwin.c   |  137 ++++++++++++++++----------------
 modules/text_renderer/freetype.c       |    4 +-
 modules/text_renderer/platform_fonts.h |    8 +-
 4 files changed, 73 insertions(+), 78 deletions(-)

diff --git a/modules/text_renderer/Makefile.am b/modules/text_renderer/Makefile.am
index e010f09..53d3501 100644
--- a/modules/text_renderer/Makefile.am
+++ b/modules/text_renderer/Makefile.am
@@ -28,7 +28,7 @@ libfreetype_plugin_la_SOURCES += text_renderer/fonts/android.c
 endif
 if HAVE_DARWIN
 libfreetype_plugin_la_SOURCES += text_renderer/fonts/darwin.c
-libfreetype_plugin_la_LDFLAGS += -Wl,-framework,Carbon
+libfreetype_plugin_la_LDFLAGS += -Wl,-framework,CoreFoundation -Wl,-framework,CoreText
 endif
 if HAVE_FRIBIDI
 libfreetype_plugin_la_CPPFLAGS += $(FRIBIDI_CFLAGS) -DHAVE_FRIBIDI
diff --git a/modules/text_renderer/fonts/darwin.c b/modules/text_renderer/fonts/darwin.c
index 26fb339..a56ee3d 100644
--- a/modules/text_renderer/fonts/darwin.c
+++ b/modules/text_renderer/fonts/darwin.c
@@ -1,14 +1,11 @@
 /*****************************************************************************
- * freetype.c : Put text on the video, using freetype2
+ * darwin.c : Put text on the video, using freetype2
  *****************************************************************************
- * Copyright (C) 2002 - 2015 VLC authors and VideoLAN
+ * Copyright (C) 2015 VLC authors and VideoLAN
  * $Id$
  *
- * Authors: Sigmund Augdal Helberg <dnumgis at videolan.org>
- *          Gildas Bazin <gbazin at videolan.org>
- *          Bernie Purcell <bitmap at videolan.org>
+ * Authors: Felix Paul Kühne <fkuehne at videolan.org>
  *          Jean-Baptiste Kempf <jb at videolan.org>
- *          Felix Paul Kühne <fkuehne at videolan.org>
  *          Salah-Eddin Shaban <salshaaban at gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -37,92 +34,94 @@
 #include <vlc_common.h>
 #include <vlc_filter.h>                                      /* filter_sys_t */
 
-#include <TargetConditionals.h>
-#if !TARGET_OS_IPHONE
-# include <Carbon/Carbon.h>
-#endif
-#include <sys/param.h>                         /* for MAXPATHLEN */
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreText/CoreText.h>
 
 #include "../platform_fonts.h"
 
-#if !TARGET_OS_IPHONE
-char* MacLegacy_Select( filter_t *p_filter, const char* psz_fontname,
-                        bool b_bold, bool b_italic,
-                        int *i_idx, uni_char_t codepoint )
+char* getPathForFontDescription(CTFontDescriptorRef fontDescriptor);
+
+char* getPathForFontDescription(CTFontDescriptorRef fontDescriptor)
+{
+    CFURLRef url = CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontURLAttribute);
+    CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+    char *cpath = (char *)CFStringGetCStringPtr(path, kCFStringEncodingUTF8);
+    char *retPath = NULL;
+    if (cpath) {
+        retPath = strdup(cpath);
+    }
+    CFRelease(path);
+    CFRelease(url);
+    return retPath;
+}
+
+char* CoreText_Select( filter_t *p_filter, const char* psz_fontname,
+                       bool b_bold, bool b_italic,
+                       int *i_idx, uni_char_t codepoint )
 {
+    VLC_UNUSED( i_idx );
     VLC_UNUSED( b_bold );
     VLC_UNUSED( b_italic );
     VLC_UNUSED( codepoint );
-    FSRef ref;
-    unsigned char path[MAXPATHLEN];
-    char * psz_path;
-
-    CFStringRef  cf_fontName;
-    ATSFontRef   ats_font_id;
-
-    *i_idx = 0;
 
     if( psz_fontname == NULL )
         return NULL;
 
-    msg_Dbg( p_filter, "looking for %s", psz_fontname );
-    cf_fontName = CFStringCreateWithCString( kCFAllocatorDefault, psz_fontname, kCFStringEncodingUTF8 );
+    const size_t numberOfAttributes = 3;
+    CTFontDescriptorRef coreTextFontDescriptors[numberOfAttributes];
+    CFMutableDictionaryRef coreTextAttributes[numberOfAttributes];
+    CFStringRef attributeNames[numberOfAttributes] = {
+        kCTFontFamilyNameAttribute,
+        kCTFontDisplayNameAttribute,
+        kCTFontNameAttribute,
+    };
+
+    CFStringRef fontName = CFStringCreateWithCString(kCFAllocatorDefault,
+                                                     psz_fontname,
+                                                     kCFStringEncodingUTF8);
+    for (size_t x = 0; x < numberOfAttributes; x++) {
+        coreTextAttributes[x] = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL);
+        CFDictionaryAddValue(coreTextAttributes[x], attributeNames[x], fontName);
+        coreTextFontDescriptors[x] = CTFontDescriptorCreateWithAttributes(coreTextAttributes[x]);
+    }
+
+    CFArrayRef coreTextFontDescriptorsArray = CFArrayCreate(kCFAllocatorDefault, (const void **)&coreTextFontDescriptors, numberOfAttributes, NULL);
 
-    ats_font_id = ATSFontFindFromName( cf_fontName, kATSOptionFlagsIncludeDisabledMask );
+    CTFontCollectionRef coreTextFontCollection = CTFontCollectionCreateWithFontDescriptors(coreTextFontDescriptorsArray, 0);
 
-    if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
-    {
-        msg_Dbg( p_filter, "ATS couldn't find %s by name, checking family", psz_fontname );
-        ats_font_id = ATSFontFamilyFindFromName( cf_fontName, kATSOptionFlagsDefault );
+    CFArrayRef matchedFontDescriptions = CTFontCollectionCreateMatchingFontDescriptors(coreTextFontCollection);
 
-        if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
-        {
-            msg_Dbg( p_filter, "ATS couldn't find either %s nor its family, checking PS name", psz_fontname );
-            ats_font_id = ATSFontFindFromPostScriptName( cf_fontName, kATSOptionFlagsDefault );
+    CFIndex numberOfFoundFontDescriptions = CFArrayGetCount(matchedFontDescriptions);
 
-            if ( ats_font_id == 0 || ats_font_id == 0xFFFFFFFFUL )
-            {
-                msg_Err( p_filter, "ATS couldn't find %s (no font name, family or PS name)", psz_fontname );
-                CFRelease( cf_fontName );
-                return NULL;
+    char *path = NULL;
+
+    for (CFIndex i = 0; i < numberOfFoundFontDescriptions; i++) {
+        CTFontDescriptorRef iter = CFArrayGetValueAtIndex(matchedFontDescriptions, i);
+        path = getPathForFontDescription(iter);
+
+        /* check if the path is empty, which can happen in rare circumstances */
+        if (path != NULL) {
+            if (strcmp("", path) == 0) {
+                FREENULL(path);
+                continue;
             }
         }
-    }
-    CFRelease( cf_fontName );
 
-    if ( noErr != ATSFontGetFileReference( ats_font_id, &ref ) )
-    {
-        msg_Err( p_filter, "ATS couldn't get file ref for %s", psz_fontname );
-        return NULL;
+        break;
     }
 
-    /* i_idx calculation by searching preceding fontIDs */
-    /* with same FSRef                                       */
-    {
-        ATSFontRef  id2 = ats_font_id - 1;
-        FSRef       ref2;
+    msg_Dbg( p_filter, "found '%s'", path );
 
-        while ( id2 > 0 )
-        {
-            if ( noErr != ATSFontGetFileReference( id2, &ref2 ) )
-                break;
-            if ( noErr != FSCompareFSRefs( &ref, &ref2 ) )
-                break;
+    CFRelease(matchedFontDescriptions);
+    CFRelease(coreTextFontCollection);
 
-            id2 --;
-        }
-        *i_idx = ats_font_id - ( id2 + 1 );
+    for (size_t x = 0; x < numberOfAttributes; x++) {
+        CFRelease(coreTextAttributes[x]);
+        CFRelease(coreTextFontDescriptors[x]);
     }
 
-    if ( noErr != FSRefMakePath( &ref, path, sizeof(path) ) )
-    {
-        msg_Err( p_filter, "failure when getting path from FSRef" );
-        return NULL;
-    }
-    msg_Dbg( p_filter, "found %s", path );
+    CFRelease(coreTextFontDescriptorsArray);
+    CFRelease(fontName);
 
-    psz_path = strdup( (char *)path );
-
-    return psz_path;
+    return path;
 }
-#endif
diff --git a/modules/text_renderer/freetype.c b/modules/text_renderer/freetype.c
index 057447d..251e841 100644
--- a/modules/text_renderer/freetype.c
+++ b/modules/text_renderer/freetype.c
@@ -1263,9 +1263,7 @@ static int Create( vlc_object_t *p_this )
     p_sys->pf_get_fallbacks = FontConfig_GetFallbacks;
     FontConfig_Prepare( p_filter );
 #elif defined( __APPLE__ )
-#if !TARGET_OS_IPHONE
-    p_sys->pf_select = MacLegacy_Select;
-#endif
+    p_sys->pf_select = CoreText_Select;
 #elif defined( _WIN32 ) && defined( HAVE_GET_FONT_BY_FAMILY_NAME )
     const char *const ppsz_win32_default[] =
         { "Tahoma", "FangSong", "SimHei", "KaiTi" };
diff --git a/modules/text_renderer/platform_fonts.h b/modules/text_renderer/platform_fonts.h
index abf76c7..7c9e051 100644
--- a/modules/text_renderer/platform_fonts.h
+++ b/modules/text_renderer/platform_fonts.h
@@ -151,11 +151,9 @@ const vlc_family_t *Win32_GetFamily( filter_t *p_filter, const char *psz_family
 #endif /* _WIN32 */
 
 #ifdef __APPLE__
-#if !TARGET_OS_IPHONE
-char* MacLegacy_Select( filter_t *p_filter, const char* psz_fontname,
-                        bool b_bold, bool b_italic,
-                        int *i_idx, uni_char_t codepoint );
-#endif
+char* CoreText_Select( filter_t *p_filter, const char* psz_fontname,
+                       bool b_bold, bool b_italic,
+                       int *i_idx, uni_char_t codepoint );
 #endif /* __APPLE__ */
 
 #ifdef __ANDROID__



More information about the vlc-commits mailing list