From a33378a4ab859901b525fecd9297921ed7696d4f Mon Sep 17 00:00:00 2001 From: lrh3321 Date: Wed, 17 Apr 2024 21:31:29 +0800 Subject: [PATCH] fix: manually load font file or fonts dirs when use resvg-go --- font.go | 3 ++- font/font.go | 36 ++++++++++++++++++++++++++++++++++++ main.go | 2 +- png.go | 34 ++++++++++++++++++++++++++-------- 4 files changed, 65 insertions(+), 10 deletions(-) diff --git a/font.go b/font.go index 68725c0..58cb269 100644 --- a/font.go +++ b/font.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/alecthomas/chroma/v2/formatters/svg" "github.com/charmbracelet/freeze/font" @@ -18,7 +19,7 @@ func fontOptions(config *Config) ([]svg.Option, error) { } var format svg.FontFormat - switch ext := filepath.Ext(config.Font.File); ext { + switch ext := filepath.Ext(config.Font.File); strings.ToLower(ext) { case ".ttf": format = svg.TRUETYPE case ".woff2": diff --git a/font/font.go b/font/font.go index aaa4035..871162e 100644 --- a/font/font.go +++ b/font/font.go @@ -97,6 +97,9 @@ package font import ( _ "embed" "encoding/base64" + "os" + "path/filepath" + "runtime" ) //go:embed JetBrainsMono-Regular.ttf @@ -107,3 +110,36 @@ var JetBrainsMonoNLTTF []byte var JetBrainsMono string = base64.StdEncoding.EncodeToString(JetBrainsMonoTTF) var JetBrainsMonoNL string = base64.StdEncoding.EncodeToString(JetBrainsMonoNLTTF) + +var DefaultFontsDirectories []string + +func init() { + switch runtime.GOOS { + case "windows": + DefaultFontsDirectories = []string{filepath.Join(os.Getenv("windir"), "Fonts")} + case "linux": + for _, d := range []string{ + "/usr/share/fonts", + "/usr/local/share/fonts", + } { + entries, err := os.ReadDir(d) + if os.IsNotExist(err) || os.IsPermission(err) { + continue + } + + for _, e := range entries { + if e.IsDir() { + DefaultFontsDirectories = append(DefaultFontsDirectories, filepath.Join(d, e.Name())) + } + } + } + + DefaultFontsDirectories = []string{ + "/usr/share/X11/fonts/Type1", + "/usr/share/X11/fonts/TTF", + filepath.Join(os.Getenv("HOME"), ".fonts"), + } + case "darwin": + DefaultFontsDirectories = []string{"/System/Library/Fonts/", "/Library/Fonts/"} + } +} diff --git a/main.go b/main.go index 3675a47..2c99bd4 100644 --- a/main.go +++ b/main.go @@ -398,7 +398,7 @@ func main() { } // could not convert with libsvg, try resvg - svgConversionErr = resvgConvert(doc, imageWidth, imageHeight, config.Output) + svgConversionErr = resvgConvert(doc, imageWidth, imageHeight, config.Output, config.Font.File) if svgConversionErr != nil { printErrorFatal("Unable to convert SVG to PNG", svgConversionErr) } diff --git a/png.go b/png.go index af0348f..5c0793e 100644 --- a/png.go +++ b/png.go @@ -30,7 +30,7 @@ func libsvgConvert(doc *etree.Document, w, h float64, output string) error { return err } -func resvgConvert(doc *etree.Document, w, h float64, output string) error { +func resvgConvert(doc *etree.Document, w, h float64, output, fontFile string) error { svg, err := doc.WriteToBytes() if err != nil { return err @@ -47,13 +47,31 @@ func resvgConvert(doc *etree.Document, w, h float64, output string) error { printErrorFatal("Unable to write output", err) } defer fontdb.Close() - err = fontdb.LoadFontData(font.JetBrainsMonoTTF) - if err != nil { - printErrorFatal("Unable to load font", err) - } - err = fontdb.LoadFontData(font.JetBrainsMonoNLTTF) - if err != nil { - printErrorFatal("Unable to load font", err) + + if fontFile == "" { + err = fontdb.LoadFontData(font.JetBrainsMonoTTF) + if err != nil { + printErrorFatal("Unable to load font", err) + } + err = fontdb.LoadFontData(font.JetBrainsMonoNLTTF) + if err != nil { + printErrorFatal("Unable to load font", err) + } + + for _, d := range font.DefaultFontsDirectories { + err = fontdb.LoadFontsDir(d) + if err != nil { + if os.IsNotExist(err) || os.IsPermission(err) { + continue + } + printErrorFatal("Unable to load font dir", err) + } + } + } else { + err = fontdb.LoadFontFile(fontFile) + if err != nil { + printErrorFatal("Unable to load font", err) + } } pixmap, err := worker.NewPixmap(uint32(w), uint32(h))