Skip to content

Commit

Permalink
Update AndroidDrawablePainter (#110)
Browse files Browse the repository at this point in the history
* Update AndroidDrawablePainter

- Fixes instrinsic size using width for height
- Now works with Drawables which change intrinsic size
  (hello LottieDrawable)
- Now properly scales drawables as per ContentScale (through
  the canvas size)

* Don't scale if the drawable has no intrinsic size
  • Loading branch information
chrisbanes committed Oct 6, 2020
1 parent 93df993 commit 4cf088f
Showing 1 changed file with 19 additions and 7 deletions.
Expand Up @@ -39,21 +39,19 @@ import androidx.compose.ui.graphics.painter.ColorPainter
import androidx.compose.ui.graphics.painter.ImagePainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.withSave
import androidx.compose.ui.unit.LayoutDirection
import androidx.core.graphics.drawable.DrawableCompat
import kotlin.math.roundToInt

/**
* A [Painter] which draws an Android [Drawable]. Supports [Animatable] drawables.
*
* Taken from https://goo.gle/compose-drawable-painter
*/
class AndroidDrawablePainter(
private val drawable: Drawable
) : Painter() {
private val drawableSize = Size(
drawable.intrinsicWidth.toFloat(),
drawable.intrinsicWidth.toFloat()
)

private var invalidateTick by mutableStateOf(0)
private var startedAnimatable = drawable is Animatable && drawable.isRunning

Expand Down Expand Up @@ -102,7 +100,11 @@ class AndroidDrawablePainter(
)
}

override val intrinsicSize: Size get() = drawableSize
override val intrinsicSize: Size
get() = Size(
drawable.intrinsicWidth.toFloat(),
drawable.intrinsicHeight.toFloat()
)

override fun DrawScope.onDraw() {
if (!startedAnimatable && drawable is Animatable && !drawable.isRunning) {
Expand All @@ -116,7 +118,17 @@ class AndroidDrawablePainter(
invalidateTick

drawable.setBounds(0, 0, size.width.toInt(), size.height.toInt())
drawable.draw(canvas.nativeCanvas)

canvas.withSave {
// Painters are responsible for scaling content to meet the canvas size
if (drawable.intrinsicWidth > 0 && drawable.intrinsicHeight > 0) {
canvas.scale(
sx = size.width / drawable.intrinsicWidth,
sy = size.height / drawable.intrinsicHeight
)
}
drawable.draw(canvas.nativeCanvas)
}
}
}
}
Expand Down

0 comments on commit 4cf088f

Please sign in to comment.