Switch to 72pt Medium Mono Atkinson Hyperlegible font
This commit is contained in:
@@ -1,41 +1,94 @@
|
||||
package streamdeck
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/draw"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/image/font"
|
||||
"golang.org/x/image/font/basicfont"
|
||||
"golang.org/x/image/font/opentype"
|
||||
"golang.org/x/image/math/fixed"
|
||||
)
|
||||
|
||||
func TextImage(bg color.Color, fg color.Color, lines ...string) image.Image {
|
||||
img := image.NewRGBA(image.Rect(0, 0, keySize, keySize))
|
||||
draw.Draw(img, img.Bounds(), &image.Uniform{bg}, image.Point{}, draw.Src)
|
||||
//go:embed fonts/*.ttf
|
||||
var fontFS embed.FS
|
||||
|
||||
face := basicfont.Face7x13
|
||||
var (
|
||||
MonoRegular font.Face
|
||||
MonoMedium font.Face
|
||||
MonoBold font.Face
|
||||
Regular font.Face
|
||||
Bold font.Face
|
||||
)
|
||||
|
||||
func init() {
|
||||
MonoRegular = loadFace("fonts/AtkinsonHyperlegibleMono-Regular.ttf", 72)
|
||||
MonoMedium = loadFace("fonts/AtkinsonHyperlegibleMono-Medium.ttf", 72)
|
||||
MonoBold = loadFace("fonts/AtkinsonHyperlegibleMono-Bold.ttf", 72)
|
||||
Regular = loadFace("fonts/AtkinsonHyperlegible-Regular.ttf", 16)
|
||||
Bold = loadFace("fonts/AtkinsonHyperlegible-Bold.ttf", 16)
|
||||
}
|
||||
|
||||
func loadFace(path string, size float64) font.Face {
|
||||
data, err := fontFS.ReadFile(path)
|
||||
if err != nil {
|
||||
log.Fatalf("streamdeck: read font %s: %v", path, err)
|
||||
}
|
||||
f, err := opentype.Parse(data)
|
||||
if err != nil {
|
||||
log.Fatalf("streamdeck: parse font %s: %v", path, err)
|
||||
}
|
||||
face, err := opentype.NewFace(f, &opentype.FaceOptions{
|
||||
Size: size,
|
||||
DPI: 72,
|
||||
Hinting: font.HintingFull,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("streamdeck: create face %s: %v", path, err)
|
||||
}
|
||||
return face
|
||||
}
|
||||
|
||||
func DrawText(img *image.RGBA, face font.Face, fg color.Color, lines ...string) {
|
||||
metrics := face.Metrics()
|
||||
lineHeight := metrics.Height.Ceil()
|
||||
bounds := img.Bounds()
|
||||
w := bounds.Dx()
|
||||
h := bounds.Dy()
|
||||
|
||||
totalHeight := lineHeight * len(lines)
|
||||
startY := (keySize-totalHeight)/2 + metrics.Ascent.Ceil()
|
||||
startY := (h-totalHeight)/2 + metrics.Ascent.Ceil()
|
||||
|
||||
for i, line := range lines {
|
||||
width := font.MeasureString(face, line).Ceil()
|
||||
x := (keySize - width) / 2
|
||||
x := (w - width) / 2
|
||||
y := startY + i*lineHeight
|
||||
|
||||
d := &font.Drawer{
|
||||
Dst: img,
|
||||
Src: &image.Uniform{fg},
|
||||
Face: face,
|
||||
Dot: fixed.P(x, y),
|
||||
Dot: fixed.P(bounds.Min.X+x, bounds.Min.Y+y),
|
||||
}
|
||||
d.DrawString(line)
|
||||
}
|
||||
}
|
||||
|
||||
func TextImage(bg color.Color, fg color.Color, lines ...string) image.Image {
|
||||
return TextImageWithFace(MonoMedium, bg, fg, lines...)
|
||||
}
|
||||
|
||||
func BoldTextImage(bg color.Color, fg color.Color, lines ...string) image.Image {
|
||||
return TextImageWithFace(MonoBold, bg, fg, lines...)
|
||||
}
|
||||
|
||||
func TextImageWithFace(face font.Face, bg color.Color, fg color.Color, lines ...string) image.Image {
|
||||
img := image.NewRGBA(image.Rect(0, 0, keySize, keySize))
|
||||
draw.Draw(img, img.Bounds(), &image.Uniform{bg}, image.Point{}, draw.Src)
|
||||
DrawText(img, face, fg, lines...)
|
||||
return img
|
||||
}
|
||||
|
||||
@@ -43,3 +96,8 @@ func (d *Device) SetKeyText(key int, bg color.Color, fg color.Color, text string
|
||||
lines := strings.Split(text, "\n")
|
||||
return d.SetKeyImage(key, TextImage(bg, fg, lines...))
|
||||
}
|
||||
|
||||
func (d *Device) SetKeyBoldText(key int, bg color.Color, fg color.Color, text string) error {
|
||||
lines := strings.Split(text, "\n")
|
||||
return d.SetKeyImage(key, BoldTextImage(bg, fg, lines...))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user