anyrender/
lib.rs

1//! 2D drawing abstraction that allows applications/frameworks to support many rendering backends through
2//! a unified API.
3//!
4//! ### Painting a scene
5//!
6//! The core abstraction in Anyrenderis the [`PaintScene`] trait.
7//!
8//! [`PaintScene`] is a "sink" which accepts drawing commands:
9//!
10//!   - Applications and libraries draw by pushing commands into a [`PaintScene`]
11//!   - Backends execute those commands to produce an output
12//!
13//! ### Rendering to surface or buffer
14//!
15//! In addition to PaintScene, there is:
16//!
17//!   - The [`ImageRenderer`] trait which provides an abstraction for rendering to a `Vec<u8>` RGBA8 buffer.
18//!   - The [`WindowRenderer`] trait which provides an abstraction for rendering to a surface/window
19//!
20//! ### SVG
21//!
22//! The [anyrender_svg](https://docs.rs/anyrender_svg) crate allows SVGs to be rendered using Anyrender
23//!
24//! ### Backends
25//!
26//! Currently existing backends are:
27//!  - [anyrender_vello](https://docs.rs/anyrender_vello)
28//!  - [anyrender_vello_cpu](https://docs.rs/anyrender_vello_cpu)
29
30use kurbo::{Affine, Rect, Shape, Stroke};
31use peniko::{BlendMode, BrushRef, Color, Fill, Font, Image, StyleRef};
32use std::sync::Arc;
33
34pub mod wasm_send_sync;
35pub use wasm_send_sync::*;
36pub mod types;
37pub use types::*;
38
39/// Abstraction for rendering a scene to a window
40pub trait WindowRenderer {
41    type ScenePainter<'a>: PaintScene
42    where
43        Self: 'a;
44    fn resume(&mut self, window: Arc<dyn WindowHandle>, width: u32, height: u32);
45    fn suspend(&mut self);
46    fn is_active(&self) -> bool;
47    fn set_size(&mut self, width: u32, height: u32);
48    fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F);
49}
50
51/// Abstraction for rendering a scene to an image buffer
52pub trait ImageRenderer {
53    type ScenePainter<'a>: PaintScene
54    where
55        Self: 'a;
56    fn new(width: u32, height: u32) -> Self;
57    fn render<F: FnOnce(&mut Self::ScenePainter<'_>)>(&mut self, draw_fn: F, buffer: &mut Vec<u8>);
58}
59
60/// Draw a scene to a buffer using an `ImageRenderer`
61pub fn render_to_buffer<R: ImageRenderer, F: FnOnce(&mut R::ScenePainter<'_>)>(
62    draw_fn: F,
63    width: u32,
64    height: u32,
65) -> Vec<u8> {
66    let mut buf = Vec::with_capacity((width * height * 4) as usize);
67    let mut renderer = R::new(width, height);
68    renderer.render(draw_fn, &mut buf);
69
70    buf
71}
72
73/// Abstraction for drawing a 2D scene
74pub trait PaintScene {
75    /// Removes all content from the scene
76    fn reset(&mut self);
77
78    /// Pushes a new layer clipped by the specified shape and composed with previous layers using the specified blend mode.
79    /// Every drawing command after this call will be clipped by the shape until the layer is popped.
80    /// However, the transforms are not saved or modified by the layer stack.
81    fn push_layer(
82        &mut self,
83        blend: impl Into<BlendMode>,
84        alpha: f32,
85        transform: Affine,
86        clip: &impl Shape,
87    );
88
89    /// Pops the current layer.
90    fn pop_layer(&mut self);
91
92    /// Strokes a shape using the specified style and brush.
93    fn stroke<'a>(
94        &mut self,
95        style: &Stroke,
96        transform: Affine,
97        brush: impl Into<BrushRef<'a>>,
98        brush_transform: Option<Affine>,
99        shape: &impl Shape,
100    );
101
102    /// Fills a shape using the specified style and brush.
103    fn fill<'a>(
104        &mut self,
105        style: Fill,
106        transform: Affine,
107        brush: impl Into<Paint<'a>>,
108        brush_transform: Option<Affine>,
109        shape: &impl Shape,
110    );
111
112    /// Returns a builder for encoding a glyph run.
113    #[allow(clippy::too_many_arguments)]
114    fn draw_glyphs<'a, 's: 'a>(
115        &'s mut self,
116        font: &'a Font,
117        font_size: f32,
118        hint: bool,
119        normalized_coords: &'a [NormalizedCoord],
120        style: impl Into<StyleRef<'a>>,
121        brush: impl Into<BrushRef<'a>>,
122        brush_alpha: f32,
123        transform: Affine,
124        glyph_transform: Option<Affine>,
125        glyphs: impl Iterator<Item = Glyph>,
126    );
127
128    /// Draw a rounded rectangle blurred with a gaussian filter.
129    fn draw_box_shadow(
130        &mut self,
131        transform: Affine,
132        rect: Rect,
133        brush: Color,
134        radius: f64,
135        std_dev: f64,
136    );
137
138    // --- Provided methods
139
140    /// Utility method to draw an image at it's natural size. For more advanced image drawing use the `fill` method
141    fn draw_image(&mut self, image: &Image, transform: Affine) {
142        self.fill(
143            Fill::NonZero,
144            transform,
145            image,
146            None,
147            &Rect::new(0.0, 0.0, image.width as f64, image.height as f64),
148        );
149    }
150}