Expand description
A shared layer for window-based backends (software, GL, wgpu).
§Architecture
retroglyph_core::backend::Input and retroglyph_core::backend::Output are two
independent facets of Backend, which fits a terminal process
(one type implements both) but not a window: there, an event loop owns input and a renderer
owns output separately. This crate keeps that split (Presenter is an Output supertrait,
WindowBackend owns its own Input event queue) and reassembles both into one Backend:
┌─────────────────────────────┐
│ event loop (winit or │
│ a custom driver) │
└──────────────┬───────────────┘
translated events
│
v
┌────────────────────────────────────────────────────┐
│ WindowBackend<P: Presenter> │
│ (implements Backend: owns the input event queue, │
│ delegates output to P) │
└───────────────────────┬──────────────────────────────┘
│ draw / flush / resize / present
v
┌───────────────────────────────┐
│ P: Presenter │
│ (retroglyph-software today; │
│ wgpu/GL renderers planned) │
└───────────────────────────────┘PresenterisOutputplus the surface lifecycle (init_surface/resize_surface/present/cell_size). Renderer crates implement only this trait, which gives themOutputfor free.WindowBackend<P: Presenter>implementsOutput(by delegating toP),Input(via its own event queue), and the no-op defaultCursor(windowed backends have no text cursor), which together give itBackendgenerically.- The
winitmodule (feature-gated, see below) drives the event loop that fills that queue and callsPresenter::presenteach frame.
§Features
Default features: winit.
§default-font
⚪ Optional.
Embeds the Unscii 16 default font (font::unscii16).
Off by default so a consumer that supplies its own bitmap font pays nothing for the ~4 KB atlas;
the graphical backends’ own default-font features forward to this one.
§dev
⚪ Optional.
Forwards retroglyph-core’s dev feature, which forces development diagnostics on in a build
that would otherwise compile them out (see retroglyph_core::dev).
Forwarded so a consumer of this crate can turn them on without adding a direct dependency on core just to reach the flag.
§legacy-computing
⚪ Optional.
Embeds a generated block-elements/braille fallback font (font::legacy_computing): the 10
quadrant, 60 sextant, and 256 braille glyphs CP437 (and so unscii16) has no mapping for.
A separate opt-in from default-font rather than folded into it: this repertoire is a much more
niche/specialized addition (subcell image rendering, braille density tricks) than the base text
font, so a consumer that only wants CP437 text shouldn’t pay for it. Computed at compile time by
a const fn, so this adds no font asset and no new dependency.
§tilesets
⚪ Optional.
Shared PNG sprite/tileset support (tileset + sprite_cache modules, issue #366).
Both graphical backends’ own tilesets features forward to this one.
§winit
🟢 Enabled by default.
The winit event loop and event translation (run, translate, run_windowed/run_app).
Renderer crates that only implement Presenter can disable this and depend solely on
raw-window-handle; loops other than winit (SDL2, tao, custom) bring their own driver against
Presenter + WindowBackend.
§Feature flags
Presenter, WindowBackend, and WindowHandle depend only on
raw-window-handle and are always available. The winit feature
(default on) additionally provides the winit module: the event loop, event translation, and
the run_windowed/run_app drivers. Disable it to implement or drive Presenter with a
different windowing library (SDL2, tao, a custom loop) without pulling in winit.
§DPI, scale, and the resize contract
Presenter::cell_size returns the cell size in physical pixels (the same pixel
space as winit::dpi::PhysicalSize), not logical/DPI-scaled (“CSS” or “point”) pixels.
This crate performs no automatic DPI scaling of it: nothing here changes cell_size() in
response to a display’s scale factor. SoftwareRenderer’s cell size, for example, is
fixed at construction (glyph size × its integer scale config) and never changes on a
Presenter::scale_factor_changed notification. A presenter that wants larger cells on a
HiDPI display has to opt into that itself from scale_factor_changed (e.g. regenerating a
font atlas at a new pixel density); until one does, the grid renders at a fixed physical
pixel size on every display, HiDPI or not.
Window resize is clamped to whole cells: a physical size that isn’t an exact multiple of
cell_size() has its sub-cell remainder truncated, not centered or cleared, and the OS
window is never resized to compensate: see Presenter::resize_surface’s doc comment
for the full contract, including the unpainted trailing strip this can leave on screen.
§Threading model
The windowed drivers (winit::run_windowed, winit::run_app, and their _with_proxy
variants) are single-threaded: the event loop, every Presenter call, and the app
closure/App callback all run on the one thread that calls
run_windowed/run_app: the main thread, on platforms (e.g. macOS) that require it for
windowing. Neither Presenter nor WindowBackend carries a Send/Sync bound
anywhere in this crate, and a presenter is free to hold thread-affine state accordingly
(an Rc, a non-Send GPU context handle). The only supported way to reach the loop from
another thread is winit::EventProxy<T>, which is Send + Sync + Clone for any
T: Send + 'static: it does not give another thread direct access to the Presenter or
Terminal. With the default T = u64 (winit::run_windowed_with_proxy/
run_app_with_proxy), the payload surfaces as an opaque
Event::Custom; a custom T
(winit::run_windowed_with_typed_proxy/run_app_with_typed_proxy) bypasses Event entirely
and goes straight to a caller-supplied handler, since Event::Custom itself stays fixed to
u64.
Re-exports§
pub use backend::WindowBackend;pub use clipboard::SystemClipboard;pub use clipboard::Clipboard;pub use clipboard::ClipboardError;pub use geometry::CellGeometry;pub use presenter::GenericSurfaceError;pub use presenter::Presenter;pub use presenter::RecoverableError;pub use presenter::WindowHandle;pub use presenter::cell_art_glyph;pub use raw_window_handle;
Modules§
- atlas
- Grid-packed glyph atlas layout shared by the GPU backends.
- backend
- The generic
Backendfor windowed presenters.WindowBackend: the genericBackendimplementation for windowed presenters. - clipboard
- System clipboard read/write (
Clipboard,SystemClipboardon native targets). System clipboard read/write for windowed apps (issue #296). - font
- Bitmap glyph fonts and CP437 mapping, shared by retroglyph’s graphical backends.
- geometry
- Shared cell/surface pixel geometry (
CellGeometry). Cell and surface pixel geometry shared by the graphical backends. - palette
- Canonical default colors (
DEFAULT_FG,DEFAULT_BG) shared by the graphical backends. Canonical default colors shared by the graphical backends. - presenter
- The
Presentertrait andWindowHandle. ThePresentertrait: what a renderer crate implements to rasterize a grid and present it to a window surface. - sprite_
cache - Decoded sprite cache: sprite sheet decoding, tile extraction, and runtime lookup.
- tileset
- Tileset configuration: codepage mappings, options, builder, and error types.
- winit
- The winit event loop, event translation, and app drivers. Everything winit-specific in this crate: the event loop, event translation, and the windowed app drivers.