Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -666,12 +666,13 @@ internal object TextLayoutManager {
// Calculate visual bounds width from unconstrained layout
var desiredVisualWidth = 0f
for (i in 0 until unconstrainedLayout.lineCount) {
val lineWidth = unconstrainedLayout.getLineRight(i) - unconstrainedLayout.getLineLeft(i)
val lineWidth = unconstrainedLayout.getLineMax(i)
Copy link
Author

@linhvovan29546 linhvovan29546 Dec 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change comes from the Expensify App( I tried to reproduce it in rn‑tester but couldn’t). When text has a lineHeight, the text rendered with width is too small, see the screenshot below where bottom‑navigation labels wrap and some text are truncated.

While debugging I found a suspicious calculation: the computed line width was too small, so I replaced the getLineRight/getLineLeft approach with getLineMax to compute the line width, which fixes the problem

Image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It makes a lot of sense - I guess it wold be great adding two sections in the PR description for the meta reviewer telling what's wrong in the current version - and one on how to fix it - I won't be reviewing it internally - so this might be a great addition before we move on.

Thanks again, @linhvovan29546, for your contribution!

desiredVisualWidth = max(desiredVisualWidth, lineWidth)
}

val layoutWidth =
when (widthYogaMeasureMode) {
YogaMeasureMode.EXACTLY -> floor(width).toInt()
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In https://github.com/facebook/react-native/pull/54721/changes#diff-8cc9a4af360b3eac066d7f9cd50d91da9cb6fc2fbf044b25d495666bcc95e2ebR662-R663 we changed Android 15+ to force layoutWidth to use AT_MOST. Since widthYogaMeasureMode may be EXACTLY, we need to handle that case otherwise the text will render incorrect as shown in the description. You can look the pre‑Android 15 logic.

YogaMeasureMode.AT_MOST -> min(ceil(desiredVisualWidth).toInt(), floor(width).toInt())
else -> ceil(desiredVisualWidth).toInt()
}
Expand Down
Loading