@@ -74,6 +74,9 @@ pub struct Rect {
7474/// A surface for drawing to a window with software buffers.
7575#[ derive( Debug ) ]
7676pub struct Surface < D , W > {
77+ alpha_mode : AlphaMode ,
78+ /// A buffer that is used when `!supported_alpha_mode.contains(alpha_mode)`.
79+ fallback_buffer : Option < Vec < u8 > > ,
7780 /// This is boxed so that `Surface` is the same size on every platform.
7881 surface_impl : Box < SurfaceDispatch < D , W > > ,
7982 _marker : PhantomData < Cell < ( ) > > ,
@@ -104,14 +107,28 @@ impl<D: HasDisplayHandle, W: HasWindowHandle> Surface<D, W> {
104107 self . surface_impl . window ( )
105108 }
106109
110+ /// The current alpha mode of the surface.
111+ pub fn alpha_mode ( & self ) -> AlphaMode {
112+ self . surface_impl . alpha_mode ( )
113+ }
114+
107115 /// Set the size of the buffer that will be returned by [`Surface::buffer_mut`].
108116 ///
109117 /// If the size of the buffer does not match the size of the window, the buffer is drawn
110118 /// in the upper-left corner of the window. It is recommended in most production use cases
111119 /// to have the buffer fill the entire window. Use your windowing library to find the size
112120 /// of the window.
113121 pub fn resize ( & mut self , width : NonZeroU32 , height : NonZeroU32 ) -> Result < ( ) , SoftBufferError > {
114- self . surface_impl . resize ( width, height)
122+ self . configure ( width, height, self . alpha_mode ( ) )
123+ }
124+
125+ pub fn configure (
126+ & mut self ,
127+ width : NonZeroU32 ,
128+ height : NonZeroU32 ,
129+ alpha_mode : AlphaMode ,
130+ ) -> Result < ( ) , SoftBufferError > {
131+ self . surface_impl . configure ( width, height, alpha_mode)
115132 }
116133
117134 /// Copies the window contents into a buffer.
@@ -424,6 +441,72 @@ impl Buffer<'_> {
424441 }
425442}
426443
444+ /// Specifies how the alpha channel of the surface should be handled by the compositor.
445+ ///
446+ /// Whether this has an effect is dependent on whether [the pixel format](crate::Format) has an
447+ /// alpha component.
448+ ///
449+ /// See [the WhatWG spec][whatwg-premultiplied] for a good description of the difference between
450+ /// premultiplied and postmultiplied alpha.
451+ ///
452+ /// [whatwg-premultiplied]: https://html.spec.whatwg.org/multipage/canvas.html#premultiplied-alpha-and-the-2d-rendering-context
453+ #[ doc( alias = "Transparency" ) ]
454+ #[ derive( Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash , Debug , Default ) ]
455+ pub enum AlphaMode {
456+ /// The alpha channel is ignored.
457+ ///
458+ /// # Platform-specific
459+ ///
460+ /// This requires a copy on Web.
461+ #[ default]
462+ Opaque ,
463+ /// The non-alpha channels are expected to already have been multiplied by the alpha channel.
464+ ///
465+ /// # Platform-specific
466+ ///
467+ /// This requires a copy on Web.
468+ PreMultiplied ,
469+ /// The non-alpha channels are not expected to already be multiplied by the alpha channel;
470+ /// instead, the compositor will multiply the non-alpha channels by the alpha channel during
471+ /// compositing.
472+ ///
473+ /// Also known as "straight alpha".
474+ ///
475+ /// # Platform-specific
476+ ///
477+ /// This is unsupported on Wayland (TODO: And others?), so there Softbuffer creates a separate
478+ /// buffer that is used later on for the conversion.
479+ ///
480+ /// Web: Works great.
481+ #[ doc( alias = "Straight" ) ]
482+ PostMultiplied ,
483+ }
484+
485+ /// Convenience helpers.
486+ impl AlphaMode {
487+ /// Check if this is [`AlphaMode::Opaque`].
488+ pub fn is_opaque ( self ) -> bool {
489+ matches ! ( self , Self :: Opaque )
490+ }
491+
492+ /// Check if this is [`AlphaMode::PreMultiplied`].
493+ pub fn is_pre_multiplied ( self ) -> bool {
494+ matches ! ( self , Self :: PreMultiplied )
495+ }
496+
497+ /// Check if this is [`AlphaMode::PostMultiplied`].
498+ pub fn is_post_multiplied ( self ) -> bool {
499+ matches ! ( self , Self :: PostMultiplied )
500+ }
501+
502+ /// Whether the alpha mode allows the surface to be transparent.
503+ ///
504+ /// This is true for pre-multiplied and post-multiplied alpha modes.
505+ pub fn has_transparency ( self ) -> bool {
506+ !self . is_opaque ( )
507+ }
508+ }
509+
427510/// There is no display handle.
428511#[ derive( Debug ) ]
429512#[ allow( dead_code) ]
0 commit comments