Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add multiplatform support to coil-svg #1965

Merged
merged 23 commits into from
Jan 3, 2024

Conversation

MohamedRejeb
Copy link
Contributor

@MohamedRejeb MohamedRejeb commented Dec 21, 2023

  • Migrate coil-svg module to multiplatform
  • Add SvgDecoder for non android platforms based on skia svg
  • Add a public API to create an SvgDecoder from commonMain
  • Add tests to jvm target

Sorry, something went wrong.

@MohamedRejeb MohamedRejeb marked this pull request as ready for review December 24, 2023 16:27
@@ -0,0 +1,11 @@
package coil3.decode

object SvgDecoder {
Copy link
Member

@colinrtwhite colinrtwhite Dec 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use an expect/actual class instead of factory functions:

expect class SvgDecoder @JvmOverloads constructor(
    source: ImageSource,
    options: Options,
    useViewBoundsAsIntrinsicSize: Boolean = true,
) : Decoder {
    class Factory : Decoder.Factory
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@colinrtwhite
Copy link
Member

Btw you can run the CI checks locally using ./test.sh. Unfortunately I can't set it to run on each push

@MohamedRejeb
Copy link
Contributor Author

It should run successfully now.

@colinrtwhite
Copy link
Member

Great! This looks pretty good. I think we should be able to merge it once the tests are updated to run on Android and the JVM

@@ -20,16 +20,17 @@ import kotlin.math.roundToInt
import kotlinx.coroutines.runInterruptible

/**
* A [Decoder] that uses [AndroidSVG](https://bigbadaboom.github.io/androidsvg/) to decode SVG
* A [Decoder] that uses [AndroidSVG](https://bigbadaboom.github.io/androidsvg/)
* and [SVGDOM](https://api.skia.org/classSkSVGDOM.html/) to decode SVG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like this should be the docs for the expect declaration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

import coil3.request.Options

/**
* A [Decoder] that uses [AndroidSVG](https://bigbadaboom.github.io/androidsvg/) and to decode SVG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be swapped with the Android implementation docs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

private val decoderFactory = SvgDecoder.Factory()

@Test
fun handlesSvgMimeType() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to implement these tests in a common way? If you can't put a common test class in jvmCommonTest, you could create AbstractSvgDecoderTest in jvmCommonTest which defines all the tests then have SvgDecoderTestAndroid and SvgDecoderTestJvm extend that class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to do this, but I can't access jvmCommonTest or even commonTest from androidInstrumentedTest.

import kotlinx.coroutines.runBlocking
import org.jetbrains.skia.Bitmap

val Bitmap.size: Size
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for converting these! Could we create a common Bitmap type (only for our tests)? Looks like something like this should be enough:

expect class Bitmap {
    val width: Int
    val height: Int

    fun getPixels(): ByteArray
}

This way we can put the rest of these functions in commonMain, which will be useful for migrating more of Coil's tests to commonMain.

@colinrtwhite colinrtwhite deleted the branch coil-kt:3.x December 30, 2023 21:08
@colinrtwhite colinrtwhite reopened this Dec 30, 2023
@MohamedRejeb
Copy link
Contributor Author

I created AbstractSvgDecoderTest in the internal test utils module, and now the svg decoder test is shared between jvm and android. Also, I created CoilBitmap for testing and the bitmap comparison functions are shared between jvm and android. I didn't name it Bitmap to avoid confusion.
The only thing that prevents us from moving these tests to common is the ability to read resources from common test.
Now some functions are still duplicated in android for Bitmap and in common for CoilBitmap just to keep the old android tests working, But after migrating those tests, these functions can be removed from android.

@MohamedRejeb
Copy link
Contributor Author

A little mistake in the dependencies caused this failure. It should be running successfully now.


class SvgDecoderTestAndroid : AbstractSvgDecoderTest(SvgDecoder.Factory()) {
@Test
override fun handlesSvgMimeType() =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can annotate the methods of the superclass so you don't need to override. We do something similar in Redwood: https://github.com/cashapp/redwood/blob/trunk/redwood-layout-shared-test/src/commonMain/kotlin/app/cash/redwood/layout/AbstractFlexContainerTest.kt#L71

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


class SvgDecoderTestJvm : AbstractSvgDecoderTest(SvgDecoder.Factory()) {
@Test
override fun handlesSvgMimeType() =
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same for here.


class SvgDecoderTest {
abstract class AbstractSvgDecoderTest(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this class live in coil-svg/jvmCommonTest instead of moving it to test-utils?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When it was in jvmCommonTest it was not visible to android instrumented test.

@@ -100,7 +129,7 @@ fun Bitmap.isSimilarTo(
*/
fun Bitmap.assertIsSimilarTo(
expected: Bitmap,
threshold: Double = 0.99
threshold: Double = 0.987
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use 0.98

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it back to 0.99 in android and 0.98 in common.

Copy link
Member

@colinrtwhite colinrtwhite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@colinrtwhite colinrtwhite merged commit d9a99c7 into coil-kt:3.x Jan 3, 2024
colinrtwhite pushed a commit that referenced this pull request Jan 3, 2024
* Add multiplatform support to coil-svg

* Remove commented code

* Move SvgDecoderTest to coil3/decode

* Add public API for creating SvgDecoder.Factory from commonMain

* Move isSvg_newLine test to common

* Apply spotless

* Run apiDump

* Change SvgDecoder to expect/actual class

* Apply spotless

* Add test to jvm target

* Run spotlessApply

* Use Okio FileSystem.RESOURCES

* Remove unnecessary code

* Fix SvgDecoder documentation

* Share SvgDecoderTest between jvm and android

* Apply spotless

* Bring back old android Bitmap test functions

* Fix SvgDecoder android documentation

* Rename common decodeBitmapAsset to decodeBitmapResource

* Fix test failure

* Update threshold default value

* Add Test annotation to AbstractSvgDecoderTest methods

* Apply spotless
@KapilYadav-dev
Copy link

@MohamedRejeb awesome to see your contribution in coil also < 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants