oxframe_render/lib.rs
1//! Renderers turn a [`SceneGraph`] into an RGBA image.
2//!
3//! > **Status:** oxframe is under very active development. The API is not stable yet and
4//! > may change from version to version. Pin the exact version in your Cargo.toml and check
5//! > the [changelog](https://github.com/oxygenframe/oxframe-sdk/blob/main/CHANGELOG.md)
6//! > before upgrading.
7//!
8//! [`CpuRenderer`] (tiny-skia) is the reference backend and the `--cpu`
9//! mode for machines without a GPU; `GpuRenderer` (vello, feature `gpu`) is
10//! the fast path. Both consume the same [`oxframe_2d::DrawItem`] list and pass
11//! the same golden tests within a ΔE tolerance.
12
13#![warn(missing_docs)]
14
15use kurbo::Affine;
16use oxframe_2d::SceneGraph;
17use oxframe_core::Color;
18pub use oxframe_core::Image;
19
20#[cfg(feature = "cpu")]
21mod blur;
22#[cfg(feature = "cpu")]
23mod cpu;
24#[cfg(feature = "cpu")]
25pub use cpu::CpuRenderer;
26
27#[cfg(feature = "gpu")]
28mod gpu;
29#[cfg(feature = "gpu")]
30pub use gpu::{GpuError, GpuRenderer};
31
32/// Size and background of one render call.
33#[derive(Debug, Clone, Copy)]
34pub struct RenderOptions {
35 /// Output size; the scene is scaled uniformly to fit and centered.
36 pub width: u32,
37 /// Output height in pixels.
38 pub height: u32,
39 /// Color drawn under the scene.
40 pub background: Color,
41}
42
43/// Draws a scene graph into an image.
44pub trait Renderer {
45 /// Draws the current state of `graph`.
46 fn render(&mut self, graph: &SceneGraph, options: &RenderOptions) -> Image;
47}
48
49/// Maps scene coordinates (origin at the center, y down) to output pixels.
50pub fn scene_to_pixels(scene: (u32, u32), out: (u32, u32)) -> Affine {
51 let (sw, sh) = (f64::from(scene.0), f64::from(scene.1));
52 let (ow, oh) = (f64::from(out.0), f64::from(out.1));
53 let k = (ow / sw).min(oh / sh);
54 Affine::translate((ow / 2.0, oh / 2.0)) * Affine::scale(k)
55}