Skip to main content

Crate retroglyph_window

Crate retroglyph_window 

Source
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)   │
        └───────────────────────────────┘
  • Presenter is Output plus the surface lifecycle (init_surface/resize_surface/present/cell_size). Renderer crates implement only this trait, which gives them Output for free.
  • WindowBackend<P: Presenter> implements Output (by delegating to P), Input (via its own event queue), and the no-op default Cursor (windowed backends have no text cursor), which together give it Backend generically.
  • The winit module (feature-gated, see below) drives the event loop that fills that queue and calls Presenter::present each 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 Backend for windowed presenters. WindowBackend: the generic Backend implementation for windowed presenters.
clipboard
System clipboard read/write (Clipboard, SystemClipboard on 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 Presenter trait and WindowHandle. The Presenter trait: 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.