diff --git a/backends/x/window.go b/backends/x/window.go index 8215b0d..8956ba5 100644 --- a/backends/x/window.go +++ b/backends/x/window.go @@ -195,19 +195,31 @@ func (window *Window) OnClose (callback func ()) { } func (window *Window) reallocateCanvas () { - window.canvas = tomo.NewBasicCanvas ( - window.metrics.width, - window.metrics.height) + window.canvas.Reallocate(window.metrics.width, window.metrics.height) + + previousWidth, previousHeight := 0, 0 if window.xCanvas != nil { - window.xCanvas.Destroy() + previousWidth = window.xCanvas.Bounds().Dx() + previousHeight = window.xCanvas.Bounds().Dy() } - window.xCanvas = xgraphics.New ( - window.backend.connection, - image.Rect ( - 0, 0, - window.metrics.width, - window.metrics.height)) - window.xCanvas.CreatePixmap() + + newWidth := window.metrics.width + newHeight := window.metrics.height + larger := newWidth > previousWidth || newHeight > previousHeight + smaller := newWidth < previousWidth / 2 || newHeight < previousHeight / 2 + if larger || smaller { + if window.xCanvas != nil { + window.xCanvas.Destroy() + } + window.xCanvas = xgraphics.New ( + window.backend.connection, + image.Rect ( + 0, 0, + (newWidth / 64) * 64 + 64, + (newHeight / 64) * 64 + 64)) + window.xCanvas.CreatePixmap() + } + } func (window *Window) redrawChildEntirely () { diff --git a/canvas.go b/canvas.go index bdfc244..c1153d0 100644 --- a/canvas.go +++ b/canvas.go @@ -61,6 +61,22 @@ func (canvas BasicCanvas) Buffer () (data []color.RGBA, stride int) { return canvas.pix, canvas.stride } +// Reallocate efficiently reallocates the canvas. The data within will be +// garbage. This method will do nothing if this is a cut image. +func (canvas *BasicCanvas) Reallocate (width, height int) { + previousLen := len(canvas.pix) + newLen := width * height + bigger := newLen > previousLen + smaller := newLen < previousLen / 2 + if bigger || smaller { + canvas.pix = make ( + []color.RGBA, + ((height * width) / 4096) * 4096 + 4096) + } + canvas.stride = width + canvas.rect = image.Rect(0, 0, width, height) +} + // Cut returns a sub-canvas of a given canvas. func Cut (canvas Canvas, bounds image.Rectangle) (reduced BasicCanvas) { // println(canvas.Bounds().String(), bounds.String())