diff --git a/gradle.properties b/gradle.properties index e315bba..5f555be 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ group=com.soywiz.korlibs.korma version=2.0.0-SNAPSHOT # korlibs -kdsVersion=2.0.6 +kdsVersion=2.0.7 # bintray location project.bintray.org=korlibs diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Matrix.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Matrix.kt index befb844..41a2ea6 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Matrix.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Matrix.kt @@ -177,17 +177,6 @@ data class Matrix( l.tx * r.b + l.ty * r.d + r.ty ) - @JvmName("multiplyNullable") - fun multiply(l: Matrix?, r: Matrix?): Matrix { - when { - l != null && r != null -> multiply(l, r) - l != null -> copyFrom(l) - r != null -> copyFrom(r) - else -> identity() - } - return this - } - /** Transform point without translation */ fun deltaTransformPoint(point: IPoint, out: Point = Point()) = deltaTransformPoint(point.x, point.y, out) fun deltaTransformPoint(x: Float, y: Float, out: Point = Point()): Point = deltaTransformPoint(x.toDouble(), y.toDouble(), out) @@ -496,4 +485,3 @@ data class Matrix( override fun toString(): String = "Matrix(a=$a, b=$b, c=$c, d=$d, tx=$tx, ty=$ty)" } - diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/MatrixExt.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/MatrixExt.kt index 7450281..b15e72f 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/MatrixExt.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/MatrixExt.kt @@ -1,5 +1,7 @@ package com.soywiz.korma.geom +import kotlin.jvm.* + fun Matrix3D.copyFrom(that: Matrix): Matrix3D = that.toMatrix3D(this) fun Matrix.toMatrix3D(out: Matrix3D = Matrix3D()): Matrix3D = out.setRows( @@ -8,3 +10,14 @@ fun Matrix.toMatrix3D(out: Matrix3D = Matrix3D()): Matrix3D = out.setRows( 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ) + +@JvmName("multiplyNullable") +fun Matrix.multiply(l: Matrix?, r: Matrix?): Matrix { + when { + l != null && r != null -> multiply(l, r) + l != null -> copyFrom(l) + r != null -> copyFrom(r) + else -> identity() + } + return this +} diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Point.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Point.kt index 153d63a..dfb5c55 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Point.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Point.kt @@ -88,15 +88,18 @@ operator fun Point.plusAssign(that: IPoint): Unit = run { setTo(this.x + that.x, data class Point( override var x: Double, override var y: Double + //override var xf: Float, + //override var yf: Float ) : MutableInterpolable, Interpolable, Comparable, IPoint, XY,XYf { + //constructor(x: Double, y: Double) : this(x.toFloat(), y.toFloat()) + constructor(x: Float, y: Float) : this(x.toDouble(), y.toDouble()) + constructor(x: Int, y: Int) : this(x.toDouble(), y.toDouble()) - override var xf: Float - get() = x.toFloat() - set(value) { x = value.toDouble() } + //override var x: Double get() = xf.toDouble() ; set(value) { xf = value.toFloat() } + //override var y: Double get() = yf.toDouble() ; set(value) { yf = value.toFloat() } - override var yf: Float - get() = y.toFloat() - set(value) { y = value.toDouble() } + override var xf: Float get() = x.toFloat() ; set(value) { x = value.toDouble() } + override var yf: Float get() = y.toFloat() ; set(value) { y = value.toDouble() } override fun compareTo(other: IPoint): Int = compare(this.x, this.y, other.x, other.y) fun compareTo(other: Point): Int = compare(this.x, this.y, other.x, other.y) @@ -121,8 +124,6 @@ data class Point( operator fun invoke(): Point = Point(0.0, 0.0) operator fun invoke(v: Point): Point = Point(v.x, v.y) operator fun invoke(v: IPoint): Point = Point(v.x, v.y) - operator fun invoke(x: Float, y: Float): Point = Point(x.toDouble(), y.toDouble()) - operator fun invoke(x: Int, y: Int): Point = Point(x.toDouble(), y.toDouble()) operator fun invoke(xy: Int): Point = Point(xy.toDouble(), xy.toDouble()) operator fun invoke(xy: Float): Point = Point(xy.toDouble(), xy.toDouble()) operator fun invoke(xy: Double): Point = Point(xy, xy) @@ -171,6 +172,12 @@ data class Point( return this } + fun setTo(x: Float, y: Float): Point { + this.xf = x + this.yf = y + return this + } + /** Updates a point from polar coordinates determined by an [angle] and a [length]. Angle 0 is pointing to the right, and the direction is counter-clock-wise */ fun setToPolar(angle: Angle, length: Double = 1.0): Point = setTo(angle.cosine * length, angle.sine * length) @@ -257,6 +264,7 @@ data class Point( val Point.unit: IPoint get() = this / length +@Deprecated("Use non Number version") inline fun Point.setTo(x: Number, y: Number): Point = setTo(x.toDouble(), y.toDouble()) interface IPointInt { @@ -286,7 +294,12 @@ inline class PointInt(val p: Point) : IPointInt, Comparable { override var y: Int set(value) = run { p.y = value.toDouble() } get() = p.y.toInt() - fun setTo(x: Int, y: Int) = this.apply { this.x = x; this.y = y } + fun setTo(x: Int, y: Int) : PointInt { + this.x = x + this.y = y + + return this + } fun setTo(that: IPointInt) = this.setTo(that.x, that.y) override fun toString(): String = "($x, $y)" } diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Rectangle.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Rectangle.kt index 6419ea0..428dbaa 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Rectangle.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Rectangle.kt @@ -101,7 +101,10 @@ data class Rectangle( infix fun intersectsX(that: Rectangle): Boolean = that.left <= this.right && that.right >= this.left infix fun intersectsY(that: Rectangle): Boolean = that.top <= this.bottom && that.bottom >= this.top - fun setToIntersection(a: Rectangle, b: Rectangle) = this.apply { a.intersection(b, this) } + fun setToIntersection(a: Rectangle, b: Rectangle): Rectangle { + a.intersection(b, this) + return this + } infix fun intersection(that: Rectangle) = intersection(that, Rectangle()) @@ -165,8 +168,10 @@ data class Rectangle( ratio.interpolate(l.height, r.height) ) - fun getAnchoredPosition(anchor: Anchor, out: Point = Point()): Point = - out.setTo(left + width * anchor.sx, top + height * anchor.sy) + fun getAnchoredPosition(anchor: Anchor, out: Point = Point()): Point = getAnchoredPosition(anchor.sx, anchor.sy, out) + + fun getAnchoredPosition(anchorX: Double, anchorY: Double, out: Point = Point()): Point = + out.setTo(left + width * anchorX, top + height * anchorY) fun toInt() = RectangleInt(x, y, width, height) fun floor(): Rectangle { @@ -183,9 +188,11 @@ data class Rectangle( } } +@Deprecated("Use non-mixed Int or Double variants for now") inline fun Rectangle.setTo(x: Number, y: Number, width: Number, height: Number) = this.setTo(x.toDouble(), y.toDouble(), width.toDouble(), height.toDouble()) +@Deprecated("Use non-mixed Int or Double variants for now") inline fun Rectangle.setBounds(left: Number, top: Number, right: Number, bottom: Number) = setBounds(left.toDouble(), top.toDouble(), right.toDouble(), bottom.toDouble()) //////////// INT @@ -261,18 +268,27 @@ inline class RectangleInt(val rect: Rectangle) : IRectangleInt { fun RectangleInt.setTo(that: RectangleInt) = setTo(that.x, that.y, that.width, that.height) -fun RectangleInt.setTo(x: Int, y: Int, width: Int, height: Int) = this.apply { +fun RectangleInt.setTo(x: Int, y: Int, width: Int, height: Int): RectangleInt { this.x = x this.y = y this.width = width this.height = height + + return this } -fun RectangleInt.setPosition(x: Int, y: Int) = this.apply { this.x = x; this.y = y } +fun RectangleInt.setPosition(x: Int, y: Int):RectangleInt { + this.x = x + this.y = y + + return this +} -fun RectangleInt.setSize(width: Int, height: Int) = this.apply { +fun RectangleInt.setSize(width: Int, height: Int): RectangleInt { this.width = width this.height = height + + return this } fun RectangleInt.getPosition(out: PointInt = PointInt()): PointInt = out.setTo(x, y) diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Size.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Size.kt index 06e3701..ebcaead 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Size.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/Size.kt @@ -87,9 +87,11 @@ inline class SizeInt(val size: Size) : ISizeInt { override fun toString(): String = "SizeInt(width=$width, height=$height)" } -fun SizeInt.setTo(width: Int, height: Int) = this.apply { +fun SizeInt.setTo(width: Int, height: Int) : SizeInt { this.width = width this.height = height + + return this } fun SizeInt.setTo(that: SizeInt) = setTo(that.width, that.height) diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/PolygonScanline.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/PolygonScanline.kt index 3d6de20..ff12200 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/PolygonScanline.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/PolygonScanline.kt @@ -40,7 +40,7 @@ class PolygonScanline : RastScale() { private val boundsBuilder = BoundsBuilder() class Bucket { - val edges = arrayListOf() + val edges = FastArrayList() fun clear() = this.apply { edges.clear() } inline fun fastForEach(block: (edge: Edge) -> Unit) = edges.fastForEach(block) } @@ -102,7 +102,7 @@ class PolygonScanline : RastScale() { private val edgesPool = Pool { Edge() } @PublishedApi - internal val edges = arrayListOf() + internal val edges = FastArrayList() private val buckets = AllBuckets() fun getBounds(out: Rectangle = Rectangle()) = boundsBuilder.getBounds(out) diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/VectorBuilder.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/VectorBuilder.kt index 103abce..51e10b5 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/VectorBuilder.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/geom/vector/VectorBuilder.kt @@ -5,6 +5,7 @@ import com.soywiz.korma.geom.* import com.soywiz.korma.geom.bezier.* import com.soywiz.korma.internal.* import com.soywiz.korma.internal.min2 +import com.soywiz.korma.math.* import kotlin.math.* @KorDslMarker @@ -99,7 +100,7 @@ fun VectorBuilder.arc(x: Double, y: Double, r: Double, start: Angle, end: Angle) val startAngle = start.radians % PI_TWO val endAngle = end.radians % PI_TWO var remainingAngle = min2(PI_TWO, abs(endAngle - startAngle)) - if (remainingAngle == 0.0 && start != end) remainingAngle = PI_TWO + if (remainingAngle.absoluteValue < EPSILON && start != end) remainingAngle = PI_TWO val sgn = if (startAngle < endAngle) +1 else -1 var a1 = startAngle val p1 = Point() @@ -170,6 +171,15 @@ fun VectorBuilder.lineTo(p: Point) = lineTo(p.x, p.y) fun VectorBuilder.quadTo(c: Point, a: Point) = quadTo(c.x, c.y, a.x, a.y) fun VectorBuilder.cubicTo(c1: Point, c2: Point, a: Point) = cubicTo(c1.x, c1.y, c2.x, c2.y, a.x, a.y) +fun VectorBuilder.polygon(path: PointArrayList, close: Boolean = true) { + moveTo(path.getX(0), path.getY(0)) + for (i in 1 until path.size) { + lineTo(path.getX(i), path.getY(i)) + } + if (close) close() +} +fun VectorBuilder.polygon(path: Array, close: Boolean = true) = polygon(PointArrayList(*path), close) +fun VectorBuilder.polygon(path: List, close: Boolean = true) = polygon(PointArrayList(path), close) fun VectorBuilder.moveToH(x: Double) = moveTo(x, lastY) fun VectorBuilder.moveToH(x: Float) = moveToH(x.toDouble()) diff --git a/korma/src/commonMain/kotlin/com/soywiz/korma/internal/Internal.kt b/korma/src/commonMain/kotlin/com/soywiz/korma/internal/Internal.kt index 352d759..f0d1afc 100644 --- a/korma/src/commonMain/kotlin/com/soywiz/korma/internal/Internal.kt +++ b/korma/src/commonMain/kotlin/com/soywiz/korma/internal/Internal.kt @@ -14,6 +14,14 @@ internal infix fun Double.umod(other: Double): Double { } } +internal infix fun Float.umod(other: Float): Float { + val remainder = this % other + return when { + remainder < 0 -> remainder + other + else -> remainder + } +} + @PublishedApi internal fun floorCeil(v: Double): Double = if (v < 0.0) ceil(v) else floor(v)