From 046ade7320a337d03f0865747a609f9a024f47c9 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Tue, 16 Apr 2024 00:56:31 +0800 Subject: [PATCH 13/13] Restore working code for text_renderer --- modules/text_renderer/Makefile.am | 2 +- modules/text_renderer/freetype/fonts/darwin.c | 275 +++++------------- modules/text_renderer/freetype/freetype.c | 6 +- .../text_renderer/freetype/platform_fonts.h | 7 +- 4 files changed, 78 insertions(+), 212 deletions(-) diff --git modules/text_renderer/Makefile.am modules/text_renderer/Makefile.am index d3cdf754aa..4cd1d762f4 100644 --- modules/text_renderer/Makefile.am +++ modules/text_renderer/Makefile.am @@ -34,7 +34,7 @@ libfreetype_plugin_la_SOURCES += text_renderer/freetype/fonts/android.c endif if HAVE_DARWIN libfreetype_plugin_la_SOURCES += text_renderer/freetype/fonts/darwin.c -libfreetype_plugin_la_LDFLAGS += -Wl,-framework,CoreFoundation -Wl,-framework,CoreText +libfreetype_plugin_la_LDFLAGS += -Wl,-framework,Carbon endif if HAVE_FRIBIDI libfreetype_plugin_la_CPPFLAGS += $(FRIBIDI_CFLAGS) -DHAVE_FRIBIDI diff --git modules/text_renderer/freetype/fonts/darwin.c modules/text_renderer/freetype/fonts/darwin.c index 40f6f4210e..26fb33926b 100644 --- modules/text_renderer/freetype/fonts/darwin.c +++ modules/text_renderer/freetype/fonts/darwin.c @@ -1,11 +1,14 @@ /***************************************************************************** - * darwin.c : Put text on the video, using freetype2 + * freetype.c : Put text on the video, using freetype2 ***************************************************************************** - * Copyright (C) 2015 VLC authors and VideoLAN + * Copyright (C) 2002 - 2015 VLC authors and VideoLAN * $Id$ * - * Authors: Felix Paul Kühne + * Authors: Sigmund Augdal Helberg + * Gildas Bazin + * Bernie Purcell * Jean-Baptiste Kempf + * Felix Paul Kühne * Salah-Eddin Shaban * * This program is free software; you can redistribute it and/or modify it @@ -33,291 +36,93 @@ #include #include /* filter_sys_t */ -#include /* FromCFString */ -#include -#include +#include +#if !TARGET_OS_IPHONE +# include +#endif +#include /* for MAXPATHLEN */ #include "../platform_fonts.h" -char* getPathForFontDescription(CTFontDescriptorRef fontDescriptor); -void addNewFontToFamily(filter_t *p_filter, CTFontDescriptorRef iter, char *path, vlc_family_t *family, int index); - - -char* getPathForFontDescription(CTFontDescriptorRef fontDescriptor) -{ - CFURLRef url = CTFontDescriptorCopyAttribute(fontDescriptor, kCTFontURLAttribute); - if (url == NULL) - return NULL; - CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle); - if (path == NULL) { - CFRelease(url); - return NULL; - } - char *retPath = FromCFString(path, kCFStringEncodingUTF8); - CFRelease(path); - CFRelease(url); - return retPath; -} - -static CFIndex getFontIndexInFontFile(const char* psz_filePath, const char* psz_family) { - CFIndex index = kCFNotFound; - CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)psz_filePath, strlen(psz_filePath), false); - if (url == NULL) { - return kCFNotFound; - } - CFArrayRef fontDescriptors = CTFontManagerCreateFontDescriptorsFromURL(url); - if (fontDescriptors == NULL) { - CFRelease(url); - return kCFNotFound; - } - CFIndex numberOfFontDescriptors = CFArrayGetCount(fontDescriptors); - CFStringRef targetFontName = CFStringCreateWithCString(kCFAllocatorDefault, psz_family, kCFStringEncodingUTF8); - if (targetFontName == NULL) { - CFRelease(fontDescriptors); - CFRelease(url); - return kCFNotFound; - } - - for (CFIndex i = 0; i < numberOfFontDescriptors; i++) { - CTFontDescriptorRef descriptor = (CTFontDescriptorRef)CFArrayGetValueAtIndex(fontDescriptors, i); - CFStringRef familyName = (CFStringRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontFamilyNameAttribute); - CFStringRef fontName = (CFStringRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontNameAttribute); - CFStringRef displayName = (CFStringRef)CTFontDescriptorCopyAttribute(descriptor, kCTFontDisplayNameAttribute); - - if (CFStringCompare(targetFontName, familyName, kCFCompareCaseInsensitive) == kCFCompareEqualTo || - CFStringCompare(targetFontName, fontName, kCFCompareCaseInsensitive) == kCFCompareEqualTo || - CFStringCompare(targetFontName, displayName, kCFCompareCaseInsensitive) == kCFCompareEqualTo) { - index = i; - } - - CFRelease(familyName); - CFRelease(fontName); - CFRelease(displayName); - - if (index != kCFNotFound) { - break; - } - } - CFRelease(targetFontName); - CFRelease(fontDescriptors); - CFRelease(url); - return index; -} - -void addNewFontToFamily(filter_t *p_filter, CTFontDescriptorRef iter, char *path, vlc_family_t *family, int index) +#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 ) { - bool b_bold = false; - bool b_italic = false; - CFDictionaryRef fontTraits = CTFontDescriptorCopyAttribute(iter, kCTFontTraitsAttribute); - CFNumberRef trait = CFDictionaryGetValue(fontTraits, kCTFontWeightTrait); - float traitValue = 0.; - CFNumberGetValue(trait, kCFNumberFloatType, &traitValue); - b_bold = traitValue > 0.23; - trait = CFDictionaryGetValue(fontTraits, kCTFontSlantTrait); - traitValue = 0.; - CFNumberGetValue(trait, kCFNumberFloatType, &traitValue); - b_italic = traitValue > 0.03; - -#ifndef NDEBUG - msg_Dbg(p_filter, "New font: bold %i italic %i path '%s'", b_bold, b_italic, path); -#else - VLC_UNUSED(p_filter); -#endif - NewFont(path, index, b_bold, b_italic, family); - - CFRelease(fontTraits); -} + VLC_UNUSED( b_bold ); + VLC_UNUSED( b_italic ); + VLC_UNUSED( codepoint ); + FSRef ref; + unsigned char path[MAXPATHLEN]; + char * psz_path; -const vlc_family_t *CoreText_GetFamily(filter_t *p_filter, const char *psz_family) -{ - filter_sys_t *p_sys = p_filter->p_sys; + CFStringRef cf_fontName; + ATSFontRef ats_font_id; - if (unlikely(psz_family == NULL)) { - return NULL; - } + *i_idx = 0; - char *psz_lc = ToLower(psz_family); - if (unlikely(!psz_lc)) { + if( psz_fontname == NULL ) return NULL; - } - - /* let's double check if we have parsed this family already */ - vlc_family_t *p_family = vlc_dictionary_value_for_key(&p_sys->family_map, psz_lc); - if (p_family) { - free(psz_lc); - return p_family; - } - - CTFontCollectionRef coreTextFontCollection = NULL; - CFArrayRef matchedFontDescriptions = NULL; - /* we search for family name, display name and name to find them all */ - const size_t numberOfAttributes = 3; - CTFontDescriptorRef coreTextFontDescriptors[numberOfAttributes]; - CFMutableDictionaryRef coreTextAttributes[numberOfAttributes]; - CFStringRef attributeNames[numberOfAttributes] = { - kCTFontFamilyNameAttribute, - kCTFontDisplayNameAttribute, - kCTFontNameAttribute, - }; + msg_Dbg( p_filter, "looking for %s", psz_fontname ); + cf_fontName = CFStringCreateWithCString( kCFAllocatorDefault, psz_fontname, kCFStringEncodingUTF8 ); -#ifndef NDEBUG - msg_Dbg(p_filter, "Creating new family for '%s'", psz_family); -#endif + ats_font_id = ATSFontFindFromName( cf_fontName, kATSOptionFlagsIncludeDisabledMask ); - CFStringRef familyName = CFStringCreateWithCString(kCFAllocatorDefault, - psz_family, - kCFStringEncodingUTF8); - for (size_t x = 0; x < numberOfAttributes; x++) { - coreTextAttributes[x] = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, NULL, NULL); - CFDictionaryAddValue(coreTextAttributes[x], attributeNames[x], familyName); - coreTextFontDescriptors[x] = CTFontDescriptorCreateWithAttributes(coreTextAttributes[x]); - } - - CFArrayRef coreTextFontDescriptorsArray = CFArrayCreate(kCFAllocatorDefault, - (const void **)&coreTextFontDescriptors, - numberOfAttributes, NULL); - - coreTextFontCollection = CTFontCollectionCreateWithFontDescriptors(coreTextFontDescriptorsArray, 0); - if (coreTextFontCollection == NULL) { - msg_Warn(p_filter,"CTFontCollectionCreateWithFontDescriptors (1) failed!"); - goto end; - } - - matchedFontDescriptions = CTFontCollectionCreateMatchingFontDescriptors(coreTextFontCollection); - if (matchedFontDescriptions == NULL) { - msg_Warn(p_filter, "CTFontCollectionCreateMatchingFontDescriptors (2) failed!"); - goto end; - } - - CFIndex numberOfFoundFontDescriptions = CFArrayGetCount(matchedFontDescriptions); - - char *path = NULL; - - /* create a new family object */ - p_family = NewFamily(p_filter, psz_lc, &p_sys->p_families, &p_sys->family_map, psz_lc); - if (unlikely(!p_family)) { - goto end; - } - - 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 || *path == '\0') { - FREENULL(path); - continue; - } - - /* get the index of the font family in the font file */ - CFIndex fontIndex = getFontIndexInFontFile(path, psz_lc); - if (fontIndex == kCFNotFound) { - FREENULL(path); - continue; + 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 ); + + 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 ); + + 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; + } } - - addNewFontToFamily(p_filter, iter, path, p_family, fontIndex); } + CFRelease( cf_fontName ); -end: - if (matchedFontDescriptions != NULL) { - CFRelease(matchedFontDescriptions); - } - if (coreTextFontCollection != NULL) { - CFRelease(coreTextFontCollection); - } - - for (size_t x = 0; x < numberOfAttributes; x++) { - CFRelease(coreTextAttributes[x]); - CFRelease(coreTextFontDescriptors[x]); - } - - CFRelease(coreTextFontDescriptorsArray); - CFRelease(familyName); - free(psz_lc); - - return p_family; -} - -vlc_family_t *CoreText_GetFallbacks(filter_t *p_filter, const char *psz_family, uni_char_t codepoint) -{ - filter_sys_t *p_sys = p_filter->p_sys; - if (unlikely(psz_family == NULL)) { + if ( noErr != ATSFontGetFileReference( ats_font_id, &ref ) ) + { + msg_Err( p_filter, "ATS couldn't get file ref for %s", psz_fontname ); return NULL; } - vlc_family_t *p_family = NULL; - CFStringRef postScriptFallbackFontname = NULL; - CTFontDescriptorRef fallbackFontDescriptor = NULL; - char *psz_lc_fallback = NULL; - char *psz_fontPath = NULL; - - CFStringRef familyName = CFStringCreateWithCString(kCFAllocatorDefault, - psz_family, - kCFStringEncodingUTF8); - CTFontRef font = CTFontCreateWithName(familyName, 0, NULL); - uint32_t littleEndianCodePoint = OSSwapHostToLittleInt32(codepoint); - CFStringRef codepointString = CFStringCreateWithBytes(kCFAllocatorDefault, - (const UInt8 *)&littleEndianCodePoint, - sizeof(littleEndianCodePoint), - kCFStringEncodingUTF32LE, - false); - CTFontRef fallbackFont = CTFontCreateForString(font, codepointString, CFRangeMake(0,1)); - CFStringRef fallbackFontFamilyName = CTFontCopyFamilyName(fallbackFont); - - /* create a new family object */ - char *psz_fallbackFamilyName = FromCFString(fallbackFontFamilyName, kCFStringEncodingUTF8); - if (psz_fallbackFamilyName == NULL) { - msg_Warn(p_filter, "Failed to convert font family name CFString to C string"); - goto done; - } -#ifndef NDEBUG - msg_Dbg(p_filter, "Will deploy fallback font '%s'", psz_fallbackFamilyName); -#endif - - psz_lc_fallback = ToLower(psz_fallbackFamilyName); + /* i_idx calculation by searching preceding fontIDs */ + /* with same FSRef */ + { + ATSFontRef id2 = ats_font_id - 1; + FSRef ref2; + + while ( id2 > 0 ) + { + if ( noErr != ATSFontGetFileReference( id2, &ref2 ) ) + break; + if ( noErr != FSCompareFSRefs( &ref, &ref2 ) ) + break; - p_family = vlc_dictionary_value_for_key(&p_sys->family_map, psz_lc_fallback); - if (p_family) { - goto done; - } - - p_family = NewFamily(p_filter, psz_lc_fallback, &p_sys->p_families, &p_sys->family_map, psz_lc_fallback); - if (unlikely(!p_family)) { - goto done; - } - - postScriptFallbackFontname = CTFontCopyPostScriptName(fallbackFont); - fallbackFontDescriptor = CTFontDescriptorCreateWithNameAndSize(postScriptFallbackFontname, 0.); - psz_fontPath = getPathForFontDescription(fallbackFontDescriptor); - - /* check if the path is empty, which can happen in rare circumstances */ - if (psz_fontPath == NULL || *psz_fontPath == '\0') { - goto done; + id2 --; + } + *i_idx = ats_font_id - ( id2 + 1 ); } - /* get the index of the font family in the font file */ - CFIndex fontIndex = getFontIndexInFontFile(psz_fontPath, psz_fallbackFamilyName); - if (fontIndex == kCFNotFound) { - goto done; + 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 ); - addNewFontToFamily(p_filter, fallbackFontDescriptor, strdup(psz_fontPath), p_family, fontIndex); + psz_path = strdup( (char *)path ); -done: - CFRelease(familyName); - CFRelease(font); - CFRelease(codepointString); - CFRelease(fallbackFont); - CFRelease(fallbackFontFamilyName); - free(psz_fallbackFamilyName); - free(psz_lc_fallback); - free(psz_fontPath); - if (postScriptFallbackFontname != NULL) - CFRelease(postScriptFallbackFontname); - if (fallbackFontDescriptor != NULL) - CFRelease(fallbackFontDescriptor); - return p_family; + return psz_path; } +#endif diff --git modules/text_renderer/freetype/freetype.c modules/text_renderer/freetype/freetype.c index 49d121888c..704cf44223 100644 --- modules/text_renderer/freetype/freetype.c +++ modules/text_renderer/freetype/freetype.c @@ -1440,9 +1440,9 @@ static int Create( vlc_object_t *p_this ) goto error; #elif defined( __APPLE__ ) - p_sys->pf_select = Generic_Select; - p_sys->pf_get_family = CoreText_GetFamily; - p_sys->pf_get_fallbacks = CoreText_GetFallbacks; +#if !TARGET_OS_IPHONE + p_sys->pf_select = MacLegacy_Select; +#endif #elif defined( _WIN32 ) if( InitDWrite( p_filter ) == VLC_SUCCESS ) { diff --git modules/text_renderer/freetype/platform_fonts.h modules/text_renderer/freetype/platform_fonts.h index 8bd4795b98..9cfd107f18 100644 --- modules/text_renderer/freetype/platform_fonts.h +++ modules/text_renderer/freetype/platform_fonts.h @@ -164,8 +164,11 @@ const vlc_family_t *Win32_GetFamily( filter_t *p_filter, const char *psz_family #endif /* _WIN32 */ #ifdef __APPLE__ -vlc_family_t *CoreText_GetFallbacks(filter_t *p_filter, const char *psz_family, uni_char_t codepoint); -const vlc_family_t *CoreText_GetFamily(filter_t *p_filter, const char *psz_family); +#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 #endif /* __APPLE__ */ #ifdef __ANDROID__