Skip to content

Commit 28c7d80

Browse files
committed
fix(steami_screen): Add true pixel-scale zoom for scaled text.
1 parent 31ca15a commit 28c7d80

2 files changed

Lines changed: 46 additions & 5 deletions

File tree

lib/steami_screen/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ 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 bold effect (text drawn with 1px offset), not a true pixel-scale zoom. Backends can provide `draw_scaled_text()` for true scaling.
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.
7879

7980
---
8081

lib/steami_screen/steami_screen/ssd1327.py

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

13+
import framebuf
14+
1315
from steami_screen.colors import rgb_to_gray4
1416

1517

@@ -18,8 +20,8 @@ class SSD1327Display:
1820

1921
def __init__(self, raw):
2022
self._raw = raw
21-
self.width = getattr(raw, 'width', 128)
22-
self.height = getattr(raw, 'height', 128)
23+
self.width = getattr(raw, "width", 128)
24+
self.height = getattr(raw, "height", 128)
2325

2426
def fill(self, color):
2527
self._raw.fill(rgb_to_gray4(color))
@@ -35,17 +37,55 @@ def line(self, x1, y1, x2, y2, color):
3537

3638
def fill_rect(self, x, y, w, h, color):
3739
gray = rgb_to_gray4(color)
38-
if hasattr(self._raw, 'fill_rect'):
40+
if hasattr(self._raw, "fill_rect"):
3941
self._raw.fill_rect(x, y, w, h, gray)
4042
else:
4143
self._raw.framebuf.fill_rect(x, y, w, h, gray)
4244

4345
def rect(self, x, y, w, h, color):
4446
gray = rgb_to_gray4(color)
45-
if hasattr(self._raw, 'rect'):
47+
if hasattr(self._raw, "rect"):
4648
self._raw.rect(x, y, w, h, gray)
4749
else:
4850
self._raw.framebuf.rect(x, y, w, h, gray)
4951

5052
def show(self):
5153
self._raw.show()
54+
55+
def draw_scaled_text(self, text, x, y, color, scale):
56+
"""Draw text scaled up using pixel-by-pixel framebuf rendering.
57+
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.
61+
"""
62+
63+
gray = rgb_to_gray4(color)
64+
65+
char_buf = bytearray(8)
66+
fb = framebuf.FrameBuffer(char_buf, 8, 8, framebuf.MONO_HLSB)
67+
68+
cx = x
69+
for char in text:
70+
fb.fill(0)
71+
fb.text(char, 0, 0, 1)
72+
for py in range(8):
73+
for px in range(8):
74+
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+
)
91+
cx += 8 * scale

0 commit comments

Comments
 (0)