@@ -9,6 +9,7 @@ extern crate core;
99mod backend_dispatch;
1010mod backend_interface;
1111mod backends;
12+ mod convert;
1213mod error;
1314mod format;
1415mod pixel;
@@ -567,6 +568,76 @@ impl Buffer<'_> {
567568 . map ( move |( x, pixel) | ( x as u32 , y as u32 , pixel) )
568569 } )
569570 }
571+
572+ /// Convert the alpha mode of the buffer in place.
573+ ///
574+ /// # Examples
575+ ///
576+ /// Write to the buffer as-if it was [`AlphaMode::Ignored`], and convert afterwards if
577+ /// necessary.
578+ ///
579+ /// ```no_run
580+ /// # let buffer: Buffer<'_> = unimplemented!();
581+ ///
582+ /// let needs_alpha_conversion = surface.supports_alpha_mode(AlphaMode::Ignored) {
583+ /// surface.set_alpha_mode(AlphaMode::Ignored);
584+ /// false
585+ /// } else {
586+ /// surface.set_alpha_mode(AlphaMode::Opaque);
587+ /// true
588+ /// };
589+ ///
590+ /// for row in buffer.pixel_rows() {
591+ /// for pixel in row {
592+ /// // Write red pixels with an arbitrary alpha value.
593+ /// pixel = Pixel::new_rgba(0xff, 0x00, 0x00, 0x7f);
594+ /// }
595+ /// }
596+ ///
597+ /// if needs_alpha_conversion {
598+ /// buffer.make_pixels_opaque();
599+ /// }
600+ ///
601+ /// // Alpha value is ignored, either by compositor () or by us above.
602+ /// buffer.present();
603+ /// ```
604+ #[ inline]
605+ pub fn make_pixels_opaque ( & mut self ) {
606+ for row in self . pixel_rows ( ) {
607+ for pixel in row {
608+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
609+ pixel. a = 0xff ;
610+ }
611+ }
612+ }
613+
614+ /// Multiply pixel color components by the alpha component.
615+ #[ inline]
616+ pub fn premultiply_pixels ( & mut self ) {
617+ for row in self . pixel_rows ( ) {
618+ for pixel in row {
619+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
620+ let a = pixel. a ;
621+ pixel. r = convert:: premultiply ( pixel. r , a) ;
622+ pixel. g = convert:: premultiply ( pixel. g , a) ;
623+ pixel. b = convert:: premultiply ( pixel. b , a) ;
624+ }
625+ }
626+ }
627+
628+ /// Divide pixel color components by the alpha component.
629+ #[ inline]
630+ pub fn unpremultiply_pixels ( & mut self ) {
631+ for row in self . pixel_rows ( ) {
632+ for pixel in row {
633+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
634+ let a = pixel. a ;
635+ pixel. r = convert:: unpremultiply ( pixel. r , a) ;
636+ pixel. g = convert:: unpremultiply ( pixel. g , a) ;
637+ pixel. b = convert:: unpremultiply ( pixel. b , a) ;
638+ }
639+ }
640+ }
570641}
571642
572643/// Specifies how the alpha channel of the surface should be handled by the compositor.
0 commit comments