[go: nahoru, domu]

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()),