RFR: 8278050: Armenian text isn't rendered on macOS if text layout is performed

Sergey Bylokhov serb at openjdk.java.net
Wed Dec 15 01:15:59 UTC 2021


On Wed, 1 Dec 2021 10:52:38 GMT, Dmitry Batrak <dbatrak at openjdk.org> wrote:

> The problem is related to the implementation of font fallback on macOS, specifically to the path used when text layout
> is performed, i.e. the one using `FontSubstitution` and cascade lists. `CTFontCopyDefaultCascadeListForLanguages`'s output contains an entry for the font, able to render Armenian text ('NotoSansArmenian-Regular'), but `CFont.createCompositeFont` cannot find this font amongst registered fonts, and the entry is skipped, resulting in broken rendering.
> System font loading (performed by `CFontManager.loadNativeFonts`) relies on `[NSFontManager availableFontFamilies]`, but its output doesn't contain 'Noto Sans Armenian' (which is a family for 'NotoSansArmenian-Regular' font). 'Noto Sans Armenian' is recognized by `[NSFontManager availableMembersOfFontFamily:]` though, 'NotoSansArmenian-Regular' is contained in `[NSFontManager availableFonts]` output, and the font can be created and used normally, just like any other system font. Not sure why its family is 'hidden', maybe macOS developers wanted to limit the number of options
> displayed in font selection drop-downs.
> For reference, another cascade list item, ignored in similar way is 'NotoSansZawgyi-Regular'.
> 
> Proposed fix is to create `CFont` objects for cascade list items explicitly, if corresponding fonts are not registered. These objects are re-used between different fonts as their fallback components (to enable caching of char-to-glyph mapping), but are not made available to public font APIs.
> I've considered an alternative solution - using `[NSFontManager availableFonts]` instead of
> `[NSFontManager availableFontFamilies]` to load system fonts. Two factors complicate it though - `loadNativeFonts` will
> take more time (on my machine about 170 additional fonts will be loaded) and the order of font loading will change (which
> impacts the selection of 'preferred' plain/bold/italic/bolditalic components in `FontFamily` class). Both factors can be
> dealt with, but they make the solution more complicated and prone to regressions. For now, it seems not worth it.
> 
> I've not created a test, as it would rely on macOS providing a fallback font for Armenian script, which is not guaranteed.
> Existing tests pass fine with the fix.

src/java.desktop/macosx/classes/sun/font/CFontManager.java line 337:

> 335:             // These fonts are present in [NSFontManager availableFonts] output though,
> 336:             // and can be accessed in the same way as other system fonts.
> 337:             return fallbackFonts.computeIfAbsent(fontName, name -> new CFont(name, null));

I would like to clarify why we cannot merge the results of the availableFontFamilies and availableFonts?

-------------

PR: https://git.openjdk.java.net/jdk/pull/6633



More information about the client-libs-dev mailing list