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}