Skip to main content

ferroui_base/rendering/composition/generated/
composition_bitmap_cache.rs

1// @generated by scripts/generate_composition.py — do not edit
2
3//! `CompositionBitmapCache`.
4//!
5//! Schema attributes: internal.
6
7use bitflags::bitflags;
8use crate::rendering::composition::animations::AnimationInstanceFactory;
9use crate::rendering::composition::animations::ICompositionAnimation;
10use crate::rendering::composition::expressions::ExpressionVariant;
11use crate::rendering::composition::server::CompositionProperty;
12use crate::rendering::composition::server::CompositionPropertyOf;
13use crate::rendering::composition::server::ServerPropertyValue;
14use crate::rendering::composition::server::props_of;
15use crate::rendering::composition::transport::BatchStreamReader;
16use crate::rendering::composition::transport::BatchStreamWriter;
17use crate::rendering::composition::transport::BatchValue;
18use crate::rendering::composition::transport::BatchValueReader;
19use std::any::Any;
20use std::any::TypeId;
21use std::cell::Cell;
22use std::sync::OnceLock;
23use std::time::Duration;
24use super::CompositionCacheModeHooks;
25use super::CompositionCacheModeProps;
26use super::ServerCompositionCacheModeHooks;
27use super::ServerCompositionCacheModeProps;
28
29bitflags! {
30    /// The fields of `CompositionBitmapCache` that changed since its last serialization.
31    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
32    pub struct CompositionBitmapCacheChangedFields: u8 {
33        const RENDER_AT_SCALE = 1;
34        const RENDER_AT_SCALE_ANIMATED = 2;
35        const SNAPS_TO_DEVICE_PIXELS = 4;
36        const SNAPS_TO_DEVICE_PIXELS_ANIMATED = 8;
37        const ENABLE_CLEAR_TYPE = 16;
38        const ENABLE_CLEAR_TYPE_ANIMATED = 32;
39    }
40}
41
42impl BatchValue for CompositionBitmapCacheChangedFields {
43    #[inline]
44    fn write_to(&self, out: &mut Vec<u8>) {
45        self.bits().write_to(out);
46    }
47
48    #[inline]
49    fn read_from(input: &mut BatchValueReader<'_>) -> Self {
50        CompositionBitmapCacheChangedFields::from_bits_retain(u8::read_from(input))
51    }
52}
53
54/// The partial methods of `CompositionBitmapCache`: implemented by the class that embeds
55/// [`CompositionBitmapCacheProps`]. Every hook defaults to doing nothing.
56pub trait CompositionBitmapCacheHooks: CompositionCacheModeHooks {
57    fn initialize_defaults_extra(&self) {}
58
59    fn validate_render_at_scale_change(&self, _old_value: f64, _new_value: f64) {}
60    fn on_render_at_scale_changed(&self) {}
61    fn on_render_at_scale_changing(&self) {}
62
63    fn validate_snaps_to_device_pixels_change(&self, _old_value: bool, _new_value: bool) {}
64    fn on_snaps_to_device_pixels_changed(&self) {}
65    fn on_snaps_to_device_pixels_changing(&self) {}
66
67    fn validate_enable_clear_type_change(&self, _old_value: bool, _new_value: bool) {}
68    fn on_enable_clear_type_changed(&self) {}
69    fn on_enable_clear_type_changing(&self) {}
70}
71
72/// The UI-thread properties of `CompositionBitmapCache`.
73pub struct CompositionBitmapCacheProps {
74    base: CompositionCacheModeProps,
75    changed_fields_of_composition_bitmap_cache: Cell<CompositionBitmapCacheChangedFields>,
76    render_at_scale: Cell<f64>,
77    snaps_to_device_pixels: Cell<bool>,
78    enable_clear_type: Cell<bool>,
79}
80
81impl Default for CompositionBitmapCacheProps {
82    fn default() -> Self {
83        Self::new()
84    }
85}
86
87impl CompositionBitmapCacheProps {
88    /// Creates the properties with every field at the default of its type.
89    /// The defaults of the schema are applied by
90    /// [`initialize_defaults`](Self::initialize_defaults).
91    pub fn new() -> Self {
92        Self {
93            base: CompositionCacheModeProps::new(),
94            changed_fields_of_composition_bitmap_cache: Cell::new(CompositionBitmapCacheChangedFields::empty()),
95            render_at_scale: Cell::new(Default::default()),
96            snaps_to_device_pixels: Cell::new(Default::default()),
97            enable_clear_type: Cell::new(Default::default()),
98        }
99    }
100
101    /// The properties of the base class.
102    pub fn base(&self) -> &CompositionCacheModeProps {
103        &self.base
104    }
105
106    /// The `InitializeDefaults` calls of the constructor chain: the base
107    /// classes first, then this class.
108    pub fn initialize_defaults(&self, host: &dyn CompositionBitmapCacheHooks) {
109        self.base.initialize_defaults(host);
110        self.initialize_own_defaults(host);
111    }
112
113    /// `InitializeDefaults` of this class alone.
114    pub fn initialize_own_defaults(&self, host: &dyn CompositionBitmapCacheHooks) {
115        CompositionBitmapCacheHooks::initialize_defaults_extra(host);
116        self.set_render_at_scale(host, 1.0);
117        self.set_snaps_to_device_pixels(host, false);
118        self.set_enable_clear_type(host, false);
119    }
120
121    /// `RenderAtScale` (animated, default `1.0`).
122    pub fn render_at_scale(&self) -> f64 {
123        self.render_at_scale.get()
124    }
125
126    /// Sets `RenderAtScale` (animated, default `1.0`).
127    pub fn set_render_at_scale(&self, host: &dyn CompositionBitmapCacheHooks, value: f64) {
128        let mut changed = false;
129        let old_value = self.render_at_scale.get();
130        if old_value.differs(&value) {
131            CompositionBitmapCacheHooks::validate_render_at_scale_change(host, old_value, value);
132            CompositionBitmapCacheHooks::on_render_at_scale_changing(host);
133            changed = true;
134            // Update the backing value
135            self.render_at_scale.set(value);
136            // Register object for serialization in the next batch
137            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::RENDER_AT_SCALE);
138            host.register_for_serialization();
139            // Reset previous animation if any
140            host.pending_animations().remove(ServerCompositionBitmapCacheProps::id_of_render_at_scale_property().base());
141            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() & !CompositionBitmapCacheChangedFields::RENDER_AT_SCALE_ANIMATED);
142            // Check for implicit animations
143            if let Some(animation) = host.implicit_animation("RenderAtScale") {
144                // Animation affects only current property
145                if let Some(a) = animation.as_composition_animation() {
146                    self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::RENDER_AT_SCALE_ANIMATED);
147                    host.pending_animations().set(
148                        ServerCompositionBitmapCacheProps::id_of_render_at_scale_property().base(),
149                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
150                    );
151                }
152                // Animation is triggered by the current field, but does not necessary affects it
153                host.start_animation_group(&animation, "RenderAtScale", ExpressionVariant::create(value));
154            }
155        }
156        self.render_at_scale.set(value);
157        if changed {
158            CompositionBitmapCacheHooks::on_render_at_scale_changed(host);
159        }
160    }
161
162    /// `SnapsToDevicePixels` (animated, default `false`).
163    pub fn snaps_to_device_pixels(&self) -> bool {
164        self.snaps_to_device_pixels.get()
165    }
166
167    /// Sets `SnapsToDevicePixels` (animated, default `false`).
168    pub fn set_snaps_to_device_pixels(&self, host: &dyn CompositionBitmapCacheHooks, value: bool) {
169        let mut changed = false;
170        let old_value = self.snaps_to_device_pixels.get();
171        if old_value.differs(&value) {
172            CompositionBitmapCacheHooks::validate_snaps_to_device_pixels_change(host, old_value, value);
173            CompositionBitmapCacheHooks::on_snaps_to_device_pixels_changing(host);
174            changed = true;
175            // Update the backing value
176            self.snaps_to_device_pixels.set(value);
177            // Register object for serialization in the next batch
178            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS);
179            host.register_for_serialization();
180            // Reset previous animation if any
181            host.pending_animations().remove(ServerCompositionBitmapCacheProps::id_of_snaps_to_device_pixels_property().base());
182            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() & !CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS_ANIMATED);
183            // Check for implicit animations
184            if let Some(animation) = host.implicit_animation("SnapsToDevicePixels") {
185                // Animation affects only current property
186                if let Some(a) = animation.as_composition_animation() {
187                    self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS_ANIMATED);
188                    host.pending_animations().set(
189                        ServerCompositionBitmapCacheProps::id_of_snaps_to_device_pixels_property().base(),
190                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
191                    );
192                }
193                // Animation is triggered by the current field, but does not necessary affects it
194                host.start_animation_group(&animation, "SnapsToDevicePixels", ExpressionVariant::create(value));
195            }
196        }
197        self.snaps_to_device_pixels.set(value);
198        if changed {
199            CompositionBitmapCacheHooks::on_snaps_to_device_pixels_changed(host);
200        }
201    }
202
203    /// `EnableClearType` (animated, default `false`).
204    pub fn enable_clear_type(&self) -> bool {
205        self.enable_clear_type.get()
206    }
207
208    /// Sets `EnableClearType` (animated, default `false`).
209    pub fn set_enable_clear_type(&self, host: &dyn CompositionBitmapCacheHooks, value: bool) {
210        let mut changed = false;
211        let old_value = self.enable_clear_type.get();
212        if old_value.differs(&value) {
213            CompositionBitmapCacheHooks::validate_enable_clear_type_change(host, old_value, value);
214            CompositionBitmapCacheHooks::on_enable_clear_type_changing(host);
215            changed = true;
216            // Update the backing value
217            self.enable_clear_type.set(value);
218            // Register object for serialization in the next batch
219            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE);
220            host.register_for_serialization();
221            // Reset previous animation if any
222            host.pending_animations().remove(ServerCompositionBitmapCacheProps::id_of_enable_clear_type_property().base());
223            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() & !CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE_ANIMATED);
224            // Check for implicit animations
225            if let Some(animation) = host.implicit_animation("EnableClearType") {
226                // Animation affects only current property
227                if let Some(a) = animation.as_composition_animation() {
228                    self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE_ANIMATED);
229                    host.pending_animations().set(
230                        ServerCompositionBitmapCacheProps::id_of_enable_clear_type_property().base(),
231                        a.create_instance(host.server(), Some(ExpressionVariant::create(value))),
232                    );
233                }
234                // Animation is triggered by the current field, but does not necessary affects it
235                host.start_animation_group(&animation, "EnableClearType", ExpressionVariant::create(value));
236            }
237        }
238        self.enable_clear_type.set(value);
239        if changed {
240            CompositionBitmapCacheHooks::on_enable_clear_type_changed(host);
241        }
242    }
243
244    /// Connects an animation with the named property. Returns `false` when
245    /// neither this class nor its generated bases have an animated property
246    /// of that name: the caller continues with its hand-written base.
247    pub fn start_animation(
248        &self,
249        host: &dyn CompositionBitmapCacheHooks,
250        property_name: &str,
251        animation: &dyn ICompositionAnimation,
252        final_value: Option<ExpressionVariant>,
253    ) -> bool {
254        if property_name == "RenderAtScale" {
255            let server = animation.create_instance(host.server(), final_value);
256            host.pending_animations().set(ServerCompositionBitmapCacheProps::id_of_render_at_scale_property().base(), server);
257            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::RENDER_AT_SCALE_ANIMATED);
258            host.register_for_serialization();
259            return true;
260        }
261        if property_name == "SnapsToDevicePixels" {
262            let server = animation.create_instance(host.server(), final_value);
263            host.pending_animations().set(ServerCompositionBitmapCacheProps::id_of_snaps_to_device_pixels_property().base(), server);
264            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS_ANIMATED);
265            host.register_for_serialization();
266            return true;
267        }
268        if property_name == "EnableClearType" {
269            let server = animation.create_instance(host.server(), final_value);
270            host.pending_animations().set(ServerCompositionBitmapCacheProps::id_of_enable_clear_type_property().base(), server);
271            self.changed_fields_of_composition_bitmap_cache.set(self.changed_fields_of_composition_bitmap_cache.get() | CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE_ANIMATED);
272            host.register_for_serialization();
273            return true;
274        }
275        false
276    }
277
278    /// Writes the changes of the object: the base class first, then the
279    /// changed-fields mask and the changed members of this class.
280    pub fn serialize_changes_core(&self, host: &dyn CompositionBitmapCacheHooks, writer: &mut BatchStreamWriter<'_>) {
281        self.base.serialize_changes_core(host, writer);
282        let changed = self.changed_fields_of_composition_bitmap_cache.get();
283        writer.write(changed);
284        if changed.contains(CompositionBitmapCacheChangedFields::RENDER_AT_SCALE_ANIMATED) {
285            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionBitmapCacheProps::id_of_render_at_scale_property().base()));
286        } else if changed.contains(CompositionBitmapCacheChangedFields::RENDER_AT_SCALE) {
287            writer.write(self.render_at_scale.get());
288        }
289        if changed.contains(CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS_ANIMATED) {
290            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionBitmapCacheProps::id_of_snaps_to_device_pixels_property().base()));
291        } else if changed.contains(CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS) {
292            writer.write(self.snaps_to_device_pixels.get());
293        }
294        if changed.contains(CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE_ANIMATED) {
295            writer.write_value(host.pending_animations().get_and_remove(ServerCompositionBitmapCacheProps::id_of_enable_clear_type_property().base()));
296        } else if changed.contains(CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE) {
297            writer.write(self.enable_clear_type.get());
298        }
299        self.changed_fields_of_composition_bitmap_cache.set(CompositionBitmapCacheChangedFields::empty());
300    }
301}
302
303/// The partial methods of `ServerCompositionBitmapCache`: implemented by the class that embeds
304/// [`ServerCompositionBitmapCacheProps`]. Every hook defaults to doing nothing.
305pub trait ServerCompositionBitmapCacheHooks: ServerCompositionCacheModeHooks {
306    fn deserialize_changes_extra(&self, _reader: &mut BatchStreamReader<'_>) {}
307    fn on_fields_deserialized(&self, _changed: CompositionBitmapCacheChangedFields) {}
308}
309
310/// The server-side properties of `ServerCompositionBitmapCache`.
311pub struct ServerCompositionBitmapCacheProps {
312    base: ServerCompositionCacheModeProps,
313    render_at_scale: Cell<f64>,
314    snaps_to_device_pixels: Cell<bool>,
315    enable_clear_type: Cell<bool>,
316}
317
318impl Default for ServerCompositionBitmapCacheProps {
319    fn default() -> Self {
320        Self::new()
321    }
322}
323
324impl ServerCompositionBitmapCacheProps {
325    /// Creates the properties with every field at the default of its type; the
326    /// values of the UI thread arrive with the first batch.
327    pub fn new() -> Self {
328        Self {
329            base: ServerCompositionCacheModeProps::new(),
330            render_at_scale: Cell::new(Default::default()),
331            snaps_to_device_pixels: Cell::new(Default::default()),
332            enable_clear_type: Cell::new(Default::default()),
333        }
334    }
335
336    /// The properties of the base class.
337    pub fn base(&self) -> &ServerCompositionCacheModeProps {
338        &self.base
339    }
340
341    /// This block or the block of a base class, by type: what
342    /// `IServerObject::get_props` of the embedding class returns.
343    pub fn find_props(&self, type_id: TypeId) -> Option<&dyn Any> {
344        if type_id == TypeId::of::<Self>() {
345            return Some(self);
346        }
347        self.base.find_props(type_id)
348    }
349
350    /// The composition property of `RenderAtScale`.
351    pub fn id_of_render_at_scale_property() -> &'static CompositionPropertyOf<f64> {
352        static PROPERTY: OnceLock<CompositionPropertyOf<f64>> = OnceLock::new();
353        PROPERTY.get_or_init(|| {
354            CompositionProperty::register::<ServerCompositionBitmapCacheProps, f64>(
355                "RenderAtScale",
356                "ServerCompositionBitmapCache",
357                |obj| props_of::<ServerCompositionBitmapCacheProps>(obj).render_at_scale.get(),
358                |obj, v| props_of::<ServerCompositionBitmapCacheProps>(obj).render_at_scale.set(v),
359                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionBitmapCacheProps>(obj).render_at_scale.get())),
360                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionBitmapCacheProps>(obj).render_at_scale.set(v.cast_or_default::<f64>())),
361            )
362        })
363    }
364
365    /// `RenderAtScale` (animated).
366    pub fn render_at_scale(&self) -> f64 {
367        self.render_at_scale.get()
368    }
369
370    pub fn set_render_at_scale(&self, host: &dyn ServerCompositionBitmapCacheHooks, value: f64) {
371        self.render_at_scale.set(value);
372        host.remove_animation_for_property(Self::id_of_render_at_scale_property().base());
373    }
374
375    /// The composition property of `SnapsToDevicePixels`.
376    pub fn id_of_snaps_to_device_pixels_property() -> &'static CompositionPropertyOf<bool> {
377        static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
378        PROPERTY.get_or_init(|| {
379            CompositionProperty::register::<ServerCompositionBitmapCacheProps, bool>(
380                "SnapsToDevicePixels",
381                "ServerCompositionBitmapCache",
382                |obj| props_of::<ServerCompositionBitmapCacheProps>(obj).snaps_to_device_pixels.get(),
383                |obj, v| props_of::<ServerCompositionBitmapCacheProps>(obj).snaps_to_device_pixels.set(v),
384                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionBitmapCacheProps>(obj).snaps_to_device_pixels.get())),
385                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionBitmapCacheProps>(obj).snaps_to_device_pixels.set(v.cast_or_default::<bool>())),
386            )
387        })
388    }
389
390    /// `SnapsToDevicePixels` (animated).
391    pub fn snaps_to_device_pixels(&self) -> bool {
392        self.snaps_to_device_pixels.get()
393    }
394
395    pub fn set_snaps_to_device_pixels(&self, host: &dyn ServerCompositionBitmapCacheHooks, value: bool) {
396        self.snaps_to_device_pixels.set(value);
397        host.remove_animation_for_property(Self::id_of_snaps_to_device_pixels_property().base());
398    }
399
400    /// The composition property of `EnableClearType`.
401    pub fn id_of_enable_clear_type_property() -> &'static CompositionPropertyOf<bool> {
402        static PROPERTY: OnceLock<CompositionPropertyOf<bool>> = OnceLock::new();
403        PROPERTY.get_or_init(|| {
404            CompositionProperty::register::<ServerCompositionBitmapCacheProps, bool>(
405                "EnableClearType",
406                "ServerCompositionBitmapCache",
407                |obj| props_of::<ServerCompositionBitmapCacheProps>(obj).enable_clear_type.get(),
408                |obj, v| props_of::<ServerCompositionBitmapCacheProps>(obj).enable_clear_type.set(v),
409                Some(|obj| ExpressionVariant::create(props_of::<ServerCompositionBitmapCacheProps>(obj).enable_clear_type.get())),
410                Some(|obj, v: ExpressionVariant| props_of::<ServerCompositionBitmapCacheProps>(obj).enable_clear_type.set(v.cast_or_default::<bool>())),
411            )
412        })
413    }
414
415    /// `EnableClearType` (animated).
416    pub fn enable_clear_type(&self) -> bool {
417        self.enable_clear_type.get()
418    }
419
420    pub fn set_enable_clear_type(&self, host: &dyn ServerCompositionBitmapCacheHooks, value: bool) {
421        self.enable_clear_type.set(value);
422        host.remove_animation_for_property(Self::id_of_enable_clear_type_property().base());
423    }
424
425    /// Reads the changes of the object: the base class first, then the
426    /// changed-fields mask and the changed members of this class.
427    pub fn deserialize_changes_core(
428        &self,
429        host: &dyn ServerCompositionBitmapCacheHooks,
430        reader: &mut BatchStreamReader<'_>,
431        committed_at: Duration,
432    ) {
433        self.base.deserialize_changes_core(host, reader, committed_at);
434        ServerCompositionBitmapCacheHooks::deserialize_changes_extra(host, reader);
435        let changed = reader.read::<CompositionBitmapCacheChangedFields>();
436        if changed.contains(CompositionBitmapCacheChangedFields::RENDER_AT_SCALE_ANIMATED) {
437            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
438                panic!("a batch starts an animation of `RenderAtScale` without an animation instance");
439            };
440            host.set_animated_value(
441                Self::id_of_render_at_scale_property().base(),
442                ExpressionVariant::create(self.render_at_scale.get()),
443                committed_at,
444                animation,
445            );
446        } else if changed.contains(CompositionBitmapCacheChangedFields::RENDER_AT_SCALE) {
447            let value = reader.read::<f64>();
448            self.set_render_at_scale(host, value);
449        }
450        if changed.contains(CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS_ANIMATED) {
451            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
452                panic!("a batch starts an animation of `SnapsToDevicePixels` without an animation instance");
453            };
454            host.set_animated_value(
455                Self::id_of_snaps_to_device_pixels_property().base(),
456                ExpressionVariant::create(self.snaps_to_device_pixels.get()),
457                committed_at,
458                animation,
459            );
460        } else if changed.contains(CompositionBitmapCacheChangedFields::SNAPS_TO_DEVICE_PIXELS) {
461            let value = reader.read::<bool>();
462            self.set_snaps_to_device_pixels(host, value);
463        }
464        if changed.contains(CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE_ANIMATED) {
465            let Some(animation) = reader.read_value::<AnimationInstanceFactory>().map(AnimationInstanceFactory::create) else {
466                panic!("a batch starts an animation of `EnableClearType` without an animation instance");
467            };
468            host.set_animated_value(
469                Self::id_of_enable_clear_type_property().base(),
470                ExpressionVariant::create(self.enable_clear_type.get()),
471                committed_at,
472                animation,
473            );
474        } else if changed.contains(CompositionBitmapCacheChangedFields::ENABLE_CLEAR_TYPE) {
475            let value = reader.read::<bool>();
476            self.set_enable_clear_type(host, value);
477        }
478        ServerCompositionBitmapCacheHooks::on_fields_deserialized(host, changed);
479    }
480
481    /// The composition property with the given name, among the properties
482    /// of this class and of its generated bases that have a variant form.
483    pub fn get_composition_property(name: &str) -> Option<&'static CompositionProperty> {
484        if name == "RenderAtScale" {
485            return Some(Self::id_of_render_at_scale_property().base());
486        }
487        if name == "SnapsToDevicePixels" {
488            return Some(Self::id_of_snaps_to_device_pixels_property().base());
489        }
490        if name == "EnableClearType" {
491            return Some(Self::id_of_enable_clear_type_property().base());
492        }
493        None
494    }
495}