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

Some mutable cleanups #1477

Merged
merged 3 commits into from
Mar 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 9 additions & 18 deletions korge/src/commonMain/kotlin/korlibs/korge/view/BaseGraphics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ abstract class BaseGraphics(
_dirtyBounds = true
}

private val bb = BoundsBuilder()

@OptIn(KorgeExperimental::class)
override fun renderInternal(ctx: RenderContext) {
bitmapsToRemove.fastForEach {
Expand Down Expand Up @@ -123,7 +121,7 @@ abstract class BaseGraphics(
var realImageScaleY = 1.0

protected abstract fun drawShape(ctx: Context2d) // this@BaseGraphics.compoundShape.draw(this)
protected abstract fun getShapeBounds(bb: BoundsBuilder, includeStrokes: Boolean) // shapes.fastForEach { it.addBounds(bb) }
protected abstract fun getShapeBounds(includeStrokes: Boolean): Rectangle // shapes.fastForEach { it.addBounds(bb) }

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

Expand Down Expand Up @@ -153,27 +151,22 @@ abstract class BaseGraphics(

override fun getLocalBoundsInternal(): Rectangle = _getLocalBoundsInternal()

private val __localBounds: MRectangle = MRectangle()
private var __localBounds: Rectangle = Rectangle()
//var boundsIncludeStrokes = false
var boundsIncludeStrokes = true
private fun _getLocalBoundsInternal(strokes: Boolean = this.boundsIncludeStrokes): Rectangle {
val bounds = boundsUnsafe(strokes = strokes)
return Rectangle(bounds.x - anchorDispX, bounds.y - anchorDispY, bounds.width, bounds.height)
return Rectangle(bounds.x - anchorDispX, bounds.y - anchorDispY, bounds.widthD, bounds.heightD)
}

private val _localBoundsWithStrokes = MRectangle()
private val _localBounds = MRectangle()
private var _localBoundsWithStrokes = Rectangle()
private var _localBounds = Rectangle()

private fun boundsUnsafe(strokes: Boolean): MRectangle {
private fun boundsUnsafe(strokes: Boolean): Rectangle {
if (_dirtyBounds) {
_dirtyBounds = false
bb.reset()
getShapeBounds(bb, includeStrokes = false)
bb.getBounds(_localBounds)

bb.reset()
getShapeBounds(bb, includeStrokes = true)
bb.getBounds(_localBoundsWithStrokes)
_localBounds = getShapeBounds(includeStrokes = false)
_localBoundsWithStrokes = getShapeBounds(includeStrokes = true)

/*
println("getLocalBoundsInternalNoAnchor: ")
Expand All @@ -185,9 +178,7 @@ abstract class BaseGraphics(
return if (strokes) _localBoundsWithStrokes else _localBounds
}

fun getLocalBoundsInternalNoAnchor(out: MRectangle, includeStrokes: Boolean) {
out.copyFrom(boundsUnsafe(includeStrokes))
}
fun getLocalBoundsInternalNoAnchor(includeStrokes: Boolean): Rectangle = boundsUnsafe(includeStrokes)

internal class InternalViewAutoscaling {
var renderedAtScaleXInv = 1.0; private set
Expand Down
7 changes: 4 additions & 3 deletions korge/src/commonMain/kotlin/korlibs/korge/view/CpuGraphics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import korlibs.image.vector.Context2d
import korlibs.image.vector.Shape
import korlibs.image.vector.ShapeBuilder
import korlibs.image.vector.buildShape
import korlibs.math.geom.BoundsBuilder
import korlibs.math.geom.*
import korlibs.math.geom.shape.Shape2d
import korlibs.math.geom.shape.toShape2d
import korlibs.math.geom.vector.VectorPath
Expand Down Expand Up @@ -121,7 +121,8 @@ open class CpuGraphics @JvmOverloads constructor(
shape?.draw(ctx)
}

override fun getShapeBounds(bb: BoundsBuilder, includeStrokes: Boolean) {
bb.add(shape?.getBounds(includeStrokes)?.mutable)
override fun getShapeBounds(includeStrokes: Boolean): Rectangle {
//return shape?.getBounds(includeStrokes) ?: Rectangle.NIL
return shape?.getBounds(includeStrokes) ?: Rectangle.ZERO
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ open class FixedSizeContainer(
//println("ctx.ag.isRenderingToWindow=${ctx.ag.isRenderingToWindow}, FIXED_CLIP: bounds=$bounds, ctx.viewMat2D=${ctx.viewMat2D}")

//println("FIXED_CLIP: bounds=$bounds")
val rect = c2d.batch.scissor.toRectOrNull(tempRect)?.immutable
val rect = c2d.batch.scissor.toRectOrNull()
var intersects = true
if (rect != null) {
intersects = bounds.intersects(rect)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ inline fun Container.ninePatchShapeView(
class NinePatchShapeView(
shape: NinePatchShape,
renderer: GraphicsRenderer,
) : UIView(shape.size.width, shape.size.height), Anchorable {
) : UIView(shape.size.widthD, shape.size.heightD), Anchorable {
private val graphics = graphics(shape.shape, renderer = renderer)
var boundsIncludeStrokes: Boolean by graphics::boundsIncludeStrokes
var antialiased: Boolean by graphics::antialiased
Expand All @@ -32,6 +32,6 @@ class NinePatchShapeView(

override fun onSizeChanged() {
super.onSizeChanged()
graphics.shape = shape.transform(MSize(width, height))
graphics.shape = shape.transform(Size(width, height))
}
}
5 changes: 2 additions & 3 deletions korge/src/commonMain/kotlin/korlibs/korge/view/VectorImage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,8 @@ class VectorImage(
ctx.draw(shape)
}

override fun getShapeBounds(bb: BoundsBuilder, includeStrokes: Boolean) {
bb.add(0.0, 0.0)
bb.add(shape.width, shape.height)
override fun getShapeBounds(includeStrokes: Boolean): Rectangle {
return Rectangle(0, 0, shape.width, shape.height)
}

override fun renderInternal(ctx: RenderContext) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,6 @@ class ViewFixedSizeContainerTest : ViewsForTesting(
stage.render(it)
}

assertEquals(listOf<Any?>(MRectangle(234, 105, 150, 150)), log)
assertEquals(listOf<Any?>(Rectangle(234, 105, 150, 150)), log)
}
}
6 changes: 3 additions & 3 deletions korgw/src/commonMain/kotlin/korlibs/graphics/AGObjects.kt
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ open class AGFrameBuffer(val base: AGFrameBufferBase, val id: Int = -1) : Closea
var fullWidth = DEFAULT_INITIAL_WIDTH
var fullHeight = DEFAULT_INITIAL_HEIGHT
private val _scissor = MRectangleInt()
var scissor: MRectangleInt? = null
var scissor: RectangleInt? = null

open fun setSize(width: Int, height: Int) {
setSize(0, 0, width, height)
Expand All @@ -221,8 +221,8 @@ open class AGFrameBuffer(val base: AGFrameBufferBase, val id: Int = -1) : Closea
markAsDirty()
}

fun scissor(scissor: MRectangleInt?) {
this.scissor = scissor?.let { _scissor.setTo(it) }
fun scissor(scissor: RectangleInt?) {
this.scissor = scissor
}

override fun close() {
Expand Down
14 changes: 5 additions & 9 deletions korgw/src/commonMain/kotlin/korlibs/graphics/AGState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ inline class AGSize(val data: Int) {
}

inline class AGScissor(val data: Short4Pack) {
val isNIL: Boolean get() = this == NIL
val isNotNIL: Boolean get() = !isNIL

//constructor(xy: Int, wh: Int) : this(short4PackOf(xy.toShort(), (xy ushr 16).toShort(), wh.toShort(), (wh ushr 16).toShort()))
constructor(x: Int, y: Int, width: Int, height: Int) : this(short4PackOf(x.toShortClamped(), y.toShortClamped(), (x + width).toShortClamped(), (y + height).toShortClamped()))
constructor(x: Float, y: Float, width: Float, height: Float) : this(x.toIntRound(), y.toIntRound(), width.toIntRound(), height.toIntRound())
Expand All @@ -629,11 +632,8 @@ inline class AGScissor(val data: Short4Pack) {
return "Scissor(x=${x}, y=${y}, width=${width}, height=${height})"
}

fun toRect(out: MRectangle = MRectangle()): MRectangle = out.setTo(x, y, width, height)
fun toRectOrNull(out: MRectangle = MRectangle()): MRectangle? {
if (this == NIL) return null
return out.setTo(x, y, width, height)
}
fun toRect(): Rectangle = if (isNIL) Rectangle.NIL else Rectangle(x, y, width, height)
fun toRectOrNull(): Rectangle? = toRect().takeIf { it.isNotNIL }

companion object {
fun fromBounds(left: Int, top: Int, right: Int, bottom: Int): AGScissor = AGScissor(left, top, right - left, bottom - top)
Expand All @@ -650,10 +650,6 @@ inline class AGScissor(val data: Short4Pack) {
if (rect.isNIL) return NIL
return AGScissor(rect.x, rect.y, rect.width, rect.height)
}
operator fun invoke(rect: MRectangle?): AGScissor {
if (rect == null) return NIL
return AGScissor(rect.x, rect.y, rect.width, rect.height)
}

// null is equivalent to Scissor(-Inf, -Inf, +Inf, +Inf)
fun combine(prev: AGScissor, next: AGScissor): AGScissor {
Expand Down
4 changes: 2 additions & 2 deletions korgw/src/commonMain/kotlin/korlibs/render/GameWindow.kt
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,8 @@ open class GameWindow :
override val dialogInterface: DialogInterface get() = DialogInterface.Unsupported

data class CustomCursor(val shape: Shape, val name: String = "custom") : ICursor, Extra by Extra.Mixin() {
val bounds: MRectangle = this.shape.bounds.mutable
fun createBitmap(size: MSize? = null, native: Boolean = true) = shape.renderWithHotspot(fit = size, native = native)
val bounds: Rectangle = this.shape.bounds
fun createBitmap(size: Size? = null, native: Boolean = true) = shape.renderWithHotspot(fit = size, native = native)
}

enum class Cursor : ICursor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,10 @@ abstract class BaseAwtGameWindow(
val CustomCursor.jvmCursor: java.awt.Cursor by extraPropertyThis {
val toolkit = Toolkit.getDefaultToolkit()
val size = toolkit.getBestCursorSize(bounds.width.toIntCeil(), bounds.height.toIntCeil())
val result = this.createBitmap(MSize(size.width, size.height))
val result = this.createBitmap(Size(size.width, size.height))
//println("BITMAP SIZE=${result.bitmap.size}, hotspot=${result.hotspot}")
val hotspotX = result.hotspot.x.toInt().coerceIn(0, result.bitmap.width - 1)
val hotspotY = result.hotspot.y.toInt().coerceIn(0, result.bitmap.height - 1)
val hotspotX = result.hotspot.x.coerceIn(0, result.bitmap.width - 1)
val hotspotY = result.hotspot.y.coerceIn(0, result.bitmap.height - 1)
toolkit.createCustomCursor(result.bitmap.toAwt(), java.awt.Point(hotspotX, hotspotY), name).also {
//println("CUSTOM CURSOR: $it")
}
Expand Down
11 changes: 5 additions & 6 deletions korgw/src/jvmMain/kotlin/korlibs/render/osx/MacosGLContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import korlibs.render.*
import korlibs.render.platform.*
import korlibs.io.dynamic.*
import korlibs.math.geom.*
import korlibs.math.geom.Rectangle
import java.awt.*
import java.security.*
import javax.swing.SwingUtilities
Expand Down Expand Up @@ -135,9 +136,7 @@ class MacosGLContext(
val fw = (frame.width * factor).toInt()
val fh = (frame.height * factor).toInt()
// factor=2.0, scissorBox: java.awt.Rectangle[x=0,y=0,width=2560,height=1496], viewport: java.awt.Rectangle[x=0,y=0,width=2560,height=1496]
val info = BaseOpenglContext.ContextInfo(MRectangleInt(), MRectangleInt(),)
info.scissors?.setTo(fx, fy, fw, fh)
info.viewport?.setTo(fx, fy, fw, fh)
val info = BaseOpenglContext.ContextInfo(RectangleInt(fx, fy, fw, fh), RectangleInt(fx, fy, fw, fh))
println("info=$info")
action(g, info)
} finally {
Expand Down Expand Up @@ -187,7 +186,7 @@ class MacAWTOpenglContext(val gwconfig: GameWindowConfig, val c: Component, var
}

val info = BaseOpenglContext.ContextInfo(
MRectangleInt(), MRectangleInt()
RectangleInt(), RectangleInt()
)

override val scaleFactor: Double get() = getDisplayScalingFactor(c)
Expand All @@ -204,9 +203,9 @@ class MacAWTOpenglContext(val gwconfig: GameWindowConfig, val c: Component, var
///println("factor=$factor, scissorBox: $scissorBox, viewport: $viewport")
//info.scissors?.setTo(scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height)
if (scissorBox != null) {
info.scissors?.setTo(scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height)
info.scissors = RectangleInt(scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height)
//info.viewport?.setTo(viewport.x, viewport.y, viewport.width, viewport.height)
info.viewport?.setTo(scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height)
info.viewport = RectangleInt(scissorBox.x, scissorBox.y, scissorBox.width, scissorBox.height)
} else {
System.err.println("ERROR !! scissorBox = $scissorBox, viewport = $viewport")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ interface BaseOpenglContext : Disposable {
val isCore: Boolean get() = false
val scaleFactor: Double get() = 1.0
data class ContextInfo(
val scissors: MRectangleInt? = null,
val viewport: MRectangleInt? = null
var scissors: RectangleInt? = null,
var viewport: RectangleInt? = null
) {
companion object {
val DEFAULT = ContextInfo()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,20 +410,20 @@ class WindowsGameWindow : EventLoopGameWindow() {
fun getWinStyle(fullscreen: Boolean, extra: Long = 0): Long = if (fullscreen) extra.without(WS_OVERLAPPEDWINDOW.toLong()).with(WS_POPUP.toLong()) else extra.with(WS_OVERLAPPEDWINDOW.toLong()).without(WS_POPUP.toLong())
fun getWinExStyle(fullscreen: Boolean): Long = if (fullscreen) 0L else WS_EX_OVERLAPPEDWINDOW.toLong()

fun getBorderSize(): MSizeInt {
fun getBorderSize(): SizeInt {
val w = 1000
val h = 1000
val out = getRealSize(w, h)
return MSizeInt(out.width - w, out.height - h)
return SizeInt(out.width - w, out.height - h)
}

fun getRealSize(width: Int, height: Int): MSizeInt {
fun getRealSize(width: Int, height: Int): SizeInt {
return memScoped {
val rect = alloc<RECT>()
rect.width = width
rect.height = height
AdjustWindowRectEx(rect.ptr, winStyle.convert(), hasMenu.toInt().convert(), winExStyle.convert())
MSizeInt(rect.width, rect.height)
SizeInt(rect.width, rect.height)
}
}

Expand Down
2 changes: 0 additions & 2 deletions korim/src/commonMain/kotlin/korlibs/image/bitmap/Bitmap32.kt
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,6 @@ fun Bitmap32.posterizeInplace(nbits: Int = 4): Bitmap32 {
return this
}

@Deprecated("")
fun Bitmap32.expandBorder(area: MRectangleInt, border: Int) = expandBorder(area.immutable, border)
fun Bitmap32.expandBorder(area: RectangleInt, border: Int) = expandBorder(area.top, area.left, area.bottom, area.right, border)

fun Bitmap32.expandBorder(areaTop: Int, areaLeft: Int, areaBottom: Int, areaRight: Int, border: Int) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ fun <T : Bitmap> RectSlice<T>.extract(): T {

fun <T : Bitmap> RectSlice<T>.toBitmap(): T = extract()

fun <T : SizeableInt> SliceCoordsWithBase<T>.slice(bounds: MRectangleInt = MRectangleInt(0, 0, width, height), name: String? = null, orientation: ImageOrientation = ImageOrientation.ROTATE_0, padding: MarginInt = MarginInt.ZERO): RectSlice<T> =
fun <T : SizeableInt> SliceCoordsWithBase<T>.slice(bounds: RectangleInt = RectangleInt(0, 0, width, height), name: String? = null, orientation: ImageOrientation = ImageOrientation.ROTATE_0, padding: MarginInt = MarginInt.ZERO): RectSlice<T> =
RectSlice(
this.base,
// @TODO: This shouldn't be necessary. But ASE test fails without this
Expand Down
6 changes: 3 additions & 3 deletions korim/src/commonMain/kotlin/korlibs/image/format/ImageInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ package korlibs.image.format

import korlibs.datastructure.Extra
import korlibs.datastructure.toMap
import korlibs.math.geom.MSize
import korlibs.math.geom.*

open class ImageInfo : Extra by Extra.Mixin() {
open class ImageInfo : Sizeable, Extra by Extra.Mixin() {
var width: Int = 0
var height: Int = 0
var bitsPerPixel: Int = 8

val size: MSize get() = MSize(width, height)
override val size: Size get() = Size(width, height)

override fun toString(): String = "ImageInfo(width=$width, height=$height, bpp=$bitsPerPixel, extra=${extra?.toMap()})"
}
Expand Down
37 changes: 18 additions & 19 deletions korim/src/commonMain/kotlin/korlibs/image/util/NinePatchSlices.kt
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
package korlibs.image.util

import korlibs.datastructure.DoubleArrayList
import korlibs.math.geom.range.DoubleRangeExclusive
import korlibs.math.geom.range.until
import korlibs.datastructure.*
import korlibs.math.geom.range.*

class NinePatchSlices private constructor(val ranges: List<DoubleRangeExclusive>, dummy: Unit) {
constructor(ranges: List<DoubleRangeExclusive>) : this(ranges.sortedBy { it.start }, Unit)
constructor(vararg ranges: DoubleRangeExclusive) : this(ranges.sortedBy { it.start }, Unit)
class NinePatchSlices private constructor(val ranges: List<FloatRangeExclusive>, dummy: Unit) {
constructor(ranges: List<FloatRangeExclusive>) : this(ranges.sortedBy { it.start }, Unit)
constructor(vararg ranges: FloatRangeExclusive) : this(ranges.sortedBy { it.start }, Unit)
companion object {
operator fun invoke(vararg doubles: Double): NinePatchSlices {
if (doubles.size % 2 != 0) error("Number of slices must be pair")
return NinePatchSlices((0 until (doubles.size / 2)).map { doubles[it * 2] until doubles[it * 2 + 1] })
operator fun invoke(vararg values: Float): NinePatchSlices {
if (values.size % 2 != 0) error("Number of slices must be pair")
return NinePatchSlices((0 until (values.size / 2)).map { values[it * 2] until values[it * 2 + 1] })
}
}

val lengths get() = ranges.sumOf { it.length }
val lengths: Float get() = ranges.sumOf { it.length.toDouble() }.toFloat()

// @TODO: newLen < oldLen should make corners (non-stretch areas) smaller
inline fun transform1DInplace(oldLen: Double, newLen: Double, count: Int, get: (index: Int) -> Double, set: (index: Int, value: Double) -> Unit, iscale: Double = 1.0) {
inline fun transform1DInplace(oldLen: Float, newLen: Float, count: Int, get: (index: Int) -> Float, set: (index: Int, value: Float) -> Unit, iscale: Float = 1f) {
val slices: NinePatchSlices = this
val rscale = if (slices.ranges.isEmpty()) {
newLen / oldLen
} else {
val rscale = if (newLen / iscale < oldLen) newLen / oldLen else iscale
val scale = (newLen / rscale - oldLen) / slices.lengths
val position = get(count - 1)
val rscale: Float = if (newLen / iscale < oldLen) newLen / oldLen else iscale
val scale: Float = (newLen / rscale - oldLen) / slices.lengths
val position: Float = get(count - 1)
for (slice in slices.ranges) {
if (position > slice.start) {
var offset = slice.length * scale
if (position <= slice.endExclusive) offset *= (position - slice.start) / slice.length
var offset: Float = slice.length.toFloat() * scale
if (position <= slice.endExclusive) offset *= (position - slice.start.toFloat()) / slice.length.toFloat()
for (i in 0 until count) set(i, get(i) + offset)
}
}
Expand All @@ -37,18 +36,18 @@ class NinePatchSlices private constructor(val ranges: List<DoubleRangeExclusive>
for (i in 0 until count) set(i, get(i) * rscale)
}

fun transform1DInplace(positions: DoubleArrayList, oldLen: Double, newLen: Double) {
fun transform1DInplace(positions: FloatArrayList, oldLen: Float, newLen: Float) {
transform1DInplace(oldLen, newLen, positions.size, get = { positions[it] }, set = { index, value -> positions[index] = value })
}

fun transform1D(input: DoubleArrayList, oldLen: Double, newLen: Double, output: DoubleArrayList = DoubleArrayList()): DoubleArrayList {
fun transform1D(input: FloatArrayList, oldLen: Float, newLen: Float, output: FloatArrayList = FloatArrayList()): FloatArrayList {
output.size = input.size
for (n in 0 until input.size) output[n] = input[n]
transform1DInplace(output, oldLen, newLen)
return output
}

fun transform1D(input: List<DoubleArrayList>, oldLen: Double, newLen: Double): List<DoubleArrayList> =
fun transform1D(input: List<FloatArrayList>, oldLen: Float, newLen: Float): List<FloatArrayList> =
input.map { transform1D(it, oldLen, newLen) }

override fun hashCode(): Int = ranges.hashCode()
Expand Down
Loading