diff --git a/devices/apa102/apa102.go b/devices/apa102/apa102.go index bd2e714..b4cf38a 100644 --- a/devices/apa102/apa102.go +++ b/devices/apa102/apa102.go @@ -78,6 +78,7 @@ func New(p spi.Port, o *Opts) (*Dev, error) { numPixels: o.NumPixels, rawBuf: buf, pixels: buf[4 : 4+4*o.NumPixels], + rect: image.Rect(0, 0, o.NumPixels, 1), }, nil } @@ -96,11 +97,12 @@ type Dev struct { // It can be changed, it will take effect on the next Draw() or Write() call. Temperature uint16 - s spi.Conn // - l lut // Updated at each .Write() call. - numPixels int // - rawBuf []byte // Raw buffer sent over SPI. Cached to reduce heap fragmentation. - pixels []byte // Double buffer of pixels, to enable partial painting via Draw(). Effectively points inside rawBuf. + s spi.Conn // + l lut // Updated at each .Write() call. + numPixels int // + rawBuf []byte // Raw buffer sent over SPI. Cached to reduce heap fragmentation. + pixels []byte // Double buffer of pixels, to enable partial painting via Draw(). Effectively points inside rawBuf. + rect image.Rectangle // Device bounds } func (d *Dev) String() string { @@ -115,7 +117,7 @@ func (d *Dev) ColorModel() color.Model { // Bounds implements devices.Display. Min is guaranteed to be {0, 0}. func (d *Dev) Bounds() image.Rectangle { - return image.Rectangle{Max: image.Point{X: d.numPixels, Y: 1}} + return d.rect } // Draw implements devices.Display. @@ -123,7 +125,7 @@ func (d *Dev) Bounds() image.Rectangle { // Using something else than image.NRGBA is 10x slower. When using image.NRGBA, // the alpha channel is ignored. func (d *Dev) Draw(r image.Rectangle, src image.Image, sp image.Point) { - r = r.Intersect(d.Bounds()) + r = r.Intersect(d.rect) srcR := src.Bounds() srcR.Min = srcR.Min.Add(sp) if dX := r.Dx(); dX < srcR.Dx() { diff --git a/devices/ssd1306/ssd1306.go b/devices/ssd1306/ssd1306.go index d7ba8da..5787e72 100644 --- a/devices/ssd1306/ssd1306.go +++ b/devices/ssd1306/ssd1306.go @@ -189,7 +189,7 @@ func (d *Dev) Bounds() image.Rectangle { // It discards any failure. func (d *Dev) Draw(r image.Rectangle, src image.Image, sp image.Point) { var next []byte - if img, ok := src.(*image1bit.VerticalLSB); ok && r == d.Bounds() && src.Bounds() == d.rect && sp.X == 0 && sp.Y == 0 { + if img, ok := src.(*image1bit.VerticalLSB); ok && r == d.rect && src.Bounds() == d.rect && sp.X == 0 && sp.Y == 0 { // Exact size, full frame, image1bit encoding: fast path! next = img.Pix } else { diff --git a/experimental/devices/nrzled/nrzled.go b/experimental/devices/nrzled/nrzled.go index b94638c..2b8029a 100644 --- a/experimental/devices/nrzled/nrzled.go +++ b/experimental/devices/nrzled/nrzled.go @@ -82,6 +82,7 @@ func New(p gpiostream.PinOut, opts *Opts) (*Dev, error) { Bits: make([]byte, opts.NumPixels*3*opts.Channels), LSBF: false, }, + rect: image.Rect(0, 0, opts.NumPixels, 1), }, nil } @@ -92,6 +93,7 @@ type Dev struct { channels int // Number of channels per pixel b gpiostream.BitStream // NRZ encoded bits; cached to reduce heap fragmentation buf []byte // Double buffer of RGB/RGBW pixels; enables partial Draw() + rect image.Rectangle // Device bounds } func (d *Dev) String() string { @@ -126,7 +128,7 @@ func (d *Dev) ColorModel() color.Model { // Bounds implements devices.Display. Min is guaranteed to be {0, 0}. func (d *Dev) Bounds() image.Rectangle { - return image.Rectangle{Max: image.Point{X: d.numPixels, Y: 1}} + return d.rect } // Draw implements devices.Display. @@ -138,7 +140,7 @@ func (d *Dev) Bounds() image.Rectangle { // A back buffer is kept so that partial updates are supported, albeit the full // LED strip is updated synchronously. func (d *Dev) Draw(r image.Rectangle, src image.Image, sp image.Point) { - r = r.Intersect(d.Bounds()) + r = r.Intersect(d.rect) srcR := src.Bounds() srcR.Min = srcR.Min.Add(sp) if dX := r.Dx(); dX < srcR.Dx() {