Skip to main content

ferroui_base/rendering/composition/brushes/
server_simple_image_brush.rs

1//! The server-side counterpart of the mutable image brush.
2
3use crate::rendering::composition::server::{
4    impl_simple_server_render_resource, server_simple_brush, IServerObject, IServerRenderResource, ServerCompositor,
5    SimpleServerRenderResource,
6};
7use crate::media::{AlignmentX, AlignmentY, IBrush, IImageBrush, IImageBrushSource, ITileBrush, ITransform, Stretch, TileMode};
8use crate::platform::IBitmapImpl;
9use crate::rendering::composition::generated::{
10    ServerCompositionSimpleBrushHooks, ServerCompositionSimpleBrushProps, ServerCompositionSimpleTileBrushHooks,
11    ServerCompositionSimpleTileBrushProps,
12};
13use crate::rendering::composition::transport::BatchStreamReader;
14use crate::utilities::RefCounted;
15use crate::{RelativePoint, RelativeRect};
16use std::any::{Any, TypeId};
17use std::cell::RefCell;
18use std::rc::{Rc, Weak};
19use std::time::Duration;
20
21/// The image of a server-side image brush: the reference to the platform
22/// bitmap the UI thread cloned for the server.
23///
24/// The server-side brush is its own image source upstream. Here the source
25/// is an object of its own, replaced with every change of the brush, so
26/// that it can be handed out as a shared handle and can lend its reference.
27struct ServerImageBrushSource {
28    bitmap: Option<RefCounted<crate::platform::SharedBitmapImpl>>,
29}
30
31impl IImageBrushSource for ServerImageBrushSource {
32    fn bitmap(&self) -> Option<&RefCounted<crate::platform::SharedBitmapImpl>> {
33        self.bitmap.as_ref().filter(|bitmap| bitmap.is_alive())
34    }
35}
36
37server_simple_brush! {
38    /// The server-side counterpart of a mutable image brush.
39    ServerCompositionSimpleImageBrush {
40        props: ServerCompositionSimpleTileBrushProps = ServerCompositionSimpleTileBrushProps::new(),
41        source: RefCell<Rc<ServerImageBrushSource>> = RefCell::new(Rc::new(ServerImageBrushSource { bitmap: None })),
42    }
43    brush: |b| b.props.base();
44    deserialize: |d, reader, committed_at| {
45        d.props.deserialize_changes_core(d, reader, committed_at);
46        d.release_bitmap();
47        let bitmap = reader.read_value::<RefCounted<crate::platform::SharedBitmapImpl>>();
48        *d.source.borrow_mut() = Rc::new(ServerImageBrushSource { bitmap });
49    };
50    find: |f, type_id| f.props.find_props(type_id);
51    dispose: |x| x.release_bitmap();
52    as: { as_tile_brush -> ITileBrush, as_image_brush -> IImageBrush }
53}
54
55impl ServerCompositionSimpleTileBrushHooks for ServerCompositionSimpleImageBrush {}
56
57impl ServerCompositionSimpleImageBrush {
58    /// The properties of the brush.
59    pub fn props(&self) -> &ServerCompositionSimpleTileBrushProps {
60        &self.props
61    }
62
63    /// The platform bitmap the brush draws, while it has one.
64    pub fn bitmap(&self) -> Option<std::sync::Arc<crate::platform::SharedBitmapImpl>> {
65        self.source.borrow().get_bitmap()
66    }
67
68    /// Releases the reference to the bitmap. A source handed out earlier
69    /// has no bitmap from then on.
70    fn release_bitmap(&self) {
71        let source = std::mem::replace(&mut *self.source.borrow_mut(), Rc::new(ServerImageBrushSource { bitmap: None }));
72        if let Some(bitmap) = &source.bitmap {
73            bitmap.dispose();
74        }
75    }
76}
77
78impl ITileBrush for ServerCompositionSimpleImageBrush {
79    fn alignment_x(&self) -> AlignmentX {
80        self.props.alignment_x()
81    }
82
83    fn alignment_y(&self) -> AlignmentY {
84        self.props.alignment_y()
85    }
86
87    fn destination_rect(&self) -> RelativeRect {
88        self.props.destination_rect()
89    }
90
91    fn source_rect(&self) -> RelativeRect {
92        self.props.source_rect()
93    }
94
95    fn stretch(&self) -> Stretch {
96        self.props.stretch()
97    }
98
99    fn tile_mode(&self) -> TileMode {
100        self.props.tile_mode()
101    }
102}
103
104impl IImageBrush for ServerCompositionSimpleImageBrush {
105    fn source(&self) -> Option<Rc<dyn IImageBrushSource>> {
106        Some(self.source.borrow().clone() as Rc<dyn IImageBrushSource>)
107    }
108}