font_manager.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import sys
  2. import os
  3. import shutil
  4. from typing import Union
  5. class FontManager:
  6. linux_font_path = "~/.fonts/"
  7. @classmethod
  8. def init_font_manager(cls):
  9. # Linux
  10. if sys.platform.startswith("linux"):
  11. try:
  12. if not os.path.isdir(os.path.expanduser(cls.linux_font_path)):
  13. os.mkdir(os.path.expanduser(cls.linux_font_path))
  14. return True
  15. except Exception as err:
  16. sys.stderr.write("FontManager error: " + str(err) + "\n")
  17. return False
  18. # other platforms
  19. else:
  20. return True
  21. @classmethod
  22. def windows_load_font(cls, font_path: Union[str, bytes], private: bool = True, enumerable: bool = False) -> bool:
  23. """ Function taken from: https://stackoverflow.com/questions/11993290/truly-custom-font-in-tkinter/30631309#30631309 """
  24. from ctypes import windll, byref, create_unicode_buffer, create_string_buffer
  25. FR_PRIVATE = 0x10
  26. FR_NOT_ENUM = 0x20
  27. if isinstance(font_path, bytes):
  28. path_buffer = create_string_buffer(font_path)
  29. add_font_resource_ex = windll.gdi32.AddFontResourceExA
  30. elif isinstance(font_path, str):
  31. path_buffer = create_unicode_buffer(font_path)
  32. add_font_resource_ex = windll.gdi32.AddFontResourceExW
  33. else:
  34. raise TypeError('font_path must be of type bytes or str')
  35. flags = (FR_PRIVATE if private else 0) | (FR_NOT_ENUM if not enumerable else 0)
  36. num_fonts_added = add_font_resource_ex(byref(path_buffer), flags, 0)
  37. return bool(min(num_fonts_added, 1))
  38. @classmethod
  39. def load_font(cls, font_path: str) -> bool:
  40. # Windows
  41. if sys.platform.startswith("win"):
  42. return cls.windows_load_font(font_path, private=True, enumerable=False)
  43. # Linux
  44. elif sys.platform.startswith("linux"):
  45. try:
  46. shutil.copy(font_path, os.path.expanduser(cls.linux_font_path))
  47. return True
  48. except Exception as err:
  49. sys.stderr.write("FontManager error: " + str(err) + "\n")
  50. return False
  51. # macOS and others
  52. else:
  53. return False