diff --git a/waveshare2in13v2/drawing.go b/waveshare2in13v2/drawing.go index f606a11..05ef1ae 100644 --- a/waveshare2in13v2/drawing.go +++ b/waveshare2in13v2/drawing.go @@ -54,6 +54,7 @@ func setMemoryArea(ctrl controller, area image.Rectangle) { type drawOpts struct { cmd byte devSize image.Point + buffer *image1bit.VerticalLSB dstRect image.Rectangle src image.Image srcPts image.Point @@ -63,15 +64,9 @@ type drawSpec struct { // Destination on display in pixels, normalized to fit into actual size. DstRect image.Rectangle - // Size of memory area to write; horizontally in bytes, vertically in - // pixels. + // Area to send to device; horizontally in bytes (thus aligned to + // 8 pixels), vertically in pixels. MemRect image.Rectangle - - // Size of image buffer, horizontally aligned to multiples of 8 pixels. - BufferSize image.Point - - // Destination rectangle within image buffer. - BufferRect image.Rectangle } func (o *drawOpts) spec() drawSpec { @@ -83,12 +78,6 @@ func (o *drawOpts) spec() drawSpec { s.DstRect.Min.X/8, s.DstRect.Min.Y, (s.DstRect.Max.X+7)/8, s.DstRect.Max.Y, ) - s.BufferSize = image.Pt(s.MemRect.Dx()*8, s.MemRect.Dy()) - s.BufferRect = image.Rectangle{ - Min: image.Point{X: s.DstRect.Min.X - (s.MemRect.Min.X * 8)}, - Max: image.Point{Y: s.DstRect.Dy()}, - } - s.BufferRect.Max.X = s.BufferRect.Min.X + s.DstRect.Dx() return s } @@ -101,8 +90,7 @@ func drawImage(ctrl controller, opts *drawOpts) { return } - img := image1bit.NewVerticalLSB(image.Rectangle{Max: s.BufferSize}) - draw.Src.Draw(img, s.BufferRect, opts.src, opts.srcPts) + draw.Src.Draw(opts.buffer, s.DstRect, opts.src, opts.srcPts) setMemoryArea(ctrl, s.MemRect) @@ -110,12 +98,12 @@ func drawImage(ctrl controller, opts *drawOpts) { rowData := make([]byte, s.MemRect.Dx()) - for y := 0; y < img.Bounds().Dy(); y++ { + for y := s.MemRect.Min.Y; y < s.MemRect.Max.Y; y++ { for x := 0; x < len(rowData); x++ { rowData[x] = 0 for bit := 0; bit < 8; bit++ { - if img.BitAt((x*8)+bit, y) { + if opts.buffer.BitAt(((s.MemRect.Min.X+x)*8)+bit, y) { rowData[x] |= 0x80 >> bit } } diff --git a/waveshare2in13v2/drawing_test.go b/waveshare2in13v2/drawing_test.go index 7ad5476..dc9a384 100644 --- a/waveshare2in13v2/drawing_test.go +++ b/waveshare2in13v2/drawing_test.go @@ -27,26 +27,24 @@ func TestDrawSpec(t *testing.T) { name: "smaller than display", opts: drawOpts{ devSize: image.Pt(100, 200), + buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 120, 210)), dstRect: image.Rect(17, 4, 25, 8), }, want: drawSpec{ - DstRect: image.Rect(17, 4, 25, 8), - MemRect: image.Rect(2, 4, 4, 8), - BufferSize: image.Pt(16, 4), - BufferRect: image.Rect(1, 0, 9, 4), + DstRect: image.Rect(17, 4, 25, 8), + MemRect: image.Rect(2, 4, 4, 8), }, }, { name: "larger than display", opts: drawOpts{ devSize: image.Pt(100, 200), + buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 100, 200)), dstRect: image.Rect(-20, 50, 125, 300), }, want: drawSpec{ - DstRect: image.Rect(0, 50, 100, 200), - MemRect: image.Rect(0, 50, 13, 200), - BufferSize: image.Pt(13*8, 150), - BufferRect: image.Rect(0, 0, 100, 150), + DstRect: image.Rect(0, 50, 100, 200), + MemRect: image.Rect(0, 50, 13, 200), }, }, } { @@ -77,6 +75,7 @@ func TestDrawImage(t *testing.T) { opts: drawOpts{ cmd: writeRAMBW, devSize: image.Pt(64, 64), + buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 64)), dstRect: image.Rect(17, 4, 41, 8), src: &image.Uniform{image1bit.On}, srcPts: image.Pt(0, 0), @@ -98,6 +97,7 @@ func TestDrawImage(t *testing.T) { opts: drawOpts{ cmd: writeRAMBW, devSize: image.Pt(80, 120), + buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 80, 120)), dstRect: image.Rect(0, 0, 80, 120), src: &image.Uniform{image1bit.On}, srcPts: image.Pt(33, 44), diff --git a/waveshare2in13v2/waveshare213v2.go b/waveshare2in13v2/waveshare213v2.go index 11b4deb..1e7454c 100644 --- a/waveshare2in13v2/waveshare213v2.go +++ b/waveshare2in13v2/waveshare213v2.go @@ -8,6 +8,7 @@ import ( "fmt" "image" "image/color" + "image/draw" "time" "periph.io/x/conn/v3" @@ -62,6 +63,8 @@ type Dev struct { rst gpio.PinOut busy gpio.PinIn + buffer *image1bit.VerticalLSB + opts *Opts } @@ -139,9 +142,15 @@ func New(p spi.Port, dc, cs, rst gpio.PinOut, busy gpio.PinIn, opts *Opts) (*Dev cs: cs, rst: rst, busy: busy, + buffer: image1bit.NewVerticalLSB(image.Rectangle{ + Max: image.Pt((opts.Width+7)/8*8, opts.Height), + }), opts: opts, } + // Default color + draw.Src.Draw(d.buffer, d.buffer.Bounds(), &image.Uniform{image1bit.On}, image.Point{}) + return d, nil } @@ -176,8 +185,10 @@ func (d *Dev) Init(partialUpdate PartialUpdate) error { func (d *Dev) Clear(color color.Color) error { eh := errorHandler{d: *d} - clearDisplay(&eh, image.Pt(d.opts.Width, d.opts.Height), - image1bit.BitModel.Convert(color).(image1bit.Bit)) + c := image1bit.BitModel.Convert(color).(image1bit.Bit) + draw.Src.Draw(d.buffer, d.buffer.Bounds(), &image.Uniform{c}, image.Point{}) + + clearDisplay(&eh, image.Pt(d.opts.Width, d.opts.Height), c) if eh.err == nil { eh.err = d.turnOnDisplay() @@ -201,6 +212,7 @@ func (d *Dev) Draw(dstRect image.Rectangle, src image.Image, srcPts image.Point) opts := drawOpts{ cmd: writeRAMBW, devSize: image.Pt(d.opts.Width, d.opts.Height), + buffer: d.buffer, dstRect: dstRect, src: src, srcPts: srcPts, @@ -221,6 +233,7 @@ func (d *Dev) Draw(dstRect image.Rectangle, src image.Image, srcPts image.Point) func (d *Dev) DrawPartial(dstRect image.Rectangle, src image.Image, srcPts image.Point) error { opts := drawOpts{ devSize: image.Pt(d.opts.Width, d.opts.Height), + buffer: d.buffer, dstRect: dstRect, src: src, srcPts: srcPts,