Skip to main content

windows_composition/
surface.rs

1//! The Direct2D bridge surface (feature `system`).
2//!
3//! Direct2D drawing-surface interop for system composition. Lifted composition has
4//! no Direct2D-surface interop.
5
6use super::*;
7
8/// Direct2D-backed composition device that allocates drawing surfaces.
9#[derive(Clone)]
10pub struct CompositionGraphicsDevice(pub(crate) bindings::CompositionGraphicsDevice);
11
12impl CompositionGraphicsDevice {
13    /// Creates a drawing surface `width`x`height` pixels in size, using a
14    /// premultiplied BGRA pixel format.
15    pub fn create_drawing_surface(
16        &self,
17        width: f32,
18        height: f32,
19    ) -> Result<CompositionDrawingSurface> {
20        let surface = self.0.CreateDrawingSurface(
21            bindings::Size { width, height },
22            bindings::DirectXPixelFormat::B8G8R8A8UIntNormalized,
23            bindings::DirectXAlphaMode::Premultiplied,
24        )?;
25        CompositionDrawingSurface::new(surface)
26    }
27}
28
29/// Composition surface that Direct2D content is drawn into.
30#[derive(Clone)]
31pub struct CompositionDrawingSurface {
32    surface: bindings::CompositionDrawingSurface,
33    interop: bindings::ICompositionDrawingSurfaceInterop,
34}
35
36impl CompositionDrawingSurface {
37    fn new(surface: bindings::CompositionDrawingSurface) -> Result<Self> {
38        let interop = surface.cast()?;
39        Ok(Self { surface, interop })
40    }
41
42    /// Begins drawing, returning the target and backing-atlas pixel offset.
43    ///
44    /// If this method succeeds, call [`end_draw`](Self::end_draw) even if a later drawing
45    /// operation fails.
46    pub fn begin_draw<T: Interface>(&self) -> Result<(T, (i32, i32))> {
47        let mut offset = bindings::POINT::default();
48        let object = unsafe { self.interop.BeginDraw::<T>(None, &mut offset)? };
49        Ok((object, (offset.x, offset.y)))
50    }
51
52    /// Finishes drawing begun with [`begin_draw`](Self::begin_draw) and presents
53    /// the surface contents.
54    pub fn end_draw(&self) -> Result<()> {
55        unsafe { self.interop.EndDraw().ok() }
56    }
57
58    /// Resizes the surface to `width`x`height` pixels.
59    pub fn resize(&self, width: i32, height: i32) -> Result<()> {
60        unsafe {
61            self.interop
62                .Resize(bindings::SIZE {
63                    cx: width,
64                    cy: height,
65                })
66                .ok()
67        }
68    }
69
70    /// The surface as the `ICompositionSurface` a surface brush paints with.
71    pub(crate) fn as_surface(&self) -> bindings::ICompositionSurface {
72        self.surface.cast().unwrap()
73    }
74}
75
76/// Brush that paints a visual with a [`CompositionDrawingSurface`].
77#[derive(Clone)]
78pub struct CompositionSurfaceBrush(pub(crate) bindings::CompositionSurfaceBrush);
79
80impl Sealed for CompositionSurfaceBrush {}
81
82impl Brush for CompositionSurfaceBrush {
83    fn as_brush(&self) -> CompositionBrush {
84        CompositionBrush(self.0.cast().unwrap())
85    }
86}