178 lines
5.2 KiB
Python
178 lines
5.2 KiB
Python
# this should contain classes for how different object can be rendered, e.g. bold, italic, regular
|
|
from PIL import ImageFont
|
|
from enum import Enum
|
|
from typing import Tuple, Union, Optional
|
|
|
|
|
|
class FontWeight(Enum):
|
|
NORMAL = "normal"
|
|
BOLD = "bold"
|
|
|
|
|
|
class FontStyle(Enum):
|
|
NORMAL = "normal"
|
|
ITALIC = "italic"
|
|
|
|
|
|
class TextDecoration(Enum):
|
|
NONE = "none"
|
|
UNDERLINE = "underline"
|
|
STRIKETHROUGH = "strikethrough"
|
|
|
|
|
|
class Font:
|
|
"""
|
|
Font class to manage text rendering properties including font face, size, color, and styling.
|
|
This class is used by the text renderer to determine how to render text.
|
|
"""
|
|
|
|
def __init__(self,
|
|
font_path: Optional[str] = None,
|
|
font_size: int = 12,
|
|
colour: Tuple[int, int, int] = (0, 0, 0),
|
|
weight: FontWeight = FontWeight.NORMAL,
|
|
style: FontStyle = FontStyle.NORMAL,
|
|
decoration: TextDecoration = TextDecoration.NONE,
|
|
background: Optional[Tuple[int, int, int, int]] = None,
|
|
language = "en_EN"):
|
|
"""
|
|
Initialize a Font object with the specified properties.
|
|
|
|
Args:
|
|
font_path: Path to the font file (.ttf, .otf). If None, uses default font.
|
|
font_size: Size of the font in points.
|
|
colour: RGB color tuple for the text.
|
|
weight: Font weight (normal or bold).
|
|
style: Font style (normal or italic).
|
|
decoration: Text decoration (none, underline, or strikethrough).
|
|
background: RGBA background color for the text. If None, transparent background.
|
|
language: Language code for hyphenation and text processing.
|
|
"""
|
|
self._font_path = font_path
|
|
self._font_size = font_size
|
|
self._colour = colour
|
|
self._weight = weight
|
|
self._style = style
|
|
self._decoration = decoration
|
|
self._background = background if background else (255, 255, 255, 0)
|
|
self.language = language
|
|
# Load the font file or use default
|
|
self._load_font()
|
|
|
|
def _load_font(self):
|
|
"""Load the font using PIL's ImageFont"""
|
|
try:
|
|
if self._font_path:
|
|
self._font = ImageFont.truetype(
|
|
self._font_path,
|
|
self._font_size
|
|
)
|
|
else:
|
|
# Use default font
|
|
self._font = ImageFont.load_default()
|
|
if self._font_size != 12: # Default size might not be 12
|
|
self._font = ImageFont.truetype(self._font.path, self._font_size)
|
|
except Exception as e:
|
|
print(f"Error loading font: {e}")
|
|
self._font = ImageFont.load_default()
|
|
|
|
@property
|
|
def font(self):
|
|
"""Get the PIL ImageFont object"""
|
|
return self._font
|
|
|
|
@property
|
|
def font_size(self):
|
|
"""Get the font size"""
|
|
return self._font_size
|
|
|
|
@property
|
|
def colour(self):
|
|
"""Get the text color"""
|
|
return self._colour
|
|
|
|
@property
|
|
def color(self):
|
|
"""Alias for colour (American spelling)"""
|
|
return self._colour
|
|
|
|
@property
|
|
def background(self):
|
|
"""Get the background color"""
|
|
return self._background
|
|
|
|
@property
|
|
def weight(self):
|
|
"""Get the font weight"""
|
|
return self._weight
|
|
|
|
@property
|
|
def style(self):
|
|
"""Get the font style"""
|
|
return self._style
|
|
|
|
@property
|
|
def decoration(self):
|
|
"""Get the text decoration"""
|
|
return self._decoration
|
|
|
|
def with_size(self, size: int):
|
|
"""Create a new Font object with modified size"""
|
|
return Font(
|
|
self._font_path,
|
|
size,
|
|
self._colour,
|
|
self._weight,
|
|
self._style,
|
|
self._decoration,
|
|
self._background
|
|
)
|
|
|
|
def with_colour(self, colour: Tuple[int, int, int]):
|
|
"""Create a new Font object with modified colour"""
|
|
return Font(
|
|
self._font_path,
|
|
self._font_size,
|
|
colour,
|
|
self._weight,
|
|
self._style,
|
|
self._decoration,
|
|
self._background
|
|
)
|
|
|
|
def with_weight(self, weight: FontWeight):
|
|
"""Create a new Font object with modified weight"""
|
|
return Font(
|
|
self._font_path,
|
|
self._font_size,
|
|
self._colour,
|
|
weight,
|
|
self._style,
|
|
self._decoration,
|
|
self._background
|
|
)
|
|
|
|
def with_style(self, style: FontStyle):
|
|
"""Create a new Font object with modified style"""
|
|
return Font(
|
|
self._font_path,
|
|
self._font_size,
|
|
self._colour,
|
|
self._weight,
|
|
style,
|
|
self._decoration,
|
|
self._background
|
|
)
|
|
|
|
def with_decoration(self, decoration: TextDecoration):
|
|
"""Create a new Font object with modified decoration"""
|
|
return Font(
|
|
self._font_path,
|
|
self._font_size,
|
|
self._colour,
|
|
self._weight,
|
|
self._style,
|
|
decoration,
|
|
self._background
|
|
)
|