fonts.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import pathlib as pl
  2. from matplotlib import font_manager
  3. from view.python_core.get_internal_files import get_internal_fonts_dir
  4. from PIL import ImageFont
  5. def resolve_font_file(mv_fontName):
  6. """
  7. Find a font file on the file system, if not found, use internal default
  8. Hierarchy for file look up: (1) system ttf font with name mv_fontName, (2) system otf font with name mv_fontName,
  9. (3) internal ttf font with name mv_fontName (4) internal otf font with name mv_fontName, fallback internal font
  10. :param str mv_fontName: name of the font, will look for <mv_fontname>.ttf or <mv_fontname>.otf
  11. :rtype: str
  12. :returns: absolute filename of the font file
  13. """
  14. font_file_lookup_hierarchy = [find_font_file_in_OS(font_name=mv_fontName, ext=".ttf"),
  15. find_font_file_in_OS(font_name=mv_fontName, ext=".otf"),
  16. find_font_file_in_dir(font_name=mv_fontName, where=get_internal_fonts_dir(),
  17. ext=".ttf"),
  18. find_font_file_in_dir(font_name=mv_fontName, where=get_internal_fonts_dir(),
  19. ext=".otf"),
  20. find_font_file_in_dir(font_name="PixelOperator8", where=get_internal_fonts_dir(),
  21. ext=".ttf")]
  22. existences = [x is not None for x in font_file_lookup_hierarchy]
  23. font2use = font_file_lookup_hierarchy[existences.index(True)]
  24. return font2use
  25. def get_maximum_font_size_by_width(font_name, text, maximum_width):
  26. font = ImageFont.truetype(font=font_name, size=10)
  27. w, h = font.getsize(text)
  28. return int(10 * maximum_width / w)
  29. def resolve_font_size(suggested_font_size, maximum_width, text, font_name):
  30. max_font_size = get_maximum_font_size_by_width(font_name=font_name, text=text,
  31. maximum_width=maximum_width)
  32. max_font_size_with_margin = int(0.95 * max_font_size)
  33. return max(min(max_font_size_with_margin, suggested_font_size), 8)
  34. def find_font_file_in_dir(font_name, where=None, ext=".ttf"):
  35. font_files = font_manager.findSystemFonts(fontpaths=where)
  36. matches = [pl.Path(f).name.lower() == f"{font_name}{ext}".lower() for f in font_files]
  37. if any(matches):
  38. return font_files[matches.index(True)]
  39. else:
  40. return None
  41. def find_font_file_in_OS(font_name, ext=".ttf"):
  42. return find_font_file_in_dir(font_name, ext=ext)