@@ -28,6 +28,7 @@ import android.text.style.LeadingMarginSpan
2828import android.text.style.LocaleSpan
2929import android.text.style.RelativeSizeSpan
3030import android.text.style.ScaleXSpan
31+ import androidx.compose.foundation.text.appendInlineContent
3132import androidx.compose.ui.geometry.Offset
3233import androidx.compose.ui.geometry.Size
3334import androidx.compose.ui.graphics.BlendMode
@@ -2078,6 +2079,148 @@ class AndroidParagraphTest {
20782079 assertThat(paragraph.textPaint.hinting).isEqualTo(TextPaint .HINTING_OFF )
20792080 }
20802081
2082+ @Test
2083+ fun placeholder_onEllipsizedLastLine_isNotNull () {
2084+ with (defaultDensity) {
2085+ val fontSize = 10 .sp
2086+ val text = " Hello World Hello World Hello World"
2087+ val inlineContentId = " inline"
2088+ val annotatedString = buildAnnotatedString {
2089+ append(text)
2090+ appendInlineContent(inlineContentId)
2091+ }
2092+ val placeholder =
2093+ Placeholder (fontSize, fontSize, PlaceholderVerticalAlign .AboveBaseline )
2094+
2095+ val placeholderRange =
2096+ AnnotatedString .Range (placeholder, start = text.length, end = text.length + 1 )
2097+
2098+ val paragraph =
2099+ AndroidParagraph (
2100+ text = annotatedString.text,
2101+ style = TextStyle (fontSize = fontSize, fontFamily = basicFontFamily),
2102+ annotations = annotatedString.spanStyles,
2103+ placeholders = listOf (placeholderRange),
2104+ maxLines = 2 ,
2105+ overflow = TextOverflow .Ellipsis ,
2106+ constraints = Constraints (maxWidth = (20 * fontSize.toPx()).roundToInt()),
2107+ fontFamilyResolver = UncachedFontFamilyResolver (context),
2108+ density = defaultDensity,
2109+ )
2110+
2111+ assertThat(paragraph.placeholderRects).hasSize(1 )
2112+ assertThat(paragraph.placeholderRects[0 ]).isNotNull()
2113+ }
2114+ }
2115+
2116+ @Test
2117+ fun placeholder_fullyEllipsizedAway_isNull () {
2118+ with (defaultDensity) {
2119+ val fontSize = 10 .sp
2120+ val text = " Hello World Hello World Hello World"
2121+ val inlineContentId = " inline"
2122+ val annotatedString = buildAnnotatedString {
2123+ append(text)
2124+ appendInlineContent(inlineContentId)
2125+ }
2126+ val placeholder =
2127+ Placeholder (fontSize, fontSize, PlaceholderVerticalAlign .AboveBaseline )
2128+
2129+ val placeholderRange =
2130+ AnnotatedString .Range (placeholder, start = text.length, end = text.length + 1 )
2131+
2132+ val paragraph =
2133+ AndroidParagraph (
2134+ text = annotatedString.text,
2135+ style = TextStyle (fontSize = fontSize, fontFamily = basicFontFamily),
2136+ annotations = annotatedString.spanStyles,
2137+ placeholders = listOf (placeholderRange),
2138+ maxLines = 2 ,
2139+ overflow = TextOverflow .Ellipsis ,
2140+ constraints = Constraints (maxWidth = (15 * fontSize.toPx()).roundToInt()),
2141+ fontFamilyResolver = UncachedFontFamilyResolver (context),
2142+ density = defaultDensity,
2143+ )
2144+
2145+ assertThat(paragraph.placeholderRects).hasSize(1 )
2146+ assertThat(paragraph.placeholderRects[0 ]).isNull()
2147+ }
2148+ }
2149+
2150+ @Test
2151+ fun placeholder_onLastLine_withOverflowClip_isNotNull () {
2152+ with (defaultDensity) {
2153+ val fontSize = 10 .sp
2154+ val text = " Hello World Hello World Hello World"
2155+ val inlineContentId = " inline"
2156+ val annotatedString = buildAnnotatedString {
2157+ append(text)
2158+ appendInlineContent(inlineContentId)
2159+ }
2160+ val placeholder =
2161+ Placeholder (fontSize, fontSize, PlaceholderVerticalAlign .AboveBaseline )
2162+
2163+ val placeholderRange =
2164+ AnnotatedString .Range (placeholder, start = text.length, end = text.length + 1 )
2165+
2166+ val paragraph =
2167+ AndroidParagraph (
2168+ text = annotatedString.text,
2169+ style = TextStyle (fontSize = fontSize, fontFamily = basicFontFamily),
2170+ annotations = annotatedString.spanStyles,
2171+ placeholders = listOf (placeholderRange),
2172+ maxLines = 2 ,
2173+ overflow = TextOverflow .Clip ,
2174+ constraints = Constraints (maxWidth = (20 * fontSize.toPx()).roundToInt()),
2175+ fontFamilyResolver = UncachedFontFamilyResolver (context),
2176+ density = defaultDensity,
2177+ )
2178+
2179+ assertThat(paragraph.placeholderRects).hasSize(1 )
2180+ assertThat(paragraph.placeholderRects[0 ]).isNotNull()
2181+ }
2182+ }
2183+
2184+ @Test
2185+ fun placeholder_onNonEllipsizedLine_isNotNull () {
2186+ with (defaultDensity) {
2187+ val fontSize = 10 .sp
2188+ val textBefore = " Hello "
2189+ val textAfter = " World Hello World Hello World"
2190+ val inlineContentId = " inline"
2191+ val annotatedString = buildAnnotatedString {
2192+ append(textBefore)
2193+ appendInlineContent(inlineContentId)
2194+ append(textAfter)
2195+ }
2196+ val placeholder =
2197+ Placeholder (fontSize, fontSize, PlaceholderVerticalAlign .AboveBaseline )
2198+
2199+ val placeholderRange =
2200+ AnnotatedString .Range (
2201+ placeholder,
2202+ start = textBefore.length,
2203+ end = textBefore.length + 1 ,
2204+ )
2205+
2206+ val paragraph =
2207+ AndroidParagraph (
2208+ text = annotatedString.text,
2209+ style = TextStyle (fontSize = fontSize, fontFamily = basicFontFamily),
2210+ annotations = annotatedString.spanStyles,
2211+ placeholders = listOf (placeholderRange),
2212+ maxLines = 2 ,
2213+ overflow = TextOverflow .Ellipsis ,
2214+ constraints = Constraints (maxWidth = (15 * fontSize.toPx()).roundToInt()),
2215+ fontFamilyResolver = UncachedFontFamilyResolver (context),
2216+ density = defaultDensity,
2217+ )
2218+
2219+ assertThat(paragraph.placeholderRects).hasSize(1 )
2220+ assertThat(paragraph.placeholderRects[0 ]).isNotNull()
2221+ }
2222+ }
2223+
20812224 private fun simpleParagraph (
20822225 text : String = "",
20832226 spanStyles : List <AnnotatedString .Range <SpanStyle >> = listOf(),
0 commit comments