diff --git a/devices/ssd1306/ssd1306_test.go b/devices/ssd1306/ssd1306_test.go index 7bcad1f..5ff3f82 100644 --- a/devices/ssd1306/ssd1306_test.go +++ b/devices/ssd1306/ssd1306_test.go @@ -11,10 +11,6 @@ import ( "log" "testing" - "golang.org/x/image/font" - "golang.org/x/image/font/basicfont" - "golang.org/x/image/math/fixed" - "periph.io/x/periph/conn/conntest" "periph.io/x/periph/conn/gpio" "periph.io/x/periph/conn/gpio/gpiotest" @@ -37,15 +33,20 @@ func Example() { } // Draw on it. - f := basicfont.Face7x13 img := image1bit.NewVerticalLSB(dev.Bounds()) - drawer := font.Drawer{ - Dst: img, - Src: &image.Uniform{image1bit.On}, - Face: f, - Dot: fixed.P(0, img.Bounds().Dy()-1-f.Descent), - } - drawer.DrawString("Hello from periph!") + // Note: this code is commented out so periph does not depend on: + // "golang.org/x/image/font" + // "golang.org/x/image/font/basicfont" + // "golang.org/x/image/math/fixed" + // + // f := basicfont.Face7x13 + // drawer := font.Drawer{ + // Dst: img, + // Src: &image.Uniform{image1bit.On}, + // Face: f, + // Dot: fixed.P(0, img.Bounds().Dy()-1-f.Descent), + // } + // drawer.DrawString("Hello from periph!") dev.Draw(dev.Bounds(), img, image.Point{}) if err := dev.Err(); err != nil { log.Fatal(err) diff --git a/devices/ssd1306/ssd1306smoketest/ssd1306smoketest.go b/devices/ssd1306/ssd1306smoketest/ssd1306smoketest.go index 28f6840..223e010 100644 --- a/devices/ssd1306/ssd1306smoketest/ssd1306smoketest.go +++ b/devices/ssd1306/ssd1306smoketest/ssd1306smoketest.go @@ -11,14 +11,11 @@ import ( "flag" "fmt" "image" + "image/color" "image/draw" "image/gif" "time" - "golang.org/x/image/font" - "golang.org/x/image/font/basicfont" - "golang.org/x/image/math/fixed" - "periph.io/x/periph/conn/gpio" "periph.io/x/periph/conn/gpio/gpioreg" "periph.io/x/periph/conn/i2c" @@ -398,8 +395,9 @@ func (s *SmokeTest) run(i2cBus i2c.Bus, spiPort spi.PortCloser, dc gpio.PinOut, bmp := image1bit.NewVerticalLSB(i2cDev.Bounds()) copy(bmp.Pix, imgPattern) - drawText(bmp, "periph.io", 1) - drawText(bmp, "is awesome!", 0) + r := bmp.Bounds() + r.Min = r.Max.Sub(periphImg.Rect.Max) + draw.DrawMask(bmp, r, &image.Uniform{C: image1bit.On}, image.Point{}, &periphImg, image.Point{}, draw.Over) for i, d := range s.devices { start := time.Now() d.Draw(d.Bounds(), bmp, image.Point{}) @@ -475,21 +473,58 @@ func round(d time.Duration) string { return fmt.Sprintf("%3d.%03dms", ms, µs) } -// drawText draws text at the bottom right of img. -func drawText(img draw.Image, text string, lastToBottom int) { - f := basicfont.Face7x13 - advance := font.MeasureString(f, text).Ceil() - bounds := img.Bounds() - if advance > bounds.Dx() { - advance = 0 - } else { - advance = bounds.Dx() - advance - } - drawer := font.Drawer{ - Dst: img, - Src: &image.Uniform{image1bit.On}, - Face: f, - Dot: fixed.P(advance, bounds.Dy()-1-f.Descent-lastToBottom*f.Height), +// image1bit.Bit is not transparent, so it cannot be used with draw.DrawMask(). +type bit bool + +func (b bit) RGBA() (uint32, uint32, uint32, uint32) { + if b { + return 65535, 65535, 65535, 65535 } - drawer.DrawString(text) + return 0, 0, 0, 0 +} + +func convertBit(c color.Color) color.Color { + r, g, b, _ := c.RGBA() + return bit((r | g | b) >= 0x8000) +} + +type alpha struct { + image1bit.VerticalLSB +} + +func (a *alpha) ColorModel() color.Model { + return color.ModelFunc(convertBit) +} + +func (a *alpha) At(x, y int) color.Color { + return convertBit(a.VerticalLSB.At(x, y)) +} + +// periphImg is the text "periph.io\nis awesome !" at the bottom right of a +// 80x24 image encoded as .Pix. +// +// It is encoded here to not have to depend on golang.org/x/image/... +var periphImg = alpha{ + image1bit.VerticalLSB{ + Pix: []byte{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xfc, 0x28, 0x44, + 0x44, 0x44, 0x38, 0, 0x78, 0x94, 0x94, 0x94, 0x94, 0x58, 0, 0x4, 0xf8, + 0x4, 0x4, 0x4, 0x8, 0, 0, 0x80, 0x84, 0xfd, 0x80, 0x80, 0, 0xfc, 0x28, + 0x44, 0x44, 0x44, 0x38, 0, 0xff, 0x8, 0x4, 0x4, 0x4, 0xf8, 0, 0, 0, 0x80, + 0xc0, 0x80, 0, 0, 0, 0x80, 0x84, 0xfd, 0x80, 0x80, 0, 0x78, 0x84, 0x84, + 0x84, 0x84, 0x78, 0, 0, 0, 0, 0, 0, 0x80, 0xa0, 0, 0, 0, 0, 0x80, 0x80, + 0x80, 0x80, 0, 0, 0x3, 0, 0, 0, 0, 0, 0, 0, 0x80, 0x80, 0x80, 0x80, 0, 0, + 0, 0x80, 0, 0, 0, 0x80, 0, 0, 0x80, 0x80, 0x80, 0x80, 0, 0, 0x3, 0x80, + 0x80, 0x80, 0x80, 0, 0, 0, 0x80, 0x80, 0x80, 0x80, 0, 0, 0, 0x80, 0x80, + 0x1, 0x80, 0, 0, 0, 0x80, 0x80, 0x80, 0x80, 0, 0, 0, 0, 0, 0xf0, 0, 0, 0, + 0, 0, 0, 0, 0x10, 0x10, 0x1f, 0x10, 0x10, 0, 0x9, 0x12, 0x12, 0x14, 0x14, + 0x9, 0, 0, 0, 0, 0, 0, 0, 0, 0xc, 0x12, 0x12, 0x12, 0xa, 0x1f, 0, 0, 0xf, + 0x10, 0xe, 0x10, 0xf, 0, 0xf, 0x12, 0x12, 0x12, 0x12, 0xb, 0, 0x9, 0x12, + 0x12, 0x14, 0x14, 0x9, 0, 0xf, 0x10, 0x10, 0x10, 0x10, 0xf, 0, 0, 0x1f, + 0, 0xf, 0, 0x1f, 0, 0xf, 0x12, 0x12, 0x12, 0x12, 0xb, 0, 0, 0, 0, 0x17, + 0, 0, 0, + }, + Stride: 80, + Rect: image.Rectangle{Max: image.Point{80, 24}}, + }, }