RFR: 8353230: Emoji rendering regression after JDK-8208377 [v2]
Daniel Gredler
dgredler at openjdk.org
Mon May 26 18:55:31 UTC 2025
> It looks like this regression actually fits into a longer series of fixes / regressions in this area:
>
> - [JDK-4517298](https://bugs.openjdk.org/browse/JDK-4517298) fixed metrics for zero-width characters, but broke some ligatures / glyph substitutions
> - [JDK-7017058](https://bugs.openjdk.org/browse/JDK-7017058) fixed the ligatures / glyph substitutions, but broke some zero-width metrics
> - [JDK-8208377](https://bugs.openjdk.org/browse/JDK-8208377) fixed some metrics and rendering for zero-width characters, but broke some ligatures / glyph substitutions
> - Now, with this PR, we aim to fix the ligatures without re-breaking zero-width metrics and display
>
> We have two different types of use cases pulling `CharToGlyphMapper` in two different directions: the users who need raw, untransformed glyph info, and the users who need normalized / transformed glyph info.
>
> It looks to me like, in the current code base, the only `CharToGlyphMapper` user which requires raw font data is HarfBuzz (explicitly confirmed with the HarfBuzz team here: https://github.com/harfbuzz/harfbuzz/discussions/5234).
>
> The regression mechanism at play here is that the HarfBuzz font callbacks are currently providing HarfBuzz with transformed glyph info (e.g. ZWJ -> INVISIBLE_GLYPH_ID), which prevents HarfBuzz from recognizing and applying the correct font GSUB substitutions (which involve ZWJ).
>
> In order to fix this without (yet again) breaking metrics and display behavior elsewhere, I've added two methods to `CharToGlyphMapper` which provide access to raw glyph info, to be used by the HarfBuzz font callbacks: `charToGlyphRaw(int)` and `charToVariationGlyphRaw(int)`.
>
> Note two intricacies related to `CompositeGlyphMapper`:
> 1. We need to be careful to only cache raw (untransformed) values, to avoid conflicts between requests for a raw version of a glyph and a transformed version of the same glyph. Another option would have been two separate caches, but I don't think that's necessary.
> 2. Consumers who are using `CompositeGlyphMapper.SLOTMASK` to check glyph slots (e.g. `FontRunIterator` and `CTextPipe`) will "see" invisible glyphs as having come from slot 0. This isn't new, and I think it's OK, but something to be aware of.
>
> The glyph cache handling in `CCharToGlyphMapper` (for macOS) also requires care to avoid mixing value types.
>
> Please also note that I'm not sure if the tweak to `sunFont.c` is being tested, since FFM is being used by default for HarfBuzz integration. (Is there a plan to remove...
Daniel Gredler has updated the pull request with a new target base due to a merge or a rebase. The pull request now contains three commits:
- Merge branch 'master' into JDK-8353230
- Finish macOS implementation
- Differentiate CharToGlyphMapper users who want raw vs normalized glyph info
-------------
Changes: https://git.openjdk.org/jdk/pull/24412/files
Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=24412&range=01
Stats: 305 lines in 10 files changed: 229 ins; 27 del; 49 mod
Patch: https://git.openjdk.org/jdk/pull/24412.diff
Fetch: git fetch https://git.openjdk.org/jdk.git pull/24412/head:pull/24412
PR: https://git.openjdk.org/jdk/pull/24412
More information about the client-libs-dev
mailing list