iOS Typography: Inconsistent Ligature Rendering
Description
Behavior: react-native-svg Text components render undesired ligatures in iOS, but does not in Android or Web. Expected behavior: Text renders the text passed to it and is the same across iOS, Android, and Web.
Steps to reproduce
- Use a font that has good ligatures support, such as Roboto.
- Render svg Text
キロ, メートル costonin iOS, web, and Android - 🎯 Notice that in iOS, the japanese text is collapsed into a combined character, and in Coston, the s and t are combined. These are not the correct values.
Snack or a link to a repository
https://github.com/coston/react-native-svg-victory-2912
SVG version
15.9.0
React Native version
0.76.2
Platforms
iOS
Workflow
Expo Dev Client
Device
iOS simulator
Device model
iPhone SE (3rd Generation) iOS 18.1
Acknowledgements
Yes
This issue was first seen in https://github.com/FormidableLabs/victory/issues/2912
The goal is for iOS to not show discretionary ligatures, by default, which is the normal iOS setting. Android is not showing discretionary ligatures.
For some reason, setting the iOS NSLigatureAttributeName value to 1 in react-native-svg code still renders discretionary ligatures (2). I'm not sure what i'm overlooking in this case.
For anyone following along, I have a demo of how the NSLigatureAttributeName values render ligatures here: https://github.com/coston/NSLigatureAttributeName-demo
I was having the same issue on iOS where text like キロ turned into ㌔ and coston combined the st ligature. It seems this happens because iOS (CoreText) automatically enables font ligatures, while Android and Web do not.
What worked for me was adding fontVariantLigatures="none" to the <Text> component:
<Text fontVariantLigatures="none">
キロ メートル coston
</Text>
After that, the text rendered as expected on iOS without those unwanted ligatures.