Skip to content
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

Fixed dynamic behavior of <Text adjustsFontSizeToFit={true}> on Android #31538

Closed
wants to merge 1 commit into from

Conversation

shergin
Copy link
Contributor

@shergin shergin commented May 17, 2021

Summary

This PR fixes #30717, a bug in <Text adjustsFontSizeToFit={true}> implementation that prevents it from adjusting text size dynamically on Android.

The way adjustsFontSizeToFit was implemented in #26389 (and the design of ReactTextShadowNode) implies that Yoga will call onMeasure on every size change of a <Text> component, which is actually not the case (Yoga can cache the results of the measures, call the function multiple times or do not call at all inferring the size from the size constraints). The implementation of adjustsFontSizeToFit computes the adjusted string inside the measure function and then eventually passes that to the view layer where it's being rendered.

The proper fix of this issue requires the full redesign of the measure and rendering pipelines and separating them, and that... would be too invasive. And, I believe, this issue is already fixed in Fabric where this part is already designed this way.

Instead, this diff implements a small workaround: if adjustsFontSizeToFit is enabled, we manually dirty the Yoga node and mark the shadow node updated to force remeasuring.

Changelog

[Android] [Fixed] - Fixed dynamic behavior of on Android

Test Plan

text-adjustments-android.mov

This PR fixes facebook#30717, a bug in `<Text adjustsFontSizeToFit={true}>` implementation that prevents it from adjusting text size dynamically on Android.

The way `adjustsFontSizeToFit` was implemented in facebook#26389 (and the design of ReactTextShadowNode) implies that Yoga will call `onMeasure` on every size change of a `<Text>` component, which is actually not the case (Yoga can cache the results of the measures, call the function multiple times or do not call at all inferring the size from the size constraints). The implementation of `adjustsFontSizeToFit` computes the adjusted string inside the measure function and then eventually passes that to the view layer where it's being rendered.

The proper fix of this issue requires the full redesign of the measure and rendering pipelines and separating them, and that... would be too invasive. And, I believe, this issue is already fixed in Fabric where this part is already designed this way.

Instead, this diff implements a small workaround: if `adjustsFontSizeToFit` is enabled, we manually dirty the Yoga node and mark the shadow node updated to force remeasuring.
@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 17, 2021
@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
ios - universal n/a --

Base commit: ebc89bf

@analysis-bot
Copy link

Platform Engine Arch Size (bytes) Diff
android hermes arm64-v8a 9,273,947 -125
android hermes armeabi-v7a 8,790,510 -138
android hermes x86 9,735,443 -123
android hermes x86_64 9,701,507 -137
android jsc arm64-v8a 10,881,576 +50
android jsc armeabi-v7a 10,391,170 +39
android jsc x86 10,909,799 +46
android jsc x86_64 11,517,759 +25

Base commit: ebc89bf

@facebook-github-bot
Copy link
Contributor

@yungsters has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

facebook-github-bot pushed a commit that referenced this pull request Jun 1, 2021
Summary:
Creates a new RNTester example to verify #31538 (D28631465).

Changelog:
[Android][Added] - RNTester example for adjusting text with dynamic layout.

Reviewed By: kacieb

Differential Revision: D28779870

fbshipit-source-id: 5297a823645d1e9e35d4c86b491f3c225ecc9543
@sota000 sota000 added this to Needs Triage in React Native Pull Requests via automation Jul 27, 2021
@yungsters yungsters moved this from Needs Triage to Imported for Internal Review in React Native Pull Requests Jul 28, 2021
@yungsters yungsters self-assigned this Jul 28, 2021
React Native Pull Requests automation moved this from Imported for Internal Review to Closed Aug 25, 2021
@facebook-github-bot
Copy link
Contributor

@yungsters merged this pull request in 5902152.

@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Aug 25, 2021
alfonsocj pushed a commit to alfonsocj/react-native that referenced this pull request Feb 17, 2022
facebook-github-bot pushed a commit that referenced this pull request Feb 17, 2022
…tely (#33135)

Summary:
Fixes the infinite loop explained in the issue #33129 by reverting commit  5902152. PR #31538.

`onCollectExtraUpdates` is part of the node update cycle. By marking the node as updated `markUpdated()` in `onCollectExtraUpdates` we are restarting the update infinitely.

Unfortunately, reverting this PR also reintroduces the original issue #30717 which IMO is minor compared to the infinite loop.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fixed] - Text with adjustsFontSizeToFit changes the text layout infinitely

Pull Request resolved: #33135

Test Plan:
I added a console.log to the Text `onTextLayout` in [packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js ](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js) to see if the infinite loop is gone.

![image](https://user-images.githubusercontent.com/3791120/154523914-e6aa7cf5-7a1c-488f-a392-898f4c85a833.png)

![Screen Shot 2022-02-17 at 11 20 31 AM](https://user-images.githubusercontent.com/3791120/154524274-880c3bed-d2c6-456b-8947-42e75793c424.jpg)

```

Reviewed By: ShikaSD

Differential Revision: D34310218

Pulled By: lunaleaps

fbshipit-source-id: 0d40f49d15c562ec25983145897bd95dc182f897
ShikaSD pushed a commit that referenced this pull request Feb 22, 2022
…tely (#33135)

Summary:
Fixes the infinite loop explained in the issue #33129 by reverting commit  5902152. PR #31538.

`onCollectExtraUpdates` is part of the node update cycle. By marking the node as updated `markUpdated()` in `onCollectExtraUpdates` we are restarting the update infinitely.

Unfortunately, reverting this PR also reintroduces the original issue #30717 which IMO is minor compared to the infinite loop.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fixed] - Text with adjustsFontSizeToFit changes the text layout infinitely

Pull Request resolved: #33135

Test Plan:
I added a console.log to the Text `onTextLayout` in [packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js ](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js) to see if the infinite loop is gone.

![image](https://user-images.githubusercontent.com/3791120/154523914-e6aa7cf5-7a1c-488f-a392-898f4c85a833.png)

![Screen Shot 2022-02-17 at 11 20 31 AM](https://user-images.githubusercontent.com/3791120/154524274-880c3bed-d2c6-456b-8947-42e75793c424.jpg)

```

Reviewed By: ShikaSD

Differential Revision: D34310218

Pulled By: lunaleaps

fbshipit-source-id: 0d40f49d15c562ec25983145897bd95dc182f897
ShikaSD pushed a commit that referenced this pull request Feb 24, 2022
…tely (#33135)

Summary:
Fixes the infinite loop explained in the issue #33129 by reverting commit  5902152. PR #31538.

`onCollectExtraUpdates` is part of the node update cycle. By marking the node as updated `markUpdated()` in `onCollectExtraUpdates` we are restarting the update infinitely.

Unfortunately, reverting this PR also reintroduces the original issue #30717 which IMO is minor compared to the infinite loop.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fixed] - Text with adjustsFontSizeToFit changes the text layout infinitely

Pull Request resolved: #33135

Test Plan:
I added a console.log to the Text `onTextLayout` in [packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js ](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js) to see if the infinite loop is gone.

![image](https://user-images.githubusercontent.com/3791120/154523914-e6aa7cf5-7a1c-488f-a392-898f4c85a833.png)

![Screen Shot 2022-02-17 at 11 20 31 AM](https://user-images.githubusercontent.com/3791120/154524274-880c3bed-d2c6-456b-8947-42e75793c424.jpg)

```

Reviewed By: ShikaSD

Differential Revision: D34310218

Pulled By: lunaleaps

fbshipit-source-id: 0d40f49d15c562ec25983145897bd95dc182f897
Saadnajmi pushed a commit to Saadnajmi/react-native-macos that referenced this pull request Jan 15, 2023
…tely (facebook#33135)

Summary:
Fixes the infinite loop explained in the issue facebook#33129 by reverting commit  5902152. PR facebook#31538.

`onCollectExtraUpdates` is part of the node update cycle. By marking the node as updated `markUpdated()` in `onCollectExtraUpdates` we are restarting the update infinitely.

Unfortunately, reverting this PR also reintroduces the original issue facebook#30717 which IMO is minor compared to the infinite loop.

## Changelog

<!-- Help reviewers and the release process by writing your own changelog entry. For an example, see:
https://github.com/facebook/react-native/wiki/Changelog
-->

[Android] [Fixed] - Text with adjustsFontSizeToFit changes the text layout infinitely

Pull Request resolved: facebook#33135

Test Plan:
I added a console.log to the Text `onTextLayout` in [packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js ](https://github.com/facebook/react-native/blob/main/packages/rn-tester/js/examples/Text/TextAdjustsDynamicLayoutExample.js) to see if the infinite loop is gone.

![image](https://user-images.githubusercontent.com/3791120/154523914-e6aa7cf5-7a1c-488f-a392-898f4c85a833.png)

![Screen Shot 2022-02-17 at 11 20 31 AM](https://user-images.githubusercontent.com/3791120/154524274-880c3bed-d2c6-456b-8947-42e75793c424.jpg)

```

Reviewed By: ShikaSD

Differential Revision: D34310218

Pulled By: lunaleaps

fbshipit-source-id: 0d40f49d15c562ec25983145897bd95dc182f897
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged This PR has been merged.
Projects
No open projects
5 participants