diff --git a/coil-test/api/android/coil-test.api b/coil-test/api/android/coil-test.api index 420123ce51..bf4d09ae6a 100644 --- a/coil-test/api/android/coil-test.api +++ b/coil-test/api/android/coil-test.api @@ -1,3 +1,28 @@ +public final class coil3/test/ColorImage : coil3/Image { + public static final field Black I + public static final field Blue I + public static final field Companion Lcoil3/test/ColorImage$Companion; + public static final field Green I + public static final field Red I + public static final field Transparent I + public static final field White I + public fun ()V + public fun (IIIJZ)V + public synthetic fun (IIIJZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun draw (Landroid/graphics/Canvas;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getColor ()I + public fun getHeight ()I + public fun getShareable ()Z + public fun getSize ()J + public fun getWidth ()I + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class coil3/test/ColorImage$Companion { +} + public final class coil3/test/FakeImage : coil3/Image { public fun ()V public fun (IIJZI)V diff --git a/coil-test/api/coil-test.klib.api b/coil-test/api/coil-test.klib.api index 4846c3f64a..c45a4de053 100644 --- a/coil-test/api/coil-test.klib.api +++ b/coil-test/api/coil-test.klib.api @@ -6,6 +6,41 @@ // - Show declarations: true // Library unique name: +final class coil3.test/ColorImage : coil3/Image { // coil3.test/ColorImage|null[0] + constructor (kotlin/Int = ..., kotlin/Int = ..., kotlin/Int = ..., kotlin/Long = ..., kotlin/Boolean = ...) // coil3.test/ColorImage.|(kotlin.Int;kotlin.Int;kotlin.Int;kotlin.Long;kotlin.Boolean){}[0] + + final val color // coil3.test/ColorImage.color|{}color[0] + final fun (): kotlin/Int // coil3.test/ColorImage.color.|(){}[0] + final val height // coil3.test/ColorImage.height|{}height[0] + final fun (): kotlin/Int // coil3.test/ColorImage.height.|(){}[0] + final val shareable // coil3.test/ColorImage.shareable|{}shareable[0] + final fun (): kotlin/Boolean // coil3.test/ColorImage.shareable.|(){}[0] + final val size // coil3.test/ColorImage.size|{}size[0] + final fun (): kotlin/Long // coil3.test/ColorImage.size.|(){}[0] + final val width // coil3.test/ColorImage.width|{}width[0] + final fun (): kotlin/Int // coil3.test/ColorImage.width.|(){}[0] + + final fun draw(org.jetbrains.skia/Canvas) // coil3.test/ColorImage.draw|draw(org.jetbrains.skia.Canvas){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // coil3.test/ColorImage.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // coil3.test/ColorImage.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // coil3.test/ColorImage.toString|toString(){}[0] + + final object Companion { // coil3.test/ColorImage.Companion|null[0] + final const val Black // coil3.test/ColorImage.Companion.Black|{}Black[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.Black.|(){}[0] + final const val Blue // coil3.test/ColorImage.Companion.Blue|{}Blue[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.Blue.|(){}[0] + final const val Green // coil3.test/ColorImage.Companion.Green|{}Green[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.Green.|(){}[0] + final const val Red // coil3.test/ColorImage.Companion.Red|{}Red[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.Red.|(){}[0] + final const val Transparent // coil3.test/ColorImage.Companion.Transparent|{}Transparent[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.Transparent.|(){}[0] + final const val White // coil3.test/ColorImage.Companion.White|{}White[0] + final fun (): kotlin/Int // coil3.test/ColorImage.Companion.White.|(){}[0] + } +} + final class coil3.test/FakeImage : coil3/Image { // coil3.test/FakeImage|null[0] constructor (kotlin/Int = ..., kotlin/Int = ..., kotlin/Long = ..., kotlin/Boolean = ..., kotlin/Int = ...) // coil3.test/FakeImage.|(kotlin.Int;kotlin.Int;kotlin.Long;kotlin.Boolean;kotlin.Int){}[0] diff --git a/coil-test/api/jvm/coil-test.api b/coil-test/api/jvm/coil-test.api index 3a32b023ca..3073d10e7d 100644 --- a/coil-test/api/jvm/coil-test.api +++ b/coil-test/api/jvm/coil-test.api @@ -1,3 +1,28 @@ +public final class coil3/test/ColorImage : coil3/Image { + public static final field Black I + public static final field Blue I + public static final field Companion Lcoil3/test/ColorImage$Companion; + public static final field Green I + public static final field Red I + public static final field Transparent I + public static final field White I + public fun ()V + public fun (IIIJZ)V + public synthetic fun (IIIJZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun draw (Lorg/jetbrains/skia/Canvas;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getColor ()I + public fun getHeight ()I + public fun getShareable ()Z + public fun getSize ()J + public fun getWidth ()I + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + +public final class coil3/test/ColorImage$Companion { +} + public final class coil3/test/FakeImage : coil3/Image { public fun ()V public fun (IIJZI)V diff --git a/coil-test/src/androidMain/kotlin/coil3/test/ColorImage.android.kt b/coil-test/src/androidMain/kotlin/coil3/test/ColorImage.android.kt new file mode 100644 index 0000000000..7b8b7b274b --- /dev/null +++ b/coil-test/src/androidMain/kotlin/coil3/test/ColorImage.android.kt @@ -0,0 +1,39 @@ +package coil3.test + +import android.graphics.Paint +import coil3.Canvas +import coil3.Image +import coil3.annotation.Poko + +@Poko +actual class ColorImage actual constructor( + actual val color: Int, + actual override val width: Int, + actual override val height: Int, + actual override val size: Long, + actual override val shareable: Boolean, +) : Image { + private var lazyPaint: Paint? = null + + actual override fun draw(canvas: Canvas) { + val paint = lazyPaint ?: run { + Paint() + .apply { color = this@ColorImage.color } + .also { lazyPaint = it } + } + if (width >= 0 && height >= 0) { + canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) + } else { + canvas.drawPaint(paint) + } + } + + actual companion object { + actual const val Black = 0xFF000000.toInt() + actual const val White = 0xFFFFFFFF.toInt() + actual const val Transparent = 0x00000000.toInt() + actual const val Red = 0xFFFF0000.toInt() + actual const val Green = 0xFF00FF00.toInt() + actual const val Blue = 0xFF0000FF.toInt() + } +} diff --git a/coil-test/src/androidMain/kotlin/coil3/test/FakeImage.android.kt b/coil-test/src/androidMain/kotlin/coil3/test/FakeImage.android.kt index e8bda40fa3..106b893f4c 100644 --- a/coil-test/src/androidMain/kotlin/coil3/test/FakeImage.android.kt +++ b/coil-test/src/androidMain/kotlin/coil3/test/FakeImage.android.kt @@ -5,6 +5,11 @@ import coil3.Canvas import coil3.Image import coil3.annotation.Poko +@Deprecated( + message = "This use case is better fulfilled by ColorImage.", + replaceWith = ReplaceWith("ColorImage", ["coil3.test.ColorImage"]), + level = DeprecationLevel.WARNING, +) @Poko actual class FakeImage actual constructor( actual override val width: Int, @@ -21,7 +26,6 @@ actual class FakeImage actual constructor( .apply { color = this@FakeImage.color } .also { lazyPaint = it } } - canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } } diff --git a/coil-test/src/commonMain/kotlin/coil3/test/ColorImage.kt b/coil-test/src/commonMain/kotlin/coil3/test/ColorImage.kt new file mode 100644 index 0000000000..201dfb4d6d --- /dev/null +++ b/coil-test/src/commonMain/kotlin/coil3/test/ColorImage.kt @@ -0,0 +1,34 @@ +package coil3.test + +import coil3.Canvas +import coil3.Image + +/** + * An image that draws a [color]. + * + * By default the image has no intrinsic size and will fill its canvas. Set [width] and [height] + * to a positive value to draw a square with those dimensions. + */ +expect class ColorImage( + color: Int = Black, + width: Int = -1, + height: Int = -1, + size: Long = 0, + shareable: Boolean = true, +) : Image { + val color: Int + override val size: Long + override val width: Int + override val height: Int + override val shareable: Boolean + override fun draw(canvas: Canvas) + + companion object { + val Black: Int + val White: Int + val Transparent: Int + val Red: Int + val Green: Int + val Blue: Int + } +} diff --git a/coil-test/src/commonMain/kotlin/coil3/test/FakeImage.kt b/coil-test/src/commonMain/kotlin/coil3/test/FakeImage.kt index 309e937bc5..4a3ccbc667 100644 --- a/coil-test/src/commonMain/kotlin/coil3/test/FakeImage.kt +++ b/coil-test/src/commonMain/kotlin/coil3/test/FakeImage.kt @@ -2,11 +2,16 @@ package coil3.test import coil3.Canvas import coil3.Image -import coil3.test.internal.Black +import coil3.test.ColorImage.Companion.Black /** * A simple [Image] that draws a 100x100 black square by default. */ +@Deprecated( + message = "This use case is better fulfilled by ColorImage.", + replaceWith = ReplaceWith("ColorImage(color, width, height, size, shareable)", ["coil3.test.ColorImage"]), + level = DeprecationLevel.WARNING, +) expect class FakeImage( width: Int = 100, height: Int = 100, @@ -19,6 +24,5 @@ expect class FakeImage( override val size: Long override val shareable: Boolean val color: Int - override fun draw(canvas: Canvas) } diff --git a/coil-test/src/commonMain/kotlin/coil3/test/internal/utils.kt b/coil-test/src/commonMain/kotlin/coil3/test/internal/utils.kt index f2f2b993b2..3a67c25e5d 100644 --- a/coil-test/src/commonMain/kotlin/coil3/test/internal/utils.kt +++ b/coil-test/src/commonMain/kotlin/coil3/test/internal/utils.kt @@ -13,6 +13,3 @@ internal fun imageResultOf( request = request, dataSource = DataSource.MEMORY, ) - -// Format: 0xALPHA_RED_GREEN_BLUE -internal const val Black = 0xFF_00_00_00.toInt() diff --git a/coil-test/src/nonAndroidMain/kotlin/coil3/test/ColorImage.nonAndroid.kt b/coil-test/src/nonAndroidMain/kotlin/coil3/test/ColorImage.nonAndroid.kt new file mode 100644 index 0000000000..d580027851 --- /dev/null +++ b/coil-test/src/nonAndroidMain/kotlin/coil3/test/ColorImage.nonAndroid.kt @@ -0,0 +1,45 @@ +package coil3.test + +import coil3.Canvas +import coil3.Image +import coil3.annotation.Poko +import org.jetbrains.skia.Paint +import org.jetbrains.skia.Rect + +@Poko +actual class ColorImage actual constructor( + actual val color: Int, + actual override val width: Int, + actual override val height: Int, + actual override val size: Long, + actual override val shareable: Boolean, +) : Image { + private var lazyPaint: Paint? = null + private var lazyRect: Rect? = null + + actual override fun draw(canvas: Canvas) { + val paint = lazyPaint ?: run { + Paint() + .apply { color = this@ColorImage.color } + .also { lazyPaint = it } + } + if (width >= 0 && height >= 0) { + val rect = lazyRect ?: run { + Rect.makeWH(width.toFloat(), height.toFloat()) + .also { lazyRect = it } + } + canvas.drawRect(rect, paint) + } else { + canvas.drawPaint(paint) + } + } + + actual companion object { + actual const val Black = 0xFF000000.toInt() + actual const val White = 0xFFFFFFFF.toInt() + actual const val Transparent = 0x00000000.toInt() + actual const val Red = 0xFFFF0000.toInt() + actual const val Green = 0xFF00FF00.toInt() + actual const val Blue = 0xFF0000FF.toInt() + } +} diff --git a/coil-test/src/nonAndroidMain/kotlin/coil3/test/FakeImage.nonAndroid.kt b/coil-test/src/nonAndroidMain/kotlin/coil3/test/FakeImage.nonAndroid.kt index cbe1539c10..5247935f58 100644 --- a/coil-test/src/nonAndroidMain/kotlin/coil3/test/FakeImage.nonAndroid.kt +++ b/coil-test/src/nonAndroidMain/kotlin/coil3/test/FakeImage.nonAndroid.kt @@ -6,6 +6,11 @@ import coil3.annotation.Poko import org.jetbrains.skia.Paint import org.jetbrains.skia.Rect +@Deprecated( + message = "This use case is better fulfilled by ColorImage.", + replaceWith = ReplaceWith("ColorImage(color, width, height, size, shareable)", ["coil3.test.ColorImage"]), + level = DeprecationLevel.WARNING, +) @Poko actual class FakeImage actual constructor( actual override val width: Int, diff --git a/internal/test-compose-screenshot/src/screenshotTest/java/coil3/composescreenshot/PreviewScreenshots.kt b/internal/test-compose-screenshot/src/screenshotTest/java/coil3/composescreenshot/PreviewScreenshots.kt index 1895b3903b..679b4e657b 100644 --- a/internal/test-compose-screenshot/src/screenshotTest/java/coil3/composescreenshot/PreviewScreenshots.kt +++ b/internal/test-compose-screenshot/src/screenshotTest/java/coil3/composescreenshot/PreviewScreenshots.kt @@ -1,6 +1,5 @@ package coil3.composescreenshot -import android.graphics.Color import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable @@ -17,12 +16,13 @@ import coil3.compose.AsyncImage import coil3.compose.AsyncImagePreviewHandler import coil3.compose.LocalAsyncImagePreviewHandler import coil3.compose.rememberAsyncImagePainter -import coil3.test.FakeImage +import coil3.test.ColorImage +import coil3.test.ColorImage.Companion.Red @OptIn(ExperimentalCoilApi::class) class PreviewScreenshots { private val previewHandler = AsyncImagePreviewHandler { - FakeImage(color = Color.RED) + ColorImage(Red, width = 100, height = 100) } @Preview( diff --git a/internal/test-paparazzi/src/test/java/coil3/paparazzi/PaparazziTest.kt b/internal/test-paparazzi/src/test/java/coil3/paparazzi/PaparazziTest.kt index edd5320cf5..21965950f1 100644 --- a/internal/test-paparazzi/src/test/java/coil3/paparazzi/PaparazziTest.kt +++ b/internal/test-paparazzi/src/test/java/coil3/paparazzi/PaparazziTest.kt @@ -1,6 +1,5 @@ package coil3.paparazzi -import android.graphics.Color import android.widget.ImageView import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize @@ -14,7 +13,8 @@ import coil3.compose.rememberAsyncImagePainter import coil3.decode.ImageSource import coil3.request.ImageRequest import coil3.request.target -import coil3.test.FakeImage +import coil3.test.ColorImage +import coil3.test.ColorImage.Companion.Red import coil3.test.FakeImageLoaderEngine import kotlin.test.assertTrue import okio.Buffer @@ -38,7 +38,7 @@ class PaparazziTest { fun imageView() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val imageLoader = ImageLoader.Builder(paparazzi.context) .components { add(engine) } @@ -60,7 +60,7 @@ class PaparazziTest { fun asyncImage() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val imageLoader = ImageLoader.Builder(paparazzi.context) .components { add(engine) } @@ -81,7 +81,7 @@ class PaparazziTest { fun rememberAsyncImagePainter() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val imageLoader = ImageLoader.Builder(paparazzi.context) .components { add(engine) } diff --git a/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziComposeTestAndroid.kt b/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziComposeTestAndroid.kt index 26dbead0c0..bf08e8924d 100644 --- a/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziComposeTestAndroid.kt +++ b/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziComposeTestAndroid.kt @@ -1,6 +1,5 @@ package coil3.roborazzi -import android.graphics.Color import androidx.compose.foundation.Image import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.ui.Modifier @@ -10,7 +9,8 @@ import androidx.compose.ui.test.onRoot import coil3.ImageLoader import coil3.compose.AsyncImage import coil3.compose.rememberAsyncImagePainter -import coil3.test.FakeImage +import coil3.test.ColorImage +import coil3.test.ColorImage.Companion.Red import coil3.test.FakeImageLoaderEngine import coil3.test.utils.ComposeTestActivity import coil3.test.utils.RobolectricTest @@ -39,7 +39,7 @@ class RoborazziComposeTestAndroid : RobolectricTest() { fun asyncImage() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val imageLoader = ImageLoader.Builder(composeTestRule.activity) .components { add(engine) } @@ -60,7 +60,7 @@ class RoborazziComposeTestAndroid : RobolectricTest() { fun rememberAsyncImagePainter() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val imageLoader = ImageLoader.Builder(composeTestRule.activity) .components { add(engine) } diff --git a/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziViewTest.kt b/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziViewTest.kt index 9487e9cfcb..59f1e19c12 100644 --- a/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziViewTest.kt +++ b/internal/test-roborazzi/src/androidUnitTest/kotlin/coil3/roborazzi/RoborazziViewTest.kt @@ -1,6 +1,5 @@ package coil3.roborazzi -import android.graphics.Color import android.widget.ImageView import androidx.test.espresso.Espresso.onView import androidx.test.espresso.matcher.ViewMatchers.isRoot @@ -8,7 +7,8 @@ import androidx.test.ext.junit.rules.activityScenarioRule import coil3.ImageLoader import coil3.request.ImageRequest import coil3.request.target -import coil3.test.FakeImage +import coil3.test.ColorImage +import coil3.test.ColorImage.Companion.Red import coil3.test.FakeImageLoaderEngine import coil3.test.utils.RobolectricTest import coil3.test.utils.ViewTestActivity @@ -37,7 +37,7 @@ class RoborazziViewTest : RobolectricTest() { fun imageView() { val url = "https://www.example.com/image.jpg" val engine = FakeImageLoaderEngine.Builder() - .intercept(url, FakeImage(color = Color.RED)) + .intercept(url, ColorImage(Red, width = 100, height = 100)) .build() val activity = activityRule.scenario.activity val imageLoader = ImageLoader.Builder(activity) diff --git a/internal/test-roborazzi/src/jvmTest/kotlin/coil3/roborazzi/RoborazziComposeTestJvm.kt b/internal/test-roborazzi/src/jvmTest/kotlin/coil3/roborazzi/RoborazziComposeTestJvm.kt index 6353ef2384..1f9130d0a0 100644 --- a/internal/test-roborazzi/src/jvmTest/kotlin/coil3/roborazzi/RoborazziComposeTestJvm.kt +++ b/internal/test-roborazzi/src/jvmTest/kotlin/coil3/roborazzi/RoborazziComposeTestJvm.kt @@ -14,7 +14,8 @@ import coil3.PlatformContext import coil3.asImage import coil3.compose.AsyncImage import coil3.compose.rememberAsyncImagePainter -import coil3.test.FakeImage +import coil3.test.ColorImage +import coil3.test.ColorImage.Companion.Red import coil3.test.FakeImageLoaderEngine import coil3.toBitmap import io.github.takahirom.roborazzi.captureRoboImage @@ -26,11 +27,7 @@ class RoborazziComposeTestJvm { @Test fun asyncImage() { val url = "https://www.example.com/image.jpg" - val image = FakeImage( - width = 100, - height = 100, - color = org.jetbrains.skia.Color.RED, - ) + val image = ColorImage(Red, width = 100, height = 100) val engine = FakeImageLoaderEngine.Builder() .intercept(url, image) @@ -60,11 +57,7 @@ class RoborazziComposeTestJvm { @Test fun rememberAsyncImagePainter() { val url = "https://www.example.com/image.jpg" - val image = FakeImage( - width = 100, - height = 100, - color = org.jetbrains.skia.Color.RED, - ) + val image = ColorImage(Red, width = 100, height = 100) val engine = FakeImageLoaderEngine.Builder() .intercept(url, image.toBitmap().asImage()) .build()