Skip to content

Commit 1daf0c5

Browse files
committed
Revert "Remove fill workaround, shortcut calculations if there's only one line of text"
This reverts commit cfdcadc.
1 parent 781043a commit 1daf0c5

File tree

3 files changed

+28
-10
lines changed

3 files changed

+28
-10
lines changed

sentry-android-replay/src/main/java/io/sentry/android/replay/util/Nodes.kt

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,28 @@ import androidx.compose.ui.node.LayoutNode
1313
import androidx.compose.ui.text.TextLayoutResult
1414
import kotlin.math.roundToInt
1515

16-
internal class ComposeTextLayout(internal val layout: TextLayoutResult) : TextLayout {
16+
internal class ComposeTextLayout(
17+
internal val layout: TextLayoutResult,
18+
private val hasFillModifier: Boolean,
19+
) : TextLayout {
1720
override val lineCount: Int
1821
get() = layout.lineCount
1922

2023
override val dominantTextColor: Int?
2124
get() = null
2225

23-
override fun getPrimaryHorizontal(line: Int, offset: Int) =
24-
layout.getHorizontalPosition(offset, usePrimaryDirection = true)
26+
override fun getPrimaryHorizontal(line: Int, offset: Int): Float {
27+
val horizontalPos = layout.getHorizontalPosition(offset, usePrimaryDirection = true)
28+
// when there's no `fill` modifier on a Text composable, compose still thinks that there's
29+
// one and wrongly calculates horizontal position relative to node's start, not text's start
30+
// for some reason. This is only the case for single-line text (multiline works fien).
31+
// So we subtract line's left to get the correct position
32+
return if (!hasFillModifier && lineCount == 1) {
33+
horizontalPos - layout.getLineLeft(line)
34+
} else {
35+
horizontalPos
36+
}
37+
}
2538

2639
override fun getEllipsisCount(line: Int): Int = if (layout.isLineEllipsized(line)) 1 else 0
2740

@@ -79,6 +92,8 @@ internal fun Painter.isMaskable(): Boolean {
7992
!className.contains("Brush")
8093
}
8194

95+
internal data class TextAttributes(val color: Color?, val hasFillModifier: Boolean)
96+
8297
/**
8398
* This method is necessary to mask text in Compose.
8499
*
@@ -93,9 +108,10 @@ internal fun Painter.isMaskable(): Boolean {
93108
*
94109
* We also add special proguard rules to keep the `Text` class names and their `color` member.
95110
*/
96-
internal fun LayoutNode.findColor(): Color? {
111+
internal fun LayoutNode.findTextAttributes(): TextAttributes {
97112
val modifierInfos = getModifierInfo()
98113
var color: Color? = null
114+
var hasFillModifier = false
99115
for (index in modifierInfos.indices) {
100116
val modifier = modifierInfos[index].modifier
101117
val modifierClassName = modifier::class.java.name
@@ -111,9 +127,11 @@ internal fun LayoutNode.findColor(): Color? {
111127
} catch (e: Throwable) {
112128
null
113129
}
130+
} else if (modifierClassName.contains("Fill")) {
131+
hasFillModifier = true
114132
}
115133
}
116-
return color
134+
return TextAttributes(color, hasFillModifier)
117135
}
118136

119137
/**

sentry-android-replay/src/main/java/io/sentry/android/replay/util/Views.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,7 @@ internal fun TextLayout?.getVisibleRects(
122122
paddingLeft: Int,
123123
paddingTop: Int,
124124
): List<Rect> {
125-
126-
if (this == null || lineCount <= 1) {
125+
if (this == null) {
127126
return listOf(globalRect)
128127
}
129128

sentry-android-replay/src/main/java/io/sentry/android/replay/viewhierarchy/ComposeViewHierarchyNode.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ import io.sentry.SentryMaskingOptions
2323
import io.sentry.android.replay.SentryReplayModifiers
2424
import io.sentry.android.replay.util.ComposeTextLayout
2525
import io.sentry.android.replay.util.boundsInWindow
26-
import io.sentry.android.replay.util.findColor
2726
import io.sentry.android.replay.util.findPainter
27+
import io.sentry.android.replay.util.findTextAttributes
2828
import io.sentry.android.replay.util.isMaskable
2929
import io.sentry.android.replay.util.toOpaque
3030
import io.sentry.android.replay.viewhierarchy.ViewHierarchyNode.GenericViewHierarchyNode
@@ -189,10 +189,11 @@ internal object ComposeViewHierarchyNode {
189189
?.action
190190
?.invoke(textLayoutResults)
191191

192+
val (color, hasFillModifier) = node.findTextAttributes()
192193
val textLayoutResult = textLayoutResults.firstOrNull()
193194
var textColor = textLayoutResult?.layoutInput?.style?.color
194195
if (textColor?.isUnspecified == true) {
195-
textColor = node.findColor()
196+
textColor = color
196197
}
197198
val isLaidOut = textLayoutResult?.layoutInput?.style?.fontSize != TextUnit.Unspecified
198199
// TODO: support editable text (currently there's a way to get @Composable's padding only
@@ -201,7 +202,7 @@ internal object ComposeViewHierarchyNode {
201202
TextViewHierarchyNode(
202203
layout =
203204
if (textLayoutResult != null && !isEditable && isLaidOut) {
204-
ComposeTextLayout(textLayoutResult)
205+
ComposeTextLayout(textLayoutResult, hasFillModifier)
205206
} else {
206207
null
207208
},

0 commit comments

Comments
 (0)