diff --git a/src/display_manager.py b/src/display_manager.py index 9cc7f622..e578ad7c 100644 --- a/src/display_manager.py +++ b/src/display_manager.py @@ -364,6 +364,7 @@ def _setup_matrix(self): # Create image with the (logical) display dimensions self.image = Image.new('RGB', (self.matrix.width, self.matrix.height)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. logger.info(f"Image canvas created with dimensions: {self.matrix.width}x{self.matrix.height}") # Initialize font with Press Start 2P @@ -403,6 +404,7 @@ def _setup_matrix(self): self.image = Image.new('RGB', (fallback_width, fallback_height)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. # Simple fallback visualization so web UI shows a realistic canvas try: self.draw.rectangle([0, 0, fallback_width - 1, fallback_height - 1], outline=(255, 0, 0)) @@ -705,6 +707,7 @@ def render_size(self, width: int, height: Optional[int] = None): # self.image, so swapping the buffer below is enough on its own. self.image = Image.new('RGB', (target_w, target_h)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. yield finally: self.matrix = real_matrix @@ -814,6 +817,7 @@ def clear(self): self.image = Image.new('RGB', (width, height)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. logger.debug("Cleared display in fallback mode") return @@ -825,6 +829,7 @@ def clear(self): # Create a new black image self.image = Image.new('RGB', (self.matrix.width, self.matrix.height)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. if not self._capture_mode_active: # Clear both canvases and the underlying matrix to ensure no artifacts. @@ -1258,6 +1263,7 @@ def cleanup(self): try: self.image = Image.new('RGB', (self.width, self.height)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # 1-bit text: the panel has no partial brightness, so AA only smears glyphs. except (OSError, RuntimeError, ValueError, MemoryError): logger.debug("Canvas reset during cleanup failed", exc_info=True) # Reset the singleton state when cleaning up diff --git a/src/plugin_system/testing/visual_display_manager.py b/src/plugin_system/testing/visual_display_manager.py index 5211a226..e33d2309 100644 --- a/src/plugin_system/testing/visual_display_manager.py +++ b/src/plugin_system/testing/visual_display_manager.py @@ -70,6 +70,7 @@ def __init__(self, width: int = 128, height: int = 32): # Canvas self.image = Image.new('RGB', (width, height), (0, 0, 0)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # Match production: 1-bit text, so goldens show what the panel shows. # Matrix proxy (plugins access display_manager.matrix.width/height) self.matrix = _MatrixProxy(width, height) @@ -184,6 +185,7 @@ def clear(self): self.clear_called = True self.image = Image.new('RGB', (self._width, self._height), (0, 0, 0)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # Match production: 1-bit text, so goldens show what the panel shows. def update_display(self): """No-op for hardware; marks that display was updated.""" @@ -211,6 +213,7 @@ def render_size(self, width: int, height: Optional[int] = None): self.matrix = _MatrixProxy(target_w, target_h) self.image = Image.new('RGB', (target_w, target_h), (0, 0, 0)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # Match production: 1-bit text, so goldens show what the panel shows. yield finally: self._width, self._height = prev_w, prev_h @@ -569,6 +572,7 @@ def reset(self): self.draw_calls = [] self.image = Image.new('RGB', (self._width, self._height), (0, 0, 0)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # Match production: 1-bit text, so goldens show what the panel shows. self._scrolling_state = { 'is_scrolling': False, 'last_scroll_activity': 0, @@ -582,3 +586,4 @@ def cleanup(self): """Clean up resources.""" self.image = Image.new('RGB', (self._width, self._height), (0, 0, 0)) self.draw = ImageDraw.Draw(self.image) + self.draw.fontmode = "1" # Match production: 1-bit text, so goldens show what the panel shows.