summaryrefslogtreecommitdiffstats
path: root/libass/ass_coretext.c
Commit message (Collapse)AuthorAgeFilesLines
* Support Core Text on Mac OS X 10.5Oleg Oshmyan2023-08-211-1/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* ass_coretext: add CHECK_AVAILABLE as a more portable __builtin_availablercombs2023-08-211-0/+12
| | | | | | This allows us to use weak symbols on older Clang and GCC while guarding them with __builtin_available on newer Clang to support -Werror=unguarded-availability.
* coretext: retain only CharacterSet, not whole FontDescriptorOleg Oshmyan2023-08-061-10/+7
| | | | | | | | | | This partly reverts commit d0566318ee5035ca3a4d2d65d46a80a4e3d8244c and complements the previous commit, which removed other uses of the FontDescriptor. By the way, I don't know why check_glyph returns true if !set. It's been this way since the very first ass_coretext commit, but no explanation is available, so I'm not sure this is correct.
* fontselect: eagerly compute is_postscript in get_font_infoOleg Oshmyan2023-08-061-24/+0
| | | | | | | | | | | | | | | | | | | This lets us get rid of the font format check in ass_coretext, which is not available on Mac OS X 10.5 and prerelease 10.6. This fixes https://github.com/libass/libass/issues/595, which is about 10.6 prerelease build 10A190, the last Mac OS X build available for PowerPC CPUs. A separate commit will expand on this and make us compatible with 10.5 on all CPUs. This partly reverts commit d0566318ee5035ca3a4d2d65d46a80a4e3d8244c, where eager is_postscript was replaced by lazy check_postscript because back then ass_directwrite eagerly loaded all of the system's fonts and reading is_postscript from each font slowed it down significantly. But eventually (in particular but not only because even without this it was still slow for huge font collections) ass_directwrite learnt to load fonts lazily, so there's a decent chance that this lazy check_postscript (as well as the lazy get_font_index) isn't necessary at all any more and can be removed in the future.
* fontselect: automatically read metadata from font file if neededOleg Oshmyan2021-07-101-31/+9
|
* Pass last-resort-fallback family name directly to get_font_infoOleg Oshmyan2021-07-101-32/+14
|
* fontselect, coretext: match whole extended family on fallbackOleg Oshmyan2021-06-071-34/+24
| | | | | | | | | | | | | | Currently implemented only for coretext, but other providers may/should add this later. This improves fallback font choice by considering the whole extended family. This also fixes remaining cases of Core Text fallback failure caused by differences among the names recognized by Core Text, the name we choose to return from get_fallback, and the names we seek in find_font. This partly reverts commit 152d0484e98f118d01987138695cf40579c9e297. This fixes https://github.com/libass/libass/issues/512.
* coretext: deduplicate found fonts in match_fontsOleg Oshmyan2021-06-071-1/+15
| | | | | | | | | | | We ask Core Text to match multiple name fields, and a single font may match several at once. In this case, by default, Core Text duly returns the font multiple times, and we add it to fontselect multiple times. This does not break anything, but it is a waste, so ask Core Text to deduplicate the returned list. This is supposedly available since Mac OS X 10.5. We support Core Text on 10.6+.
* coretext: check all allocation failures and release soonerOleg Oshmyan2021-04-291-32/+66
| | | | | | All Create and Copy functions create new objects, so all of them may fail. Keep using SAFE_CFRelease only in shared cleanup clauses.
* fontselect: coretext: get fallback font family name via FreeTypeOleg Oshmyan2021-04-291-7/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Since commit be0d1613f79a95073d18d96a60e1394abf9316a2, get_fallback can return a name from Core Text that is different from all names that match_fonts registers for the same font. This causes font fallback to fail as find_fonts fails to find any font having the name received from get_fallback. (Moreover, libass will keep retrying fallback for other glyphs, and the coretext match_fonts will keep readding the same fonts over and over again.) Commit 152d0484e98f118d01987138695cf40579c9e297 attempted to fix font fallback by getting a full name from Core Text instead of a family name when it was noticed that Core Text's family name can come from TT_NAME_ID_TYPOGRAPHIC_FAMILY in addition to TT_NAME_ID_FONT_FAMILY, which we fetch in get_font_info, but the problem goes deeper: Core Text can return Macintosh-platform names that don't match Microsoft-platform names, or the font might have no Microsoft-platform names at all. Furthermore, returning a full name breaks style matching: get_fallback does not know about weight, slant etc. and is expected to return a whole family of fonts that will be lazy-loaded in its entirety (if applicable) and searched through for the best stylistic match by find_fonts. To fix fallback while preserving maximum name portability in the spirit of be0d1613f79a95073d18d96a60e1394abf9316a2, use the same API in get_fallback as is used in match_fonts to look up a family name. Note: this could be more efficient if ass_get_font_info could be told to return just an arbitrary family name. This fixes https://github.com/libass/libass/issues/457.
* fontselect: coretext: ask Core Text for family name as last resortOleg Oshmyan2021-04-291-11/+45
| | | | | | | | If a font contains no recognized Microsoft-platform family names, use the family name reported by Core Text. Skip FreeType's face->family_name because it is an ASCII bastardization of a family name and may not exist at all.
* fontselect: coretext: reuse main FT_LibraryOleg Oshmyan2021-04-291-14/+8
|
* coretext: don't call strcmp to check for empty stringOleg Oshmyan2021-04-291-1/+1
|
* coretext: return full/PostScript name on fallbackOleg Oshmyan2020-10-231-9/+16
| | | | | | | | | CoreText's "family name" can use TT_NAME_ID_TYPOGRAPHIC_FAMILY names, which we ignore for compatibility with VSFilter. As a result, fallback returns a family name that we then fail to find, and fallback fails. Return a fuller name (fullname or postscriptname as appropriate) instead, which should be more reliable.
* Style-Nit: Adjust whitespacesOneric2020-07-051-1/+1
| | | | | | | - Convert tabs to spaces - Ensure one space between keywords and parenthesis - Ensure space between ')' and '{' - Trim trailing whitespace
* coretext: fix leak on errorrcombs2020-05-261-5/+6
|
* coretext: move meta var into loop and zero-initializeRodger Combs2019-11-071-4/+1
| | | | | This makes it a bit clearer that the struct's contents won't be reused across multiple iterations
* coretext: fix error handling in get_font_fileMarvin Scholz2019-11-071-1/+7
| | | | | | | | Fixes a crash in case a font does not has kCTFontURLAttribute, which is the case for example on macOS 10.15.1 for the ".AppleSymbolsFB" font. Fix #358
* coretext: replace CT attr reads with freetype lookupsRodger Combs2019-09-261-112/+24
| | | | | This makes results much more consistent with other platforms, particularly around cases where fonts have multiple conflicting names.
* coretext: use weight steps from macOS SDKRodger Combs2019-09-261-6/+26
|
* coretext: fix reading weights of some fontsRodger Combs2019-09-261-4/+4
| | | | | | | Some fonts have weights that can be expressed more precisely as doubles than as floats. In these cases, when writing to a float, CFNumberGetValue will set the value to the closest approximation, but return false (so we'd just clobber whatever it set with 0). Easy fix: just store to a double instead.
* Support Core Text on earlier versions of Mac OS XOleg Oshmyan2017-10-311-0/+5
| | | | | | | | | | | | | | | | | | | Loosely based on behdad/harfbuzz@b96af03c20e46105982b3608b608614403540661. Prefer to link against ApplicationServices to maximize the portability of binaries built on newer versions of macOS. The symbol kCTFontURLAttribute, which is checked in this commit, was introduced in Mac OS X 10.6, the latest of any Core Text symbols that we use. It is essential to our Core Text font provider, so this is the earliest version of Mac OS X where we can support this font provider. The TARGET_OS_IPHONE conditional that this commit adds is necessary to continue supporting iOS in addition to supporting old Mac OS X. On iOS, CoreText.h *must* be included to use Core Text, whereas on old Mac OS X, CoreText.h is not directly accessible and ApplicationServices.h must be used. On modern macOS, either header works. This conditional is also used in HarfBuzz.
* coretext: don't use a variable-length arrayOleg Oshmyan2017-10-311-1/+1
| | | | | This fixes compilation with GCC, which complains that a variable-length array declaration must not have an initializer.
* coretext: fix NULL CFStringRef dereferencewm42015-12-091-0/+2
|
* coretext: don't fetch character set when it isn't neededOleg Oshmyan2015-12-011-3/+3
| | | | | This avoids unnecessary work and fixes a memory leak: the character set wasn't released when code == 0.
* coretext: don't forget to release font format attributeOleg Oshmyan2015-11-071-0/+2
|
* fontselect: replace is_postscript flag with check_postscript functionOleg Oshmyan2015-11-041-22/+25
| | | | | | | | | | | | | | | | | | | | | | | DirectWrite does not provide fast access to the is_postscript flag, requiring each font to be loaded before its format can be determined. Eagerly doing this for every installed font can be quite slow, on the order of seconds. To improve performance, ask the font provider for this information only when it is actually needed, i.e. when one of the font's full names or its PostScript name matches a requested font name and we need to know whether to accept this match. The return value of check_postscript is not cached in this commit. This makes repeated calls slower than accessing is_postscript was. This should not be a problem, but if it is, the value can be cached (or precomputed) by font providers in their font private data. This commit also potentially increases the memory usage of some font providers by retaining data structures needed to implement check_postscript in their font private data. This should not be a problem either, but if it is, the value of check_postscript can be precomputed by all providers other than DirectWrite.
* fontselect: use stdbool.h wherever appropriateOleg Oshmyan2015-10-231-3/+3
|
* fontselect: find fonts with PostScript outlines by PostScript nameOleg Oshmyan2015-10-231-0/+15
| | | | | | | Fonts without PostScript outlines (such as TrueType fonts) are unaffected, and their PostScript names continue to be ignored when searching for fonts. This matches the behavior of GDI and hence VSFilter.
* fontselect: move PostScript name into ASS_FontProviderMetaDataOleg Oshmyan2015-10-211-5/+6
|
* Fully fix compilation with MSVC/ICLOleg Oshmyan2015-09-171-0/+1
| | | | | | | | | As before, this does not add any build system support: a config.h file and a project must still be manually created (or the compiler can be run manually instead of using a project). Signed-off-by: Grigori Goronzy <greg@kinoho.net> Signed-off-by: Oleg Oshmyan <chortos@inbox.lv>
* directwrite, coretext: implement substitutionsGrigori Goronzy2015-09-021-0/+14
| | | | | This adds simple and sensible substitutions for generic font family names. A helper function is introduced to reduce code duplication.
* coretext: use SAFE_CFRelease() for robustnesswm42015-09-011-17/+18
| | | | | | CFRelease(NULL) can crash. While we're still not sure which CoreText API calls can fail etc. (thanks Apple), this should fix a couple of theoretically possible crashes.
* coretext: fix sizeof vs. strlenwm42015-09-011-2/+1
|
* coretext: always use lazy loadingwm42015-09-011-29/+1
| | | | | We already decided that eager loading is too slow. No need to keep multiple code paths around.
* fontselect: simplify get_fallback signaturewm42015-09-011-5/+4
| | | | | Apparently we only need the font family (and even that isn't used in all font providers). Drop the others.
* fontselect: use designated initializerswm42015-09-011-10/+5
| | | | | | Tired of matching the names and order of the callbacks in my head. While we're at it, also give some of the callbacks better names.
* coretext: implement GetFallbackFuncStefano Pigozzi2015-09-011-1/+25
|
* configure: proper configure switches for DirectWrite and CoreTextwm42015-08-281-4/+0
| | | | | Also, remove the ass_coretext.c conditional compilation hack, and fix Makefile.am instead.
* fontselect: add fallback and substitution callbacksGrigori Goronzy2015-07-101-2/+4
| | | | | Add callbacks to introduce more sane fallback handling and font alias substitutions.
* fontselect: expose a fontprovider selection APIStefano Pigozzi2015-07-101-1/+2
| | | | | | | | | Allow the user of libass to select the font provider from ass_set_fonts. This API change actually doesn't break client code which was passing `fc=1`; now the same value will autodetect a usable font provider. Also add an api to list available font providers as that is useful for client code to show drop down menus with a font provider to choose from.
* coretext: fix conversion from CFStringRef to utf8 bufferStefano Pigozzi2015-07-101-3/+5
| | | | | | The code incorrectly assumed that the utf8 characters could always be represented with only one byte. This commit queries CFStringRef instances for the actual amount of bytes needed.
* coretext: also lazy load fonts based on Family and PostScript namesStefano Pigozzi2015-07-101-8/+21
| | | | | Previously, the lazy load of fonts was only using display name. Also use the other names available through the CoreText API (FamilyName and PostScriptName).
* fontselect: coretext: allow to match fontname using the providerStefano Pigozzi2015-07-101-3/+58
| | | | | | | | | | | | | | | | | | | | | | Not all APIs cache everything the same way that fontconfig does. This allows to first perform a match based on the font name and then score the matched fonts using the common code using and in memory database approach. The benefit is the application doesn't have to load all of the fonts and query for weight, slant, width, path and fullnames. I left both code paths inside ass_coretext.c. This allows to test matching problems and have a term of comparison with the slower implementation. To activate it one just has to flip the CT_FONTS_EAGER_LOAD define to 1. Here are some benchmarks with a pretty typical OS X font library of ~600 fonts and using Libass's test program to load a script with 'Helvetica Neue': CT_FONTS_EAGER_LOAD=0 0.04s user 0.02s system 79% cpu 0.081 total CT_FONTS_EAGER_LOAD=1 0.12s user 0.06s system 44% cpu 0.420 total
* fontselect: coretext: allow selection based on PostScript nameStefano Pigozzi2015-07-101-5/+10
| | | | | | | | | | | Up until now fontselect used the face index to identify which font to load from a font collection. While this pretty convenient when using something freetype based like fontconfig, it seems to be somewhat freetype specific. CoreText uses the PostScript name as the unique identifier of a font. This commit allows to use that instead of the index to decide which face to open with FT_New_Face. To use the PostScript name the provider must return a -1 index and the PostScript name.
* fontselect: implement a coretext font providerStefano Pigozzi2015-07-101-0/+217
Fontconfig is known to be very slow on OS X and Windows, this has to do with the extremely prohibitive cache times (which are getting even longer with latest versions of Fontconfig). This commits starts to address the problem by using CoreText on OS X to load the font data. The commit uses the simplest possible approach to load all of the data in memory and then use it to match. This causes a somewhat slow startup time (around ~400ms on my i7) but it is already better than waiting *minutes* for Fontconfig to cache the fonts data. A later commit will improve the speed of the match by using a hybrid approach that lazy loads in the libass database only the necessary fonts.