78 lines
2.5 KiB
Python
78 lines
2.5 KiB
Python
import logging
|
|
from pathlib import Path
|
|
from typing import Tuple
|
|
|
|
from PIL.ImageFont import FreeTypeFont, load_default as load_default_font, truetype as load_truetype
|
|
|
|
from folder_paths import get_folder_paths
|
|
|
|
|
|
default_font_path = Path(get_folder_paths("custom_nodes")[0]) / "comfyui-imagelabel" / "fonts"
|
|
|
|
|
|
class FontCollection(dict):
|
|
"""
|
|
A dictionary that maps font names to PIL font objects.
|
|
"""
|
|
|
|
def __init__(self, directory: Path = default_font_path):
|
|
"""
|
|
Initialize the FontCollection with fonts found in the given directory (including subdirectories).
|
|
|
|
Args:
|
|
directory (Path): The path to the directory containing font files.
|
|
"""
|
|
|
|
paths = [font for font in directory.rglob("*.[tT][tT][fF]") if font.is_file()]
|
|
self.default_font_name, self.default_font = self.load_default_font()
|
|
fonts = {
|
|
self.default_font_name: self.default_font,
|
|
}
|
|
for path in paths:
|
|
font_info = self.load_font(path)
|
|
if font_info:
|
|
if font_info[0] in fonts:
|
|
logging.warning(f"Fonts with duplicate names found: {font_info[0]}")
|
|
fonts[font_info[0]] = font_info[1]
|
|
super().__init__(fonts)
|
|
|
|
@classmethod
|
|
def load_default_font(cls) -> Tuple[str, FreeTypeFont]:
|
|
"""
|
|
Load the default PIL font.
|
|
|
|
Returns:
|
|
tuple[str, FreeTypeFont]: The font's name and the font object.
|
|
"""
|
|
|
|
font = load_default_font()
|
|
family, style = None, None
|
|
if not isinstance(font, FreeTypeFont):
|
|
raise RuntimeError("Could not load default FreeType font.")
|
|
family, style = font.getname()
|
|
family = family or "Unknown"
|
|
style = style or "Regular"
|
|
return " ".join([family, style]), font
|
|
|
|
@classmethod
|
|
def load_font(cls, path: Path) -> Tuple[str, FreeTypeFont]:
|
|
"""
|
|
Load a font and extract its name and style.
|
|
|
|
Args:
|
|
path (Path): The path to the font file.
|
|
|
|
Returns:
|
|
tuple[str, ImageFont.FreeTypeFont]: A tuple containing the font's name and the font object.
|
|
|
|
Raises:
|
|
OSError: If the font file could not be read.
|
|
ValueError: If the font size is not greater than zero.
|
|
"""
|
|
|
|
font = load_truetype(path)
|
|
family, style = font.getname()
|
|
family = family or "Unknown"
|
|
style = style or "Regular"
|
|
return " ".join([family, style]), font
|