mirror of
https://github.com/KevinMidboe/motdGO.git
synced 2025-10-29 01:30:25 +00:00
177 lines
3.9 KiB
Go
177 lines
3.9 KiB
Go
package motdGO
|
|
|
|
import (
|
|
"errors"
|
|
"io/ioutil"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// Default font if no other valid given
|
|
const defaultFont string = "standard"
|
|
|
|
// Extension of a font file
|
|
const extension string = "flf"
|
|
|
|
// Builtin fonts to load
|
|
var defaultFonts []string = []string{
|
|
"standard",
|
|
"larry3d",
|
|
}
|
|
|
|
// Holds the available fonts
|
|
type fontManager struct {
|
|
// The already read fonts
|
|
fontLib map[string]*font
|
|
// The in given pathes found fonts
|
|
fontList map[string]string
|
|
}
|
|
|
|
// Create a new fontmanager
|
|
// Initializes the fontManager,
|
|
// loads the builtin fonts and returns it
|
|
func newFontManager() *fontManager {
|
|
fm := &fontManager{
|
|
fontLib: make(map[string]*font),
|
|
fontList: make(map[string]string),
|
|
}
|
|
fm.loadBuildInFont()
|
|
return fm
|
|
}
|
|
|
|
// Get a font by name
|
|
// Default font if no other font could be loaded
|
|
func (fm *fontManager) getFont(fontName string) *font {
|
|
// Get the font from the fontLib
|
|
_, ok := fm.fontLib[fontName]
|
|
// Font not found
|
|
if !ok {
|
|
// Try to load it from loaded fontList
|
|
err := fm.loadDiskFont(fontName)
|
|
// Font also not found here, use the default font
|
|
if err != nil {
|
|
fontName = defaultFont
|
|
}
|
|
}
|
|
|
|
return fm.fontLib[fontName]
|
|
}
|
|
|
|
// Loads all .flf files recursively in the fontPath path
|
|
// Saves the found font files in a map with the name as the key
|
|
// and the path as the value. Doesn't load them at this point
|
|
// for performance. Called in the AsciiRenderer
|
|
func (fm *fontManager) loadFontList(fontPath string) error {
|
|
// Walk through the path
|
|
return filepath.Walk(fontPath, func(path string, info os.FileInfo, err error) error {
|
|
// Return an error if occurred
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// If the current item is a directory or has not the correct suffix
|
|
if info.IsDir() || !strings.HasSuffix(info.Name(), "."+extension) {
|
|
return nil
|
|
}
|
|
// Extract the font name
|
|
fontName := strings.TrimSuffix(info.Name(), "."+extension)
|
|
// Save the font to the list
|
|
fm.fontList[fontName] = path
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
// Load a font from disk
|
|
// The font must be registered in the fontList
|
|
func (fm *fontManager) loadDiskFont(fontName string) error {
|
|
// Get the fontpath
|
|
path, ok := fm.fontList[fontName]
|
|
// Font is not registered
|
|
if !ok {
|
|
return errors.New("Font Not Found: " + fontName)
|
|
}
|
|
|
|
// Read file contents
|
|
fontStr, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Parse the file contents
|
|
font, err := parseFontContent(string(fontStr))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Register the font object in the fontLib
|
|
fm.fontLib[fontName] = font
|
|
|
|
return nil
|
|
}
|
|
|
|
// Load the builtin fonts from the bindata.go file
|
|
// Load all fonts specified on top (defaultFonts)
|
|
func (fm *fontManager) loadBuildInFont() error {
|
|
|
|
// Load each default font
|
|
for _, name := range defaultFonts {
|
|
// Get Contents
|
|
fontStr, err := Asset(name + "." + extension)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Load the font
|
|
err = fm.loadBindataFont(fontStr, name)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Load a bindata font
|
|
func (fm *fontManager) loadBindataFont(fontBinary []byte, fontName string) error {
|
|
|
|
// Get the font
|
|
font, err := parseFontContent(string(fontBinary))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// Register the font object in the fontLib
|
|
fm.fontLib[fontName] = font
|
|
|
|
return nil
|
|
}
|
|
|
|
// Parse a font from a content string
|
|
// Used to load fonts from disk and the builtin fonts
|
|
func parseFontContent(cont string) (*font, error) {
|
|
// Get all lines
|
|
lines := strings.Split(cont, "\n")
|
|
|
|
if len(lines) < 1 {
|
|
return nil, errors.New("Font content error")
|
|
}
|
|
|
|
// Get the header metadata
|
|
header := strings.Split(lines[0], " ")
|
|
|
|
// Line end of the comment
|
|
commentEndLine, _ := strconv.Atoi(header[5])
|
|
|
|
// Char height
|
|
height, _ := strconv.Atoi(header[1])
|
|
|
|
// Initialize the font
|
|
font := &font{
|
|
hardblank: header[0][len(header[0])-1:],
|
|
height: height,
|
|
fontSlice: lines[commentEndLine+1:],
|
|
}
|
|
|
|
return font, nil
|
|
}
|