summaryrefslogtreecommitdiff
path: root/cmd/orca/display.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/orca/display.go')
-rw-r--r--cmd/orca/display.go108
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)
+ }
+}