mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-10 13:04:04 -08:00
fix(font): install correctly on Windows
This commit is contained in:
parent
c301864021
commit
265790659c
|
@ -1,34 +1,37 @@
|
|||
// Derived from https://github.com/Crosse/font-install
|
||||
// Copyright 2020 Seth Wright <seth@crosse.org>
|
||||
package font
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
// FontsDir denotes the path to the user's fonts directory on Linux.
|
||||
// Windows doesn't have the concept of a permanent, per-user collection
|
||||
// of fonts, meaning that all fonts are stored in the system-level fonts
|
||||
// directory, which is %WINDIR%\Fonts by default.
|
||||
var FontsDir = path.Join(os.Getenv("WINDIR"), "Fonts")
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontresourcea
|
||||
var FontsDir = filepath.Join(os.Getenv("WINDIR"), "Fonts")
|
||||
|
||||
const (
|
||||
WM_FONTCHANGE = 0x001D // nolint:revive
|
||||
HWND_BROADCAST = 0xFFFF // nolint:revive
|
||||
)
|
||||
|
||||
func install(font *Font) (err error) {
|
||||
// To install a font on Windows:
|
||||
// - Copy the file to the fonts directory
|
||||
// - Create a registry entry for the font
|
||||
fullPath := path.Join(FontsDir, font.FileName)
|
||||
|
||||
err = ioutil.WriteFile(fullPath, font.Data, 0644) //nolint:gosec
|
||||
// - Add registry entry
|
||||
// - Call AddFontResourceW to set the font
|
||||
// - Notify other applications that the fonts have changed
|
||||
fullPath := filepath.Join(FontsDir, font.FileName)
|
||||
err = os.WriteFile(fullPath, font.Data, 0644)
|
||||
if err != nil {
|
||||
return err
|
||||
return
|
||||
}
|
||||
|
||||
// Second, write metadata about the font to the registry.
|
||||
// Add registry entry
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts`, registry.WRITE)
|
||||
if err != nil {
|
||||
// If this fails, remove the font file as well.
|
||||
|
@ -40,12 +43,8 @@ func install(font *Font) (err error) {
|
|||
}
|
||||
defer k.Close()
|
||||
|
||||
// Apparently it's "ok" to mark an OpenType font as "TrueType",
|
||||
// and since this tool only supports True- and OpenType fonts,
|
||||
// this should be Okay(tm).
|
||||
// Besides, Windows does it, so why can't I?
|
||||
valueName := fmt.Sprintf("%v (TrueType)", font.FileName)
|
||||
if err = k.SetStringValue(font.Name, valueName); err != nil {
|
||||
name := fmt.Sprintf("%v (TrueType)", font.Name)
|
||||
if err = k.SetStringValue(name, font.FileName); err != nil {
|
||||
// If this fails, remove the font file as well.
|
||||
if nexterr := os.Remove(fullPath); nexterr != nil {
|
||||
return nexterr
|
||||
|
@ -54,5 +53,26 @@ func install(font *Font) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
gdi32 := syscall.NewLazyDLL("gdi32.dll")
|
||||
proc := gdi32.NewProc("AddFontResourceW")
|
||||
|
||||
fontPtr, err := syscall.UTF16PtrFromString(fullPath)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ret, _, _ := proc.Call(uintptr(unsafe.Pointer(fontPtr)))
|
||||
if ret == 0 {
|
||||
return errors.New("unable to add font resource")
|
||||
}
|
||||
|
||||
// Notify other applications that the fonts have changed
|
||||
user32 := syscall.NewLazyDLL("user32.dll")
|
||||
procSendMessageW := user32.NewProc("SendMessageW")
|
||||
_, _, e1 := syscall.SyscallN(procSendMessageW.Addr(), uintptr(HWND_BROADCAST), uintptr(WM_FONTCHANGE), 0, 0)
|
||||
if e1 != 0 {
|
||||
return errors.New("unable to broadcast font change")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue