Mi2dRPGamEng/engine/render/ui_draw.py

52 lines
1.8 KiB
Python

from __future__ import annotations
# Screen-space (pixel) UI drawing: pure instance-list builders, no wgpu/rendering dependency,
# so this is testable without a GPU. Renderer feeds the dicts these functions build into a
# second, screen-space camera pass alongside the normal world-space one - see
# engine/render/renderer.py::render_frame's `ui_instances` parameter, and engine/ui_assets.py
# for how the glyph/panel textures referenced here actually get generated on disk.
GLYPH_SIZE = 16.0 # both the source PNG's pixel dimensions and its default on-screen size
CHAR_ADVANCE = 10.0 # horizontal spacing between glyph left edges when drawing a string
LINE_HEIGHT = 18.0
PRINTABLE_MIN = 32
PRINTABLE_MAX = 126
FALLBACK_CHAR = "?"
def glyph_texture_path(ch: str) -> str:
code = ord(ch)
if not (PRINTABLE_MIN <= code <= PRINTABLE_MAX):
ch = FALLBACK_CHAR
return f"ui/font/{ord(ch)}.png"
def panel_texture_path(name: str) -> str:
return f"ui/panel/{name}.png"
def text_width(text: str, char_advance: float = CHAR_ADVANCE) -> float:
return len(text) * char_advance
def draw_text(
buckets: dict[str, list[float]],
text: str,
x: float,
y: float,
size: float = GLYPH_SIZE,
char_advance: float = CHAR_ADVANCE,
) -> float:
"""Appends one instance per non-space glyph in `text` at (x, y), advancing left to right.
Returns the total pixel width advanced, so callers can center/right-align follow-up text.
"""
for i, ch in enumerate(text):
if ch == " ":
continue
buckets[glyph_texture_path(ch)].extend((x + i * char_advance, y, size, size))
return text_width(text, char_advance)
def draw_panel(buckets: dict[str, list[float]], name: str, x: float, y: float, w: float, h: float) -> None:
buckets[panel_texture_path(name)].extend((x, y, w, h))