[go: nahoru, domu]

blob: 595f4ae6874b9c190e6d7d16adf8a85b6811d65f [file] [log] [blame]
package androidx.ui.port.engine.text.platform
import android.graphics.Paint
import android.text.TextPaint
import android.text.style.AbsoluteSizeSpan
import android.text.style.BackgroundColorSpan
import android.text.style.ForegroundColorSpan
import android.text.style.LocaleSpan
import android.text.style.StrikethroughSpan
import android.text.style.UnderlineSpan
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import androidx.text.StaticLayoutCompat
import androidx.text.style.LetterSpacingSpan
import androidx.text.style.TypefaceSpan
import androidx.text.style.WordSpacingSpan
import androidx.ui.engine.text.FontStyle
import androidx.ui.engine.text.FontSynthesis
import androidx.ui.engine.text.FontWeight
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.font.FontFamily
import androidx.ui.engine.text.font.asFontFamily
import androidx.ui.engine.text.platform.ParagraphAndroid
import androidx.ui.engine.text.platform.TypefaceAdapter
import androidx.ui.engine.window.Locale
import androidx.ui.painting.Color
import androidx.ui.port.engine.text.FontTestData.Companion.BASIC_MEASURE_FONT
import androidx.ui.port.matchers.equalToBitmap
import androidx.ui.port.matchers.hasSpan
import androidx.ui.port.matchers.hasSpanOnTop
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.never
import com.nhaarman.mockitokotlin2.spy
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import org.hamcrest.Matchers.equalTo
import org.hamcrest.Matchers.not
import org.hamcrest.Matchers.nullValue
import org.junit.Assert.assertFalse
import org.junit.Assert.assertThat
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import kotlin.math.ceil
@RunWith(JUnit4::class)
@SmallTest
class ParagraphAndroidTest {
private lateinit var fontFamily: FontFamily
@Before
fun setup() {
// This sample font provides the following features:
// 1. The width of most of visible characters equals to font size.
// 2. The LTR/RTL characters are rendered as ▶/◀.
// 3. The fontMetrics passed to TextPaint has descend - ascend equal to 1.2 * fontSize.
fontFamily = BASIC_MEASURE_FONT.asFontFamily()
fontFamily.context = InstrumentationRegistry.getInstrumentation().context
}
@Test
fun draw_with_newline_and_line_break_default_values() {
val fontSize = 50.0f
for (text in arrayOf("abc\ndef", "\u05D0\u05D1\u05D2\n\u05D3\u05D4\u05D5")) {
val paragraphAndroid = simpleParagraph(
text = StringBuilder(text),
fontSize = fontSize,
fontFamily = fontFamily
)
// 2 chars width
paragraphAndroid.layout(width = 2 * fontSize)
val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
textPaint.textSize = fontSize
textPaint.typeface = TypefaceAdapter().create(fontFamily)
val staticLayout = StaticLayoutCompat.Builder(
text,
textPaint,
ceil(paragraphAndroid.width).toInt()
)
.setEllipsizedWidth(ceil(paragraphAndroid.width).toInt())
.build()
assertThat(paragraphAndroid.bitmap(), equalToBitmap(staticLayout.bitmap()))
}
}
@Test
fun textStyle_setColorOnWholeText() {
val text = "abcde"
val textStyle = TextStyle(color = Color(0xFF0000FF.toInt()))
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(ForegroundColorSpan::class, 0, text.length))
}
@Test
fun textStyle_setColorOnPartOfText() {
val text = "abcde"
val textStyle = TextStyle(color = Color(0xFF0000FF.toInt()))
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(ForegroundColorSpan::class, 0, "abc".length))
}
@Test
fun textStyle_setColorTwice_lastOneOverwrite() {
val text = "abcde"
val textStyle = TextStyle(color = Color(0xFF0000FF.toInt()))
val textStyleOverwrite = TextStyle(color = Color(0xFF00FF00.toInt()))
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(ForegroundColorSpan::class, 0, text.length))
assertThat(paragraph.underlyingText, hasSpan(ForegroundColorSpan::class, 0, "abc".length))
assertThat(
paragraph.underlyingText,
hasSpanOnTop(ForegroundColorSpan::class, 0, "abc".length)
)
}
@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.0f)
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.0f)
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.0f)
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.0f)
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.0f)
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.0f
val paragraphWidth = text.length * fontSize
val textStyle = TextStyle(fontSize = fontSize)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
paragraph.layout(paragraphWidth)
assertThat(paragraph.underlyingText, hasSpan(AbsoluteSizeSpan::class, 0, text.length))
}
@Test
fun textStyle_setFontSizeOnPartText() {
val text = "abcde"
val fontSize = 20.0f
val paragraphWidth = text.length * fontSize
val textStyle = TextStyle(fontSize = fontSize)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
paragraph.layout(paragraphWidth)
assertThat(paragraph.underlyingText, hasSpan(AbsoluteSizeSpan::class, 0, "abc".length))
}
@Test
fun textStyle_setFontSizeTwice_lastOneOverwrite() {
val text = "abcde"
val fontSize = 20.0f
val fontSizeOverwrite = 30.0f
val paragraphWidth = text.length * fontSizeOverwrite
val textStyle = TextStyle(fontSize = fontSize)
val textStyleOverwrite = TextStyle(fontSize = fontSizeOverwrite)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
paragraph.layout(paragraphWidth)
assertThat(paragraph.underlyingText, hasSpan(AbsoluteSizeSpan::class, 0, text.length))
assertThat(paragraph.underlyingText, hasSpan(AbsoluteSizeSpan::class, 0, "abc".length))
assertThat(
paragraph.underlyingText,
hasSpanOnTop(AbsoluteSizeSpan::class, 0, "abc".length)
)
}
@Test
fun textStyle_setLetterSpacingOnWholeText() {
val text = "abcde"
val letterSpacing = 2.0f
val textStyle = TextStyle(letterSpacing = letterSpacing)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText, hasSpan(LetterSpacingSpan::class, 0, text.length))
}
@Test
fun textStyle_setLetterSpacingOnPartText() {
val text = "abcde"
val textStyle = TextStyle(letterSpacing = 2.0f)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText, hasSpan(LetterSpacingSpan::class, 0, "abc".length))
}
@Test
fun textStyle_setLetterSpacingTwice_lastOneOverwrite() {
val text = "abcde"
val textStyle = TextStyle(letterSpacing = 2.0f)
val textStyleOverwrite = TextStyle(letterSpacing = 3.0f)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText, hasSpan(LetterSpacingSpan::class, 0, text.length))
assertThat(paragraph.underlyingText, hasSpan(LetterSpacingSpan::class, 0, "abc".length))
assertThat(
paragraph.underlyingText,
hasSpanOnTop(LetterSpacingSpan::class, 0, "abc".length)
)
}
@Test
@SdkSuppress(minSdkVersion = 28)
fun textStyle_setWordSpacingOnWholeText() {
val text = "ab cd"
val wordSpacing = 2.0f
val textStyle = TextStyle(wordSpacing = wordSpacing)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
// Notice that the width doesn't matter for this test.
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(
paragraph.underlyingText,
hasSpan(WordSpacingSpan::class, 0, text.length) { span ->
span.wordSpacing == wordSpacing.toFloat()
}
)
}
@Test
@SdkSuppress(minSdkVersion = 28)
fun textStyle_setWordSpacingOnPartText() {
val text = "abc d"
val wordSpacing = 2.0f
val textStyle = TextStyle(wordSpacing = wordSpacing)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
// Notice that the width doesn't matter for this test.
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(
paragraph.underlyingText,
hasSpan(WordSpacingSpan::class, 0, "abc".length) { span ->
span.wordSpacing == wordSpacing.toFloat()
}
)
}
@Test
@SdkSuppress(minSdkVersion = 28)
fun textStyle_setWordSpacingTwice_lastOneOverwrite() {
val text = "abc d"
val wordSpacing = 2.0f
val textStyle = TextStyle(wordSpacing = wordSpacing)
val wordSpacingOverwrite = 3.0f
val textStyleOverwrite = TextStyle(wordSpacing = wordSpacingOverwrite)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
// Notice that the width doesn't matter for this test.
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(
paragraph.underlyingText,
hasSpan(WordSpacingSpan::class, 0, text.length) { span ->
span.wordSpacing == wordSpacing.toFloat()
}
)
assertThat(
paragraph.underlyingText,
hasSpan(WordSpacingSpan::class, 0, "abc".length) { span ->
span.wordSpacing == wordSpacingOverwrite.toFloat()
}
)
assertThat(
paragraph.underlyingText,
hasSpanOnTop(WordSpacingSpan::class, 0, "abc".length) { span ->
span.wordSpacing == wordSpacingOverwrite.toFloat()
}
)
}
@Test
fun textStyle_setBackgroundOnWholeText() {
val text = "abcde"
val color = Color(0xFF0000FF.toInt())
val textStyle = TextStyle(background = color)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText,
hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
span.backgroundColor == color.value
}
)
}
@Test
fun textStyle_setBackgroundOnPartText() {
val text = "abcde"
val color = Color(0xFF0000FF.toInt())
val textStyle = TextStyle(background = color)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText,
hasSpan(BackgroundColorSpan::class, 0, "abc".length) { span ->
span.backgroundColor == color.value
}
)
}
@Test
fun textStyle_setBackgroundTwice_lastOneOverwrite() {
val text = "abcde"
val color = Color(0xFF0000FF.toInt())
val textStyle = TextStyle(background = color)
val colorOverwrite = Color(0xFF00FF00.toInt())
val textStyleOverwrite = TextStyle(background = colorOverwrite)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(paragraph.underlyingText,
hasSpan(BackgroundColorSpan::class, 0, text.length) { span ->
span.backgroundColor == color.value
}
)
assertThat(paragraph.underlyingText,
hasSpan(BackgroundColorSpan::class, 0, "abc".length) { span ->
span.backgroundColor == colorOverwrite.value
}
)
assertThat(
paragraph.underlyingText,
hasSpanOnTop(BackgroundColorSpan::class, 0, "abc".length) { span ->
span.backgroundColor == colorOverwrite.value
}
)
}
@Test
fun textStyle_setLocaleOnWholeText() {
val text = "abcde"
val locale = Locale("en", "US")
val textStyle = TextStyle(locale = locale)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(LocaleSpan::class, 0, text.length))
}
@Test
fun textStyle_setLocaleOnPartText() {
val text = "abcde"
val locale = Locale("en", "US")
val textStyle = TextStyle(locale = locale)
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(ParagraphBuilder.TextStyleIndex(textStyle, 0, "abc".length))
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(LocaleSpan::class, 0, "abc".length))
}
@Test
fun textStyle_setLocaleTwice_lastOneOverwrite() {
val text = "abcde"
val textStyle = TextStyle(locale = Locale("en", "US"))
val textStyleOverwrite = TextStyle(locale = Locale("ja", "JP"))
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(textStyle, 0, text.length),
ParagraphBuilder.TextStyleIndex(textStyleOverwrite, 0, "abc".length)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText, hasSpan(LocaleSpan::class, 0, text.length))
assertThat(paragraph.underlyingText, hasSpan(LocaleSpan::class, 0, "abc".length))
assertThat(
paragraph.underlyingText,
hasSpanOnTop(LocaleSpan::class, 0, "abc".length)
)
}
@Test
fun textStyle_fontFamily_addsTypefaceSpanWithCorrectTypeface() {
val text = "abcde"
val textStyle = TextStyle(
fontFamily = fontFamily,
fontStyle = FontStyle.italic,
fontWeight = FontWeight.bold
)
val expectedTypeface = TypefaceAdapter().create(
fontFamily = fontFamily,
fontStyle = FontStyle.italic,
fontWeight = FontWeight.bold
)
val expectedStart = 0
val expectedEnd = "abc".length
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(
textStyle,
expectedStart,
expectedEnd
)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(
paragraph.underlyingText,
hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
span.typeface == expectedTypeface
})
}
@Test
fun textStyle_fontFamily_whenFontSynthesizeTurnedOff() {
val text = "abcde"
val textStyle = TextStyle(
fontFamily = fontFamily,
fontStyle = FontStyle.italic,
fontWeight = FontWeight.bold,
fontSynthesis = FontSynthesis.none
)
val expectedTypeface = TypefaceAdapter().create(
fontFamily = fontFamily,
fontStyle = FontStyle.italic,
fontWeight = FontWeight.bold,
fontSynthesis = FontSynthesis.none
)
val expectedStart = 0
val expectedEnd = "abc".length
val paragraph = simpleParagraph(
text = text,
textStyles = listOf(
ParagraphBuilder.TextStyleIndex(
textStyle,
expectedStart,
expectedEnd
)
)
)
paragraph.layout(100.0f)
assertThat(paragraph.underlyingText.toString(), equalTo(text))
assertThat(
paragraph.underlyingText,
hasSpan(TypefaceSpan::class, expectedStart, expectedEnd) { span ->
span.typeface == expectedTypeface
})
}
@Test
fun testEmptyFontFamily() {
val typefaceAdapter = mock<TypefaceAdapter>()
val paragraph = simpleParagraph(
text = "abc",
typefaceAdapter = typefaceAdapter
)
paragraph.layout(Float.MAX_VALUE)
verify(typefaceAdapter, never()).create(
fontFamily = any(),
fontWeight = any(),
fontStyle = any(),
fontSynthesis = any()
)
assertThat(paragraph.textPaint.typeface, nullValue())
}
@Test
fun testEmptyFontFamily_withBoldFontWeightSelection() {
val typefaceAdapter = spy(TypefaceAdapter())
val paragraph = simpleParagraph(
text = "abc",
fontFamily = null,
fontWeight = FontWeight.bold,
typefaceAdapter = typefaceAdapter
)
paragraph.layout(Float.MAX_VALUE)
verify(typefaceAdapter, times(1)).create(
fontFamily = eq(null),
fontWeight = eq(FontWeight.bold),
fontStyle = eq(FontStyle.normal),
fontSynthesis = eq(FontSynthesis.all)
)
val typeface = paragraph.textPaint.typeface
assertThat(typeface, not(nullValue()))
assertThat(typeface.isBold, equalTo(true))
assertThat(typeface.isItalic, equalTo(false))
}
@Test
fun testEmptyFontFamily_withFontStyleSelection() {
val typefaceAdapter = spy(TypefaceAdapter())
val paragraph = simpleParagraph(
text = "abc",
fontFamily = null,
fontStyle = FontStyle.italic,
typefaceAdapter = typefaceAdapter
)
paragraph.layout(Float.MAX_VALUE)
verify(typefaceAdapter, times(1)).create(
fontFamily = eq(null),
fontWeight = eq(FontWeight.normal),
fontStyle = eq(FontStyle.italic),
fontSynthesis = eq(FontSynthesis.all)
)
val typeface = paragraph.textPaint.typeface
assertThat(typeface, not(nullValue()))
assertThat(typeface.isBold, equalTo(false))
assertThat(typeface.isItalic, equalTo(true))
}
@Test
fun testFontFamily_withGenericFamilyName() {
val typefaceAdapter = spy(TypefaceAdapter())
val fontFamily = FontFamily("sans-serif")
val paragraph = simpleParagraph(
text = "abc",
fontFamily = fontFamily,
typefaceAdapter = typefaceAdapter
)
paragraph.layout(Float.MAX_VALUE)
verify(typefaceAdapter, times(1)).create(
fontFamily = eq(fontFamily),
fontWeight = eq(FontWeight.normal),
fontStyle = eq(FontStyle.normal),
fontSynthesis = eq(FontSynthesis.all)
)
val typeface = paragraph.textPaint.typeface
assertThat(typeface, not(nullValue()))
assertThat(typeface.isBold, equalTo(false))
assertThat(typeface.isItalic, equalTo(false))
}
@Test
fun testFontFamily_withCustomFont() {
val typefaceAdapter = spy(TypefaceAdapter())
val paragraph = simpleParagraph(
text = "abc",
fontFamily = fontFamily,
typefaceAdapter = typefaceAdapter
)
paragraph.layout(Float.MAX_VALUE)
verify(typefaceAdapter, times(1)).create(
fontFamily = eq(fontFamily),
fontWeight = eq(FontWeight.normal),
fontStyle = eq(FontStyle.normal),
fontSynthesis = eq(FontSynthesis.all)
)
val typeface = paragraph.textPaint.typeface
assertThat(typeface.isBold, equalTo(false))
assertThat(typeface.isItalic, equalTo(false))
}
@Test
fun testEllipsis_withMaxLineEqualsNull_doesNotEllipsis() {
val text = "abc"
val fontSize = 20f
val paragraphWidth = (text.length - 1) * fontSize
val paragraph = simpleParagraph(
text = text,
fontFamily = fontFamily,
fontSize = fontSize,
ellipsis = true
)
paragraph.layout(paragraphWidth)
for (i in 0 until paragraph.lineCount) {
assertFalse(paragraph.isEllipsisApplied(i))
}
}
@Test
fun testEllipsis_withMaxLinesLessThanTextLines_doesEllipsis() {
val text = "abcde"
val fontSize = 100f
// Note that on API 21, if the next line only contains 1 character, ellipsis won't work
val paragraphWidth = (text.length - 1.5f) * fontSize
val paragraph = simpleParagraph(
text = text,
fontFamily = fontFamily,
fontSize = fontSize,
ellipsis = true,
maxLines = 1
)
paragraph.layout(paragraphWidth)
assertTrue(paragraph.isEllipsisApplied(0))
}
@Test
fun testEllipsis_withMaxLinesMoreThanTextLines_doesNotEllipsis() {
val text = "abc"
val fontSize = 100f
val paragraphWidth = (text.length - 1) * fontSize
val maxLines = ceil(text.length * fontSize / paragraphWidth).toInt()
val paragraph = simpleParagraph(
text = text,
fontFamily = fontFamily,
fontSize = fontSize,
ellipsis = true,
maxLines = maxLines
)
paragraph.layout(paragraphWidth)
for (i in 0 until paragraph.lineCount) {
assertFalse(paragraph.isEllipsisApplied(i))
}
}
private fun simpleParagraph(
text: CharSequence = "",
textStyles: List<ParagraphBuilder.TextStyleIndex> = listOf(),
textAlign: TextAlign? = null,
fontSize: Float? = null,
ellipsis: Boolean? = null,
maxLines: Int? = null,
fontFamily: FontFamily? = null,
fontWeight: FontWeight? = null,
fontStyle: FontStyle? = null,
typefaceAdapter: TypefaceAdapter = TypefaceAdapter()
): ParagraphAndroid {
return ParagraphAndroid(
text = StringBuilder(text),
textStyles = textStyles,
typefaceAdapter = typefaceAdapter,
paragraphStyle = ParagraphStyle(
textAlign = textAlign,
ellipsis = ellipsis,
maxLines = maxLines,
fontFamily = fontFamily,
fontSize = fontSize,
fontWeight = fontWeight,
fontStyle = fontStyle
)
)
}
}