|
21 | 21 | import sys |
22 | 22 | import threading |
23 | 23 | import time |
| 24 | +import math |
24 | 25 | from abc import ABC, abstractmethod |
25 | 26 | from enum import IntEnum |
26 | 27 | from typing import Tuple |
@@ -206,7 +207,8 @@ def DisplayText( |
206 | 207 | font_color: Tuple[int, int, int] = (0, 0, 0), |
207 | 208 | background_color: Tuple[int, int, int] = (255, 255, 255), |
208 | 209 | background_image: str = None, |
209 | | - align: str = 'left' |
| 210 | + align: str = 'left', |
| 211 | + anchor: str = None, |
210 | 212 | ): |
211 | 213 | # Convert text to bitmap using PIL and display it |
212 | 214 | # Provide the background image path to display text with transparent background |
@@ -238,19 +240,26 @@ def DisplayText( |
238 | 240 | # Get text bounding box |
239 | 241 | font = ImageFont.truetype("./res/fonts/" + font, font_size) |
240 | 242 | d = ImageDraw.Draw(text_image) |
241 | | - left, top, text_width, text_height = d.textbbox((0, 0), text, font=font) |
| 243 | + left, top, right, bottom = d.textbbox((x, y), text, font=font, align=align, anchor=anchor) |
242 | 244 |
|
243 | | - # Draw text with specified color & font, remove left/top margins |
244 | | - d.text((x - left, y - top), text, font=font, fill=font_color, align=align) |
| 245 | + # textbbox may return float values, which is not good for the bitmap operations below. |
| 246 | + # Let's extend the bounding box to the next whole pixel in all directions |
| 247 | + left, top = math.floor(left), math.floor(top) |
| 248 | + right, bottom = math.ceil(right), math.ceil(bottom) |
245 | 249 |
|
246 | | - # Crop text bitmap to keep only the text (also crop if text overflows display) |
247 | | - text_image = text_image.crop(box=( |
248 | | - x, y, |
249 | | - min(x + text_width - left, self.get_width()), |
250 | | - min(y + text_height - top, self.get_height()) |
251 | | - )) |
| 250 | + # Draw text onto the background image with specified color & font |
| 251 | + d.text((x, y), text, font=font, fill=font_color, align=align, anchor=anchor) |
252 | 252 |
|
253 | | - self.DisplayPILImage(text_image, x, y) |
| 253 | + # Restrict the dimensions if they overflow the display size |
| 254 | + left = max(left, 0) |
| 255 | + top = max(top, 0) |
| 256 | + right = min(right, self.get_width()) |
| 257 | + bottom = min(bottom, self.get_height()) |
| 258 | + |
| 259 | + # Crop text bitmap to keep only the text |
| 260 | + text_image = text_image.crop(box=(left, top, right, bottom)) |
| 261 | + |
| 262 | + self.DisplayPILImage(text_image, left, top) |
254 | 263 |
|
255 | 264 | def DisplayProgressBar(self, x: int, y: int, width: int, height: int, min_value: int = 0, max_value: int = 100, |
256 | 265 | value: int = 50, |
|
0 commit comments