summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg Oshmyan <chortos@inbox.lv>2023-08-06 04:57:20 +0300
committerOleg Oshmyan <chortos@inbox.lv>2023-08-21 04:11:57 +0300
commit5c15c883a4783641f7e71a6a1f440209965eb64f (patch)
tree22506f26940deb3916b9a320e7d4485f2f58ecc1
parent847af2a1ce67cc2ac0db1252f41ee99ff724b05b (diff)
downloadlibass-5c15c883a4783641f7e71a6a1f440209965eb64f.tar.bz2
libass-5c15c883a4783641f7e71a6a1f440209965eb64f.tar.xz
Support Core Text on Mac OS X 10.5
Based on the logic in HarfBuzz's hb-coretext. See: 1. https://github.com/harfbuzz/harfbuzz/pull/952 2. https://github.com/harfbuzz/harfbuzz/pull/1180 Core Text was introduced in 10.5, so this is as far back as we can go. Tested on ppc32 10.5.8 in: https://github.com/libass/libass/issues/595#issuecomment-1324548120 Manrope Regular failed to be selected by full name, but other fonts (including other faces of Manrope) worked fine, so this should be good enough to avoid requiring Fontconfig. I have tested that the code in the 10.5-compatible branch still works on 10.13.6 (the newest macOS instance I have access to), but the API involved is officially "deprecated" and produces deprecation warnings during compilation unless the build's deployment target is set to a version below 10.8. In addition, it's not unimaginable that it might work worse in some specific situations now or in the future: for example, it uses FSRef, which, according to the docs, is "designed to work with 32-bit inode numbers", which "may result in performance issues" on newer systems. As far as I'm aware, Apple doesn't tend to remove APIs/ABIs completely except when combined with architecture changes, but it seems the overall safest course of action is: * to prefer the newer API if it is available at runtime, * and to avoid referencing the older API at all if it's known at compile-time to be unnecessary. To nearly maximize build-environment compatibility, use Availability.h and CHECK_AVAILABLE: * Recent versions of Apple's compiler support __builtin_available for OS version detection, and so does modern non-Apple Clang. This is what Apple recommends nowadays. However, none of Apple's official compilers on macOS up to 10.10 have had this builtin, and no third-party compilers besides Clang have ever had it. Non-Clang compilers may have issues with Apple's more recent SDK headers anyway, but they're perfectly viable with older SDK releases and all the more likely to be used when the build is being performed on an older machine, e. g. when targeting that same machine, which is precisely where the 10.5-compatible code is most likely to be relevant. On 10.5 or nearby versions, the build is most likely to use one of Apple's old compilers or a custom-built modern upstream GCC. Apple's older method of checking for availability at runtime is to check whether the symbol's address is NULL, which works in all of Apple's compilers and in upstream Clang and GCC. We implement this in our CHECK_AVAILABLE macro. * There are multiple ways to determine whether the newer symbol is declared at all. To keep it simple, avoid a configure check and stick to a simple macro check. In older versions of Apple's SDK, Core Text headers have reacted to "Mac OS X version max allowed" control-knob macros and marked newer APIs "unavailable" (making any use of them a compilation error) even if they were known to that SDK. However, the exact macros differ between SDK versions, and this mechanism (unlike the "version min required") has apparently never been exposed in compiler/IDE knobs and possibly not publicized at all. Newer SDKs also no longer mark symbols unavailable in any case. So do the simplest thing and just check for the existence of a macro that was introduced in the same SDK version. * In 10.5-10.6 SDKs, Core Text used AvailabilityMacros.h and its MAC_OS_X_VERSION_MIN_REQUIRED; in later versions, it switched to Availability.h and its __MAC_OS_X_VERSION_MIN_REQUIRED with two leading underscores. Both headers are available since 10.5, and Availability.h is more flexible as it has version iOS macros in addition to macOS, which we may need for other APIs in the future, so just use Availability.h.
-rw-r--r--configure.ac4
-rw-r--r--libass/ass_coretext.c24
2 files changed, 25 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 012478a..c616f3a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -146,7 +146,7 @@ AS_IF([test "x$enable_coretext" != xno], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM( dnl# First test for legacy include
[[#include <ApplicationServices/ApplicationServices.h>]],
- [[CTFontDescriptorCopyAttribute(NULL, kCTFontURLAttribute);]]
+ [[CTFontDescriptorCopyAttribute(NULL, kCTFontNameAttribute);]]
)
], [
pkg_libs="$pkg_libs -framework ApplicationServices -framework CoreFoundation"
@@ -158,7 +158,7 @@ AS_IF([test "x$enable_coretext" != xno], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM( dnl# Otherwise check newer include style
[[#include <CoreText/CoreText.h>]],
- [[CTFontDescriptorCopyAttribute(NULL, kCTFontURLAttribute);]]
+ [[CTFontDescriptorCopyAttribute(NULL, kCTFontNameAttribute);]]
)
], [
pkg_libs="$pkg_libs -framework CoreText -framework CoreFoundation"
diff --git a/libass/ass_coretext.c b/libass/ass_coretext.c
index 7009264..ba40cca 100644
--- a/libass/ass_coretext.c
+++ b/libass/ass_coretext.c
@@ -19,6 +19,7 @@
#include "config.h"
#include "ass_compat.h"
+#include <Availability.h>
#include <CoreFoundation/CoreFoundation.h>
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
@@ -88,7 +89,28 @@ static bool check_glyph(void *priv, uint32_t code)
static char *get_font_file(CTFontDescriptorRef fontd)
{
- CFURLRef url = CTFontDescriptorCopyAttribute(fontd, kCTFontURLAttribute);
+ CFURLRef url = NULL;
+ if (false) {}
+#ifdef __MAC_10_6
+ // Declared in SDKs since 10.6, including iOS SDKs
+ else if (CHECK_AVAILABLE(kCTFontURLAttribute, macOS 10.6, *)) {
+ url = CTFontDescriptorCopyAttribute(fontd, kCTFontURLAttribute);
+ }
+#endif
+#if !TARGET_OS_IPHONE && (!defined(__MAC_10_6) || __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_6)
+ // ATS is declared deprecated in newer macOS SDKs
+ // and not declared at all in iOS SDKs
+ else {
+ CTFontRef font = CTFontCreateWithFontDescriptor(fontd, 0, NULL);
+ if (!font)
+ return NULL;
+ ATSFontRef ats_font = CTFontGetPlatformFont(font, NULL);
+ FSRef fs_ref;
+ if (ATSFontGetFileReference(ats_font, &fs_ref) == noErr)
+ url = CFURLCreateFromFSRef(NULL, &fs_ref);
+ CFRelease(font);
+ }
+#endif
if (!url)
return NULL;
CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);