Skip to main content

ps_anyrender/
types.rs

1//! Types that are used within the Anyrender traits
2
3use peniko::{Brush, BrushRef, Color, Gradient, ImageBrush, ImageBrushRef};
4use std::{any::Any, sync::Arc};
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::ResourceId;
10
11pub type NormalizedCoord = i16;
12
13/// A positioned glyph.
14#[derive(Copy, Clone, Debug, PartialEq)]
15#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
16pub struct Glyph {
17    pub id: u32,
18    pub x: f32,
19    pub y: f32,
20}
21
22#[derive(Clone, Debug)]
23#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
24pub enum Paint<I = ImageBrush, G = Gradient, C = Arc<dyn Any + Send + Sync>> {
25    /// Solid color brush.
26    Solid(Color),
27    /// Gradient brush.
28    Gradient(G),
29    /// Image brush.
30    Image(I),
31    /// Custom paint (referenced by ID)
32    Resource(ImageBrush<ResourceId>),
33    /// Custom paint (type erased as each backend will have their own)
34    #[cfg_attr(feature = "serde", serde(skip))]
35    Custom(C),
36}
37
38impl<I: PartialEq, G: PartialEq> PartialEq for Paint<I, G, Arc<dyn Any + Send + Sync>> {
39    fn eq(&self, other: &Self) -> bool {
40        match (self, other) {
41            (Self::Solid(l0), Self::Solid(r0)) => l0 == r0,
42            (Self::Gradient(l0), Self::Gradient(r0)) => l0 == r0,
43            (Self::Image(l0), Self::Image(r0)) => l0 == r0,
44            (Self::Resource(l0), Self::Resource(r0)) => l0 == r0,
45            (Self::Custom(l0), Self::Custom(r0)) => Arc::ptr_eq(l0, r0),
46            _ => false,
47        }
48    }
49}
50
51pub type PaintRef<'a> = Paint<ImageBrushRef<'a>, &'a Gradient, &'a (dyn Any + Send + Sync)>;
52
53impl Paint {
54    pub fn as_ref(&self) -> PaintRef<'_> {
55        match self {
56            Paint::Solid(color) => Paint::Solid(*color),
57            Paint::Gradient(gradient) => Paint::Gradient(gradient),
58            Paint::Image(image) => Paint::Image(image.as_ref()),
59            Paint::Resource(id) => Paint::Resource(*id),
60            Paint::Custom(custom) => Paint::Custom(custom.as_ref()),
61        }
62    }
63}
64
65impl<'a> From<&'a Paint> for PaintRef<'a> {
66    fn from(paint: &'a Paint) -> Self {
67        paint.as_ref()
68    }
69}
70
71impl<'a> From<PaintRef<'a>> for BrushRef<'a> {
72    fn from(value: PaintRef<'a>) -> Self {
73        match value {
74            Paint::Solid(color) => Brush::Solid(color),
75            Paint::Gradient(gradient) => Brush::Gradient(gradient),
76            Paint::Image(image) => Brush::Image(image),
77
78            // Custom paints are translated into "invisible" where they are not supported
79            Paint::Resource(_) => Brush::Solid(Color::TRANSPARENT),
80            Paint::Custom(_) => Brush::Solid(Color::TRANSPARENT),
81        }
82    }
83}
84
85// #[derive(Clone, Debug)]
86// pub enum PaintRef<'a> {
87//     /// Solid color brush.
88//     Solid(Color),
89//     /// Gradient brush.
90//     Gradient(&'a Gradient),
91//     /// Image brush.
92//     Image(ImageBrushRef<'a>),
93//     /// Custom paint (type erased as each backend will have their own)
94//     Custom(Arc<dyn Any + Send + Sync>),
95// }
96
97impl<I, G, C> From<Color> for Paint<I, G, C> {
98    fn from(value: Color) -> Self {
99        Paint::Solid(value)
100    }
101}
102impl<'a, I, C> From<&'a Gradient> for Paint<I, &'a Gradient, C> {
103    fn from(value: &'a Gradient) -> Self {
104        Paint::Gradient(value)
105    }
106}
107impl<'a, G, C> From<ImageBrushRef<'a>> for Paint<ImageBrushRef<'a>, G, C> {
108    fn from(value: ImageBrushRef<'a>) -> Self {
109        Paint::Image(value)
110    }
111}
112impl<I, G> From<Arc<dyn Any + Send + Sync>> for Paint<I, G, Arc<dyn Any + Send + Sync>> {
113    fn from(value: Arc<dyn Any + Send + Sync>) -> Self {
114        Paint::Custom(value)
115    }
116}
117impl<'a> From<BrushRef<'a>> for PaintRef<'a> {
118    fn from(value: BrushRef<'a>) -> Self {
119        match value {
120            BrushRef::Solid(color) => PaintRef::Solid(color),
121            BrushRef::Gradient(gradient) => PaintRef::Gradient(gradient),
122            BrushRef::Image(image) => PaintRef::Image(image),
123        }
124    }
125}
126
127/// Alpha mode used when compositing the window surface.
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
129#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
130pub enum CompositeAlphaMode {
131    #[default]
132    Auto,
133    Opaque,
134    Transparent,
135}
136
137/// Unified renderer configuration options.
138#[derive(Debug, Clone, Default, PartialEq)]
139#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
140#[non_exhaustive]
141pub struct RendererConfig {
142    /// Background color used to clear the frame.
143    pub base_color: Option<Color>,
144    /// Alpha mode used when compositing the window surface.
145    pub composite_alpha_mode: Option<CompositeAlphaMode>,
146}
147
148impl RendererConfig {
149    /// Create a new configuration with default (None) values.
150    pub const fn new() -> Self {
151        Self {
152            base_color: None,
153            composite_alpha_mode: None,
154        }
155    }
156
157    /// Set the background color.
158    pub const fn base_color(self, base_color: Color) -> Self {
159        Self {
160            base_color: Some(base_color),
161            ..self
162        }
163    }
164
165    /// Set the composite alpha mode.
166    pub const fn composite_alpha_mode(self, mode: CompositeAlphaMode) -> Self {
167        Self {
168            composite_alpha_mode: Some(mode),
169            ..self
170        }
171    }
172}