Skip to content

Commit 025be81

Browse files
yungstersfacebook-github-bot
authored andcommitted
RN: Fix Text Layout Ignoring Parent Bounds
Summary: Fixes text layout so that the parent bounds are correctly respected. This fixes two bugs: - **Parent width is not respected.** This was caused by the recent change to shrink-wrap text layout. - **Parent height is not respected.** This has always been a bug. After this change, Android will behave like iOS. Changelog: [Android] [Fixed] - Text layout no longer ignores parent bounds Reviewed By: mdvacca Differential Revision: D21199030 fbshipit-source-id: cc072bdcff64167db1f79b7bf965e57a7396cdf4
1 parent ed29ba1 commit 025be81

File tree

2 files changed

+43
-13
lines changed

2 files changed

+43
-13
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextShadowNode.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -130,14 +130,29 @@ public long measure(
130130
// Instead of using `layout.getWidth()` (which may yield a significantly larger width for
131131
// text that is wrapping), compute width using the longest line.
132132
float layoutWidth = 0;
133-
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
134-
float lineWidth = layout.getLineWidth(lineIndex);
135-
if (lineWidth > layoutWidth) {
136-
layoutWidth = lineWidth;
133+
if (widthMode == YogaMeasureMode.EXACTLY) {
134+
layoutWidth = width;
135+
} else {
136+
for (int lineIndex = 0; lineIndex < lineCount; lineIndex++) {
137+
float lineWidth = layout.getLineWidth(lineIndex);
138+
if (lineWidth > layoutWidth) {
139+
layoutWidth = lineWidth;
140+
}
141+
}
142+
if (widthMode == YogaMeasureMode.AT_MOST && layoutWidth > width) {
143+
layoutWidth = width;
144+
}
145+
}
146+
147+
float layoutHeight = height;
148+
if (heightMode != YogaMeasureMode.EXACTLY) {
149+
layoutHeight = layout.getLineBottom(lineCount - 1);
150+
if (heightMode == YogaMeasureMode.AT_MOST && layoutHeight > height) {
151+
layoutHeight = height;
137152
}
138153
}
139154

140-
return YogaMeasureOutput.make(layoutWidth, layout.getLineBottom(lineCount - 1));
155+
return YogaMeasureOutput.make(layoutWidth, layoutHeight);
141156
}
142157
};
143158

ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java

+23-8
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,28 @@ public static long measureText(
311311
? layout.getLineCount()
312312
: Math.min(maximumNumberOfLines, layout.getLineCount());
313313

314-
int calculatedHeight = layout.getLineBottom(calculatedLineCount - 1);
315314
// Instead of using `layout.getWidth()` (which may yield a significantly larger width for
316315
// text that is wrapping), compute width using the longest line.
317-
int calculatedWidth = 0;
318-
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
319-
float lineWidth = layout.getLineWidth(lineIndex);
320-
if (lineWidth > calculatedWidth) {
321-
calculatedWidth = (int) Math.ceil(lineWidth);
316+
float calculatedWidth = 0;
317+
if (widthYogaMeasureMode == YogaMeasureMode.EXACTLY) {
318+
calculatedWidth = width;
319+
} else {
320+
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
321+
float lineWidth = layout.getLineWidth(lineIndex);
322+
if (lineWidth > calculatedWidth) {
323+
calculatedWidth = lineWidth;
324+
}
325+
}
326+
if (widthYogaMeasureMode == YogaMeasureMode.AT_MOST && calculatedWidth > width) {
327+
calculatedWidth = width;
328+
}
329+
}
330+
331+
float calculatedHeight = height;
332+
if (heightYogaMeasureMode != YogaMeasureMode.EXACTLY) {
333+
calculatedHeight = layout.getLineBottom(calculatedLineCount - 1);
334+
if (heightYogaMeasureMode == YogaMeasureMode.AT_MOST && calculatedHeight > height) {
335+
calculatedHeight = height;
322336
}
323337
}
324338

@@ -356,7 +370,7 @@ public static long measureText(
356370
isRtlParagraph
357371
// Equivalent to `layout.getLineLeft(line)` but `getLineLeft` returns incorrect
358372
// values when the paragraph is RTL and `setSingleLine(true)`.
359-
? calculatedWidth - (int) layout.getLineWidth(line)
373+
? (int) calculatedWidth - (int) layout.getLineWidth(line)
360374
: (int) layout.getLineRight(line) - placeholderWidth;
361375
} else {
362376
// The direction of the paragraph may not be exactly the direction the string is heading
@@ -379,7 +393,8 @@ public static long measureText(
379393
// The result is equivalent to bugless versions of
380394
// `getPrimaryHorizontal`/`getSecondaryHorizontal`.
381395
placeholderLeftPosition =
382-
calculatedWidth - ((int) layout.getLineRight(line) - placeholderLeftPosition);
396+
(int) calculatedWidth
397+
- ((int) layout.getLineRight(line) - placeholderLeftPosition);
383398
}
384399
if (isRtlChar) {
385400
placeholderLeftPosition -= placeholderWidth;

0 commit comments

Comments
 (0)