Files
matrix-screen-controller/核桃派软件源代码/app/display/wifi_indicator.py
T

67 lines
2.1 KiB
Python

from __future__ import annotations
from PIL import Image, ImageDraw, ImageFont
from .text_renderer import load_font
WIFI_INDICATOR_BRIGHTNESS = 50
WIFI_SCROLL_PIXELS_PER_SECOND = 16.0
WIFI_SCROLL_FPS = 20.0
WIFI_SCROLL_GAP_PIXELS = 16
WIFI_TEXT_SIZE = 10
def _draw_binary_text(
image: Image.Image,
position: tuple[int, int],
message: str,
*,
font: ImageFont.ImageFont,
) -> None:
probe = ImageDraw.Draw(image)
bbox = probe.textbbox((0, 0), message, font=font)
width = max(1, bbox[2] - bbox[0])
height = max(1, bbox[3] - bbox[1])
mask = Image.new("L", (width, height), 0)
ImageDraw.Draw(mask).text((-bbox[0], -bbox[1]), message, font=font, fill=255)
# Promote every covered font sample to a complete LED pixel. At this size,
# retaining grayscale antialiasing makes thin strokes disappear at 50%.
mask = mask.point(lambda value: 255 if value >= 64 else 0)
image.paste((255, 255, 255), (position[0] + bbox[0], position[1] + bbox[1]), mask)
def text_width(message: str) -> int:
font = load_font("default", WIFI_TEXT_SIZE, message)
draw = ImageDraw.Draw(Image.new("RGB", (1, 1)))
box = draw.textbbox((0, 0), message, font=font)
return max(1, box[2] - box[0])
def _draw_disconnected_icon(draw: ImageDraw.ImageDraw) -> None:
# A compact WiFi fan with a red slash remains recognizable on 64x64.
white = (255, 255, 255)
red = (255, 48, 48)
draw.arc((19, 4, 45, 28), 205, 335, fill=white, width=2)
draw.arc((23, 10, 41, 28), 205, 335, fill=white, width=2)
draw.arc((28, 17, 36, 27), 205, 335, fill=white, width=2)
draw.rectangle((31, 27, 33, 29), fill=white)
draw.line((19, 4, 45, 30), fill=red, width=3)
def render_wifi_indicator(
message: str,
*,
offset: float,
connected: bool,
size: tuple[int, int] = (64, 64),
) -> Image.Image:
image = Image.new("RGB", size, (0, 0, 0))
draw = ImageDraw.Draw(image)
font = load_font("default", WIFI_TEXT_SIZE, message)
if not connected:
_draw_disconnected_icon(draw)
x = size[0] - int(offset)
y = 26 if connected else 42
_draw_binary_text(image, (x, y), message, font=font)
return image