[go: nahoru, domu]

blob: d0822aa21b8abdb5b14eb800e8b570923df7f8fa [file] [log] [blame]
/*
* Copyright 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.foundation.newtext.text.modifiers
import androidx.compose.foundation.newtext.text.TEST_FONT_FAMILY
import androidx.compose.foundation.newtext.text.toIntPx
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Canvas
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextPainter
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.createFontFamilyResolver
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.sp
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith
import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.IntegerSubject
import kotlin.math.floor
@RunWith(AndroidJUnit4::class)
@SmallTest
class TextLayoutResultIntegrationTest {
private val fontFamily = TEST_FONT_FAMILY
private val density = Density(density = 1f)
private val context = InstrumentationRegistry.getInstrumentation().context
private val fontFamilyResolver = createFontFamilyResolver(context)
private val layoutDirection = LayoutDirection.Ltr
@Test
fun width_getter() {
with(density) {
val fontSize = 20.sp
val text = "Hello"
val spanStyle = SpanStyle(fontSize = fontSize, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = this,
)
textDelegate.layoutWithConstraints(Constraints(0, 200), layoutDirection)
val layoutResult = textDelegate.layout
assertThat(layoutResult.size.width).isEqualTo(
(fontSize.toPx() * text.length).toIntPx()
)
}
}
@Test
fun width_getter_with_small_width() {
val text = "Hello"
val width = 80
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints(maxWidth = width), layoutDirection)
val layoutResult = textDelegate.layout
assertThat(layoutResult.size.width).isEqualTo(width)
}
@Test
fun height_getter() {
with(density) {
val fontSize = 20.sp
val spanStyle = SpanStyle(fontSize = fontSize, fontFamily = fontFamily)
val text = "hello"
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = this,
)
textDelegate.layoutWithConstraints(Constraints(), layoutDirection)
val layoutResult = textDelegate.layout
assertThat(layoutResult.size.height).isEqualTo((fontSize.toPx()).toIntPx())
}
}
@Test
fun layout_build_layoutResult() {
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = AnnotatedString("Hello"),
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints(0, 20), layoutDirection)
val layoutResult = textDelegate.layout
assertThat(layoutResult).isNotNull()
}
private fun IntegerSubject.isZero() {
this.isEqualTo(0)
}
@Test
fun getPositionForOffset_First_Character() {
val text = "Hello"
val annotatedString = AnnotatedString(
text,
SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints(), layoutDirection)
val layoutResult = textDelegate.layout
val selection = layoutResult.getOffsetForPosition(Offset.Zero)
assertThat(selection).isZero()
}
@Test
fun getPositionForOffset_other_Character() {
with(density) {
val fontSize = 20.sp
val characterIndex = 2 // Start from 0.
val text = "Hello"
val annotatedString = AnnotatedString(
text,
SpanStyle(fontSize = fontSize, fontFamily = fontFamily)
)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = this,
)
textDelegate.layoutWithConstraints(Constraints(), layoutDirection)
val layoutResult = textDelegate.layout
val selection = layoutResult.getOffsetForPosition(
position = Offset((fontSize.toPx() * characterIndex + 1), 0f)
)
assertThat(selection).isEqualTo(characterIndex)
}
}
@Test
fun hasOverflowShaderFalse() {
val text = "Hello"
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints(), layoutDirection)
val layoutResult = textDelegate.layout
assertThat(layoutResult.hasVisualOverflow).isFalse()
// paint should not throw exception
TextPainter.paint(Canvas(android.graphics.Canvas()), layoutResult)
}
@Test
fun didOverflowHeight_isTrue_when_maxLines_exceeded() {
val text = "HelloHellowHelloHello"
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val maxLines = 3
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver,
maxLines = maxLines
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints.fixed(0, 0), LayoutDirection.Ltr)
// Tries to make 5 lines of text, which exceeds the given maxLines(3).
val maxWidth = textDelegate.maxIntrinsicWidth / 5
textDelegate.layoutWithConstraints(
Constraints(maxWidth = maxWidth),
layoutDirection
)
val layoutResult = textDelegate.layout
assertThat(layoutResult.didOverflowHeight).isTrue()
}
@Test
fun didOverflowHeight_isFalse_when_maxLines_notExceeded() {
val text = "HelloHellowHelloHello"
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val maxLines = 10
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver,
maxLines = maxLines
),
density = density,
)
textDelegate.layoutWithConstraints(Constraints.fixed(0, 0), LayoutDirection.Ltr)
// Tries to make 5 lines of text, which doesn't exceed the given maxLines(10).
val maxWidth = textDelegate.maxIntrinsicWidth / 5
textDelegate.layoutWithConstraints(
Constraints(maxWidth = maxWidth),
layoutDirection
)
val layoutResult = textDelegate.layout
assertThat(layoutResult.didOverflowHeight).isFalse()
}
@Test
fun didOverflowHeight_isTrue_when_maxHeight_exceeded() {
val text = "HelloHellowHelloHello"
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver,
),
density = density,
)
textDelegate.layoutWithConstraints(
Constraints(),
layoutDirection
)
val maxIntrinsicsHeight = textDelegate.layout.multiParagraph.height
// Make maxHeight smaller than needed.
val maxHeight = floor(maxIntrinsicsHeight / 2).toInt()
textDelegate.layoutWithConstraints(
Constraints(maxHeight = maxHeight),
layoutDirection
)
val layoutResult = textDelegate.layout
assertThat(layoutResult.didOverflowHeight).isTrue()
}
@Test
fun didOverflowHeight_isFalse_when_maxHeight_notExceeded() {
val text = "HelloHellowHelloHello"
val spanStyle = SpanStyle(fontSize = 20.sp, fontFamily = fontFamily)
val annotatedString = AnnotatedString(text, spanStyle)
val textDelegate = MultiParagraphLayoutCache(
StaticTextLayoutDrawParams(
text = annotatedString,
style = TextStyle.Default,
fontFamilyResolver = fontFamilyResolver
),
density = density,
)
textDelegate.layoutWithConstraints(
Constraints(),
layoutDirection
)
val maxIntrinsicsHeight = textDelegate.layout.multiParagraph.height
// Make max height larger than the needed.
val maxHeight = floor(maxIntrinsicsHeight * 2).toInt()
textDelegate.layoutWithConstraints(
Constraints(maxHeight = maxHeight),
layoutDirection
)
val layoutResult = textDelegate.layout
assertThat(layoutResult.didOverflowHeight).isFalse()
}
}