Skip to content

Commit

Permalink
Implement rounded rectangle fallback behavior (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
cedrickcooke authored Jan 21, 2022
1 parent e26d493 commit 71eadd9
Showing 1 changed file with 33 additions and 9 deletions.
42 changes: 33 additions & 9 deletions element/src/commonMain/kotlin/RoundedRectangleElement.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,22 @@ public class RoundedRectangleElement : Element() {
public var paint: Paint by attributes.withDefault { DEFAULT_FILL }

override fun <PATH> draw(canvas: Kanvas<PATH>) {
val width = (right - left).coerceAtLeast(0f)
val height = (bottom - top).coerceAtLeast(0f)
val tlr = safeRadius(topLeftRadius, horizontalNeighbor = topRightRadius, verticalNeighbor = bottomLeftRadius, width, height)
val trr = safeRadius(topRightRadius, horizontalNeighbor = topLeftRadius, verticalNeighbor = bottomRightRadius, width, height)
val blr = safeRadius(bottomLeftRadius, horizontalNeighbor = bottomRightRadius, verticalNeighbor = topLeftRadius, width, height)
val brr = safeRadius(bottomRightRadius, horizontalNeighbor = bottomLeftRadius, verticalNeighbor = topRightRadius, width, height)
val path = canvas.buildPath {
moveTo(left + topLeftRadius, top)
lineTo(right - topRightRadius, top)
arcTo(right - 2 * topRightRadius, top, right, top + 2 * topRightRadius, -90f, 90f, false)
lineTo(right, bottom - bottomRightRadius)
arcTo(right - 2 * bottomRightRadius, bottom - 2 * bottomRightRadius, right, bottom, 0f, 90f, false)
lineTo(left + bottomLeftRadius, bottom)
arcTo(left, bottom - 2 * bottomLeftRadius, left + 2 * bottomLeftRadius, bottom, 90f, 90f, false)
lineTo(left, top + topLeftRadius)
arcTo(left, top, left + 2 * topLeftRadius, top + 2 * topLeftRadius, 180f, 90f, false)
moveTo(left + tlr, top)
lineTo(right - trr, top)
arcTo(right - 2 * trr, top, right, top + 2 * trr, -90f, 90f, false)
lineTo(right, bottom - brr)
arcTo(right - 2 * brr, bottom - 2 * brr, right, bottom, 0f, 90f, false)
lineTo(left + blr, bottom)
arcTo(left, bottom - 2 * blr, left + 2 * blr, bottom, 90f, 90f, false)
lineTo(left, top + tlr)
arcTo(left, top, left + 2 * tlr, top + 2 * tlr, 180f, 90f, false)
close()
}
canvas.drawPath(path, paint)
Expand All @@ -40,3 +46,21 @@ public class RoundedRectangleElement : Element() {
override fun trySelect(element: Element): RoundedRectangleElement? = element as? RoundedRectangleElement
}
}

/** Transforms a radius such that requested radii which are larger than their rectangle behave nicely. */
private fun safeRadius(desired: Float, horizontalNeighbor: Float, verticalNeighbor: Float, width: Float, height: Float): Float {
val requiresHorizontalAdjustment = width < (desired + horizontalNeighbor)
val requiresVerticalAdjustment = height < (desired + verticalNeighbor)
return if (requiresHorizontalAdjustment && requiresVerticalAdjustment) {
minOf(
width * desired / (desired + horizontalNeighbor),
height * desired / (desired + verticalNeighbor)
)
} else if (requiresHorizontalAdjustment) {
width * desired / (desired + horizontalNeighbor)
} else if (requiresVerticalAdjustment) {
height * desired / (desired + verticalNeighbor)
} else {
desired
}
}

0 comments on commit 71eadd9

Please sign in to comment.