draw2d/font.go

231 lines
5.1 KiB
Go
Raw Normal View History

2011-04-27 08:06:14 +00:00
// Copyright 2010 The draw2d Authors. All rights reserved.
// created: 13/12/2010 by Laurent Le Goff
2012-04-17 09:03:56 +00:00
2011-04-27 08:06:14 +00:00
package draw2d
import (
"io/ioutil"
2012-01-13 09:14:12 +00:00
"log"
2015-07-10 00:06:47 +00:00
"path/filepath"
2015-04-16 09:51:13 +00:00
2017-12-24 11:44:25 +00:00
"sync"
2018-11-16 11:21:14 +00:00
"git.fromouter.space/crunchy-rocks/freetype/truetype"
2011-04-27 08:06:14 +00:00
)
2015-11-05 13:43:36 +00:00
// FontStyle defines bold and italic styles for the font
// It is possible to combine values for mixed styles, eg.
// FontData.Style = FontStyleBold | FontStyleItalic
2011-04-27 08:06:14 +00:00
type FontStyle byte
const (
FontStyleNormal FontStyle = iota
FontStyleBold
FontStyleItalic
)
type FontFamily byte
const (
FontFamilySans FontFamily = iota
FontFamilySerif
FontFamilyMono
)
type FontData struct {
Name string
Family FontFamily
Style FontStyle
}
type FontFileNamer func(fontData FontData) string
2015-06-27 17:41:34 +00:00
func FontFileName(fontData FontData) string {
2011-04-27 08:06:14 +00:00
fontFileName := fontData.Name
switch fontData.Family {
case FontFamilySans:
fontFileName += "s"
case FontFamilySerif:
fontFileName += "r"
case FontFamilyMono:
fontFileName += "m"
}
if fontData.Style&FontStyleBold != 0 {
fontFileName += "b"
} else {
fontFileName += "r"
}
if fontData.Style&FontStyleItalic != 0 {
fontFileName += "i"
}
fontFileName += ".ttf"
2012-04-17 08:18:26 +00:00
return fontFileName
}
func RegisterFont(fontData FontData, font *truetype.Font) {
2015-11-18 22:59:19 +00:00
fontCache.Store(fontData, font)
2012-04-17 08:18:26 +00:00
}
2015-11-18 22:59:19 +00:00
func GetFont(fontData FontData) (font *truetype.Font) {
var err error
if font, err = fontCache.Load(fontData); err != nil {
log.Println(err)
2011-04-27 08:06:14 +00:00
}
2015-11-18 22:59:19 +00:00
return
2011-04-27 08:06:14 +00:00
}
func GetFontFolder() string {
2015-11-18 22:59:19 +00:00
return defaultFonts.folder
2011-04-27 08:06:14 +00:00
}
func SetFontFolder(folder string) {
defaultFonts.setFolder(filepath.Clean(folder))
2017-12-04 15:29:40 +00:00
}
func GetGlobalFontCache() FontCache {
2017-12-11 16:32:57 +00:00
return fontCache
2011-04-27 08:06:14 +00:00
}
func SetFontNamer(fn FontFileNamer) {
defaultFonts.setNamer(fn)
}
2015-11-18 22:59:19 +00:00
// Types implementing this interface can be passed to SetFontCache to change the
// way fonts are being stored and retrieved.
type FontCache interface {
// Loads a truetype font represented by the FontData object passed as
// argument.
// The method returns an error if the font could not be loaded, either
// because it didn't exist or the resource it was loaded from was corrupted.
Load(FontData) (*truetype.Font, error)
// Sets the truetype font that will be returned by Load when given the font
// data passed as first argument.
Store(FontData, *truetype.Font)
}
// Changes the font cache backend used by the package. After calling this
// functionSetFontFolder and SetFontNamer will not affect anymore how fonts are
// loaded.
// To restore the default font cache, call this function passing nil as argument.
func SetFontCache(cache FontCache) {
if cache == nil {
fontCache = defaultFonts
} else {
fontCache = cache
2011-04-27 08:06:14 +00:00
}
2015-11-18 22:59:19 +00:00
}
2017-12-04 15:29:40 +00:00
// FolderFontCache can Load font from folder
type FolderFontCache struct {
2015-11-18 22:59:19 +00:00
fonts map[string]*truetype.Font
folder string
namer FontFileNamer
}
2017-12-24 11:44:25 +00:00
// NewFolderFontCache creates FolderFontCache
2017-12-04 15:29:40 +00:00
func NewFolderFontCache(folder string) *FolderFontCache {
return &FolderFontCache{
fonts: make(map[string]*truetype.Font),
folder: folder,
namer: FontFileName,
}
}
// Load a font from cache if exists otherwise it will load the font from file
func (cache *FolderFontCache) Load(fontData FontData) (font *truetype.Font, err error) {
if font = cache.fonts[cache.namer(fontData)]; font != nil {
return font, nil
}
2015-11-18 22:59:19 +00:00
var data []byte
var file = cache.namer(fontData)
if data, err = ioutil.ReadFile(filepath.Join(cache.folder, file)); err != nil {
return
}
if font, err = truetype.Parse(data); err != nil {
return
2011-04-27 08:06:14 +00:00
}
2015-11-18 22:59:19 +00:00
cache.fonts[file] = font
return
}
2017-12-04 15:29:40 +00:00
// Store a font to this cache
func (cache *FolderFontCache) Store(fontData FontData, font *truetype.Font) {
2015-11-18 22:59:19 +00:00
cache.fonts[cache.namer(fontData)] = font
2011-04-27 08:06:14 +00:00
}
2015-11-18 22:59:19 +00:00
// SyncFolderFontCache can Load font from folder
type SyncFolderFontCache struct {
sync.RWMutex
fonts map[string]*truetype.Font
folder string
namer FontFileNamer
}
2017-12-24 11:44:25 +00:00
// NewSyncFolderFontCache creates SyncFolderFontCache
func NewSyncFolderFontCache(folder string) *SyncFolderFontCache {
return &SyncFolderFontCache{
fonts: make(map[string]*truetype.Font),
folder: folder,
namer: FontFileName,
}
}
func (cache *SyncFolderFontCache) setFolder(folder string) {
cache.Lock()
cache.folder = folder
cache.Unlock()
}
func (cache *SyncFolderFontCache) setNamer(namer FontFileNamer) {
cache.Lock()
cache.namer = namer
cache.Unlock()
}
// Load a font from cache if exists otherwise it will load the font from file
func (cache *SyncFolderFontCache) Load(fontData FontData) (font *truetype.Font, err error) {
cache.RLock()
font = cache.fonts[cache.namer(fontData)]
cache.RUnlock()
if font != nil {
return font, nil
}
var data []byte
var file = cache.namer(fontData)
if data, err = ioutil.ReadFile(filepath.Join(cache.folder, file)); err != nil {
return
}
if font, err = truetype.Parse(data); err != nil {
return
}
cache.Lock()
cache.fonts[file] = font
cache.Unlock()
return
}
// Store a font to this cache
func (cache *SyncFolderFontCache) Store(fontData FontData, font *truetype.Font) {
cache.Lock()
cache.fonts[cache.namer(fontData)] = font
cache.Unlock()
}
2015-11-18 22:59:19 +00:00
var (
defaultFonts = NewSyncFolderFontCache("../resource/font")
2015-11-18 22:59:19 +00:00
fontCache FontCache = defaultFonts
)