[go: nahoru, domu]

blob: 70f0de9114cc5ed9be19f75598022580b2623f2a [file] [log] [blame]
Siyamed Sinirff51df92019-07-02 15:35:20 -07001package androidx.ui.text.platform
Haoyu Zhang10fc6502018-11-09 15:50:11 -08002
Haoyu Zhang10fc6502018-11-09 15:50:11 -08003import android.graphics.Paint
Haoyu Zhang10fc6502018-11-09 15:50:11 -08004import android.text.TextPaint
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -08005import android.text.style.AbsoluteSizeSpan
Haoyu Zhang0c4fd022019-01-02 13:53:10 -08006import android.text.style.BackgroundColorSpan
Haoyu Zhang47f57a22018-12-12 13:16:40 -08007import android.text.style.ForegroundColorSpan
Haoyu Zhang7fc59172019-03-01 17:03:31 -08008import android.text.style.LeadingMarginSpan
Haoyu Zhang4b201d22018-12-18 14:27:38 -08009import android.text.style.LocaleSpan
Haoyu Zhang24eb32f2019-05-21 16:16:37 -070010import android.text.style.RelativeSizeSpan
Haoyu Zhang15750922019-02-19 13:44:17 -080011import android.text.style.ScaleXSpan
Haoyu Zhangb5677202018-12-19 14:22:18 -080012import android.text.style.StrikethroughSpan
13import android.text.style.UnderlineSpan
Haoyu Zhang10fc6502018-11-09 15:50:11 -080014import androidx.test.filters.SmallTest
15import androidx.test.platform.app.InstrumentationRegistry
Siyamed Sinir97d0ccf2019-11-02 02:51:24 -070016import androidx.text.TextLayout
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -080017import androidx.text.style.BaselineShiftSpan
Haoyu Zhang588aaef2019-02-20 14:47:39 -080018import androidx.text.style.FontFeatureSpan
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -080019import androidx.text.style.LetterSpacingSpan
Haoyu Zhang2a036c832019-03-08 11:57:13 -080020import androidx.text.style.ShadowSpan
Haoyu Zhang15750922019-02-19 13:44:17 -080021import androidx.text.style.SkewXSpan
Siyamed Sinir70f336a2018-12-27 10:37:09 -080022import androidx.text.style.TypefaceSpan
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070023import androidx.ui.core.Density
Haoyu Zhangf2e9e032019-10-16 15:23:39 -070024import androidx.ui.core.em
Haoyu Zhang7fc59172019-03-01 17:03:31 -080025import androidx.ui.core.px
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070026import androidx.ui.core.sp
27import androidx.ui.core.withDensity
Haoyu Zhang2a036c832019-03-08 11:57:13 -080028import androidx.ui.engine.geometry.Offset
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -070029import androidx.ui.graphics.Color
Nader Jawadad983532019-08-29 16:27:37 -070030import androidx.ui.graphics.Shadow
Siyamed Sinir63789c92019-09-25 10:44:11 -070031import androidx.ui.graphics.toArgb
32import androidx.ui.text.AnnotatedString
33import androidx.ui.text.FontTestData.Companion.BASIC_MEASURE_FONT
Seigo Nonaka8de69792019-09-04 14:55:15 -070034import androidx.ui.text.LocaleList
Siyamed Sinir63789c92019-09-25 10:44:11 -070035import androidx.ui.text.ParagraphConstraints
Siyamed Sinir6a1f0362019-07-08 15:58:32 -070036import androidx.ui.text.ParagraphStyle
Siyamed Sinirc4c308e2019-07-03 16:14:22 -070037import androidx.ui.text.TestFontResourceLoader
Siyamed Sinirff51df92019-07-02 15:35:20 -070038import androidx.ui.text.TextStyle
Siyamed Sinir63789c92019-09-25 10:44:11 -070039import androidx.ui.text.font.FontFamily
40import androidx.ui.text.font.FontStyle
41import androidx.ui.text.font.FontSynthesis
42import androidx.ui.text.font.FontWeight
43import androidx.ui.text.font.asFontFamily
44import androidx.ui.text.matchers.assertThat
45import androidx.ui.text.style.BaselineShift
46import androidx.ui.text.style.TextAlign
47import androidx.ui.text.style.TextDecoration
Seigo Nonakac4f136a2019-08-16 16:48:44 -070048import androidx.ui.text.style.TextDirectionAlgorithm
Siyamed Sinir63789c92019-09-25 10:44:11 -070049import androidx.ui.text.style.TextGeometricTransform
50import androidx.ui.text.style.TextIndent
51import com.google.common.truth.Truth.assertThat
Siyamed Sinirf18dcca2018-12-20 18:25:10 -080052import com.nhaarman.mockitokotlin2.any
53import com.nhaarman.mockitokotlin2.eq
54import com.nhaarman.mockitokotlin2.mock
55import com.nhaarman.mockitokotlin2.never
56import com.nhaarman.mockitokotlin2.spy
57import com.nhaarman.mockitokotlin2.times
58import com.nhaarman.mockitokotlin2.verify
Haoyu Zhang10fc6502018-11-09 15:50:11 -080059import org.junit.Test
60import org.junit.runner.RunWith
61import org.junit.runners.JUnit4
Haoyu Zhang10fc6502018-11-09 15:50:11 -080062import kotlin.math.ceil
63
64@RunWith(JUnit4::class)
65@SmallTest
Siyamed Sinire75976f2019-07-03 09:24:30 -070066class AndroidParagraphTest {
Siyamed Sinir472ed132019-07-03 15:43:43 -070067 // This sample font provides the following features:
68 // 1. The width of most of visible characters equals to font size.
69 // 2. The LTR/RTL characters are rendered as â–¶/â—€.
70 // 3. The fontMetrics passed to TextPaint has descend - ascend equal to 1.2 * fontSize.
71 private val fontFamily = BASIC_MEASURE_FONT.asFontFamily()
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070072 private val defaultDensity = Density(density = 1f)
Siyamed Sinir472ed132019-07-03 15:43:43 -070073 private val context = InstrumentationRegistry.getInstrumentation().context
Haoyu Zhang10fc6502018-11-09 15:50:11 -080074
75 @Test
76 fun draw_with_newline_and_line_break_default_values() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070077 withDensity(defaultDensity) {
78 val fontSize = 50.sp
79 for (text in arrayOf("abc\ndef", "\u05D0\u05D1\u05D2\n\u05D3\u05D4\u05D5")) {
80 val paragraphAndroid = simpleParagraph(
81 text = text,
82 textStyle = TextStyle(
83 fontSize = fontSize,
84 fontFamily = fontFamily
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -070085 ),
86 // 2 chars width
87 constraints = ParagraphConstraints(width = 2 * fontSize.toPx().value)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -070088 )
Haoyu Zhang10fc6502018-11-09 15:50:11 -080089
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070090 val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
91 textPaint.textSize = fontSize.toPx().value
92 textPaint.typeface = TypefaceAdapter().create(fontFamily)
Haoyu Zhang10fc6502018-11-09 15:50:11 -080093
Siyamed Sinir97d0ccf2019-11-02 02:51:24 -070094 val layout = TextLayout(
95 charSequence = text,
96 width = ceil(paragraphAndroid.width),
97 textPaint = textPaint
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -070098 )
Siyamed Sinir97d0ccf2019-11-02 02:51:24 -070099
100 assertThat(paragraphAndroid.bitmap()).isEqualToBitmap(layout.bitmap())
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700101 }
Haoyu Zhang10fc6502018-11-09 15:50:11 -0800102 }
103 }
104
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800105 @Test
haoyua8e48a52019-06-25 12:23:27 -0700106 fun testAnnotatedString_setColorOnWholeText() {
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800107 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700108 val textStyle = TextStyle(color = Color(0xFF0000FF))
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800109
110 val paragraph = simpleParagraph(
111 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700112 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
113 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800114 )
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800115
Siyamed Sinir63789c92019-09-25 10:44:11 -0700116 assertThat(paragraph.charSequence).hasSpan(ForegroundColorSpan::class, 0, text.length)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800117 }
118
119 @Test
haoyua8e48a52019-06-25 12:23:27 -0700120 fun testAnnotatedString_setColorOnPartOfText() {
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800121 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700122 val textStyle = TextStyle(color = Color(0xFF0000FF))
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800123
124 val paragraph = simpleParagraph(
125 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700126 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
127 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800128 )
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800129
Siyamed Sinir63789c92019-09-25 10:44:11 -0700130 assertThat(paragraph.charSequence).hasSpan(ForegroundColorSpan::class, 0, "abc".length)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800131 }
132
133 @Test
haoyua8e48a52019-06-25 12:23:27 -0700134 fun testAnnotatedString_setColorTwice_lastOneOverwrite() {
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800135 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700136 val textStyle = TextStyle(color = Color(0xFF0000FF))
137 val textStyleOverwrite = TextStyle(color = Color(0xFF00FF00))
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800138
139 val paragraph = simpleParagraph(
140 text = text,
141 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700142 AnnotatedString.Item(textStyle, 0, text.length),
143 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700144 ),
145 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800146 )
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800147
Siyamed Sinir63789c92019-09-25 10:44:11 -0700148 assertThat(paragraph.charSequence).hasSpan(ForegroundColorSpan::class, 0, text.length)
149 assertThat(paragraph.charSequence).hasSpan(ForegroundColorSpan::class, 0, "abc".length)
150 assertThat(paragraph.charSequence).hasSpanOnTop(ForegroundColorSpan::class, 0, "abc".length)
Haoyu Zhang47f57a22018-12-12 13:16:40 -0800151 }
152
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800153 @Test
Haoyu Zhangb5677202018-12-19 14:22:18 -0800154 fun testStyle_setTextDecorationOnWholeText_withLineThrough() {
155 val text = "abcde"
Siyamed Sinir9fd89f42019-05-20 18:04:29 -0700156 val textStyle = TextStyle(decoration = TextDecoration.LineThrough)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800157
158 val paragraph = simpleParagraph(
159 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700160 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
161 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800162 )
Haoyu Zhangb5677202018-12-19 14:22:18 -0800163
Siyamed Sinir63789c92019-09-25 10:44:11 -0700164 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
165 assertThat(paragraph.charSequence).hasSpan(StrikethroughSpan::class, 0, text.length)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800166 }
167
168 @Test
169 fun testStyle_setTextDecorationOnWholeText_withUnderline() {
170 val text = "abcde"
Siyamed Sinir9fd89f42019-05-20 18:04:29 -0700171 val textStyle = TextStyle(decoration = TextDecoration.Underline)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800172
173 val paragraph = simpleParagraph(
174 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700175 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
176 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800177 )
Haoyu Zhangb5677202018-12-19 14:22:18 -0800178
Siyamed Sinir63789c92019-09-25 10:44:11 -0700179 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
180 assertThat(paragraph.charSequence).hasSpan(UnderlineSpan::class, 0, text.length)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800181 }
182
183 @Test
184 fun testStyle_setTextDecorationOnPartText_withLineThrough() {
185 val text = "abcde"
Siyamed Sinir9fd89f42019-05-20 18:04:29 -0700186 val textStyle = TextStyle(decoration = TextDecoration.LineThrough)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800187
188 val paragraph = simpleParagraph(
189 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700190 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
191 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800192 )
Haoyu Zhangb5677202018-12-19 14:22:18 -0800193
Siyamed Sinir63789c92019-09-25 10:44:11 -0700194 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
195 assertThat(paragraph.charSequence).hasSpan(StrikethroughSpan::class, 0, "abc".length)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800196 }
197
198 @Test
199 fun testStyle_setTextDecorationOnPartText_withUnderline() {
200 val text = "abcde"
Siyamed Sinir9fd89f42019-05-20 18:04:29 -0700201 val textStyle = TextStyle(decoration = TextDecoration.Underline)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800202
203 val paragraph = simpleParagraph(
204 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700205 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
206 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800207 )
Haoyu Zhangb5677202018-12-19 14:22:18 -0800208
Siyamed Sinir63789c92019-09-25 10:44:11 -0700209 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
210 assertThat(paragraph.charSequence).hasSpan(UnderlineSpan::class, 0, "abc".length)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800211 }
212
213 @Test
214 fun testStyle_setTextDecoration_withLineThroughAndUnderline() {
215 val text = "abcde"
216 val textStyle = TextStyle(
217 decoration = TextDecoration.combine(
Siyamed Sinir9fd89f42019-05-20 18:04:29 -0700218 listOf(TextDecoration.LineThrough, TextDecoration.Underline)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800219 )
220 )
221
222 val paragraph = simpleParagraph(
223 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700224 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
225 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800226 )
Haoyu Zhangb5677202018-12-19 14:22:18 -0800227
Siyamed Sinir63789c92019-09-25 10:44:11 -0700228 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
229 assertThat(paragraph.charSequence).hasSpan(UnderlineSpan::class, 0, "abc".length)
230 assertThat(paragraph.charSequence).hasSpan(StrikethroughSpan::class, 0, "abc".length)
Haoyu Zhangb5677202018-12-19 14:22:18 -0800231 }
232
233 @Test
haoyua8e48a52019-06-25 12:23:27 -0700234 fun testAnnotatedString_setFontSizeOnWholeText() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700235 withDensity(defaultDensity) {
236 val text = "abcde"
237 val fontSize = 20.sp
238 val paragraphWidth = text.length * fontSize.toPx().value
239 val textStyle = TextStyle(fontSize = fontSize)
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800240
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700241 val paragraph = simpleParagraph(
242 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700243 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
244 constraints = ParagraphConstraints(width = paragraphWidth)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700245 )
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800246
Siyamed Sinir63789c92019-09-25 10:44:11 -0700247 assertThat(paragraph.charSequence).hasSpan(AbsoluteSizeSpan::class, 0, text.length)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700248 }
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800249 }
250
251 @Test
haoyua8e48a52019-06-25 12:23:27 -0700252 fun testAnnotatedString_setFontSizeOnPartText() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700253 withDensity(defaultDensity) {
254 val text = "abcde"
255 val fontSize = 20.sp
256 val paragraphWidth = text.length * fontSize.toPx().value
257 val textStyle = TextStyle(fontSize = fontSize)
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800258
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700259 val paragraph = simpleParagraph(
260 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700261 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
262 constraints = ParagraphConstraints(width = paragraphWidth)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700263 )
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800264
Siyamed Sinir63789c92019-09-25 10:44:11 -0700265 assertThat(paragraph.charSequence).hasSpan(AbsoluteSizeSpan::class, 0, "abc".length)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700266 }
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800267 }
268
269 @Test
haoyua8e48a52019-06-25 12:23:27 -0700270 fun testAnnotatedString_setFontSizeTwice_lastOneOverwrite() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700271 withDensity(defaultDensity) {
272 val text = "abcde"
273 val fontSize = 20.sp
274 val fontSizeOverwrite = 30.sp
275 val paragraphWidth = text.length * fontSizeOverwrite.toPx().value
276 val textStyle = TextStyle(fontSize = fontSize)
277 val textStyleOverwrite = TextStyle(fontSize = fontSizeOverwrite)
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800278
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700279 val paragraph = simpleParagraph(
280 text = text,
281 textStyles = listOf(
282 AnnotatedString.Item(textStyle, 0, text.length),
283 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700284 ),
285 constraints = ParagraphConstraints(width = paragraphWidth)
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800286 )
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800287
Siyamed Sinir63789c92019-09-25 10:44:11 -0700288 assertThat(paragraph.charSequence).hasSpan(AbsoluteSizeSpan::class, 0, text.length)
289 assertThat(paragraph.charSequence).hasSpan(AbsoluteSizeSpan::class, 0, "abc".length)
290 assertThat(paragraph.charSequence)
291 .hasSpanOnTop(AbsoluteSizeSpan::class, 0, "abc".length)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700292 }
Haoyu Zhangbb51ccf2018-12-17 15:07:43 -0800293 }
294
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800295 @Test
haoyua8e48a52019-06-25 12:23:27 -0700296 fun testAnnotatedString_setFontSizeScaleOnWholeText() {
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700297 val text = "abcde"
298 val fontSizeScale = 2.0f
299 val textStyle = TextStyle(fontSizeScale = fontSizeScale)
300
301 val paragraph = simpleParagraph(
302 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700303 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
304 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700305 )
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700306
Siyamed Sinir63789c92019-09-25 10:44:11 -0700307 assertThat(paragraph.charSequence).hasSpan(RelativeSizeSpan::class, 0, text.length) {
308 it.sizeChange == fontSizeScale
309 }
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700310 }
311
312 @Test
haoyua8e48a52019-06-25 12:23:27 -0700313 fun testAnnotatedString_setFontSizeScaleOnPartText() {
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700314 val text = "abcde"
315 val fontSizeScale = 2.0f
316 val textStyle = TextStyle(fontSizeScale = fontSizeScale)
317
318 val paragraph = simpleParagraph(
319 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700320 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
321 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700322 )
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700323
Siyamed Sinir63789c92019-09-25 10:44:11 -0700324 assertThat(paragraph.charSequence).hasSpan(RelativeSizeSpan::class, 0, "abc".length) {
325 it.sizeChange == fontSizeScale
326 }
Haoyu Zhang24eb32f2019-05-21 16:16:37 -0700327 }
328
329 @Test
haoyua8e48a52019-06-25 12:23:27 -0700330 fun testAnnotatedString_setLetterSpacingOnWholeText() {
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800331 val text = "abcde"
George Mountb1cdd862018-12-21 10:54:42 -0800332 val letterSpacing = 2.0f
Haoyu Zhangf2e9e032019-10-16 15:23:39 -0700333 val textStyle = TextStyle(letterSpacing = letterSpacing.em)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800334
335 val paragraph = simpleParagraph(
336 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700337 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
338 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800339 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700340
Siyamed Sinir63789c92019-09-25 10:44:11 -0700341 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
342 assertThat(paragraph.charSequence).hasSpan(LetterSpacingSpan::class, 0, text.length)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800343 }
344
345 @Test
haoyua8e48a52019-06-25 12:23:27 -0700346 fun testAnnotatedString_setLetterSpacingOnPartText() {
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800347 val text = "abcde"
Haoyu Zhangf2e9e032019-10-16 15:23:39 -0700348 val textStyle = TextStyle(letterSpacing = 2.em)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800349
350 val paragraph = simpleParagraph(
351 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700352 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
353 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800354 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700355
Siyamed Sinir63789c92019-09-25 10:44:11 -0700356 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
357 assertThat(paragraph.charSequence).hasSpan(LetterSpacingSpan::class, 0, "abc".length)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800358 }
359
360 @Test
haoyua8e48a52019-06-25 12:23:27 -0700361 fun testAnnotatedString_setLetterSpacingTwice_lastOneOverwrite() {
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800362 val text = "abcde"
Haoyu Zhangf2e9e032019-10-16 15:23:39 -0700363 val textStyle = TextStyle(letterSpacing = 2.em)
364 val textStyleOverwrite = TextStyle(letterSpacing = 3.em)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800365
366 val paragraph = simpleParagraph(
367 text = text,
368 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700369 AnnotatedString.Item(textStyle, 0, text.length),
370 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700371 ),
372 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800373 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700374
Siyamed Sinir63789c92019-09-25 10:44:11 -0700375 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
376 assertThat(paragraph.charSequence).hasSpan(LetterSpacingSpan::class, 0, text.length)
377 assertThat(paragraph.charSequence).hasSpan(LetterSpacingSpan::class, 0, "abc".length)
378 assertThat(paragraph.charSequence).hasSpanOnTop(LetterSpacingSpan::class, 0, "abc".length)
Haoyu Zhang1588ba0f2018-12-19 16:47:10 -0800379 }
380
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800381 @Test
haoyua8e48a52019-06-25 12:23:27 -0700382 fun testAnnotatedString_setBackgroundOnWholeText() {
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800383 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700384 val color = Color(0xFF0000FF)
Haoyu Zhang437d9452019-01-04 17:34:04 -0800385 val textStyle = TextStyle(background = color)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800386
387 val paragraph = simpleParagraph(
388 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700389 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
390 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800391 )
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800392
Siyamed Sinir63789c92019-09-25 10:44:11 -0700393 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
394 assertThat(paragraph.charSequence)
395 .hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
George Mounta3145782019-05-02 10:08:03 -0700396 span.backgroundColor == color.toArgb()
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800397 }
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800398 }
399
400 @Test
haoyua8e48a52019-06-25 12:23:27 -0700401 fun testAnnotatedString_setBackgroundOnPartText() {
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800402 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700403 val color = Color(0xFF0000FF)
Haoyu Zhang437d9452019-01-04 17:34:04 -0800404 val textStyle = TextStyle(background = color)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800405
406 val paragraph = simpleParagraph(
407 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700408 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
409 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800410 )
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800411
Siyamed Sinir63789c92019-09-25 10:44:11 -0700412 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
413 assertThat(paragraph.charSequence)
414 .hasSpan(BackgroundColorSpan::class, 0, "abc".length) { span ->
George Mounta3145782019-05-02 10:08:03 -0700415 span.backgroundColor == color.toArgb()
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800416 }
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800417 }
418
419 @Test
haoyua8e48a52019-06-25 12:23:27 -0700420 fun testAnnotatedString_setBackgroundTwice_lastOneOverwrite() {
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800421 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700422 val color = Color(0xFF0000FF)
Haoyu Zhang437d9452019-01-04 17:34:04 -0800423 val textStyle = TextStyle(background = color)
George Mountaa12c482019-08-14 14:51:38 -0700424 val colorOverwrite = Color(0xFF00FF00)
Haoyu Zhang437d9452019-01-04 17:34:04 -0800425 val textStyleOverwrite = TextStyle(background = colorOverwrite)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800426
427 val paragraph = simpleParagraph(
428 text = text,
429 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700430 AnnotatedString.Item(textStyle, 0, text.length),
431 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700432 ),
433 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800434 )
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800435
Siyamed Sinir63789c92019-09-25 10:44:11 -0700436 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
437 assertThat(paragraph.charSequence)
438 .hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
George Mounta3145782019-05-02 10:08:03 -0700439 span.backgroundColor == color.toArgb()
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800440 }
Siyamed Sinir63789c92019-09-25 10:44:11 -0700441 assertThat(paragraph.charSequence)
442 .hasSpan(BackgroundColorSpan::class, 0, "abc".length) { span ->
George Mounta3145782019-05-02 10:08:03 -0700443 span.backgroundColor == colorOverwrite.toArgb()
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800444 }
Siyamed Sinir63789c92019-09-25 10:44:11 -0700445 assertThat(paragraph.charSequence)
446 .hasSpanOnTop(BackgroundColorSpan::class, 0, "abc".length) { span ->
George Mounta3145782019-05-02 10:08:03 -0700447 span.backgroundColor == colorOverwrite.toArgb()
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800448 }
Haoyu Zhang0c4fd022019-01-02 13:53:10 -0800449 }
450
451 @Test
haoyua8e48a52019-06-25 12:23:27 -0700452 fun testAnnotatedString_setLocaleOnWholeText() {
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800453 val text = "abcde"
Seigo Nonaka8de69792019-09-04 14:55:15 -0700454 val localeList = LocaleList("en-US")
455 val textStyle = TextStyle(localeList = localeList)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800456
457 val paragraph = simpleParagraph(
458 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700459 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
460 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800461 )
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800462
Siyamed Sinir63789c92019-09-25 10:44:11 -0700463 assertThat(paragraph.charSequence).hasSpan(LocaleSpan::class, 0, text.length)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800464 }
465
466 @Test
haoyua8e48a52019-06-25 12:23:27 -0700467 fun testAnnotatedString_setLocaleOnPartText() {
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800468 val text = "abcde"
Seigo Nonaka8de69792019-09-04 14:55:15 -0700469 val localeList = LocaleList("en-US")
470 val textStyle = TextStyle(localeList = localeList)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800471
472 val paragraph = simpleParagraph(
473 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700474 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
475 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800476 )
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800477
Siyamed Sinir63789c92019-09-25 10:44:11 -0700478 assertThat(paragraph.charSequence).hasSpan(LocaleSpan::class, 0, "abc".length)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800479 }
480
481 @Test
haoyua8e48a52019-06-25 12:23:27 -0700482 fun testAnnotatedString_setLocaleTwice_lastOneOverwrite() {
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800483 val text = "abcde"
Seigo Nonaka8de69792019-09-04 14:55:15 -0700484 val textStyle = TextStyle(localeList = LocaleList("en-US"))
485 val textStyleOverwrite = TextStyle(localeList = LocaleList("ja-JP"))
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800486
487 val paragraph = simpleParagraph(
488 text = text,
489 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700490 AnnotatedString.Item(textStyle, 0, text.length),
491 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700492 ),
493 constraints = ParagraphConstraints(width = 100.0f)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800494 )
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800495
Siyamed Sinir63789c92019-09-25 10:44:11 -0700496 assertThat(paragraph.charSequence).hasSpan(LocaleSpan::class, 0, text.length)
497 assertThat(paragraph.charSequence).hasSpan(LocaleSpan::class, 0, "abc".length)
498 assertThat(paragraph.charSequence).hasSpanOnTop(LocaleSpan::class, 0, "abc".length)
Haoyu Zhang4b201d22018-12-18 14:27:38 -0800499 }
500
501 @Test
haoyua8e48a52019-06-25 12:23:27 -0700502 fun testAnnotatedString_setBaselineShiftOnWholeText() {
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800503 val text = "abcde"
Siyamed Sinirf544c152019-05-21 12:12:21 -0700504 val textStyle = TextStyle(baselineShift = BaselineShift.Subscript)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800505
506 val paragraph = simpleParagraph(
507 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700508 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
509 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800510 )
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800511
Siyamed Sinir63789c92019-09-25 10:44:11 -0700512 assertThat(paragraph.charSequence).hasSpan(BaselineShiftSpan::class, 0, text.length)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800513 }
514
515 @Test
haoyua8e48a52019-06-25 12:23:27 -0700516 fun testAnnotatedString_setBaselineShiftOnPartText() {
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800517 val text = "abcde"
Siyamed Sinirf544c152019-05-21 12:12:21 -0700518 val textStyle = TextStyle(baselineShift = BaselineShift.Superscript)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800519
520 val paragraph = simpleParagraph(
521 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700522 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
523 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800524 )
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800525
Siyamed Sinir63789c92019-09-25 10:44:11 -0700526 assertThat(paragraph.charSequence).hasSpan(BaselineShiftSpan::class, 0, "abc".length)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800527 }
528
529 @Test
haoyua8e48a52019-06-25 12:23:27 -0700530 fun testAnnotatedString_setBaselineShiftTwice_LastOneOnTop() {
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800531 val text = "abcde"
Siyamed Sinirf544c152019-05-21 12:12:21 -0700532 val textStyle = TextStyle(baselineShift = BaselineShift.Subscript)
Siyamed Sinirff51df92019-07-02 15:35:20 -0700533 val textStyleOverwrite =
534 TextStyle(baselineShift = BaselineShift.Superscript)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800535
536 val paragraph = simpleParagraph(
537 text = text,
538 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700539 AnnotatedString.Item(textStyle, 0, text.length),
540 AnnotatedString.Item(textStyleOverwrite, 0, "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700541 ),
542 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800543 )
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800544
Siyamed Sinir63789c92019-09-25 10:44:11 -0700545 assertThat(paragraph.charSequence).hasSpan(BaselineShiftSpan::class, 0, text.length)
546 assertThat(paragraph.charSequence).hasSpan(BaselineShiftSpan::class, 0, "abc".length)
547 assertThat(paragraph.charSequence).hasSpanOnTop(BaselineShiftSpan::class, 0, "abc".length)
Haoyu Zhang40ce6bf2019-01-28 15:58:20 -0800548 }
549
550 @Test
haoyua8e48a52019-06-25 12:23:27 -0700551 fun testAnnotatedString_setTextGeometricTransformWithNull_noSpanSet() {
Haoyu Zhang15750922019-02-19 13:44:17 -0800552 val text = "abcde"
Siyamed Sinirff51df92019-07-02 15:35:20 -0700553 val textStyle =
554 TextStyle(textGeometricTransform = TextGeometricTransform(
555 null,
556 null
557 )
558 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800559
560 val paragraph = simpleParagraph(
561 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700562 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
563 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang15750922019-02-19 13:44:17 -0800564 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800565
Siyamed Sinir63789c92019-09-25 10:44:11 -0700566 assertThat(paragraph.charSequence).spans(ScaleXSpan::class).isEmpty()
567 assertThat(paragraph.charSequence).spans(SkewXSpan::class).isEmpty()
Haoyu Zhang15750922019-02-19 13:44:17 -0800568 }
569
570 @Test
haoyua8e48a52019-06-25 12:23:27 -0700571 fun testAnnotatedString_setTextGeometricTransformWithScaleX() {
Haoyu Zhang15750922019-02-19 13:44:17 -0800572 val text = "abcde"
573 val scaleX = 0.5f
Siyamed Sinirff51df92019-07-02 15:35:20 -0700574 val textStyle = TextStyle(
575 textGeometricTransform = TextGeometricTransform(
576 scaleX,
577 null
578 )
579 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800580
581 val paragraph = simpleParagraph(
582 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700583 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
584 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang15750922019-02-19 13:44:17 -0800585 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800586
Siyamed Sinir63789c92019-09-25 10:44:11 -0700587 assertThat(paragraph.charSequence).hasSpan(ScaleXSpan::class, 0, text.length) {
588 it.scaleX == scaleX
589 }
590 assertThat(paragraph.charSequence).spans(SkewXSpan::class).isEmpty()
Haoyu Zhang15750922019-02-19 13:44:17 -0800591 }
592
593 @Test
haoyua8e48a52019-06-25 12:23:27 -0700594 fun testAnnotatedString_setTextGeometricTransformWithSkewX() {
Haoyu Zhang15750922019-02-19 13:44:17 -0800595 val text = "aa"
596 val skewX = 1f
Siyamed Sinirff51df92019-07-02 15:35:20 -0700597 val textStyle =
598 TextStyle(textGeometricTransform = TextGeometricTransform(
599 null,
600 skewX
601 )
602 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800603
604 val paragraph = simpleParagraph(
605 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700606 textStyles = listOf(AnnotatedString.Item(textStyle, 0, text.length)),
607 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang15750922019-02-19 13:44:17 -0800608 )
Haoyu Zhang15750922019-02-19 13:44:17 -0800609
Siyamed Sinir63789c92019-09-25 10:44:11 -0700610 assertThat(paragraph.charSequence).hasSpan(SkewXSpan::class, 0, text.length) {
611 it.skewX == skewX
612 }
613 assertThat(paragraph.charSequence).spans(ScaleXSpan::class).isEmpty()
Haoyu Zhang15750922019-02-19 13:44:17 -0800614 }
615
616 @Test
Siyamed Sinir2690d532019-06-21 13:16:00 -0700617 fun textIndent_onWholeParagraph() {
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800618 val text = "abc\ndef"
619 val firstLine = 40
620 val restLine = 20
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800621
622 val paragraph = simpleParagraph(
623 text = text,
Haoyu Zhangb0e43c12019-10-15 16:37:51 -0700624 textIndent = TextIndent(firstLine.sp, restLine.sp),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700625 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800626 )
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800627
Siyamed Sinir63789c92019-09-25 10:44:11 -0700628 assertThat(paragraph.charSequence)
629 .hasSpan(LeadingMarginSpan.Standard::class, 0, text.length) {
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800630 it.getLeadingMargin(true) == firstLine && it.getLeadingMargin(false) == restLine
631 }
Haoyu Zhang7fc59172019-03-01 17:03:31 -0800632 }
633
634 @Test
haoyua8e48a52019-06-25 12:23:27 -0700635 fun testAnnotatedString_setShadow() {
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800636 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700637 val color = Color(0xFF00FF00)
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800638 val offset = Offset(1f, 2f)
639 val radius = 3.px
640 val textStyle = TextStyle(shadow = Shadow(color, offset, radius))
641
642 val paragraph = simpleParagraph(
643 text = text,
644 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700645 AnnotatedString.Item(textStyle, start = 0, end = text.length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700646 ),
647 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800648 )
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800649
Siyamed Sinir63789c92019-09-25 10:44:11 -0700650 assertThat(paragraph.charSequence)
651 .hasSpan(ShadowSpan::class, start = 0, end = text.length) {
George Mounta3145782019-05-02 10:08:03 -0700652 return@hasSpan it.color == color.toArgb() &&
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800653 it.offsetX == offset.dx &&
654 it.offsetY == offset.dy &&
655 it.radius == radius.value
656 }
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800657 }
658
659 @Test
haoyua8e48a52019-06-25 12:23:27 -0700660 fun testAnnotatedString_setShadowTwice_lastOnTop() {
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800661 val text = "abcde"
George Mountaa12c482019-08-14 14:51:38 -0700662 val color = Color(0xFF00FF00)
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800663 val offset = Offset(1f, 2f)
664 val radius = 3.px
665 val textStyle = TextStyle(shadow = Shadow(color, offset, radius))
666
George Mountaa12c482019-08-14 14:51:38 -0700667 val colorOverwrite = Color(0xFF0000FF)
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800668 val offsetOverwrite = Offset(3f, 2f)
669 val radiusOverwrite = 1.px
670 val textStyleOverwrite = TextStyle(
671 shadow = Shadow(colorOverwrite, offsetOverwrite, radiusOverwrite)
672 )
673
674 val paragraph = simpleParagraph(
675 text = text,
676 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700677 AnnotatedString.Item(textStyle, start = 0, end = text.length),
678 AnnotatedString.Item(textStyleOverwrite, start = 0, end = "abc".length)
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700679 ),
680 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800681 )
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800682
Siyamed Sinir63789c92019-09-25 10:44:11 -0700683 assertThat(paragraph.charSequence)
684 .hasSpan(ShadowSpan::class, start = 0, end = text.length) {
George Mounta3145782019-05-02 10:08:03 -0700685 return@hasSpan it.color == color.toArgb() &&
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800686 it.offsetX == offset.dx &&
687 it.offsetY == offset.dy &&
688 it.radius == radius.value
689 }
Siyamed Sinir63789c92019-09-25 10:44:11 -0700690 assertThat(paragraph.charSequence)
691 .hasSpanOnTop(ShadowSpan::class, start = 0, end = "abc".length) {
George Mounta3145782019-05-02 10:08:03 -0700692 return@hasSpanOnTop it.color == colorOverwrite.toArgb() &&
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800693 it.offsetX == offsetOverwrite.dx &&
694 it.offsetY == offsetOverwrite.dy &&
695 it.radius == radiusOverwrite.value
696 }
Haoyu Zhang2a036c832019-03-08 11:57:13 -0800697 }
698
699 @Test
haoyua8e48a52019-06-25 12:23:27 -0700700 fun testAnnotatedString_fontFamily_addsTypefaceSpanWithCorrectTypeface() {
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800701 val text = "abcde"
702 val textStyle = TextStyle(
703 fontFamily = fontFamily,
Siyamed Siniradf982d2019-05-20 17:35:13 -0700704 fontStyle = FontStyle.Italic,
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700705 fontWeight = FontWeight.Bold
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800706 )
707 val expectedTypeface = TypefaceAdapter().create(
708 fontFamily = fontFamily,
Siyamed Siniradf982d2019-05-20 17:35:13 -0700709 fontStyle = FontStyle.Italic,
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700710 fontWeight = FontWeight.Bold
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800711 )
Siyamed Sinir37298412018-12-27 19:47:15 -0800712 val expectedStart = 0
713 val expectedEnd = "abc".length
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800714
715 val paragraph = simpleParagraph(
716 text = text,
Siyamed Sinir37298412018-12-27 19:47:15 -0800717 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700718 AnnotatedString.Item(
Siyamed Sinir37298412018-12-27 19:47:15 -0800719 textStyle,
720 expectedStart,
721 expectedEnd
722 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700723 ),
724 constraints = ParagraphConstraints(width = 100.0f)
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800725 )
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800726
Siyamed Sinir63789c92019-09-25 10:44:11 -0700727 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
728 assertThat(paragraph.charSequence)
729 .hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800730 span.typeface == expectedTypeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700731 }
Siyamed Sinir37298412018-12-27 19:47:15 -0800732 }
733
734 @Test
haoyua8e48a52019-06-25 12:23:27 -0700735 fun testAnnotatedString_fontFamily_whenFontSynthesizeTurnedOff() {
Siyamed Sinir37298412018-12-27 19:47:15 -0800736 val text = "abcde"
737 val textStyle = TextStyle(
738 fontFamily = fontFamily,
Siyamed Siniradf982d2019-05-20 17:35:13 -0700739 fontStyle = FontStyle.Italic,
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700740 fontWeight = FontWeight.Bold,
Siyamed Sinir934a3442019-06-18 12:57:13 -0700741 fontSynthesis = FontSynthesis.None
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800742 )
Siyamed Sinir37298412018-12-27 19:47:15 -0800743 val expectedTypeface = TypefaceAdapter().create(
744 fontFamily = fontFamily,
Siyamed Siniradf982d2019-05-20 17:35:13 -0700745 fontStyle = FontStyle.Italic,
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700746 fontWeight = FontWeight.Bold,
Siyamed Sinir934a3442019-06-18 12:57:13 -0700747 fontSynthesis = FontSynthesis.None
Siyamed Sinir37298412018-12-27 19:47:15 -0800748 )
749 val expectedStart = 0
750 val expectedEnd = "abc".length
751
752 val paragraph = simpleParagraph(
753 text = text,
754 textStyles = listOf(
Haoyu Zhang27429892019-06-11 13:19:57 -0700755 AnnotatedString.Item(
Siyamed Sinir37298412018-12-27 19:47:15 -0800756 textStyle,
757 expectedStart,
758 expectedEnd
759 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700760 ),
761 constraints = ParagraphConstraints(width = 100.0f)
Siyamed Sinir37298412018-12-27 19:47:15 -0800762 )
Siyamed Sinir37298412018-12-27 19:47:15 -0800763
Siyamed Sinir63789c92019-09-25 10:44:11 -0700764 assertThat(paragraph.charSequence.toString()).isEqualTo(text)
765 assertThat(paragraph.charSequence)
766 .hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
Siyamed Sinir37298412018-12-27 19:47:15 -0800767 span.typeface == expectedTypeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700768 }
Siyamed Sinir70f336a2018-12-27 10:37:09 -0800769 }
770
771 @Test
haoyua8e48a52019-06-25 12:23:27 -0700772 fun testAnnotatedString_fontFeatureSetting_setSpanOnText() {
Haoyu Zhang588aaef2019-02-20 14:47:39 -0800773 val text = "abc"
774 val fontFeatureSettings = "\"kern\" 0"
775 val textStyle = TextStyle(fontFeatureSettings = fontFeatureSettings)
776
777 val paragraph = simpleParagraph(
778 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700779 textStyles = listOf(AnnotatedString.Item(textStyle, 0, "abc".length)),
780 constraints = ParagraphConstraints(width = 100.0f) // width is not important
Haoyu Zhang588aaef2019-02-20 14:47:39 -0800781 )
Haoyu Zhang588aaef2019-02-20 14:47:39 -0800782
Siyamed Sinir63789c92019-09-25 10:44:11 -0700783 assertThat(paragraph.charSequence).hasSpan(FontFeatureSpan::class, 0, "abc".length) {
784 it.fontFeatureSettings == fontFeatureSettings
785 }
Haoyu Zhang588aaef2019-02-20 14:47:39 -0800786 }
787
788 @Test
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800789 fun testEmptyFontFamily() {
790 val typefaceAdapter = mock<TypefaceAdapter>()
791 val paragraph = simpleParagraph(
792 text = "abc",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700793 typefaceAdapter = typefaceAdapter,
794 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800795 )
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800796
797 verify(typefaceAdapter, never()).create(
798 fontFamily = any(),
799 fontWeight = any(),
Siyamed Sinir21796012018-12-26 13:51:17 -0800800 fontStyle = any(),
801 fontSynthesis = any()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800802 )
Siyamed Sinir63789c92019-09-25 10:44:11 -0700803 assertThat(paragraph.textPaint.typeface).isNull()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800804 }
805
806 @Test
807 fun testEmptyFontFamily_withBoldFontWeightSelection() {
808 val typefaceAdapter = spy(TypefaceAdapter())
809
810 val paragraph = simpleParagraph(
811 text = "abc",
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700812 textStyle = TextStyle(
813 fontFamily = null,
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700814 fontWeight = FontWeight.Bold
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700815 ),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700816 typefaceAdapter = typefaceAdapter,
817 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800818 )
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800819
820 verify(typefaceAdapter, times(1)).create(
821 fontFamily = eq(null),
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700822 fontWeight = eq(FontWeight.Bold),
Siyamed Siniradf982d2019-05-20 17:35:13 -0700823 fontStyle = eq(FontStyle.Normal),
Siyamed Sinir934a3442019-06-18 12:57:13 -0700824 fontSynthesis = eq(FontSynthesis.All)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800825 )
826
827 val typeface = paragraph.textPaint.typeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700828 assertThat(typeface).isNotNull()
829 assertThat(typeface.isBold).isTrue()
830 assertThat(typeface.isItalic).isFalse()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800831 }
832
833 @Test
834 fun testEmptyFontFamily_withFontStyleSelection() {
835 val typefaceAdapter = spy(TypefaceAdapter())
836 val paragraph = simpleParagraph(
837 text = "abc",
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700838 textStyle = TextStyle(
839 fontFamily = null,
840 fontStyle = FontStyle.Italic
841 ),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700842 typefaceAdapter = typefaceAdapter,
843 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800844 )
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800845
846 verify(typefaceAdapter, times(1)).create(
847 fontFamily = eq(null),
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700848 fontWeight = eq(FontWeight.Normal),
Siyamed Siniradf982d2019-05-20 17:35:13 -0700849 fontStyle = eq(FontStyle.Italic),
Siyamed Sinir934a3442019-06-18 12:57:13 -0700850 fontSynthesis = eq(FontSynthesis.All)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800851 )
852
853 val typeface = paragraph.textPaint.typeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700854 assertThat(typeface).isNotNull()
855 assertThat(typeface.isBold).isFalse()
856 assertThat(typeface.isItalic).isTrue()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800857 }
858
859 @Test
860 fun testFontFamily_withGenericFamilyName() {
861 val typefaceAdapter = spy(TypefaceAdapter())
862 val fontFamily = FontFamily("sans-serif")
863
864 val paragraph = simpleParagraph(
865 text = "abc",
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700866 textStyle = TextStyle(
867 fontFamily = fontFamily
868 ),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700869 typefaceAdapter = typefaceAdapter,
870 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800871 )
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800872
873 verify(typefaceAdapter, times(1)).create(
874 fontFamily = eq(fontFamily),
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700875 fontWeight = eq(FontWeight.Normal),
Siyamed Siniradf982d2019-05-20 17:35:13 -0700876 fontStyle = eq(FontStyle.Normal),
Siyamed Sinir934a3442019-06-18 12:57:13 -0700877 fontSynthesis = eq(FontSynthesis.All)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800878 )
879
880 val typeface = paragraph.textPaint.typeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700881 assertThat(typeface).isNotNull()
882 assertThat(typeface.isBold).isFalse()
883 assertThat(typeface.isItalic).isFalse()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800884 }
885
886 @Test
887 fun testFontFamily_withCustomFont() {
888 val typefaceAdapter = spy(TypefaceAdapter())
889 val paragraph = simpleParagraph(
890 text = "abc",
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700891 textStyle = TextStyle(
892 fontFamily = fontFamily
893 ),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700894 typefaceAdapter = typefaceAdapter,
895 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800896 )
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800897
898 verify(typefaceAdapter, times(1)).create(
899 fontFamily = eq(fontFamily),
Siyamed Sinirdc8f5742019-10-04 21:03:28 -0700900 fontWeight = eq(FontWeight.Normal),
Siyamed Siniradf982d2019-05-20 17:35:13 -0700901 fontStyle = eq(FontStyle.Normal),
Siyamed Sinir934a3442019-06-18 12:57:13 -0700902 fontSynthesis = eq(FontSynthesis.All)
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800903 )
904 val typeface = paragraph.textPaint.typeface
Siyamed Sinir63789c92019-09-25 10:44:11 -0700905 assertThat(typeface.isBold).isFalse()
906 assertThat(typeface.isItalic).isFalse()
Siyamed Sinirf18dcca2018-12-20 18:25:10 -0800907 }
908
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800909 @Test
910 fun testEllipsis_withMaxLineEqualsNull_doesNotEllipsis() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700911 withDensity(defaultDensity) {
912 val text = "abc"
913 val fontSize = 20.sp
914 val paragraphWidth = (text.length - 1) * fontSize.toPx().value
915 val paragraph = simpleParagraph(
916 text = text,
917 textStyle = TextStyle(
918 fontFamily = fontFamily,
919 fontSize = fontSize
920 ),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700921 ellipsis = true,
922 constraints = ParagraphConstraints(width = paragraphWidth)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700923 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700924
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700925 for (i in 0 until paragraph.lineCount) {
Siyamed Sinir63789c92019-09-25 10:44:11 -0700926 assertThat(paragraph.isEllipsisApplied(i)).isFalse()
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700927 }
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800928 }
929 }
930
931 @Test
932 fun testEllipsis_withMaxLinesLessThanTextLines_doesEllipsis() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700933 withDensity(defaultDensity) {
934 val text = "abcde"
935 val fontSize = 100.sp
936 // Note that on API 21, if the next line only contains 1 character, ellipsis won't work
937 val paragraphWidth = (text.length - 1.5f) * fontSize.toPx().value
938 val paragraph = simpleParagraph(
939 text = text,
940 ellipsis = true,
941 maxLines = 1,
942 textStyle = TextStyle(
943 fontFamily = fontFamily,
944 fontSize = fontSize
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700945 ),
946 constraints = ParagraphConstraints(width = paragraphWidth)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700947 )
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800948
Siyamed Sinir63789c92019-09-25 10:44:11 -0700949 assertThat(paragraph.isEllipsisApplied(0)).isTrue()
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700950 }
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800951 }
952
953 @Test
954 fun testEllipsis_withMaxLinesMoreThanTextLines_doesNotEllipsis() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700955 withDensity(defaultDensity) {
956 val text = "abc"
957 val fontSize = 100.sp
958 val paragraphWidth = (text.length - 1) * fontSize.toPx().value
959 val maxLines = ceil(text.length * fontSize.toPx().value / paragraphWidth).toInt()
960 val paragraph = simpleParagraph(
961 text = text,
962 ellipsis = true,
963 maxLines = maxLines,
964 textStyle = TextStyle(
965 fontFamily = fontFamily,
966 fontSize = fontSize
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700967 ),
968 constraints = ParagraphConstraints(width = paragraphWidth)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700969 )
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800970
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700971 for (i in 0 until paragraph.lineCount) {
Siyamed Sinir63789c92019-09-25 10:44:11 -0700972 assertThat(paragraph.isEllipsisApplied(i)).isFalse()
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700973 }
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -0800974 }
975 }
976
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700977 @Test
978 fun testTextStyle_fontSize_appliedOnTextPaint() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700979 withDensity(defaultDensity) {
980 val fontSize = 100.sp
981 val paragraph = simpleParagraph(
982 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -0700983 textStyle = TextStyle(fontSize = fontSize),
984 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700985 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700986
Siyamed Sinir63789c92019-09-25 10:44:11 -0700987 assertThat(paragraph.textPaint.textSize).isEqualTo(fontSize.toPx().value)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700988 }
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -0700989 }
990
991 @Test
992 fun testTextStyle_fontSizeScale_appliedOnTextPaint() {
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -0700993 withDensity(defaultDensity) {
994 val fontSize = 100.sp
995 val fontSizeScale = 2f
996 val paragraph = simpleParagraph(
997 text = "",
998 textStyle = TextStyle(
999 fontSize = fontSize,
1000 fontSizeScale = fontSizeScale
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001001 ),
1002 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001003 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001004
Siyamed Sinir63789c92019-09-25 10:44:11 -07001005 assertThat(paragraph.textPaint.textSize).isEqualTo(fontSize.toPx().value *fontSizeScale)
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -07001006 }
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001007 }
1008
1009 @Test
1010 fun testTextStyle_locale_appliedOnTextPaint() {
Seigo Nonaka8de69792019-09-04 14:55:15 -07001011 val platformLocale = java.util.Locale.JAPANESE
1012 val localeList = LocaleList(platformLocale.toLanguageTag())
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001013
1014 val paragraph = simpleParagraph(
1015 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001016 textStyle = TextStyle(localeList = localeList),
1017 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001018 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001019
Siyamed Sinir63789c92019-09-25 10:44:11 -07001020 assertThat(paragraph.textPaint.textLocale.language).isEqualTo(platformLocale.language)
1021 assertThat(paragraph.textPaint.textLocale.country).isEqualTo(platformLocale.country)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001022 }
1023
1024 @Test
1025 fun testTextStyle_color_appliedOnTextPaint() {
1026 val color = Color(0x12345678)
1027 val paragraph = simpleParagraph(
1028 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001029 textStyle = TextStyle(color = color),
1030 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001031 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001032
Siyamed Sinir63789c92019-09-25 10:44:11 -07001033 assertThat(paragraph.textPaint.color).isEqualTo(color.toArgb())
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001034 }
1035
1036 @Test
1037 fun testTextStyle_letterSpacing_appliedOnTextPaint() {
Haoyu Zhangf2e9e032019-10-16 15:23:39 -07001038 val letterSpacing = 2
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001039 val paragraph = simpleParagraph(
1040 text = "",
Haoyu Zhangf2e9e032019-10-16 15:23:39 -07001041 textStyle = TextStyle(letterSpacing = letterSpacing.em),
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001042 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001043 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001044
Siyamed Sinir63789c92019-09-25 10:44:11 -07001045 assertThat(paragraph.textPaint.letterSpacing).isEqualTo((letterSpacing))
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001046 }
1047
1048 @Test
1049 fun testTextStyle_fontFeatureSettings_appliedOnTextPaint() {
1050 val fontFeatureSettings = "\"kern\" 0"
1051 val paragraph = simpleParagraph(
1052 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001053 textStyle = TextStyle(fontFeatureSettings = fontFeatureSettings),
1054 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001055 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001056
Siyamed Sinir63789c92019-09-25 10:44:11 -07001057 assertThat(paragraph.textPaint.fontFeatureSettings).isEqualTo(fontFeatureSettings)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001058 }
1059
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001060 @Test
1061 fun testTextStyle_scaleX_appliedOnTextPaint() {
1062 val scaleX = 0.5f
1063 val paragraph = simpleParagraph(
1064 text = "",
1065 textStyle = TextStyle(
1066 textGeometricTransform = TextGeometricTransform(
1067 scaleX = scaleX
1068 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001069 ),
1070 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001071 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001072
Siyamed Sinir63789c92019-09-25 10:44:11 -07001073 assertThat(paragraph.textPaint.textScaleX).isEqualTo(scaleX)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001074 }
1075
1076 @Test
1077 fun testTextStyle_skewX_appliedOnTextPaint() {
1078 val skewX = 0.5f
1079 val paragraph = simpleParagraph(
1080 text = "",
1081 textStyle = TextStyle(
1082 textGeometricTransform = TextGeometricTransform(
1083 skewX = skewX
1084 )
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001085 ),
1086 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001087 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001088
Siyamed Sinir63789c92019-09-25 10:44:11 -07001089 assertThat(paragraph.textPaint.textSkewX).isEqualTo(skewX)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001090 }
1091
1092 @Test
1093 fun testTextStyle_decoration_underline_appliedOnTextPaint() {
1094 val paragraph = simpleParagraph(
1095 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001096 textStyle = TextStyle(decoration = TextDecoration.Underline),
1097 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001098 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001099
Siyamed Sinir18914522019-09-25 15:41:44 -07001100 assertThat(paragraph.textPaint.isUnderlineText).isTrue()
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001101 }
1102
1103 @Test
1104 fun testTextStyle_decoration_lineThrough_appliedOnTextPaint() {
1105 val paragraph = simpleParagraph(
1106 text = "",
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001107 textStyle = TextStyle(decoration = TextDecoration.LineThrough),
1108 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001109 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001110
Siyamed Sinir18914522019-09-25 15:41:44 -07001111 assertThat(paragraph.textPaint.isStrikeThruText).isTrue()
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001112 }
1113
1114 @Test
1115 fun testTextStyle_background_appliedAsSpan() {
1116 // bgColor is reset in the Android Layout constructor.
1117 // therefore we cannot apply them on paint, have to use spans.
1118 val text = "abc"
1119 val color = Color(0x12345678)
1120 val paragraph = simpleParagraph(
1121 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001122 textStyle = TextStyle(background = color),
1123 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001124 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001125
Siyamed Sinir63789c92019-09-25 10:44:11 -07001126 assertThat(paragraph.charSequence)
1127 .hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001128 span.backgroundColor == color.toArgb()
1129 }
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001130 }
1131
1132 @Test
1133 fun testTextStyle_baselineShift_appliedAsSpan() {
1134 // baselineShift is reset in the Android Layout constructor.
1135 // therefore we cannot apply them on paint, have to use spans.
1136 val text = "abc"
1137 val baselineShift = BaselineShift.Subscript
1138 val paragraph = simpleParagraph(
1139 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001140 textStyle = TextStyle(baselineShift = baselineShift),
1141 constraints = ParagraphConstraints(width = 0.0f)
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001142 )
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001143
Siyamed Sinir63789c92019-09-25 10:44:11 -07001144 assertThat(paragraph.charSequence)
1145 .hasSpan(BaselineShiftSpan::class, 0, text.length) { span ->
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001146 span.multiplier == BaselineShift.Subscript.multiplier
1147 }
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001148 }
1149
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001150 @Test
1151 fun locale_isDefaultLocaleIfNotProvided() {
1152 val text = "abc"
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001153 val paragraph = simpleParagraph(
1154 text = text,
1155 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
1156 )
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001157
Siyamed Sinir63789c92019-09-25 10:44:11 -07001158 assertThat(paragraph.textLocale.toLanguageTag())
1159 .isEqualTo(java.util.Locale.getDefault().toLanguageTag())
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001160 }
1161
1162 @Test
1163 fun locale_isSetOnParagraphImpl_enUS() {
Seigo Nonaka8de69792019-09-04 14:55:15 -07001164 val localeList = LocaleList("en-US")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001165 val text = "abc"
1166 val paragraph = simpleParagraph(
1167 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001168 textStyle = TextStyle(localeList = localeList),
1169 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001170 )
1171
Siyamed Sinir63789c92019-09-25 10:44:11 -07001172 assertThat(paragraph.textLocale.toLanguageTag()).isEqualTo("en-US")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001173 }
1174
1175 @Test
1176 fun locale_isSetOnParagraphImpl_jpJP() {
Seigo Nonaka8de69792019-09-04 14:55:15 -07001177 val localeList = LocaleList("ja-JP")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001178 val text = "abc"
1179 val paragraph = simpleParagraph(
1180 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001181 textStyle = TextStyle(localeList = localeList),
1182 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001183 )
1184
Siyamed Sinir63789c92019-09-25 10:44:11 -07001185 assertThat(paragraph.textLocale.toLanguageTag()).isEqualTo("ja-JP")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001186 }
1187
1188 @Test
1189 fun locale_noCountryCode_isSetOnParagraphImpl() {
Seigo Nonaka8de69792019-09-04 14:55:15 -07001190 val localeList = LocaleList("ja")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001191 val text = "abc"
1192 val paragraph = simpleParagraph(
1193 text = text,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001194 textStyle = TextStyle(localeList = localeList),
1195 constraints = ParagraphConstraints(width = Float.MAX_VALUE)
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001196 )
1197
Siyamed Sinir63789c92019-09-25 10:44:11 -07001198 assertThat(paragraph.textLocale.toLanguageTag()).isEqualTo("ja")
Siyamed Sinir031e5bf2019-07-02 11:49:05 -07001199 }
1200
Seigo Nonakac4f136a2019-08-16 16:48:44 -07001201 @Test
Seigo Nonakaad4a3772019-08-26 12:06:58 -07001202 fun floatingWidth() {
1203 val floatWidth = 1.3f
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001204 val paragraph = simpleParagraph(
1205 text = "Hello, World",
1206 constraints = ParagraphConstraints(floatWidth)
1207 )
1208
Siyamed Sinir63789c92019-09-25 10:44:11 -07001209 assertThat(floatWidth).isEqualTo(paragraph.width)
Seigo Nonakaad4a3772019-08-26 12:06:58 -07001210 }
1211
Haoyu Zhang10fc6502018-11-09 15:50:11 -08001212 private fun simpleParagraph(
Haoyu Zhang27429892019-06-11 13:19:57 -07001213 text: String = "",
1214 textStyles: List<AnnotatedString.Item<TextStyle>> = listOf(),
Siyamed Sinir2690d532019-06-21 13:16:00 -07001215 textIndent: TextIndent? = null,
Haoyu Zhang10fc6502018-11-09 15:50:11 -08001216 textAlign: TextAlign? = null,
Siyamed Sinir504d5b02019-09-24 13:39:43 -07001217 textDirectionAlgorithm: TextDirectionAlgorithm? = TextDirectionAlgorithm.ContentOrLtr,
Haoyu Zhangc11ef5a2019-01-14 16:35:05 -08001218 ellipsis: Boolean? = null,
Siyamed Sinirf18dcca2018-12-20 18:25:10 -08001219 maxLines: Int? = null,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001220 constraints: ParagraphConstraints,
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001221 textStyle: TextStyle? = null,
Siyamed Sinirf18dcca2018-12-20 18:25:10 -08001222 typefaceAdapter: TypefaceAdapter = TypefaceAdapter()
Siyamed Sinire75976f2019-07-03 09:24:30 -07001223 ): AndroidParagraph {
1224 return AndroidParagraph(
Haoyu Zhang27429892019-06-11 13:19:57 -07001225 text = text,
Haoyu Zhang47f57a22018-12-12 13:16:40 -08001226 textStyles = textStyles,
Siyamed Sinirf18dcca2018-12-20 18:25:10 -08001227 typefaceAdapter = typefaceAdapter,
Siyamed Sinirbf9f3ba2019-06-25 22:40:56 -07001228 style = TextStyle().merge(textStyle),
Siyamed Sinir883e0232019-06-25 12:38:12 -07001229 paragraphStyle = ParagraphStyle(
1230 textAlign = textAlign,
Siyamed Sinir504d5b02019-09-24 13:39:43 -07001231 textIndent = textIndent,
1232 textDirectionAlgorithm = textDirectionAlgorithm
Siyamed Sinir7d4c98f2019-06-27 16:23:31 -07001233 ),
Siyamed Sinir6a1f0362019-07-08 15:58:32 -07001234 maxLines = maxLines,
1235 ellipsis = ellipsis,
Siyamed Sinir3f44b9a2019-09-21 13:13:38 -07001236 constraints = constraints,
Siyamed Sinir504d5b02019-09-24 13:39:43 -07001237 density = Density(density = 1f)
Haoyu Zhang10fc6502018-11-09 15:50:11 -08001238 )
1239 }
Siyamed Sinir472ed132019-07-03 15:43:43 -07001240
1241 private fun TypefaceAdapter() = TypefaceAdapter(
Siyamed Sinirc4c308e2019-07-03 16:14:22 -07001242 resourceLoader = TestFontResourceLoader(context)
Siyamed Sinir472ed132019-07-03 15:43:43 -07001243 )
Siyamed Sinir2690d532019-06-21 13:16:00 -07001244}