Skip to content

Commit

Permalink
Fix adjustsFontSizeToFit for strings with a single character (#47082)
Browse files Browse the repository at this point in the history
Summary:
Fixes #47045

On Android `adjustsFontSizeToFit` relies on two metrics:
- Text with line breaks results in more lines than `maximumNumberOfLines`
- The overall height of the text is larger than the available height

None of these two was fulfilled when a single-character string had a higher width than the available one (a single character will not be broken into multiple lines). This PR adds exactly that as a third option to trigger the scaling algorithm - a single-character string that has a higher width than the available one.

On iOS `adjustsFontSizeToFit` relies on `truncatedGlyphRangeInLineFragmentForGlyphAtIndex` which seems to be returning `NSNotFound` when a single-character sting gets truncated. Similarly to Android, this PR adds an additional check to make sure that single-character strings actually fit inside the container.

## Changelog:

[GENERAL] [FIXED] - Fixed `adjustsFontSizeToFit` not working for text with a single character

Pull Request resolved: #47082

Test Plan:
Tested on the code from the issue:

|Android (old arch)|Android (new arch)|iOS (old arch)|iOS (new arch)|
|-|-|-|-|
|<img width="406" alt="android_old" src="https://github.com/user-attachments/assets/91b1af41-4ef7-46cc-bb04-374f860d93ac">|<img width="406" alt="android_new" src="https://github.com/user-attachments/assets/90e3cde1-e6c0-4b25-8325-c62a37773002">|<img width="546" alt="ios_old" src="https://github.com/user-attachments/assets/902b9c10-84e0-4372-bcc8-07cd1ef006f6">|<img width="546" alt="ios_new" src="https://github.com/user-attachments/assets/f4df4f0e-7649-47f3-9c81-e38f8665d9a2">|

Reviewed By: javache

Differential Revision: D64664351

Pulled By: NickGerleman

fbshipit-source-id: b68f318a0fbd5ebed947a70d1e3fb0515b5fb409
  • Loading branch information
j-piasecki authored and facebook-github-bot committed Dec 9, 2024
1 parent eda4f18 commit 47822e9
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,15 @@ - (RCTTextSizeComparisonOptions)compareToSize:(CGSize)size thresholdRatio:(CGFlo
NSLayoutManager *layoutManager = self.layoutManagers.firstObject;
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;

// A workaround for truncatedGlyphRangeInLineFragmentForGlyphAtIndex returning NSNotFound when text has only
// one character and it gets truncated
if ([self length] == 1) {
CGSize characterSize = [[self string] sizeWithAttributes:[self attributesAtIndex:0 effectiveRange:nil]];
if (characterSize.width > size.width) {
return RCTTextSizeComparisonLarger;
}
}

[layoutManager ensureLayoutForTextContainer:textContainer];

// Does it fit the text container?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,8 +629,8 @@ private static Layout createLayout(
&& ((maximumNumberOfLines != ReactConstants.UNSET
&& maximumNumberOfLines != 0
&& layout.getLineCount() > maximumNumberOfLines)
|| (heightYogaMeasureMode != YogaMeasureMode.UNDEFINED
&& layout.getHeight() > height))) {
|| (heightYogaMeasureMode != YogaMeasureMode.UNDEFINED && layout.getHeight() > height)
|| (text.length() == 1 && layout.getLineWidth(0) > width))) {
// TODO: We could probably use a smarter algorithm here. This will require 0(n)
// measurements based on the number of points the font size needs to be reduced by.
currentFontSize -= Math.max(1, (int) PixelUtil.toPixelFromDIP(1));
Expand All @@ -648,6 +648,9 @@ private static Layout createLayout(
text.getSpanFlags(span));
text.removeSpan(span);
}
if (boring != null) {
boring = BoringLayout.isBoring(text, paint);
}
layout =
createLayout(
text,
Expand Down

0 comments on commit 47822e9

Please sign in to comment.