Open rcombs opened 2 years ago
How does this relate to #312?
See also my own plans/hopes for reworked font providers in https://github.com/libass/libass/pull/511#issuecomment-873572826.
First, we should attempt to find a match using memory fonts only, then search system fonts.
We already do this, and we are too eager to avoid system fonts; see #509. In the sense that this is incompatible with VSFilter: it always merges attached fonts with system fonts. Of course, one could argue that it’s undesirable for script portability etc., but that’s when the fabled authoring mode comes up, and we’ve generally stuck to striving for VSFilter compatibility in this respect as far as each font provider backend allows.
These should really be separate lists.
Agree.
What text should we use if
code
== 0? Maybe" "
?
Yeah, I’m thinking of U+0020 SPACE, too. It’s a very ubiquitous glyph, and even HarfBuzz uses it for rendering invisible characters by default.
When searching system fonts, we should give the font selection mechanism an opportunity to perform a complete match and return a single font (path/stream + name/ID) directly, rather than […] enter
ASS_FontProviderMetaData
(Correct me if I got that abridgement wrong.)
We could load the file at the given path and read & return all fonts from it, with ASS_FontProviderMetaData
and all. This would trivially work for single-font files and could be extra beneficial for single-family multiple-font collection files, where we could then (in our usual manner) refine the result by attributes other than the name.
This replaces #312. It has the downside of only working on recent-ish Android, but consumers that want to support older versions can point a fontconfig .conf file at /system/fonts
and get better performance anyway. I don't like #312's approach, both because it relies on internal data that's explicitly stated not to be meant for application usage, and because it individually opens and loads every single installed font, which is problematic performance-wise.
The concept I'm suggesting here seems to be more or less the same as what you described in #511, so I think we're more or less on the same page here.
- There's no way to get a list of fonts that matched a name;
AFontMatcher_match
always returns a single font.
A user opened this issue: [Feature Request] Be able to get all the font in a FontFamily. If google implement it, it would resolve this problem.
Note that Android now supports if (__builtin_available(android 29, *))
and weak linking, just like on Apple platforms. This means we can define __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__
and build with -Werror=unguarded-availability
, and skip all the dlsym
rigamarole. This should work regardless of runtime android version (or target version), and just requires NDK r23 or newer at build-time.
It has the downside of only working on recent-ish Android, but consumers that want to support older versions can point a fontconfig .conf file at
/system/fonts
and get better performance anyway.
Just as a side note. I used FindSystemFontsFilename and it actually retrieve font not only in /system/fonts
. It also retrieved font in /product/fonts
. FindSystemFontsFilename use ASystemFontIterator from the NDK. But, my phone is under Android 14 (a.k.a API 34), so fonts in /product/fonts
may only exist on recent android version. It doesn't seems documented. Actually, it is a bit documented here, but it doesn't say in which version it was introduced
The Android NDK functions applicable to font selection are documented here: https://developer.android.com/ndk/reference/group/font
Using this API conditionally depending on the API's existence should be fairly easy using something like this:
The hard parts come from the API's limitations:
AFontMatcher_match
always returns a single font.AFontMatcher_match
requires at least 1 character.AFont
only provides a path and index.So, I think there are a few major changes that'll be needed here:
code
== 0? Maybe" "
?)This means that Provider fonts may never enter
ASS_FontProviderMetaData
, or would only enter a secondary internal list that isn't used for our internal first-pass matching.This mechanism is entirely reasonable for fallback/unstyled cases, but isn't suitable for authoring. In authoring mode (…a thing we should have), we should fall back on fontconfig, or the slow-but-cross-platform "load every font on the system" method. This probably isn't particularly relevant to Android, but we may want to transition other platforms to this new mechanism for performance and locale-handling reasons.
Any thoughts?