Skip to main content

leaf_raster/
lib.rs

1//! CPU rasterization shared by leaf frontends — the pieces of pixel rendering
2//! that are the same whatever the pixels end up painted with.
3//!
4//! Each leaf frontend has its own paint path (terminal cells, a gpui scene,
5//! Core Text, the DOM), but several of them also need actual pixels: the
6//! terminal ships graphics-protocol images for block media and oversized
7//! headings, and a headless consumer wants a frame with no toolkit at all.
8//! What those uses share lives here, in backend-neutral units:
9//!
10//! - [`resolve_image_path`] — which image destinations a synchronous local
11//!   loader handles, and where a relative one anchors. One policy, because two
12//!   frontends disagreeing about what loads is a bug report.
13//! - [`load_image`] / [`load_svg`] — file bytes to a decoded [`image`] raster,
14//!   vector pictures included; [`rasterize_svg`] for a vector picture whose
15//!   declared size is meant, such as a typeset formula.
16//! - [`fit_within`] — aspect-preserving containment in pixels, so frontends
17//!   with different display units (cells, points) share the sizing policy and
18//!   only round differently.
19//! - [`Rasterizer`] — shape and rasterize oversized heading text to an RGBA
20//!   frame, with the *editing UI* — caret and selection — painted into the
21//!   pixels. That last part is the reason this is a crate and not a helper: a
22//!   terminal cannot composite cells over a graphics-protocol image, so the
23//!   only way a rasterized heading stays editable is for the raster itself to
24//!   carry the caret. [`Rasterizer::heading_hit`] is the reverse mapping, so a
25//!   click on the raster lands on the glyph it visually hit.
26//!
27//! Everything here is CPU-side (cosmic-text, resvg, `image`): the consumers
28//! are terminals reading escape sequences and headless frames, none of which
29//! are latency-bound enough to want a GPU pipeline — and the one leaf backend
30//! that is (gpui) has its own. The contract is "hand me RGBA", so a GPU
31//! implementation could slot in behind it without callers changing.
32
33pub use image;
34
35mod fit;
36mod load;
37mod path;
38mod text;
39
40pub use fit::fit_within;
41pub use load::{load_image, load_svg, rasterize_svg};
42pub use path::resolve_image_path;
43pub use text::{EditingUi, HeadingSpec, Rasterizer};