vello_cpu/
lib.rs

1// Copyright 2025 the Vello Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4//! Vello CPU is a 2D graphics rendering engine written in Rust, for devices with no or underpowered GPUs.
5//!
6//! It is currently available as an alpha.
7//! See the [Caveats](#caveats) section for things you need to be aware of.
8//!
9//! We also develop [Vello](https://crates.io/crates/vello), which makes use of the GPU for 2D rendering and has higher performance than Vello CPU.
10//! Vello CPU is being developed as part of work to address shortcomings in Vello.
11//!
12//! ## Usage
13//!
14//! To use Vello CPU, you need to:
15//!
16//! - Create a [`RenderContext`][], a 2D drawing context for a fixed-size target area.
17//! - For each object in your scene:
18//!   - Set how the object will be painted, using [`set_paint`][RenderContext::set_paint].
19//!   - Set the shape to be drawn for that object, using methods like [`fill_path`][RenderContext::fill_path],
20//!     [`stroke_path`][RenderContext::stroke_path], or [`glyph_run`][RenderContext::glyph_run].
21//! - Render it to an image using [`RenderContext::render_to_pixmap`][].
22//!
23//! ```rust
24//! use vello_cpu::{RenderContext, Pixmap, RenderMode};
25//! use vello_cpu::{color::{palette::css, PremulRgba8}, kurbo::Rect};
26//! let width = 10;
27//! let height = 5;
28//! let mut context = RenderContext::new(width, height);
29//! context.set_paint(css::MAGENTA);
30//! context.fill_rect(&Rect::from_points((3., 1.), (7., 4.)));
31//!
32//! let mut target = Pixmap::new(width, height);
33//! // This is only necessary if you activated the `multithreading` feature.
34//! context.flush();
35//! context.render_to_pixmap(&mut target);
36//!
37//! let expected_render = b"\
38//!     0000000000\
39//!     0001111000\
40//!     0001111000\
41//!     0001111000\
42//!     0000000000";
43//! let magenta = css::MAGENTA.premultiply().to_rgba8();
44//! let transparent = PremulRgba8 {r: 0, g: 0, b: 0, a: 0};
45//! let mut result = Vec::new();
46//! for pixel in target.data() {
47//!     if *pixel == magenta {
48//!         result.push(b'1');
49//!     } else if *pixel == transparent {
50//!         result.push(b'0');
51//!     } else {
52//!          panic!("Got unexpected pixel value {pixel:?}");
53//!     }
54//! }
55//! assert_eq!(&result, expected_render);
56//! ```
57//!
58//! ## Features
59//!
60//! - `std` (enabled by default): Get floating point functions from the standard library
61//!   (likely using your target's libc).
62//! - `libm`: Use floating point implementations from `libm`.
63//! - `png`(enabled by default): Allow loading [`Pixmap`]s from PNG images.
64//!   Also required for rendering glyphs with an embedded PNG.
65//! - `multithreading`: Enable multi-threaded rendering.
66//!
67//! At least one of `std` and `libm` is required; `std` overrides `libm`.
68//!
69//! ## Caveats
70//!
71//! Vello CPU is an alpha for several reasons, including the following.
72//!
73//! ### API stability
74//!
75//! This API has been developed for an initial version, and has no stability guarantees.
76//! Whilst we are in the `0.0.x` release series, any release is likely to breaking.
77//! We have known plans to change the API around how image resources are used.
78//!
79//! ### Documentation
80//!
81//! We have not yet put any work into documentation.
82//!
83//! ### Performance
84//!
85//! We do not perform several important optimisations, such as the use of multithreading and SIMD.
86//! Additionally, some algorithms we use aren't final, and will be replaced with higher-performance variants.
87//!
88//! ## Implementation
89//!
90//! TODO: Point to documentation of sparse strips pattern.
91// LINEBENDER LINT SET - lib.rs - v3
92// See https://linebender.org/wiki/canonical-lints/
93// These lints shouldn't apply to examples or tests.
94#![cfg_attr(not(test), warn(unused_crate_dependencies))]
95// These lints shouldn't apply to examples.
96#![warn(clippy::print_stdout, clippy::print_stderr)]
97// Targeting e.g. 32-bit means structs containing usize can give false positives for 64-bit.
98#![cfg_attr(target_pointer_width = "64", warn(clippy::trivially_copy_pass_by_ref))]
99// END LINEBENDER LINT SET
100#![cfg_attr(docsrs, feature(doc_auto_cfg))]
101#![forbid(unsafe_code)]
102#![expect(
103    clippy::cast_possible_truncation,
104    reason = "We cast u16s to u8 in various places where we know for sure that it's < 256"
105)]
106#![no_std]
107
108extern crate alloc;
109extern crate core;
110#[cfg(feature = "std")]
111extern crate std;
112
113mod render;
114
115mod dispatch;
116#[doc(hidden)]
117pub mod fine;
118#[doc(hidden)]
119pub mod region;
120mod util;
121
122pub use render::{RenderContext, RenderSettings};
123pub use vello_common::fearless_simd::Level;
124#[cfg(feature = "text")]
125pub use vello_common::glyph::Glyph;
126pub use vello_common::mask::Mask;
127pub use vello_common::paint::{Image, ImageSource, Paint, PaintType};
128pub use vello_common::pixmap::Pixmap;
129pub use vello_common::{color, kurbo, peniko};
130
131/// The selected rendering mode.
132#[derive(Copy, Clone, Debug, Default)]
133pub enum RenderMode {
134    /// Optimize speed (by performing calculations with u8/16).
135    #[default]
136    OptimizeSpeed,
137    /// Optimize quality (by performing calculations with f32).
138    OptimizeQuality,
139}