As far as I'm aware, mpv and libass are doing the right thing (performing font lookup via CoreText), but still fail to render some Chinese text in many cases. For instance, attempting to render the character "菱" on a machine with the en-US locale will result in last-resort fallback (and tofu), as the PingFang.ttc MobileAsset isn't downloaded (and I haven't been able to find any documented way to trigger it to download). Not all rendering of Chinese text takes place on machines with a Chinese locale.
I filed FB15161959 on this subject in September, and haven't received any response.
Currently, my recommendation to work around this issue is for app developers to ship a copy of Noto Sans CJK (which is permissively licensed), though depending on the application's font management infrastructure, this might require "pseudo-installing" the font via CTFontManagerRegisterFontsForURL. CJK fonts are fairly large, so the added filesize may be prohibitive for some developers; hopefully the system-font situation will be resolved soon.
Post
Replies
Boosts
Views
Activity
The more significant issue here is that on macOS 15/iOS 18, the shipped version of PingFang is no longer a standards-compliant TTC file, but instead uses a nonstandard "hvgl" table to store glyph data (FB15161959). This means that despite CoreText being used to look up a font for Chinese text, the resulting font file cannot be parsed by cross-platform libraries. This has also been reported to Freetype, but they're unable to make progress without documentation on the new format: https://gitlab.freedesktop.org/freetype/freetype/-/issues/1281
Is there a corresponding API for macOS, or only for mobile and Catalyst apps? The setting appears to exist on Mac, but I don't see any documentation on how to make use of it.
So, how should content that may be beyond the P3 colorspace, but also doesn't come from AVPlayer or related classes, be displayed? And content uses the P3 gamut with the PQ transfer function, how should that be displayed? It seems like AVSampleBufferDisplayLayer is meant to handle these cases, but the documentation remains unclear.
I'd appreciate some clearer documentation on how these formats map to the display. If my input data is BT2020 PQ, should I map that into RGBA16Float? The maximum value there represents 10,000 nits; what should that be in a Metal texture? Should BT2020 colors simply be matrix-converted to sRGB without clipping, or should I be restricting content to P3 on my end? If MTLPixelFormatRGBA16Float is in linear light, it's not entirely clear if that provides sufficient precision to distinguish all values that a 10-bit integer PQ transfer curve can express. We've sort of had to guess at these things.