mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Exclude trailing whitespace on measuring text width (#37590)
Summary: Multiline text in Android shows some extra space. It's easily noticeable when you set the text `alignSelf` to `flex-start`. This is because we are using `layout.getLineWidth` which will include trailing whitespace. <img width="300" alt="image" src="https://github.com/facebook/react-native/assets/50919443/8939092b-caef-4ad8-9b34-2ccef5d20968"> Based on Android doc, `getLineMax` exclude trailing whitespace. <img width="625" alt="image" src="https://github.com/facebook/react-native/assets/50919443/0b32e842-5fab-4fc7-8fd9-299877b9c553"> ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID] [FIXED] - Exclude trailing whitespace from newline character on measuring text line width For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [ANDROID] [FIXED] - Exclude trailing whitespace from newline character on measuring text line width Pull Request resolved: https://github.com/facebook/react-native/pull/37590 Test Plan: After applying the changes: <img width="300" alt="image" src="https://github.com/facebook/react-native/assets/50919443/bfbf52b0-7e7d-4c89-8958-6af38d8bc1c7"> Code snippet: ``` <Text style={{backgroundColor: 'red', alignSelf: 'flex-start', color: 'white'}}> 1{'\n'} </Text> ``` Reviewed By: rshest Differential Revision: D46501420 Pulled By: NickGerleman fbshipit-source-id: fba4acd38747f09791ce8af4439ee88ab12ac827
This commit is contained in:
committed by
Facebook GitHub Bot
parent
6b62f12ce9
commit
2674d9bf7c
+3
-1
@@ -42,12 +42,14 @@ public class FontMetricsUtil {
|
||||
X_HEIGHT_MEASUREMENT_TEXT, 0, X_HEIGHT_MEASUREMENT_TEXT.length(), xHeightBounds);
|
||||
double xHeight = xHeightBounds.height() / AMPLIFICATION_FACTOR / dm.density;
|
||||
for (int i = 0; i < layout.getLineCount(); i++) {
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(i) - 1) == '\n';
|
||||
float lineWidth = endsWithNewLine ? layout.getLineMax(i) : layout.getLineWidth(i);
|
||||
Rect bounds = new Rect();
|
||||
layout.getLineBounds(i, bounds);
|
||||
WritableMap line = Arguments.createMap();
|
||||
line.putDouble("x", layout.getLineLeft(i) / dm.density);
|
||||
line.putDouble("y", bounds.top / dm.density);
|
||||
line.putDouble("width", layout.getLineWidth(i) / dm.density);
|
||||
line.putDouble("width", lineWidth / dm.density);
|
||||
line.putDouble("height", bounds.height() / dm.density);
|
||||
line.putDouble("descender", layout.getLineDescent(i) / dm.density);
|
||||
line.putDouble("ascender", -layout.getLineAscent(i) / dm.density);
|
||||
|
||||
+3
-1
@@ -135,7 +135,9 @@ public class ReactTextShadowNode extends ReactBaseTextShadowNode {
|
||||
layoutWidth = width;
|
||||
} else {
|
||||
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
|
||||
float lineWidth = layout.getLineWidth(lineIndex);
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
|
||||
float lineWidth =
|
||||
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
|
||||
if (lineWidth > layoutWidth) {
|
||||
layoutWidth = lineWidth;
|
||||
}
|
||||
|
||||
+3
-1
@@ -267,11 +267,13 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
// the last offset in the layout will result in an endless loop. Work around
|
||||
// this bug by avoiding getPrimaryHorizontal in that case.
|
||||
if (start == text.length() - 1) {
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(line) - 1) == '\n';
|
||||
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
|
||||
placeholderHorizontalPosition =
|
||||
isRtlParagraph
|
||||
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns incorrect
|
||||
// values when the paragraph is RTL and `setSingleLine(true)`.
|
||||
? textViewWidth - (int) layout.getLineWidth(line)
|
||||
? textViewWidth - (int) lineWidth
|
||||
: (int) layout.getLineRight(line) - width;
|
||||
} else {
|
||||
// The direction of the paragraph may not be exactly the direction the string is heading
|
||||
|
||||
+6
-2
@@ -407,7 +407,9 @@ public class TextLayoutManager {
|
||||
calculatedWidth = width;
|
||||
} else {
|
||||
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
|
||||
float lineWidth = layout.getLineWidth(lineIndex);
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
|
||||
float lineWidth =
|
||||
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
|
||||
if (lineWidth > calculatedWidth) {
|
||||
calculatedWidth = lineWidth;
|
||||
}
|
||||
@@ -462,11 +464,13 @@ public class TextLayoutManager {
|
||||
// the last offset in the layout will result in an endless loop. Work around
|
||||
// this bug by avoiding getPrimaryHorizontal in that case.
|
||||
if (start == text.length() - 1) {
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(line) - 1) == '\n';
|
||||
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
|
||||
placeholderLeftPosition =
|
||||
isRtlParagraph
|
||||
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns incorrect
|
||||
// values when the paragraph is RTL and `setSingleLine(true)`.
|
||||
? calculatedWidth - layout.getLineWidth(line)
|
||||
? calculatedWidth - lineWidth
|
||||
: layout.getLineRight(line) - placeholderWidth;
|
||||
} else {
|
||||
// The direction of the paragraph may not be exactly the direction the string is heading
|
||||
|
||||
+6
-2
@@ -429,7 +429,9 @@ public class TextLayoutManagerMapBuffer {
|
||||
calculatedWidth = width;
|
||||
} else {
|
||||
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
|
||||
float lineWidth = layout.getLineWidth(lineIndex);
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
|
||||
float lineWidth =
|
||||
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
|
||||
if (lineWidth > calculatedWidth) {
|
||||
calculatedWidth = lineWidth;
|
||||
}
|
||||
@@ -484,12 +486,14 @@ public class TextLayoutManagerMapBuffer {
|
||||
// the last offset in the layout will result in an endless loop. Work around
|
||||
// this bug by avoiding getPrimaryHorizontal in that case.
|
||||
if (start == text.length() - 1) {
|
||||
boolean endsWithNewLine = text.charAt(layout.getLineEnd(line) - 1) == '\n';
|
||||
float lineWidth = endsWithNewLine ? layout.getLineMax(line) : layout.getLineWidth(line);
|
||||
placeholderLeftPosition =
|
||||
isRtlParagraph
|
||||
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns
|
||||
// incorrect
|
||||
// values when the paragraph is RTL and `setSingleLine(true)`.
|
||||
? calculatedWidth - layout.getLineWidth(line)
|
||||
? calculatedWidth - lineWidth
|
||||
: layout.getLineRight(line) - placeholderWidth;
|
||||
} else {
|
||||
// The direction of the paragraph may not be exactly the direction the string is
|
||||
|
||||
Reference in New Issue
Block a user