diff --git a/library/display.py b/library/display.py index a3d60429..809136e5 100644 --- a/library/display.py +++ b/library/display.py @@ -136,7 +136,8 @@ def display_static_text(self): background_color=config.THEME_DATA['static_text'][text].get("BACKGROUND_COLOR", (255, 255, 255)), background_image=_get_full_path(config.THEME_DATA['PATH'], config.THEME_DATA['static_text'][text].get("BACKGROUND_IMAGE", - None)) + None)), + anchor="lt" ) diff --git a/library/lcd/lcd_comm.py b/library/lcd/lcd_comm.py index 7336b46f..64208bf1 100644 --- a/library/lcd/lcd_comm.py +++ b/library/lcd/lcd_comm.py @@ -21,6 +21,7 @@ import sys import threading import time +import math from abc import ABC, abstractmethod from enum import IntEnum from typing import Tuple @@ -206,7 +207,8 @@ def DisplayText( font_color: Tuple[int, int, int] = (0, 0, 0), background_color: Tuple[int, int, int] = (255, 255, 255), background_image: str = None, - align: str = 'left' + align: str = 'left', + anchor: str = None, ): # Convert text to bitmap using PIL and display it # Provide the background image path to display text with transparent background @@ -238,19 +240,26 @@ def DisplayText( # Get text bounding box font = ImageFont.truetype("./res/fonts/" + font, font_size) d = ImageDraw.Draw(text_image) - left, top, text_width, text_height = d.textbbox((0, 0), text, font=font) + left, top, right, bottom = d.textbbox((x, y), text, font=font, align=align, anchor=anchor) - # Draw text with specified color & font, remove left/top margins - d.text((x - left, y - top), text, font=font, fill=font_color, align=align) + # textbbox may return float values, which is not good for the bitmap operations below. + # Let's extend the bounding box to the next whole pixel in all directions + left, top = math.floor(left), math.floor(top) + right, bottom = math.ceil(right), math.ceil(bottom) - # Crop text bitmap to keep only the text (also crop if text overflows display) - text_image = text_image.crop(box=( - x, y, - min(x + text_width - left, self.get_width()), - min(y + text_height - top, self.get_height()) - )) + # Draw text onto the background image with specified color & font + d.text((x, y), text, font=font, fill=font_color, align=align, anchor=anchor) - self.DisplayPILImage(text_image, x, y) + # Restrict the dimensions if they overflow the display size + left = max(left, 0) + top = max(top, 0) + right = min(right, self.get_width()) + bottom = min(bottom, self.get_height()) + + # Crop text bitmap to keep only the text + text_image = text_image.crop(box=(left, top, right, bottom)) + + self.DisplayPILImage(text_image, left, top) def DisplayProgressBar(self, x: int, y: int, width: int, height: int, min_value: int = 0, max_value: int = 100, value: int = 50, diff --git a/library/stats.py b/library/stats.py index a5086877..5e417d40 100644 --- a/library/stats.py +++ b/library/stats.py @@ -94,7 +94,8 @@ def display_themed_value(theme_data, value, min_size=0, unit=''): font_size=theme_data.get("FONT_SIZE", 10), font_color=theme_data.get("FONT_COLOR", (0, 0, 0)), background_color=theme_data.get("BACKGROUND_COLOR", (255, 255, 255)), - background_image=get_theme_file_path(theme_data.get("BACKGROUND_IMAGE", None)) + background_image=get_theme_file_path(theme_data.get("BACKGROUND_IMAGE", None)), + anchor="lt" )