gui/font.go
2023-01-22 12:38:03 +01:00

76 lines
1.2 KiB
Go

package gui
import (
"bytes"
"io"
"os"
"golang.org/x/image/font"
"golang.org/x/image/font/opentype"
"golang.org/x/image/font/sfnt"
)
type Font struct {
font *sfnt.Font
faces map[int]font.Face
}
func LoadOpenTypeFont(otfFile string) (*Font, error) {
ff, err := os.Open(otfFile)
if err != nil {
return nil, err
}
return LoadFontFromReaderAt(ff)
}
func LoadFontFromBytes(data []byte) (*Font, error) {
return LoadFontFromReaderAt(bytes.NewReader(data))
}
func LoadFontFromReaderAt(r io.ReaderAt) (*Font, error) {
fnt, err := opentype.ParseReaderAt(r)
if err != nil {
return nil, err
}
return &Font{
font: fnt,
faces: map[int]font.Face{},
}, nil
}
func (f *Font) FaceErr(fontSize int) (face font.Face, err error) {
if v, ok := f.faces[fontSize]; ok {
return v, nil
}
face, err = opentype.NewFace(f.font, &opentype.FaceOptions{
Size: float64(fontSize),
DPI: 72,
Hinting: font.HintingFull,
})
if err == nil {
f.faces[fontSize] = face
}
return face, err
}
func (f *Font) Face(fontSize int) font.Face {
face, err := f.FaceErr(fontSize)
if err != nil {
panic(err)
}
return face
}
func (f *Font) Close() error {
for _, face := range f.faces {
if err := face.Close(); err != nil {
return err
}
}
return nil
}