-
-
Save romainguy/4beb128d2349e081ebbcd4b717305187 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
inline fun Int.uncheckedCoerceIn(minimumValue: Int, maximumValue: Int) = | |
this.coerceAtLeast(minimumValue).coerceAtMost(maximumValue) | |
inline fun Rect(l: Int, t: Int, r: Int, b: Int) = | |
Rect(( | |
((l.uncheckedCoerceIn(0, 8) and 0xf) shl 12) or | |
((t.uncheckedCoerceIn(0, 8) and 0xf) shl 8) or | |
((r.uncheckedCoerceIn(0, 8) and 0xf) shl 4) or | |
((b.uncheckedCoerceIn(0, 8) and 0xf) ) | |
).toShort()) | |
@JvmInline | |
value class Rect @PublishedApi internal constructor(@PublishedApi internal val points: Short) { | |
inline val l: Int get() = points.toInt() ushr 12 | |
inline val t: Int get() = (points.toInt() shr 8) and 0xf | |
inline val r: Int get() = (points.toInt() shr 4) and 0xf | |
inline val b: Int get() = points.toInt() and 0xf | |
override fun toString() = "Rect($l, $t, $r, $b)" | |
} | |
inline fun Grid() = Grid(0L) | |
inline fun Grid(r: Rect) = Grid(rasterize(r.l, r.t, r.r, r.b)) | |
inline fun Grid(l: Int, t: Int, r: Int, b: Int) = Grid(rasterize(l, t, r, b)) | |
@JvmInline | |
value class Grid @PublishedApi internal constructor(@PublishedApi internal val cells: Long) { | |
inline fun forEach(block: (Int, Int) -> Unit) { | |
var v = cells | |
while (v.hasNext()) { | |
val index = v.get() | |
block(index and 0x7, index ushr 3) | |
v = v.next() | |
} | |
} | |
inline operator fun get(x: Int, y: Int) = | |
((cells ushr ((7 - y) shl 3)) and (0x1L shl (7 - x))) != 0L | |
inline operator fun plus(r: Rect) = | |
Grid(cells or rasterize(r.l, r.t, r.r, r.b)) | |
inline operator fun minus(r: Rect) = | |
Grid(cells and rasterize(r.l, r.t, r.r, r.b).inv()) | |
inline infix fun and(r: Rect) = | |
Grid(cells and rasterize(r.l, r.t, r.r, r.b)) | |
inline fun intersects(r: Rect) = | |
(cells and rasterize(r.l, r.t, r.r, r.b)) != 0L | |
override fun toString() = buildString { | |
for (y in 0..7) { | |
val line = (cells ushr (56 - y shl 3) and 0xffL).toString(2).padStart(8, '0') | |
appendLine(line) | |
} | |
} | |
} | |
@PublishedApi | |
internal inline fun Long.get() = 63 - countTrailingZeroBits() | |
@PublishedApi | |
internal inline fun Long.hasNext() = this != 0L | |
@PublishedApi | |
internal inline fun Long.next() = this and (this - 1L) | |
@PublishedApi | |
internal fun rasterize(l: Int, t: Int, r: Int, b: Int): Long { | |
val w = r - l | |
val h = b - t | |
val scanline = 0xffL ushr (8 - w) shl (8 - r) | |
val rows = 0x01_01_01_01_01_01_01_01L ushr ((8 - h) shl 3) shl ((8 - b) shl 3) | |
return rows * scanline | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment