86 lines
1.6 KiB
Go
86 lines
1.6 KiB
Go
|
package fontinfo
|
||
|
|
||
|
import (
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
// Font represents a font file on disk
|
||
|
type Font struct {
|
||
|
Family string
|
||
|
Style string
|
||
|
Path string
|
||
|
}
|
||
|
|
||
|
var validExtensions = []string{
|
||
|
".ttf",
|
||
|
".otf",
|
||
|
}
|
||
|
|
||
|
var fontDirs = []string{
|
||
|
"~/.fonts",
|
||
|
"~/.local/share/fonts",
|
||
|
"/usr/local/share/fonts",
|
||
|
"/usr/share/fonts",
|
||
|
filepath.Join(os.Getenv("XDG_DATA_HOME"), "fonts"),
|
||
|
filepath.Join(os.Getenv("XDG_DATA_DIRS"), "fonts"),
|
||
|
}
|
||
|
|
||
|
// Match finds all fonts installed on the system which match the provided matchers
|
||
|
func Match(matchers ...matcher) ([]Font, error) {
|
||
|
|
||
|
var fonts []Font
|
||
|
meta := make(map[string]*fontMetadata)
|
||
|
|
||
|
for _, dir := range fontDirs {
|
||
|
|
||
|
if info, err := os.Stat(dir); os.IsNotExist(err) {
|
||
|
continue
|
||
|
} else if !info.IsDir() {
|
||
|
continue
|
||
|
}
|
||
|
|
||
|
if err := filepath.WalkDir(dir, func(path string, info fs.DirEntry, err error) error {
|
||
|
if _, ok := meta[path]; ok {
|
||
|
return nil
|
||
|
}
|
||
|
ext := filepath.Ext(path)
|
||
|
for _, valid := range validExtensions {
|
||
|
if strings.EqualFold(ext, valid) {
|
||
|
f, err := os.Open(path)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
defer f.Close()
|
||
|
metadata, err := readMetadata(f)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for _, match := range matchers {
|
||
|
if !match(metadata) {
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
meta[path] = metadata
|
||
|
return nil
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}); err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for path, metadata := range meta {
|
||
|
fonts = append(fonts, Font{
|
||
|
Family: metadata.FontFamily,
|
||
|
Style: metadata.FontStyle,
|
||
|
Path: path,
|
||
|
})
|
||
|
}
|
||
|
|
||
|
return fonts, nil
|
||
|
}
|