Skip to content

Commit 9f78f34

Browse files
committed
Change the handling of out-of-bounds canvas
1 parent 321290f commit 9f78f34

File tree

2 files changed

+311
-68
lines changed
  • mosaic-runtime/src

2 files changed

+311
-68
lines changed

mosaic-runtime/src/commonMain/kotlin/com/jakewharton/mosaic/surface.kt

+21-3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ import de.cketti.codepoints.appendCodePoint
1818

1919
private val blankPixel = TextPixel(' ')
2020

21+
/**
22+
* Returns always a new blank [TextPixel].
23+
*/
24+
private inline fun newBlankPixel(): TextPixel = TextPixel(' ')
25+
2126
public interface TextCanvas {
2227
public val height: Int
2328
public val width: Int
@@ -35,19 +40,32 @@ internal class TextSurface(
3540

3641
private val cells = Array(width * height) { TextPixel(' ') }
3742

43+
/**
44+
* It is used in places where the [TextPixel] state is not important
45+
* and it can change.
46+
*/
47+
private val reusableDirtyPixel: TextPixel = newBlankPixel()
48+
49+
/**
50+
* It is used in places where it is important that the [TextPixel]
51+
* has its original state and **will not change**.
52+
*/
53+
private val reusableBlankPixel: TextPixel = newBlankPixel()
54+
3855
operator fun get(row: Int, column: Int): TextPixel {
3956
val x = translationX + column
4057
val y = row + translationY
41-
check(x in 0 until width)
42-
check(y in 0 until height)
58+
if (x >= width || y >= height || x < 0 || y < 0) {
59+
return reusableDirtyPixel
60+
}
4361
return cells[y * width + x]
4462
}
4563

4664
override fun appendRowTo(appendable: Appendable, row: Int, ansiLevel: AnsiLevel) {
4765
// Reused heap allocation for building ANSI attributes inside the loop.
4866
val attributes = mutableIntListOf()
4967

50-
var lastPixel = blankPixel
68+
var lastPixel = reusableBlankPixel
5169

5270
val rowStart = row * width
5371
val rowStop = rowStart + width

0 commit comments

Comments
 (0)