revery-ui / revery

:zap: Native, high-performance, cross-platform desktop apps - built with Reason!
https://www.outrunlabs.com/revery/
MIT License
8.06k stars 196 forks source link

fix(font-fallback): Hang when trying to shape 'flaming heart' emoji #1007

Closed bryphe closed 3 years ago

bryphe commented 3 years ago

Issue: While working on https://github.com/onivim/oni2/pull/2563, I observed a hang in the editor some emojis, like the 'heart on fire' emoji:

2764 FE0F 200D 1F525                                   ; fully-qualified     # ❤️‍🔥 E13.1 heart on fire

From these cases: https://unicode.org/Public/emoji/13.1/emoji-test.txt

Defect: We use a counter to break cycles in the font-fallback resolution strategy (attempts), so that we don't get in an infinite loop when we shape, fallback to a font, and then try shaping again.

However, in this case, we had a hole spanning multiple unicode characters - the heart (2764) would resolve correctly, but then the modifiers would not discover a fallback font. In this case, we were resetting the attempts counter, and would fail to completely resolve the hole, causing us to spin.

The rendering still isn't completely correct for this, as we use unresolved glyphs for the modifiers. We should be smart enough to recognize grapheme clusters and that these modifiers should not be drawn as unresolved glyphs. This fix, though, does prevent us from hanging in this case.

Fix: Don't reset attempts in this case. Add test case covering this sort of emoji.

github-actions[bot] commented 3 years ago

I have updated your lock dirs and formatted the code. Please @bryphe pull the last commit before pushing any more changes.