denise_render/lib.rs
1//! Denise's software rasteriser.
2//!
3//! Rectangles, rounded rectangles, lines, rectangular clipping and source-over
4//! alpha blending, straight into a [`denise::Frame`]. No GPU, no path builder, no
5//! allocator: this crate needs neither `std` nor `alloc`, and every operation
6//! writes through a borrowed slice the caller already owns.
7//!
8//! ```no_run
9//! # use denise::{Color, Frame, Rect, Point};
10//! # use denise_render::Canvas;
11//! # fn draw(frame: &mut Frame<'_>, damage: &[Rect]) {
12//! let mut canvas = Canvas::new(frame);
13//! for region in damage {
14//! // Everything inside this borrow is confined to `region`.
15//! let mut c = canvas.with_clip(*region);
16//! c.clear(Color::from_rgb888(0x1E1E2E));
17//! c.fill_rounded_rect(Rect::new(40, 40, 200, 64), 12, Color::rgba(255, 255, 255, 32));
18//! c.draw_line(Point::new(40, 120), Point::new(240, 121), Color::WHITE);
19//! }
20//! # }
21//! ```
22//!
23//! # No floating point
24//!
25//! The rasteriser is integer throughout, including anti-aliasing coverage. That
26//! avoids a `libm` dependency on `no_std` targets and keeps output bit-identical
27//! between x86 and ARM, so the reference tests mean the same thing on a developer's
28//! desktop and on the Pi.
29//!
30//! # No `unsafe`
31//!
32//! Deliberately, for now. Bounds checks are hoisted by working through row slices
33//! rather than indexing pixel by pixel. If the benches ever show that costing real
34//! time, that is the evidence needed to justify unchecked access — not before.
35
36#![cfg_attr(not(feature = "std"), no_std)]
37
38pub mod blend;
39pub mod canvas;
40pub mod coverage;
41pub mod font;
42
43mod line;
44mod rect;
45mod rounded;
46
47#[cfg(test)]
48mod testing;
49
50pub use blend::Paint;
51pub use canvas::{Canvas, PixelView};
52pub use coverage::Mask;
53pub use font::BitmapFont;