Skip to content

Commit 716acdb

Browse files
committed
fix(steami_screen): Optimize draw_scaled_text and address review.
Address Copilot review comments on #398: 1. Defer `import framebuf` into draw_scaled_text() so steami_screen remains importable in CPython environments (tests, stubs, IDE). 2. Resolve fill_rect dispatch once at __init__ (self._fill_rect_raw) instead of calling hasattr() on every lit pixel in the inner loop. Also simplifies the public fill_rect() method. 3. Cache the dispatch as a local `blit` variable inside draw_scaled_text to avoid attribute lookups in the hot pixel loop. 4. Fix README note: scaling works for any scale > 1, not just scale=2. Mention the bold offset fallback for backends without draw_scaled_text.
1 parent 93cab98 commit 716acdb

2 files changed

Lines changed: 15 additions & 29 deletions

File tree

lib/steami_screen/README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,7 @@ screen.text("Big", at="CENTER", scale=2)
7474

7575
Cardinal positions: `"N"`, `"NE"`, `"E"`, `"SE"`, `"S"`, `"SW"`, `"W"`, `"NW"`, `"CENTER"`.
7676

77-
Note: `scale=2` produces a true pixel-scale zoom on SSD1327 displays via pixel-by-pixel
78-
framebuf rendering. Other backends can implement `draw_scaled_text()` for native scaling support.
77+
Note: `scale` > 1 produces a true pixel-scale zoom on SSD1327 displays via pixel-by-pixel framebuf rendering. Other backends can implement `draw_scaled_text()` for native scaling support. Backends without it fall back to a bold offset effect.
7978

8079
---
8180

lib/steami_screen/steami_screen/ssd1327.py

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
display = SSD1327Display(raw)
1111
"""
1212

13-
import framebuf
14-
1513
from steami_screen.colors import rgb_to_gray4
1614

1715

@@ -22,6 +20,11 @@ def __init__(self, raw):
2220
self._raw = raw
2321
self.width = getattr(raw, "width", 128)
2422
self.height = getattr(raw, "height", 128)
23+
# Resolve fill_rect dispatch once at init (avoids repeated hasattr)
24+
if hasattr(raw, "fill_rect"):
25+
self._fill_rect_raw = raw.fill_rect
26+
else:
27+
self._fill_rect_raw = raw.framebuf.fill_rect
2528

2629
def fill(self, color):
2730
self._raw.fill(rgb_to_gray4(color))
@@ -36,11 +39,7 @@ def line(self, x1, y1, x2, y2, color):
3639
self._raw.line(x1, y1, x2, y2, rgb_to_gray4(color))
3740

3841
def fill_rect(self, x, y, w, h, color):
39-
gray = rgb_to_gray4(color)
40-
if hasattr(self._raw, "fill_rect"):
41-
self._raw.fill_rect(x, y, w, h, gray)
42-
else:
43-
self._raw.framebuf.fill_rect(x, y, w, h, gray)
42+
self._fill_rect_raw(x, y, w, h, rgb_to_gray4(color))
4443

4544
def rect(self, x, y, w, h, color):
4645
gray = rgb_to_gray4(color)
@@ -53,14 +52,17 @@ def show(self):
5352
self._raw.show()
5453

5554
def draw_scaled_text(self, text, x, y, color, scale):
56-
"""Draw text scaled up using pixel-by-pixel framebuf rendering.
55+
"""Draw text with true pixel-scale zoom.
5756
58-
Renders each character into a temporary 8x8 MONO_HLSB framebuf,
59-
reads each lit pixel, and draws a scale x scale filled rectangle.
60-
This produces a true pixel-scale zoom instead of a bold offset effect.
57+
Each character is rendered into a temporary 8x8 MONO_HLSB framebuf,
58+
then each lit pixel is expanded into a scale x scale filled rectangle
59+
on the display. The framebuf import is deferred to avoid breaking
60+
imports in CPython environments where framebuf is not available.
6161
"""
62+
import framebuf
6263

6364
gray = rgb_to_gray4(color)
65+
blit = self._fill_rect_raw
6466

6567
char_buf = bytearray(8)
6668
fb = framebuf.FrameBuffer(char_buf, 8, 8, framebuf.MONO_HLSB)
@@ -72,20 +74,5 @@ def draw_scaled_text(self, text, x, y, color, scale):
7274
for py in range(8):
7375
for px in range(8):
7476
if fb.pixel(px, py):
75-
if hasattr(self._raw, "fill_rect"):
76-
self._raw.fill_rect(
77-
cx + px * scale,
78-
y + py * scale,
79-
scale,
80-
scale,
81-
gray,
82-
)
83-
else:
84-
self._raw.framebuf.fill_rect(
85-
cx + px * scale,
86-
y + py * scale,
87-
scale,
88-
scale,
89-
gray,
90-
)
77+
blit(cx + px * scale, y + py * scale, scale, scale, gray)
9178
cx += 8 * scale

0 commit comments

Comments
 (0)