glifo/interface.rs
1// Copyright 2026 the Vello Authors
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3
4//! Traits for rendering glyphs and replaying them.
5
6use crate::atlas::{AtlasPaint, AtlasSlot};
7use crate::color::{AlphaColor, Srgb};
8use crate::kurbo::{Affine, BezPath, Rect};
9use crate::peniko::BlendMode;
10use vello_common::paint::{Image, ImageSource, PaintType, Tint};
11
12// TODO: This trait is only temporary and will hopefully be replaced once we have a better
13// unifying imaging API.
14/// A sink for low-level glyph drawing commands.
15pub trait DrawSink {
16 /// Set the current transform.
17 fn set_transform(&mut self, t: Affine);
18 /// Set the current paint.
19 fn set_paint(&mut self, paint: AtlasPaint);
20 /// Set the paint transform.
21 fn set_paint_transform(&mut self, t: Affine);
22 /// Fill a path with the current paint and transform.
23 fn fill_path(&mut self, path: &BezPath);
24 /// Fill a rectangle with the current paint and transform.
25 fn fill_rect(&mut self, rect: &Rect);
26 // TODO: `push/pop_clip_layer` are only needed temporarily for Vello renderers so the impact of
27 // destructive blend modes can be limited to a smaller area. Once the limitation is lifted,
28 // we can remove this method and just use `push_clip_path` and `push_blend_layer`.
29 /// Push a clip layer defined by a path.
30 fn push_clip_layer(&mut self, clip: &BezPath);
31 /// Push a clip path.
32 ///
33 /// This method _can_ be implemented in terms of `push_clip_layer` without losing correctness.
34 /// However, clients are allowed to choose a more efficient clipping implementation that
35 /// doesn't require pushing an isolated layer.
36 ///
37 /// When providing a custom implementation of this method, the `pop_clip_path` method also
38 /// needs to be overridden correspondingly.
39 fn push_clip_path(&mut self, clip: &BezPath) {
40 self.push_clip_layer(clip);
41 }
42 /// Push a blend/compositing layer.
43 fn push_blend_layer(&mut self, blend_mode: BlendMode);
44 /// Pop the most recent clip or blend layer.
45 fn pop_layer(&mut self);
46 /// Pop the most recent clip path.
47 ///
48 /// See the documentation for [`DrawSink::push_clip_path`].
49 fn pop_clip_path(&mut self) {
50 self.pop_layer();
51 }
52 /// Width of the surface.
53 fn width(&self) -> u16;
54 /// Height of the surface.
55 fn height(&self) -> u16;
56}
57
58/// A stateful renderer that can draw sequences of cached and uncached glyphs.
59pub trait GlyphRenderer: DrawSink {
60 /// The type of state used by the renderer.
61 type SavedState;
62
63 /// Save the current state.
64 fn save_state(&mut self) -> Self::SavedState;
65
66 /// Restore the current state.
67 fn restore_state(&mut self, state: Self::SavedState);
68
69 /// Stroke a path with the current paint and stroke settings.
70 fn stroke_path(&mut self, path: &BezPath);
71
72 /// Set the current paint to an image.
73 fn set_paint_image(&mut self, image: Image);
74
75 /// Set the tint for subsequent image draws.
76 fn set_tint(&mut self, tint: Option<Tint>);
77
78 /// Get the context color from the renderer's current paint, used for resolving the
79 /// context-dependent colors of COLR glyphs.
80 fn get_context_color(&self) -> AlphaColor<Srgb>;
81
82 /// Get the currently active paint.
83 fn current_paint(&self) -> &PaintType;
84
85 // Hopefully we can get rid of those below in the future.
86
87 /// Construct the [`ImageSource`] for sampling a cached glyph from the atlas.
88 fn atlas_image_source(&self, atlas_slot: &AtlasSlot) -> ImageSource;
89
90 /// Compute the paint transform for sampling a cached glyph from the atlas.
91 fn atlas_paint_transform(&self, atlas_slot: &AtlasSlot) -> Affine;
92}