4

I wanted to install .ttf font file on windows 10 with python3 (more precise Python 3.6) code, I googled but the only thing I found was this one Install TTF fonts on windows with python, I tested it but it didn't do anything. Is there a way to install .ttf with python3 code?

Thanks in advance.

Senhor Sardinhas
  • 51
  • 1
  • 1
  • 3

2 Answers2

7

This library seems promising (I haven't tried myself).

Installing

pip install --user fonttools

or

pip3 install --user fonttools

Code

from fontTools.ttLib import TTFont
font = TTFont('/path/to/font.ttf')

Then use font.save method:

Definition: font.save(self, file, reorderTables=True)

Docstring: Save the font to disk. Similarly to the constructor, the 'file' argument can be either a pathname or a writable file object.

Rafael
  • 7,002
  • 5
  • 43
  • 52
  • I'm on windows and it gives me a error when I try to run it on Visual Code: _ImportError: No module named fontTools.ttLib_ – Senhor Sardinhas Jul 04 '18 at 17:59
  • 1
    Have you installed the library in your environment? – Rafael Jul 04 '18 at 20:28
  • Now the part of import and `font = TTFont('/path/to/font.ttf')` are working but now there is a another problem, that is when I try to `font.save` gives me a error _NameError: name 'self' is not defined_ – Senhor Sardinhas Jul 04 '18 at 23:55
  • 1
    `.save` is a method. You need to call it like that: `font.save("path/to/save/")` – Rafael Jul 05 '18 at 06:56
  • 1
    i'm having a hard time reading the docs. any info for an easier alternative? – greendino Oct 14 '20 at 06:24
  • Ha-ha, tried to install font to `Fonts` folder, but, `PermissionError: [Errno 13] Permission denied: 'C:\\Windows\\Fonts'` –  Mar 19 '21 at 22:41
0

This might help you, it tries to install all fonts in a folder but you can modify it to install 1 font only with the install_font function: https://gist.github.com/tushortz/598bf0324e37033ed870c4e46461fb1e

import os
import shutil
import ctypes
from ctypes import wintypes
import sys
import ntpath
try:
    import winreg
except ImportError:
    import _winreg as winreg

user32 = ctypes.WinDLL('user32', use_last_error=True)
gdi32 = ctypes.WinDLL('gdi32', use_last_error=True)

FONTS_REG_PATH = r'Software\Microsoft\Windows NT\CurrentVersion\Fonts'

HWND_BROADCAST = 0xFFFF
SMTO_ABORTIFHUNG = 0x0002
WM_FONTCHANGE = 0x001D
GFRI_DESCRIPTION = 1
GFRI_ISTRUETYPE = 3

def install_font(src_path):
    # copy the font to the Windows Fonts folder
    dst_path = os.path.join(os.environ['SystemRoot'], 'Fonts',
                            os.path.basename(src_path))
    shutil.copy(src_path, dst_path)
    # load the font in the current session
    if not gdi32.AddFontResourceW(dst_path):
        os.remove(dst_path)
        raise WindowsError('AddFontResource failed to load "%s"' % src_path)
    # notify running programs
    user32.SendMessageTimeoutW(HWND_BROADCAST, WM_FONTCHANGE, 0, 0,
                               SMTO_ABORTIFHUNG, 1000, None)
    # store the fontname/filename in the registry
    filename = os.path.basename(dst_path)
    fontname = os.path.splitext(filename)[0]
    # try to get the font's real name
    cb = wintypes.DWORD()
    if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), None,
                                  GFRI_DESCRIPTION):
        buf = (ctypes.c_wchar * cb.value)()
        if gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb), buf,
                                      GFRI_DESCRIPTION):
            fontname = buf.value
    is_truetype = wintypes.BOOL()
    cb.value = ctypes.sizeof(is_truetype)
    gdi32.GetFontResourceInfoW(filename, ctypes.byref(cb),
                               ctypes.byref(is_truetype), GFRI_ISTRUETYPE)
    if is_truetype:
        fontname += ' (TrueType)'
    with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, FONTS_REG_PATH, 0,
                        winreg.KEY_SET_VALUE) as key:
        winreg.SetValueEx(key, fontname, 0, winreg.REG_SZ, filename)

Essentially, use AddFontResourceW from gdi32 API of Windows to load a font and notify running programs by using SendMessage API - this will make the font visible in running programs.

To permanently install the font into Windows, you need to copy the font file into Fonts folder (C:\Windows\Fonts, or %userprofile%\AppData\Local\Microsoft\Windows\Fonts for per-user folder) and then add a key in registry at HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Fonts (or HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts for per-user installation).

NKSL2001
  • 11
  • 5
  • While this may answer the question, [it would be preferable](https://meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Sergey Shubin Aug 10 '21 at 09:14