diff options
Diffstat (limited to 'cmd/orca/display.go')
| -rw-r--r-- | cmd/orca/display.go | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/cmd/orca/display.go b/cmd/orca/display.go new file mode 100644 index 0000000..5bd4f87 --- /dev/null +++ b/cmd/orca/display.go @@ -0,0 +1,108 @@ +package main + +import ( + "embed" + "image" + "image/color" + "image/draw" + _ "image/png" + "io" + "io/fs" + "os" + + "golang.org/x/image/font" + "golang.org/x/image/font/opentype" + "golang.org/x/image/font/sfnt" + "golang.org/x/image/math/fixed" +) + +// openSFNT opens the specified font file +// It keeps the file open indefinitely for lazy loading when the font is used. +// It never attempts to close the file and is meant only for loading fonts permanently at init time. +func openSFNT(fs fs.FS, path string) *sfnt.Font { + f, err := fs.Open(path) + if err != nil { + panic(err) + } + font, err := sfnt.ParseReaderAt(f.(io.ReaderAt)) + if err != nil { + panic(err) + } + return font +} + +func openImage(fs fs.FS, path string) image.Image { + f, err := fs.Open(path) + if err != nil { + panic(err) + } + img, _, err := image.Decode(f) + if err != nil { + panic(err) + } + return img +} + +//go:embed *.ttf *.png +var embedFS embed.FS +var qtFonts = os.DirFS("/usr/lib/fonts") + +var ( + dejaVuSans = openSFNT(qtFonts, "DejaVuSans.ttf") + notoSans_Regular = openSFNT(embedFS, "NotoSans-Regular.ttf") + notoSans_Bold = openSFNT(embedFS, "NotoSans-Bold.ttf") +) + +var ( + orcaImg = openImage(embedFS, "orca.png") + belowImg = openImage(embedFS, "below.png") +) + +type justify int + +const ( + _ justify = iota + justifyLeft + justifyCenter + justifyRight +) + +func drawText(img draw.Image, sfnt *sfnt.Font, size float64, just justify, c color.Color, dot fixed.Point26_6, text string) { + face, err := opentype.NewFace(sfnt, &opentype.FaceOptions{ + Size: size, + DPI: 72, + Hinting: font.HintingNone, + }) + if err != nil { + panic(err) + } + defer face.Close() + drawer := font.Drawer{ + Dst: img, + Src: &image.Uniform{c}, + Face: face, + Dot: dot, + } + _, adv := drawer.BoundString(text) + var offset fixed.Int26_6 + switch just { + case justifyCenter: + offset = adv / 2 + case justifyRight: + offset = adv + } + drawer.Dot.X -= offset + drawer.DrawString(text) +} + +func drawDisplay(img draw.Image, s displayState) { + draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{34, 31, 32, 255}}, image.Point{}, draw.Src) + drawText(img, dejaVuSans, 20, justifyLeft, color.White, fixed.P(50, 25), s.now.Format("Jan 02, 2006")) + drawText(img, dejaVuSans, 20, justifyRight, color.White, fixed.P(750, 25), s.now.Format("3:04 pm")) + drawText(img, notoSans_Regular, 16, justifyCenter, color.White, fixed.P(400, 25), "V1234567-D98765") + draw.Draw(img, orcaImg.Bounds().Add(image.Point{400 - orcaImg.Bounds().Dx()/2, 75}), orcaImg, image.Point{}, draw.Over) + if s.cvend.ready { + drawText(img, notoSans_Bold, 48, justifyCenter, color.White, fixed.P(400, 330), "Tap below") + draw.Draw(img, belowImg.Bounds().Add(image.Point{400 - belowImg.Bounds().Dx()/2, 380}), belowImg, image.Point{}, draw.Over) + } +} |