mirror of https://github.com/periph/devices
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
641 lines
18 KiB
Go
641 lines
18 KiB
Go
// Copyright 2021 The Periph Authors. All rights reserved.
|
|
// Use of this source code is governed under the Apache License, Version 2.0
|
|
// that can be found in the LICENSE file.
|
|
|
|
package waveshare2in13v3
|
|
|
|
import (
|
|
"bytes"
|
|
"image"
|
|
"image/draw"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/google/go-cmp/cmp/cmpopts"
|
|
"periph.io/x/devices/v3/ssd1306/image1bit"
|
|
)
|
|
|
|
func checkRectCanon(t *testing.T, got image.Rectangle) {
|
|
if diff := cmp.Diff(got, got.Canon()); diff != "" {
|
|
t.Errorf("Rectangle is not canonical (-got +want):\n%s", diff)
|
|
}
|
|
}
|
|
|
|
func TestDrawSpec(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
opts drawOpts
|
|
want drawSpec
|
|
}
|
|
|
|
for _, tc := range []testCase{
|
|
{
|
|
name: "empty",
|
|
opts: drawOpts{
|
|
buffer: image1bit.NewVerticalLSB(image.Rectangle{}),
|
|
},
|
|
},
|
|
{
|
|
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{
|
|
bufferDstRect: image.Rect(17, 4, 25, 8),
|
|
memDstRect: 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{
|
|
bufferDstRect: image.Rect(0, 50, 100, 200),
|
|
memDstRect: image.Rect(0, 50, 100, 200),
|
|
memRect: image.Rect(0, 50, 13, 200),
|
|
},
|
|
},
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin top left full",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(48, 96),
|
|
origin: TopLeft,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 6*8, 12*8)),
|
|
dstRect: image.Rect(0, 0, 48, 96),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memRect.Max = image.Pt(6, 96)
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin top right, empty dest",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(105, 50),
|
|
origin: TopRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 12*8, 8*8)),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstOffset.Y = tc.opts.buffer.Bounds().Dy() - tc.opts.devSize.Y
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin top right",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(100, 50),
|
|
origin: TopRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 12*8, 8*8)),
|
|
dstRect: image.Rect(0, 0, 20, 30),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstOffset.Y = tc.opts.buffer.Bounds().Dy() - tc.opts.devSize.Y
|
|
tc.want.bufferDstRect = image.Rectangle{
|
|
Min: tc.want.bufferDstOffset,
|
|
Max: image.Point{
|
|
X: tc.opts.dstRect.Max.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Max.Y,
|
|
},
|
|
}
|
|
tc.want.memDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.opts.devSize.Y - tc.opts.dstRect.Max.Y,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.opts.devSize.Y,
|
|
Y: tc.opts.dstRect.Max.X,
|
|
},
|
|
}
|
|
tc.want.memRect = image.Rectangle{
|
|
Min: image.Pt(2, tc.want.memDstRect.Min.Y),
|
|
Max: image.Pt(7, tc.want.memDstRect.Max.Y),
|
|
}
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin top right full",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(48, 96),
|
|
origin: TopRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 6*8, 12*8)),
|
|
dstRect: image.Rect(0, 0, 48, 96),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memDstRect.Max = image.Pt(96, 48)
|
|
tc.want.memRect.Max = image.Pt(12, 48)
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin top right with offset",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(101, 83),
|
|
origin: TopRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 14*8, 11*8)),
|
|
dstRect: image.Rect(9, 17, 19, 27),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstOffset.Y = tc.opts.buffer.Bounds().Dy() - tc.opts.devSize.Y
|
|
tc.want.bufferDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.opts.dstRect.Min.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Min.Y,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.opts.dstRect.Max.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Max.Y,
|
|
},
|
|
}
|
|
tc.want.memDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.opts.devSize.Y - tc.opts.dstRect.Max.Y,
|
|
Y: tc.opts.dstRect.Min.X,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.opts.devSize.Y - tc.opts.dstRect.Min.Y,
|
|
Y: tc.opts.dstRect.Max.X,
|
|
},
|
|
}
|
|
tc.want.memRect = image.Rectangle{
|
|
Min: image.Pt(7, tc.want.memDstRect.Min.Y),
|
|
Max: image.Pt(9, tc.want.memDstRect.Max.Y),
|
|
}
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin bottom right full",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(48, 96),
|
|
origin: BottomRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 6*8, 12*8)),
|
|
dstRect: image.Rect(0, 0, 48, 96),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memRect.Max = image.Pt(6, 96)
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin bottom right with offset",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(75, 103),
|
|
origin: BottomRight,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 10*8, 14*8)),
|
|
dstRect: image.Rect(9, 17, 19, 49),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstOffset = image.Point{
|
|
X: tc.opts.buffer.Bounds().Dx() - tc.opts.devSize.X,
|
|
Y: tc.opts.buffer.Bounds().Dy() - tc.opts.devSize.Y,
|
|
}
|
|
tc.want.bufferDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.want.bufferDstOffset.X + tc.opts.dstRect.Min.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Min.Y,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.want.bufferDstOffset.X + tc.opts.dstRect.Max.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Max.Y,
|
|
},
|
|
}
|
|
tc.want.memDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.opts.devSize.X - tc.opts.dstRect.Max.X,
|
|
Y: tc.opts.devSize.Y - tc.opts.dstRect.Max.Y,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.opts.devSize.X - tc.opts.dstRect.Min.X,
|
|
Y: tc.opts.devSize.Y - tc.opts.dstRect.Min.Y,
|
|
},
|
|
}
|
|
tc.want.memRect = image.Rectangle{
|
|
Min: image.Pt(7, tc.want.memDstRect.Min.Y),
|
|
Max: image.Pt(9, tc.want.memDstRect.Max.Y),
|
|
}
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin bottom left full",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(48, 96),
|
|
origin: BottomLeft,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 6*8, 12*8)),
|
|
dstRect: image.Rect(0, 0, 48, 96),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstRect.Max = image.Pt(48, 96)
|
|
tc.want.memDstRect.Max = image.Pt(96, 48)
|
|
tc.want.memRect.Max = image.Pt(12, 48)
|
|
|
|
return tc
|
|
}(),
|
|
func() testCase {
|
|
tc := testCase{
|
|
name: "origin bottom left with offset",
|
|
opts: drawOpts{
|
|
devSize: image.Pt(101, 81),
|
|
origin: BottomLeft,
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 15*8, 11*8)),
|
|
dstRect: image.Rect(9, 17, 21, 49),
|
|
},
|
|
}
|
|
|
|
tc.want.bufferDstOffset = image.Point{
|
|
X: tc.opts.buffer.Bounds().Dx() - tc.opts.devSize.X,
|
|
Y: tc.opts.buffer.Bounds().Dy() - tc.opts.devSize.Y,
|
|
}
|
|
tc.want.bufferDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.want.bufferDstOffset.X + tc.opts.dstRect.Min.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Min.Y,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.want.bufferDstOffset.X + tc.opts.dstRect.Max.X,
|
|
Y: tc.want.bufferDstOffset.Y + tc.opts.dstRect.Max.Y,
|
|
},
|
|
}
|
|
tc.want.memDstRect = image.Rectangle{
|
|
Min: image.Point{
|
|
X: tc.opts.dstRect.Min.Y,
|
|
Y: tc.opts.devSize.X - tc.opts.dstRect.Max.X,
|
|
},
|
|
Max: image.Point{
|
|
X: tc.opts.dstRect.Max.Y,
|
|
Y: tc.opts.devSize.X - tc.opts.dstRect.Min.X,
|
|
},
|
|
}
|
|
tc.want.memRect = image.Rectangle{
|
|
Min: image.Pt(2, tc.want.memDstRect.Min.Y),
|
|
Max: image.Pt(7, tc.want.memDstRect.Max.Y),
|
|
}
|
|
|
|
return tc
|
|
}(),
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
checkRectCanon(t, tc.opts.dstRect)
|
|
|
|
got := tc.opts.spec()
|
|
|
|
checkRectCanon(t, got.bufferDstRect)
|
|
checkRectCanon(t, got.memRect)
|
|
|
|
if diff := cmp.Diff(got, tc.want, cmp.AllowUnexported(drawSpec{})); diff != "" {
|
|
t.Errorf("spec() difference (-got +want):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSendImage(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
cmd byte
|
|
opts drawOpts
|
|
want []record
|
|
}{
|
|
{
|
|
name: "empty",
|
|
opts: drawOpts{
|
|
buffer: image1bit.NewVerticalLSB(image.Rectangle{}),
|
|
},
|
|
},
|
|
{
|
|
name: "partial",
|
|
cmd: writeRAMBW,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(64, 64),
|
|
dstRect: image.Rect(16, 20, 32, 40),
|
|
buffer: image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 64)),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{2, 4 - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{20, 0, 40 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{20, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: bytes.Repeat([]byte{0}, 2*(30-10)),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "partial non-aligned",
|
|
cmd: writeRAMRed,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(100, 64),
|
|
dstRect: image.Rect(17, 4, 41, 8),
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 64))
|
|
draw.Src.Draw(img, image.Rect(17, 4, 41, 8), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{2, 6 - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{4, 0, 8 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{4, 0}},
|
|
{
|
|
cmd: writeRAMRed,
|
|
data: bytes.Repeat([]byte{0x7f, 0xff, 0xff, 0x80}, 4),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "full",
|
|
cmd: writeRAMBW,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(80, 120),
|
|
dstRect: image.Rect(0, 0, 80, 120),
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 80, 120))
|
|
draw.Src.Draw(img, image.Rect(0, 0, 80, 120), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{0, 10 - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{0, 0, 120 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{0}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{0, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: bytes.Repeat([]byte{0xff}, 80/8*120),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "top left",
|
|
cmd: writeRAMBW,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(100, 40),
|
|
dstRect: image.Rect(20, 17-5, 44, 29+5),
|
|
origin: TopLeft,
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 100, 40))
|
|
draw.Src.Draw(img, image.Rect(20, 17, 44, 29), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{2, 5}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{17 - 5, 0, 29 + 5 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{12, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: append(
|
|
append(
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00, 0x00}, 5),
|
|
bytes.Repeat([]byte{0x0f, 0xff, 0xff, 0xf0}, 29-17)...),
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00, 0x00}, 5)...,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "top right",
|
|
cmd: writeRAMBW,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(64, 48),
|
|
dstRect: image.Rect(15-5, 16, 30+5, 40),
|
|
origin: TopRight,
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 48))
|
|
draw.Src.Draw(img, image.Rect(15, 20, 30, 36), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{(48 - 40) / 8, ((48 - 16 + 7) / 8) - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{15 - 5, 0, (30 + 5) - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{1}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{10, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: append(
|
|
append(
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5),
|
|
bytes.Repeat([]byte{0x0f, 0xff, 0xf0}, 30-15)...),
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5)...,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "top right uneven size",
|
|
cmd: writeRAMBW,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(61, 53),
|
|
dstRect: image.Rect(15-5, 16, 30+5, 36),
|
|
origin: TopRight,
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 99))
|
|
yoff := img.Bounds().Dy() - 53 + 1
|
|
draw.Src.Draw(img, image.Rect(15, yoff+16, 30, yoff+32), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{(53 - 32) / 8, ((53 - 16 + 7) / 8) - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{15 - 5, 0, (30 + 5) - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{10, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: append(
|
|
append(
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5),
|
|
bytes.Repeat([]byte{0x0f, 0xff, 0xf0}, 30-15)...),
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5)...,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "bottom right",
|
|
cmd: writeRAMRed,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(64, 48),
|
|
dstRect: image.Rect(16, 15-5, 40, 30+5),
|
|
origin: BottomRight,
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 48))
|
|
draw.Src.Draw(img, image.Rect(20, 15, 36, 30), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{(64 - 40) / 8, ((64 - 16 + 7) / 8) - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{48 - (30 + 5), 0, 48 - (15 - 5) - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{3}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{48 - (30 + 5), 0}},
|
|
{
|
|
cmd: writeRAMRed,
|
|
data: append(
|
|
append(
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5),
|
|
bytes.Repeat([]byte{0x0f, 0xff, 0xf0}, 30-15)...),
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5)...,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "bottom left",
|
|
cmd: writeRAMRed,
|
|
opts: drawOpts{
|
|
devSize: image.Pt(64, 48),
|
|
dstRect: image.Rect(15-5, 16, 30+5, 40),
|
|
origin: BottomLeft,
|
|
buffer: func() *image1bit.VerticalLSB {
|
|
img := image1bit.NewVerticalLSB(image.Rect(0, 0, 64, 48))
|
|
draw.Src.Draw(img, image.Rect(15, 20, 30, 36), &image.Uniform{image1bit.On}, image.Point{})
|
|
return img
|
|
}(),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{16 / 8, ((40 + 7) / 8) - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{64 - (30 + 5), 0, 64 - (15 - 5) - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{64 - (30 + 5), 0}},
|
|
{
|
|
cmd: writeRAMRed,
|
|
data: append(
|
|
append(
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5),
|
|
bytes.Repeat([]byte{0x0f, 0xff, 0xf0}, 30-15)...),
|
|
bytes.Repeat([]byte{0x00, 0x00, 0x00}, 5)...,
|
|
),
|
|
},
|
|
},
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
var got fakeController
|
|
|
|
checkRectCanon(t, tc.opts.dstRect)
|
|
|
|
spec := tc.opts.spec()
|
|
|
|
tc.opts.sendImage(&got, tc.cmd, &spec)
|
|
|
|
if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" {
|
|
t.Errorf("sendImage() difference (-got +want):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDrawImage(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
opts drawOpts
|
|
want []record
|
|
}{
|
|
{
|
|
name: "empty",
|
|
opts: drawOpts{
|
|
buffer: image1bit.NewVerticalLSB(image.Rectangle{}),
|
|
},
|
|
},
|
|
{
|
|
name: "partial",
|
|
opts: drawOpts{
|
|
commands: []byte{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),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{2, 6 - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{4, 0, 8 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{2}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{4, 0}},
|
|
{
|
|
cmd: writeRAMBW,
|
|
data: bytes.Repeat([]byte{0x7f, 0xff, 0xff, 0x80}, 4),
|
|
},
|
|
{cmd: displayUpdateControl2, data: []byte{0x0f}},
|
|
{cmd: masterActivation},
|
|
},
|
|
},
|
|
{
|
|
name: "full",
|
|
opts: drawOpts{
|
|
commands: []byte{writeRAMRed},
|
|
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),
|
|
},
|
|
want: []record{
|
|
{cmd: dataEntryModeSetting, data: []byte{0x3}},
|
|
{cmd: setRAMXAddressStartEndPosition, data: []byte{0, 10 - 1}},
|
|
{cmd: setRAMYAddressStartEndPosition, data: []byte{0, 0, 120 - 1, 0}},
|
|
{cmd: setRAMXAddressCounter, data: []byte{0}},
|
|
{cmd: setRAMYAddressCounter, data: []byte{0, 0}},
|
|
{
|
|
cmd: writeRAMRed,
|
|
data: bytes.Repeat([]byte{0xff}, 80/8*120),
|
|
},
|
|
{cmd: displayUpdateControl2, data: []byte{0x0f}},
|
|
{cmd: masterActivation},
|
|
},
|
|
},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
var got fakeController
|
|
|
|
drawImage(&got, &tc.opts, true)
|
|
|
|
if diff := cmp.Diff([]record(got), tc.want, cmpopts.EquateEmpty(), cmp.AllowUnexported(record{})); diff != "" {
|
|
t.Errorf("drawImage() difference (-got +want):\n%s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|