ferroui_base/rendering/composition/
enums.rs1use super::transport::{BatchValue, BatchValueReader};
2use crate::media::imaging::BitmapInterpolationMode;
3use bitflags::bitflags;
4
5#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
6#[repr(i32)]
7pub enum CompositionBlendMode {
8 #[default]
10 Clear,
11 Src,
13 Dst,
15 SrcOver,
17 DstOver,
19 SrcIn,
21 DstIn,
23 SrcOut,
25 DstOut,
27 SrcATop,
29 DstATop,
31 Xor,
33 Plus,
35 Modulate,
37 Screen,
40 Overlay,
43 Darken,
45 Lighten,
47 ColorDodge,
49 ColorBurn,
51 HardLight,
54 SoftLight,
56 Difference,
59 Exclusion,
62 Multiply,
65 Hue,
68 Saturation,
71 Color,
74 Luminosity,
77}
78
79#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
80#[repr(i32)]
81pub enum CompositionGradientExtendMode {
82 #[default]
83 Clamp,
84 Wrap,
85 Mirror,
86}
87
88bitflags! {
89 #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
90 pub struct CompositionTileMode: i32 {
91 const NONE = 0;
92 const TILE_X = 1;
93 const TILE_Y = 2;
94 const FLIP_X = 4;
95 const FLIP_Y = 8;
96 const TILE = Self::TILE_X.bits() | Self::TILE_Y.bits();
97 const FLIP = Self::FLIP_X.bits() | Self::FLIP_Y.bits();
98 }
99}
100
101#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
104#[repr(i32)]
105pub enum CompositionStretch {
106 #[default]
108 None = 0,
109 Fill = 1,
111 Uniform = 2,
113 UniformToFill = 3,
116}
117
118#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
121#[repr(i32)]
122pub enum CompositionBitmapInterpolationMode {
123 NearestNeighbor = 0,
125 #[default]
127 Linear = 1,
128 MagLinearMinLinearMipLinear = 2,
129 MagLinearMinLinearMipNearest = 3,
130 MagLinearMinNearestMipLinear = 4,
131 MagLinearMinNearestMipNearest = 5,
132 MagNearestMinLinearMipLinear = 6,
133 MagNearestMinLinearMipNearest = 7,
134 MagNearestMinNearestMipLinear = 8,
135 MagNearestMinNearestMipNearest = 9,
136}
137
138impl CompositionBitmapInterpolationMode {
139 const ALL: [CompositionBitmapInterpolationMode; 10] = [
140 Self::NearestNeighbor,
141 Self::Linear,
142 Self::MagLinearMinLinearMipLinear,
143 Self::MagLinearMinLinearMipNearest,
144 Self::MagLinearMinNearestMipLinear,
145 Self::MagLinearMinNearestMipNearest,
146 Self::MagNearestMinLinearMipLinear,
147 Self::MagNearestMinLinearMipNearest,
148 Self::MagNearestMinNearestMipLinear,
149 Self::MagNearestMinNearestMipNearest,
150 ];
151
152 pub fn to_bitmap_interpolation_mode(self) -> BitmapInterpolationMode {
160 match self {
161 Self::NearestNeighbor
162 | Self::MagNearestMinLinearMipLinear
163 | Self::MagNearestMinLinearMipNearest
164 | Self::MagNearestMinNearestMipLinear
165 | Self::MagNearestMinNearestMipNearest => BitmapInterpolationMode::None,
166 Self::MagLinearMinLinearMipLinear => BitmapInterpolationMode::MediumQuality,
167 Self::Linear
168 | Self::MagLinearMinLinearMipNearest
169 | Self::MagLinearMinNearestMipLinear
170 | Self::MagLinearMinNearestMipNearest => BitmapInterpolationMode::LowQuality,
171 }
172 }
173}
174
175#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
178#[repr(i32)]
179pub enum CompositionDropShadowSourcePolicy {
180 #[default]
183 Default = 0,
184 InheritFromVisualContent = 1,
186}
187
188impl BatchValue for CompositionBitmapInterpolationMode {
189 fn write_to(&self, out: &mut Vec<u8>) {
190 (*self as i32).write_to(out);
191 }
192
193 fn read_from(input: &mut BatchValueReader<'_>) -> Self {
194 let value = i32::read_from(input);
195 match Self::ALL.iter().find(|mode| **mode as i32 == value) {
196 Some(mode) => *mode,
197 None => panic!("the batch value stream holds {value}, which is not a CompositionBitmapInterpolationMode"),
198 }
199 }
200}
201
202impl BatchValue for CompositionDropShadowSourcePolicy {
203 fn write_to(&self, out: &mut Vec<u8>) {
204 (*self as i32).write_to(out);
205 }
206
207 fn read_from(input: &mut BatchValueReader<'_>) -> Self {
208 match i32::read_from(input) {
209 0 => Self::Default,
210 1 => Self::InheritFromVisualContent,
211 value => panic!("the batch value stream holds {value}, which is not a CompositionDropShadowSourcePolicy"),
212 }
213 }
214}
215
216#[cfg(test)]
217mod tests {
218 use super::*;
219
220 #[test]
221 fn values_match_the_reference() {
222 assert_eq!(CompositionBlendMode::Clear as i32, 0);
223 assert_eq!(CompositionBlendMode::SrcOver as i32, 3);
224 assert_eq!(CompositionBlendMode::Luminosity as i32, 28);
225 assert_eq!(CompositionGradientExtendMode::Mirror as i32, 2);
226 assert_eq!(CompositionTileMode::TILE.bits(), 3);
227 assert_eq!(CompositionTileMode::FLIP.bits(), 12);
228 assert_eq!(CompositionStretch::Fill as i32, 1);
229 }
230
231 #[test]
232 fn winui_values() {
233 assert_eq!(CompositionStretch::Uniform as i32, 2);
234 assert_eq!(CompositionStretch::UniformToFill as i32, 3);
235 assert_eq!(CompositionBitmapInterpolationMode::default(), CompositionBitmapInterpolationMode::Linear);
236 assert_eq!(CompositionBitmapInterpolationMode::MagNearestMinNearestMipNearest as i32, 9);
237 assert_eq!(CompositionDropShadowSourcePolicy::InheritFromVisualContent as i32, 1);
238 }
239
240 #[test]
241 fn enums_cross_a_batch() {
242 use crate::rendering::composition::transport::{BatchValue, BatchValueReader};
243
244 let mut out = Vec::new();
245 CompositionBitmapInterpolationMode::MagLinearMinNearestMipLinear.write_to(&mut out);
246 CompositionDropShadowSourcePolicy::InheritFromVisualContent.write_to(&mut out);
247 CompositionStretch::UniformToFill.write_to(&mut out);
248 let mut offset = 0;
249 let mut input = BatchValueReader::new(&out, &mut offset);
250 assert_eq!(
251 CompositionBitmapInterpolationMode::MagLinearMinNearestMipLinear,
252 CompositionBitmapInterpolationMode::read_from(&mut input)
253 );
254 assert_eq!(
255 CompositionDropShadowSourcePolicy::InheritFromVisualContent,
256 CompositionDropShadowSourcePolicy::read_from(&mut input)
257 );
258 assert_eq!(CompositionStretch::UniformToFill, CompositionStretch::read_from(&mut input));
259 }
260}