Covert TextDecoration to framework UnderlineSpan and StrikeThroughSpan
Bug: 121157451
Test: ./gradlew ui-port:test
Test: ./gradlew ui-port:connectedAndroidTest
Change-Id: I769219ccf32ceabde61c183b69fee6acd83ef6e1
diff --git a/ui/port/src/androidTest/java/androidx/ui/port/engine/text/platform/ParagraphAndroidTest.kt b/ui/port/src/androidTest/java/androidx/ui/port/engine/text/platform/ParagraphAndroidTest.kt
index 27875c02..4223e5e 100644
--- a/ui/port/src/androidTest/java/androidx/ui/port/engine/text/platform/ParagraphAndroidTest.kt
+++ b/ui/port/src/androidTest/java/androidx/ui/port/engine/text/platform/ParagraphAndroidTest.kt
@@ -6,6 +6,8 @@
import android.text.TextPaint
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
+import android.text.style.StrikethroughSpan
+import android.text.style.UnderlineSpan
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.text.StaticLayoutCompat
@@ -13,6 +15,7 @@
import androidx.ui.engine.text.ParagraphBuilder
import androidx.ui.engine.text.ParagraphStyle
import androidx.ui.engine.text.TextAlign
+import androidx.ui.engine.text.TextDecoration
import androidx.ui.engine.text.TextStyle
import androidx.ui.engine.text.platform.ParagraphAndroid
import androidx.ui.painting.Color
@@ -20,6 +23,7 @@
import androidx.ui.port.matchers.equalToBitmap
import androidx.ui.port.matchers.hasSpan
import androidx.ui.port.matchers.hasSpanOnTop
+import org.hamcrest.Matchers.equalTo
import org.junit.Assert.assertThat
import org.junit.Before
import org.junit.Test
@@ -132,6 +136,86 @@
}
@Test
+ fun testStyle_setTextDecorationOnWholeText_withLineThrough() {
+ val text = "abcde"
+ val textStyle = TextStyle(decoration = TextDecoration.lineThrough)
+
+ val paragraph = simpleParagraph(
+ text = text,
+ textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
+ )
+ paragraph.layout(100.0)
+
+ assertThat(paragraph.underlyingText.toString(), equalTo(text))
+ assertThat(paragraph.underlyingText, hasSpan(StrikethroughSpan::class, 0, text.length))
+ }
+
+ @Test
+ fun testStyle_setTextDecorationOnWholeText_withUnderline() {
+ val text = "abcde"
+ val textStyle = TextStyle(decoration = TextDecoration.underline)
+
+ val paragraph = simpleParagraph(
+ text = text,
+ textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
+ )
+ paragraph.layout(100.0)
+
+ assertThat(paragraph.underlyingText.toString(), equalTo(text))
+ assertThat(paragraph.underlyingText, hasSpan(UnderlineSpan::class, 0, text.length))
+ }
+
+ @Test
+ fun testStyle_setTextDecorationOnPartText_withLineThrough() {
+ val text = "abcde"
+ val textStyle = TextStyle(decoration = TextDecoration.lineThrough)
+
+ val paragraph = simpleParagraph(
+ text = text,
+ textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
+ )
+ paragraph.layout(100.0)
+
+ assertThat(paragraph.underlyingText.toString(), equalTo(text))
+ assertThat(paragraph.underlyingText, hasSpan(StrikethroughSpan::class, 0, "abc".length))
+ }
+
+ @Test
+ fun testStyle_setTextDecorationOnPartText_withUnderline() {
+ val text = "abcde"
+ val textStyle = TextStyle(decoration = TextDecoration.underline)
+
+ val paragraph = simpleParagraph(
+ text = text,
+ textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
+ )
+ paragraph.layout(100.0)
+
+ assertThat(paragraph.underlyingText.toString(), equalTo(text))
+ assertThat(paragraph.underlyingText, hasSpan(UnderlineSpan::class, 0, "abc".length))
+ }
+
+ @Test
+ fun testStyle_setTextDecoration_withLineThroughAndUnderline() {
+ val text = "abcde"
+ val textStyle = TextStyle(
+ decoration = TextDecoration.combine(
+ listOf(TextDecoration.lineThrough, TextDecoration.underline)
+ )
+ )
+
+ val paragraph = simpleParagraph(
+ text = text,
+ textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
+ )
+ paragraph.layout(100.0)
+
+ assertThat(paragraph.underlyingText.toString(), equalTo(text))
+ assertThat(paragraph.underlyingText, hasSpan(UnderlineSpan::class, 0, "abc".length))
+ assertThat(paragraph.underlyingText, hasSpan(StrikethroughSpan::class, 0, "abc".length))
+ }
+
+ @Test
fun textStyle_setFontSizeOnWholeText() {
val text = "abcde"
val fontSize = 20.0
diff --git a/ui/port/src/main/java/androidx/ui/engine/text/platform/ParagraphAndroid.kt b/ui/port/src/main/java/androidx/ui/engine/text/platform/ParagraphAndroid.kt
index ee86092..427a19e 100644
--- a/ui/port/src/main/java/androidx/ui/engine/text/platform/ParagraphAndroid.kt
+++ b/ui/port/src/main/java/androidx/ui/engine/text/platform/ParagraphAndroid.kt
@@ -20,6 +20,8 @@
import android.text.TextPaint
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
+import android.text.style.StrikethroughSpan
+import android.text.style.UnderlineSpan
import androidx.text.LayoutCompat.ALIGN_CENTER
import androidx.text.LayoutCompat.ALIGN_LEFT
import androidx.text.LayoutCompat.ALIGN_NORMAL
@@ -39,6 +41,7 @@
import androidx.ui.engine.text.ParagraphStyle
import androidx.ui.engine.text.TextAffinity
import androidx.ui.engine.text.TextAlign
+import androidx.ui.engine.text.TextDecoration
import androidx.ui.engine.text.TextDirection
import androidx.ui.engine.text.TextPosition
import androidx.ui.painting.Canvas
@@ -200,7 +203,29 @@
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
}
- // TODO(Migration/haoyuchang): implement decoration, decorationStyle, decorationColor
+ // TODO(Migration/haoyuchang): implement decorationStyle, decorationColor
+ style.decoration?.let {
+ if (it.contains(TextDecoration.underline)) {
+ spannableString.setSpan(
+ UnderlineSpan(),
+ start,
+ end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }
+ if (it.contains(TextDecoration.overline)) {
+ // TODO(Migration/haoyuchang): implement overline
+ }
+ if (it.contains(TextDecoration.lineThrough)) {
+ spannableString.setSpan(
+ StrikethroughSpan(),
+ start,
+ end,
+ Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+ )
+ }
+ }
+
style.fontSize?.let {
spannableString.setSpan(
AbsoluteSizeSpan(it.roundToInt()),