Skip to content

Commit

Permalink
Added NinePatch*.getScaledPointAt methods to get what the point would…
Browse files Browse the repository at this point in the history
… be in a rescaled surface (#993)

This would help for example to create extra guides for padding/margin content inside the nine patch,
for example in a chat bubble
  • Loading branch information
soywiz-invideo authored Sep 16, 2022
1 parent 36114f7 commit 1a15eeb
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package com.soywiz.korim.util

import com.soywiz.korma.geom.IPoint
import com.soywiz.korma.geom.ISize
import com.soywiz.korma.geom.Point
import com.soywiz.korma.geom.PointArrayList
import com.soywiz.korma.geom.firstX
import com.soywiz.korma.geom.firstY
import com.soywiz.korma.geom.pointArrayListOf
import kotlin.math.absoluteValue
import kotlin.math.sign

Expand Down Expand Up @@ -32,4 +37,11 @@ data class NinePatchSlices2D(val x: NinePatchSlices, val y: NinePatchSlices) {
fun transform2D(
positions: List<PointArrayList>, oldSize: ISize, newSize: ISize
): List<PointArrayList> = positions.map { transform2D(it, oldSize, newSize) }

fun getScaledPointAt(point: IPoint, oldSize: ISize, newSize: ISize, out: Point = Point()): IPoint {
val p = pointArrayListOf(point)
transform2DInplace(p, oldSize, newSize)
out.setTo(p.firstX, p.firstY)
return out
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import com.soywiz.korim.color.Colors
import com.soywiz.korim.color.RGBA
import com.soywiz.korim.util.NinePatchSlices
import com.soywiz.korim.util.NinePatchSlices2D
import com.soywiz.korma.geom.IPoint
import com.soywiz.korma.geom.ISize
import com.soywiz.korma.geom.Point
import com.soywiz.korma.geom.asSize
import com.soywiz.korma.geom.bottomRight
import com.soywiz.korma.geom.vector.VectorPath

class NinePatchShape(val shape: Shape, val slices: NinePatchSlices2D) {
val size: ISize = shape.bounds.bottomRight.asSize()

fun getScaledPointAt(point: IPoint, newSize: ISize, out: Point = Point()): IPoint =
slices.getScaledPointAt(point, size, newSize, out)

fun transform(newSize: ISize): Shape {
return shape.scaleNinePatch(newSize, slices)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.soywiz.korim.vector

import com.soywiz.korim.util.NinePatchSlices2D
import com.soywiz.korma.geom.IPoint
import com.soywiz.korma.geom.ISize
import com.soywiz.korma.geom.Point
import com.soywiz.korma.geom.PointArrayList
import com.soywiz.korma.geom.Size
import com.soywiz.korma.geom.vector.VectorPath
Expand All @@ -11,34 +13,36 @@ class NinePatchVector(
val slices: NinePatchSlices2D,
oldSize: ISize? = null
) {
private val pathBounds = path.getBounds()
private val oldSize = oldSize ?: Size(pathBounds.right, pathBounds.bottom)
val size = oldSize ?: path.getBounds().let { Size(it.right, it.bottom) }
private val tempPoints = PointArrayList()

private inline fun transform(newSize: ISize, gen: PointArrayList.() -> Unit): PointArrayList {
fun getScaledPointAt(point: IPoint, newSize: ISize, out: Point = Point()): IPoint =
slices.getScaledPointAt(point, size, newSize, out)

private inline fun transformPoints(newSize: ISize, gen: PointArrayList.() -> Unit): PointArrayList {
tempPoints.clear()
gen(tempPoints)
slices.transform2DInplace(tempPoints, oldSize, newSize)
slices.transform2DInplace(tempPoints, size, newSize)
return tempPoints
}

fun transform(newSize: ISize, out: VectorPath = VectorPath()): VectorPath {
out.clear()
path.visitCmds(
moveTo = { x, y ->
val p = transform(newSize) { add(x, y) }
val p = transformPoints(newSize) { add(x, y) }
out.moveTo(p.getX(0), p.getY(0))
},
lineTo = { x, y ->
val p = transform(newSize) { add(x, y) }
val p = transformPoints(newSize) { add(x, y) }
out.lineTo(p.getX(0), p.getY(0))
},
quadTo = { x1, y1, x2, y2 ->
val p = transform(newSize) { add(x1, y1).add(x2, y2) }
val p = transformPoints(newSize) { add(x1, y1).add(x2, y2) }
out.quadTo(p.getX(0), p.getY(0), p.getX(1), p.getY(1))
},
cubicTo = { x1, y1, x2, y2, x3, y3 ->
val p = transform(newSize) { add(x1, y1).add(x2, y2).add(x3, y3) }
val p = transformPoints(newSize) { add(x1, y1).add(x2, y2).add(x3, y3) }
out.cubicTo(p.getX(0), p.getY(0), p.getX(1), p.getY(1), p.getX(2), p.getY(2))
},
close = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ open class PointArrayList(capacity: Int = 7) : IPointArrayList, Extra by Extra.M
}
fun setXY(index: Int, x: Int, y: Int) = setXY(index, x.toDouble(), y.toDouble())
fun setXY(index: Int, x: Float, y: Float) = setXY(index, x.toDouble(), y.toDouble())
fun setXY(index: Int, p: IPoint) = setXY(index, p.x, p.y)

fun transform(matrix: Matrix) {
for (n in 0 until size) {
Expand Down

0 comments on commit 1a15eeb

Please sign in to comment.