diff --git a/backends/x/draw.go b/backends/x/draw.go index 8200f06..5523463 100644 --- a/backends/x/draw.go +++ b/backends/x/draw.go @@ -46,9 +46,8 @@ func (backend *Backend) drawCells (forceRedraw bool) (areas []image.Rectangle) { for y := 0; y < height; y ++ { for x := 0; x < width; x ++ { if !forceRedraw && backend.application.Clean(x, y) { continue } - backend.application.MarkClean(x, y) - cell := backend.application.Cell(x, y) + cell := backend.application.GetForRendering(x, y) content := cell.Rune() if forceRedraw && content < 32 { continue } @@ -93,13 +92,24 @@ func (backend *Backend) drawRune ( if character < 32 { return } origin := backend.originOfCell(x, y + 1) - destinationRectangle, mask, maskPoint, _, _ := backend.font.face.Glyph ( + destinationRectangle, mask, maskPoint, _, ok := backend.font.face.Glyph ( fixed.Point26_6 { X: fixed.I(origin.X), Y: fixed.I(origin.Y - backend.metrics.descent), }, character) + if !ok { + println("warning") + strokeRectangle ( + &image.Uniform { + C: backend.config.Color(stone.ColorForeground), + }, + backend.canvas, + backend.boundsOfCell(x, y)) + return + } + if backend.drawCellBounds { strokeRectangle ( &image.Uniform { diff --git a/buffer.go b/buffer.go index 0609001..10b6271 100644 --- a/buffer.go +++ b/buffer.go @@ -69,8 +69,8 @@ type Buffer interface { // dirty by default, are only clean when marked as clean, and become dirty again // when they are altered in some way. type DamageBuffer struct { - content []Cell - clean []bool + content []Cell + onScreen []Cell width int height int @@ -127,9 +127,7 @@ func (buffer *DamageBuffer) SetColor (x, y int, color Color) { defer buffer.lock.RUnlock() if buffer.isOutOfBounds(x, y) { return } - index := x + y * buffer.width - buffer.clean[index] = buffer.content[index].color == color - buffer.content[index].color = color + buffer.content[x + y * buffer.width].color = color } // SetSize sets the width and height of the buffer. This clears all data in the @@ -139,10 +137,10 @@ func (buffer *DamageBuffer) SetSize (width, height int) { defer buffer.lock.Unlock() if width < 0 || height < 0 { return } - buffer.width = width - buffer.height = height - buffer.content = make([]Cell, width * height) - buffer.clean = make([]bool, width * height) + buffer.width = width + buffer.height = height + buffer.content = make([]Cell, width * height) + buffer.onScreen = make([]Cell, width * height) for index := 0; index < len(buffer.content); index ++ { buffer.content[index].color = ColorForeground } @@ -154,9 +152,7 @@ func (buffer *DamageBuffer) SetStyle (x, y int, style Style) { defer buffer.lock.RUnlock() if buffer.isOutOfBounds(x, y) { return } - index := x + y * buffer.width - buffer.clean[index] = buffer.content[index].style == style - buffer.content[index].style = style + buffer.content[x + y * buffer.width].style = style } // SetRune sets the rune of the cell at the specified x and y coordinates. @@ -173,7 +169,6 @@ func (buffer *DamageBuffer) Clear () { defer buffer.lock.RUnlock() for index := 0; index < len(buffer.content); index ++ { - buffer.clean[index] = false buffer.content[index] = Cell { color: ColorForeground, } @@ -182,9 +177,7 @@ func (buffer *DamageBuffer) Clear () { func (buffer *DamageBuffer) setRune (x, y int, content rune) { if buffer.isOutOfBounds(x, y) { return } - index := x + y * buffer.width - buffer.clean[index] = buffer.content[index].content == content - buffer.content[index].content = content + buffer.content[x + y * buffer.width].content = content } // Write writes data stored in a byte slice to the buffer at the current dot @@ -212,15 +205,20 @@ func (buffer *DamageBuffer) Clean (x, y int) (clean bool) { defer buffer.lock.RUnlock() if buffer.isOutOfBounds(x, y) { return } - clean = buffer.clean[x + y * buffer.width] + index := x + y * buffer.width + clean = buffer.content[index] == buffer.onScreen[index] return } -// MarkClean marks the cell at the specified x and y coordinates as clean. -func (buffer *DamageBuffer) MarkClean (x, y int) { +// GetForRendering returns the cell at the specified x and y coordinates and +// marks it as clean. +func (buffer *DamageBuffer) GetForRendering (x, y int) (cell Cell) { buffer.lock.RLock() defer buffer.lock.RUnlock() if buffer.isOutOfBounds(x, y) { return } - buffer.clean[x + y * buffer.width] = true + index := x + y * buffer.width + buffer.onScreen[index] = buffer.content[index] + cell = buffer.content[index] + return }