-
Notifications
You must be signed in to change notification settings - Fork 24k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Android React Text Component includeFontPadding:false incorrect height #14606
Comments
@hramos Can you provide a reason for closing the issue? Does it need more information? |
I'd like to reopen this issue as I believe font rendering remains to be one of the biggest reasons for cross-platform differences across iOS and Android and this is an important thing to explore. |
We're tracking similar issues in react-native-svg here: software-mansion/react-native-svg#362 and here software-mansion/react-native-svg#377 I've fixed most of the issues. Font rendering, ligatures, kerning, spacing etc. has a surprisingly big effect on the user / reading experience, especially if there are large amounts of text or larger font-sizes on headers and labels etc. |
#14609 is a PR to fix this issue |
Summary: Overview - This PR resolves the issue described in #14606. This PR makes Text components take into account the includeFontPadding property when calculating their size. Background - Currently, on Android, when includeFontPadding is set to false, the React Text component does not adjust its height. This makes it difficult to lay out other components at a precise spacing relative to a Text component. iOS calculates the height of a UILabel based on the font's descent + ascent. Android lets you choose whether to calculate the height of a TextView based on the font's top + bottom (includeFontPadding=true) or ascent + descent (includeFontPadding=false). In order for a text component to be the same size on iOS and Android (relative to the rest of the layout in points and dips), one should set includeFontPadding=false on Android - but the React Text component needs to take this property into account when sizing itself for this to work. Please see this stack overflow post for a visual explanation of the difference between a font's ascent/descent and top/bottom - https://stackoverflow.com/questions/27631736/meaning-of-top-ascent-baseline-descent-bottom-and-leading-in-androids-font Testing - Please see the attached screenshots to see the height difference of a Text component with this PR when includeFontPadding is true vs false. The font I am using has an ascent + descent = em-size so that the height of the Text component will be equal to the font-size for a single line of text. This is to clearly show the additional height that includeFontPadding=true adds to the Text component. For Text components that are styled in the same way, When includeFontPadding=true, height = ~29.714 dips When includeFontPadding=false, height= 24 dips <img width="342" alt="includefontpaddingtrue" src="https://user-images.githubusercontent.com/1437344/27299391-3eec9de0-54fa-11e7-81d5-d0aeb40e8e27.png"> <img width="346" alt="includefontpaddingfalse" src="https://user-images.githubusercontent.com/1437344/27299401-45c95248-54fa-11e7-98d7-17dd152d3cb8.png"> Closes #14609 Reviewed By: AaaChiuuu Differential Revision: D5587602 Pulled By: achen1 fbshipit-source-id: 6d2f12ba72ec7462676645519cd27820279278eb
#14609 was merged |
On Android, when includeFontPadding is set to false, the React Text component does not adjust its height. This makes it difficult to lay out other components at a precise spacing relative to a Text component.
For the native TextView component, the height is different depending on the value of includeFontPadding-
When includeFontPadding is set to true, the height of the TextView is based on abs(FontMetrics.top) + abs(FontMetrics.bottom).
When includeFontPadding to set to false, the height of the TextView is based on abs(FontMetrics.ascent) + abs(FontMetrics.descent).
This is happening because in ReactTextShadowNode.java, includeFontPadding is hardcoded to true when passing parameters to StaticLayout and BoringLayout. This seems like an easy fix.
An example from the measure function in ReactTextShadowNode.java -
private final YogaMeasureFunction mTextMeasureFunction = new YogaMeasureFunction() {
The text was updated successfully, but these errors were encountered: