@@ -9,6 +9,7 @@ extern crate core;
99mod backend_dispatch;
1010mod backend_interface;
1111mod backends;
12+ mod convert;
1213mod error;
1314mod format;
1415mod pixel;
@@ -623,6 +624,76 @@ impl Buffer<'_> {
623624 . map ( move |( x, pixel) | ( x as u32 , y as u32 , pixel) )
624625 } )
625626 }
627+
628+ /// Convert the alpha mode of the buffer in place.
629+ ///
630+ /// # Examples
631+ ///
632+ /// Write to the buffer as-if it was [`AlphaMode::Ignored`], and convert afterwards if
633+ /// necessary.
634+ ///
635+ /// ```no_run
636+ /// # let buffer: Buffer<'_> = unimplemented!();
637+ ///
638+ /// let needs_alpha_conversion = surface.supports_alpha_mode(AlphaMode::Ignored) {
639+ /// surface.set_alpha_mode(AlphaMode::Ignored);
640+ /// false
641+ /// } else {
642+ /// surface.set_alpha_mode(AlphaMode::Opaque);
643+ /// true
644+ /// };
645+ ///
646+ /// for row in buffer.pixel_rows() {
647+ /// for pixel in row {
648+ /// // Write red pixels with an arbitrary alpha value.
649+ /// pixel = Pixel::new_rgba(0xff, 0x00, 0x00, 0x7f);
650+ /// }
651+ /// }
652+ ///
653+ /// if needs_alpha_conversion {
654+ /// buffer.make_pixels_opaque();
655+ /// }
656+ ///
657+ /// // Alpha value is ignored, either by compositor () or by us above.
658+ /// buffer.present();
659+ /// ```
660+ #[ inline]
661+ pub fn make_pixels_opaque ( & mut self ) {
662+ for row in self . pixel_rows ( ) {
663+ for pixel in row {
664+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
665+ pixel. a = 0xff ;
666+ }
667+ }
668+ }
669+
670+ /// Multiply pixel color components by the alpha component.
671+ #[ inline]
672+ pub fn premultiply_pixels ( & mut self ) {
673+ for row in self . pixel_rows ( ) {
674+ for pixel in row {
675+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
676+ let a = pixel. a ;
677+ pixel. r = convert:: premultiply ( pixel. r , a) ;
678+ pixel. g = convert:: premultiply ( pixel. g , a) ;
679+ pixel. b = convert:: premultiply ( pixel. b , a) ;
680+ }
681+ }
682+ }
683+
684+ /// Divide pixel color components by the alpha component.
685+ #[ inline]
686+ pub fn unpremultiply_pixels ( & mut self ) {
687+ for row in self . pixel_rows ( ) {
688+ for pixel in row {
689+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
690+ let a = pixel. a ;
691+ pixel. r = convert:: unpremultiply ( pixel. r , a) ;
692+ pixel. g = convert:: unpremultiply ( pixel. g , a) ;
693+ pixel. b = convert:: unpremultiply ( pixel. b , a) ;
694+ }
695+ }
696+ }
626697}
627698
628699/// Specifies how the alpha channel of the surface should be handled by the compositor.
0 commit comments