Skip to content

Commit

Permalink
fix(font): only notify on font change when necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
JanDeDobbeleer committed Dec 16, 2024
1 parent 8a2db6e commit a2c1c0f
Showing 1 changed file with 38 additions and 16 deletions.
54 changes: 38 additions & 16 deletions src/font/install_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ func install(font *Font, admin bool) error {
// - Copy the file to the fonts directory
// - Add registry entry
// - Call AddFontResourceW to set the font
// - Notify other applications that the fonts have changed
fontsDir := filepath.Join(os.Getenv("WINDIR"), "Fonts")
if !admin {
fontsDir = filepath.Join(os.Getenv("USERPROFILE"), "AppData", "Local", "Microsoft", "Windows", "Fonts")
Expand All @@ -32,21 +31,21 @@ func install(font *Font, admin bool) error {
// check if the Fonts folder exists, if not, create it
if _, err := os.Stat(fontsDir); os.IsNotExist(err) {
if err = os.MkdirAll(fontsDir, 0755); err != nil {
return fmt.Errorf("Unable to create fonts directory: %s", err.Error())
return fmt.Errorf("unable to create fonts directory: %s", err.Error())
}
}

fullPath := filepath.Join(fontsDir, font.FileName)
// validate if font is already installed, remove it in case it is
// validate if the font is already installed, remove it in case it is
if _, err := os.Stat(fullPath); err == nil {
if err = os.Remove(fullPath); err != nil {
return fmt.Errorf("Unable to remove existing font file: %s", err.Error())
return fmt.Errorf("unable to remove existing font file: %s", err.Error())
}
}

err := os.WriteFile(fullPath, font.Data, 0644)
if err != nil {
return fmt.Errorf("Unable to write font file: %s", err.Error())
return fmt.Errorf("unable to write font file: %s", err.Error())
}

// Add registry entry
Expand All @@ -61,34 +60,57 @@ func install(font *Font, admin bool) error {
if err != nil {
// If this fails, remove the font file as well.
if nexterr := os.Remove(fullPath); nexterr != nil {
return errors.New("Unable to delete font file after registry key open error")
return errors.New("unable to delete font file after registry key open error")
}

return fmt.Errorf("Unable to open registry key: %s", err.Error())
return fmt.Errorf("unable to open registry key: %s", err.Error())
}

defer k.Close()

name := fmt.Sprintf("%v (TrueType)", font.Name)
if err = k.SetStringValue(name, regValue); err != nil {
var alreadyInstalled, newFontType bool

// check if we already had this key set
fontPath, _, err := k.GetStringValue(font.Name)
if err == nil {
alreadyInstalled = fontPath == fullPath
newFontType = fontPath != fullPath
}

// do not call AddFontResourceW if the font was already installed
if alreadyInstalled && !newFontType {
return nil
}

gdi32 := syscall.NewLazyDLL("gdi32.dll")
addFontResourceW := gdi32.NewProc("AddFontResourceW")

// remove the old font resource in case we have a new font type with the same name
if newFontType {
fontPtr, err := syscall.UTF16PtrFromString(fullPath)
if err == nil {
removeFontResourceW := gdi32.NewProc("RemoveFontResourceW")
_, _, _ = removeFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))
}
}

if err = k.SetStringValue(font.Name, regValue); err != nil {
// If this fails, remove the font file as well.
if nexterr := os.Remove(fullPath); nexterr != nil {
return errors.New("Unable to delete font file after registry key set error")
return errors.New("unable to delete font file after registry key set error")
}

return fmt.Errorf("Unable to set registry value: %s", err.Error())
return fmt.Errorf("unable to set registry value: %s", err.Error())
}

gdi32 := syscall.NewLazyDLL("gdi32.dll")
proc := gdi32.NewProc("AddFontResourceW")

fontPtr, err := syscall.UTF16PtrFromString(fullPath)
if err != nil {
return err
}

ret, _, _ := proc.Call(uintptr(unsafe.Pointer(fontPtr)))
ret, _, _ := addFontResourceW.Call(uintptr(unsafe.Pointer(fontPtr)))
if ret == 0 {
return errors.New("Unable to add font resource using AddFontResourceW")
return errors.New("unable to add font resource using AddFontResourceW")
}

return nil
Expand Down

0 comments on commit a2c1c0f

Please sign in to comment.