ferroui_base/media/imaging/
render_target_bitmap.rs1use crate::media::imaging::{Bitmap, BitmapEncoderOptions, IBitmap};
2use crate::media::{Colors, DrawingContext, IImage, IImageBrushSource, PlatformDrawingContext};
3use crate::platform::{self, IBitmapImpl, IDrawingContextImpl, IRenderTargetBitmapImpl};
4use crate::rendering::ImmediateRenderer;
5use crate::utilities::{RefCountable, RefCounted};
6use crate::{PixelSize, Rect, Ref, Size, Vector, Visual};
7use std::any::Any;
8use std::io::Write;
9use std::ops::Deref;
10
11pub struct RenderTargetBitmap {
13 base: Bitmap,
14 platform_impl: RefCounted<dyn IRenderTargetBitmapImpl>,
15}
16
17impl Deref for RenderTargetBitmap {
18 type Target = Bitmap;
19
20 #[inline]
21 fn deref(&self) -> &Bitmap {
22 &self.base
23 }
24}
25
26impl RenderTargetBitmap {
27 pub fn new(pixel_size: PixelSize) -> RenderTargetBitmap {
29 Self::with_dpi(pixel_size, Vector::new(96.0, 96.0))
30 }
31
32 pub fn with_dpi(pixel_size: PixelSize, dpi: Vector) -> RenderTargetBitmap {
34 let item = Self::create_impl(pixel_size, dpi);
35 let release = item.clone();
36 Self::from_ref(RefCountable::create(item, move || release.dispose()))
37 }
38
39 fn from_ref(platform_impl: RefCounted<dyn IRenderTargetBitmapImpl>) -> RenderTargetBitmap {
40 let base_impl: RefCounted<crate::platform::SharedBitmapImpl> = platform_impl.clone_as(|item| item as std::sync::Arc<crate::platform::SharedBitmapImpl>);
41 let base = Bitmap::from_ref(&base_impl);
42 base_impl.dispose();
43 RenderTargetBitmap { base, platform_impl }
44 }
45
46 pub fn platform_impl(&self) -> &RefCounted<dyn IRenderTargetBitmapImpl> {
48 &self.platform_impl
49 }
50
51 pub fn render(&self, visual: &Ref<Visual>) {
53 let mut context = self.create_drawing_context();
54 ImmediateRenderer::render(&mut context, visual);
55 context.dispose();
56 }
57
58 fn create_impl(size: PixelSize, dpi: Vector) -> std::sync::Arc<dyn IRenderTargetBitmapImpl> {
59 platform::render_interface().create_render_target_bitmap(size, dpi)
60 }
61
62 pub fn create_drawing_context(&self) -> DrawingContext<'static> {
65 self.create_drawing_context_with_clear(true)
66 }
67
68 pub fn create_drawing_context_with_clear(&self, clear: bool) -> DrawingContext<'static> {
71 let platform = self.create_platform_drawing_context(clear);
72 DrawingContext::owned(Box::new(PlatformDrawingContext::new(platform)))
73 }
74
75 pub fn create_platform_drawing_context(&self, clear: bool) -> Box<dyn IDrawingContextImpl> {
78 let mut platform = self.platform_impl.item().create_drawing_context();
79 if clear {
80 platform.clear(Colors::TRANSPARENT);
81 }
82 platform
83 }
84
85 pub fn dispose(&self) {
87 self.platform_impl.dispose();
88 self.base.dispose();
89 }
90}
91
92impl IImage for RenderTargetBitmap {
93 fn size(&self) -> Size {
94 self.base.size()
95 }
96
97 fn draw(&self, context: &mut DrawingContext<'_>, source_rect: Rect, dest_rect: Rect) {
98 IImage::draw(&self.base, context, source_rect, dest_rect)
99 }
100
101 fn as_any(&self) -> &dyn Any {
102 self
103 }
104
105 fn as_bitmap(&self) -> Option<&dyn IBitmap> {
106 Some(self)
107 }
108}
109
110impl IBitmap for RenderTargetBitmap {
111 fn dpi(&self) -> Vector {
112 self.base.dpi()
113 }
114
115 fn pixel_size(&self) -> PixelSize {
116 self.base.pixel_size()
117 }
118
119 fn platform_impl(&self) -> &RefCounted<crate::platform::SharedBitmapImpl> {
120 self.base.platform_impl()
121 }
122
123 fn save(&self, stream: &mut dyn Write, options: &BitmapEncoderOptions) -> std::io::Result<()> {
124 self.base.save(stream, options)
125 }
126
127 fn dispose(&self) {
128 RenderTargetBitmap::dispose(self)
129 }
130}
131
132impl IImageBrushSource for RenderTargetBitmap {
133 fn bitmap(&self) -> Option<&RefCounted<crate::platform::SharedBitmapImpl>> {
134 IImageBrushSource::bitmap(&self.base)
135 }
136}