Skip to content

Commit a20fbe6

Browse files
cortinicofacebook-github-bot
authored andcommitted
Fix text decoration color fallback to use per-span foreground color
Summary: D104680895 introduced custom decoration drawing that falls back to `layout.paint.color` when `textDecorationColor` is not set. This is the base paint color (typically black), not the actual foreground color of the text span. For text with `ForegroundColorSpan` (e.g., link text with teal color, white text on dark backgrounds), the decoration was drawn in the wrong color. Fix: when `textDecorationColor` is TRANSPARENT (default), look up the `ForegroundColorSpan` at the decoration start position and use its color instead. Changelog: [Android][Fixed] - Fix text decoration color not matching foreground color when `textDecorationColor` is not set Differential Revision: D107645191
1 parent 503c0a5 commit a20fbe6

1 file changed

Lines changed: 14 additions & 1 deletion

File tree

packages/react-native/ReactAndroid/src/main/java/com/facebook/react/views/text/TextDecorationStyle.kt

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import android.graphics.Paint
1414
import android.graphics.Path
1515
import android.os.Build
1616
import android.text.Layout
17+
import android.text.Spanned
18+
import android.text.style.ForegroundColorSpan
1719
import kotlin.math.max
1820
import kotlin.math.min
1921
import kotlin.math.roundToInt
@@ -126,7 +128,18 @@ internal fun drawSpannedDecoration(
126128
yOffsetForLine: (paint: Paint, baseline: Float, thickness: Float) -> Float,
127129
) {
128130
val textPaint = layout.paint
129-
val effectiveColor = if (color != Color.TRANSPARENT) color else textPaint.color
131+
val effectiveColor =
132+
if (color != Color.TRANSPARENT) {
133+
color
134+
} else {
135+
// Look up the actual foreground color at the span position. layout.paint
136+
// is the base paint whose color may differ from per-span foreground colors
137+
// applied via ForegroundColorSpan (e.g., link text, colored text).
138+
val spanned = layout.text as? Spanned
139+
val fgSpans = spanned?.getSpans(start, start + 1, ForegroundColorSpan::class.java)
140+
if (fgSpans != null && fgSpans.isNotEmpty()) fgSpans.last().foregroundColor
141+
else textPaint.color
142+
}
130143
val minThickness = 1.5f * textPaint.density
131144
val thickness =
132145
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {

0 commit comments

Comments
 (0)