Skip to main content

ferroui_base/rendering/composition/
composition_winui_enums.rs

1//! The enumerations of the WinUI visual and brush members of phase 2 (not
2//! from upstream): the 3D modes of a visual, which a 2D renderer stores,
3//! and the mapping mode of the gradient brushes. (The colour space of the
4//! gradient brushes is the `CompositionColorSpace` of the animations.)
5
6use super::server::ServerPropertyValue;
7use super::transport::{BatchValue, BatchValueReader};
8
9/// How the edges of a visual are antialiased (WinUI `CompositionBorderMode`).
10///
11/// Deviation (winui-composition.md): stored only; the drawing contexts
12/// antialias every edge.
13#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
14#[repr(i32)]
15pub enum CompositionBorderMode {
16    /// The mode of the parent visual (the WinUI default).
17    #[default]
18    Inherit = 0,
19    /// Antialiased edges.
20    Soft = 1,
21    /// Aliased edges.
22    Hard = 2,
23}
24
25/// Whether the back of a visual rotated in 3D is shown (WinUI
26/// `CompositionBackfaceVisibility`).
27///
28/// Deviation (winui-composition.md): stored only; a 2D renderer has no back
29/// face.
30#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
31#[repr(i32)]
32pub enum CompositionBackfaceVisibility {
33    /// The visibility of the parent visual (the WinUI default).
34    #[default]
35    Inherit = 0,
36    /// The back face is shown.
37    Visible = 1,
38    /// The back face is hidden.
39    Hidden = 2,
40}
41
42/// How a visual is blended with what is behind it (WinUI
43/// `CompositionCompositeMode`).
44///
45/// Deviation (winui-composition.md): stored only; the drawing contexts
46/// blend whole subtrees with source-over only.
47#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
48#[repr(i32)]
49pub enum CompositionCompositeMode {
50    /// The mode of the parent visual (the WinUI default).
51    #[default]
52    Inherit = 0,
53    /// The visual is drawn over what is behind it.
54    SourceOver = 1,
55    /// What is behind the visual is inverted where the visual is.
56    DestinationInvert = 2,
57    /// The minimum of the visual and what is behind it.
58    MinBlend = 3,
59}
60
61/// How the points of a gradient brush are measured (WinUI
62/// `CompositionMappingMode`).
63#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
64#[repr(i32)]
65pub enum CompositionMappingMode {
66    /// In pixels of the area the brush paints.
67    Absolute = 0,
68    /// As fractions of the size of the area the brush paints (the WinUI
69    /// default).
70    #[default]
71    Relative = 1,
72}
73
74/// The enumerations of the schema cross a batch as their numeric value and
75/// compare as values on the server.
76macro_rules! winui_schema_enum {
77    ($ty:ident { $($variant:ident),* $(,)? }) => {
78        impl BatchValue for $ty {
79            fn write_to(&self, out: &mut Vec<u8>) {
80                (*self as i32).write_to(out);
81            }
82
83            fn read_from(input: &mut BatchValueReader<'_>) -> Self {
84                let value = i32::read_from(input);
85                $(if value == $ty::$variant as i32 {
86                    return $ty::$variant;
87                })*
88                panic!("the batch value stream holds {value}, which is not a {}", stringify!($ty));
89            }
90        }
91
92        impl ServerPropertyValue for $ty {
93            fn differs(&self, other: &Self) -> bool {
94                self != other
95            }
96        }
97    };
98}
99
100winui_schema_enum!(CompositionBorderMode { Inherit, Soft, Hard });
101winui_schema_enum!(CompositionBackfaceVisibility { Inherit, Visible, Hidden });
102winui_schema_enum!(CompositionCompositeMode { Inherit, SourceOver, DestinationInvert, MinBlend });
103
104#[cfg(test)]
105mod tests {
106    use super::*;
107
108    #[test]
109    fn winui_values() {
110        assert_eq!(CompositionBorderMode::Hard as i32, 2);
111        assert_eq!(CompositionBackfaceVisibility::Hidden as i32, 2);
112        assert_eq!(CompositionCompositeMode::MinBlend as i32, 3);
113        assert_eq!(CompositionMappingMode::default(), CompositionMappingMode::Relative);
114    }
115
116    #[test]
117    fn the_visual_modes_cross_a_batch() {
118        let mut out = Vec::new();
119        CompositionBorderMode::Soft.write_to(&mut out);
120        CompositionBackfaceVisibility::Visible.write_to(&mut out);
121        CompositionCompositeMode::DestinationInvert.write_to(&mut out);
122        let mut offset = 0;
123        let mut input = BatchValueReader::new(&out, &mut offset);
124        assert_eq!(CompositionBorderMode::Soft, CompositionBorderMode::read_from(&mut input));
125        assert_eq!(CompositionBackfaceVisibility::Visible, CompositionBackfaceVisibility::read_from(&mut input));
126        assert_eq!(CompositionCompositeMode::DestinationInvert, CompositionCompositeMode::read_from(&mut input));
127    }
128}