@@ -9,6 +9,7 @@ extern crate core;
99mod backend_dispatch;
1010mod backend_interface;
1111mod backends;
12+ mod convert;
1213mod error;
1314mod format;
1415mod pixel;
@@ -506,6 +507,76 @@ impl Buffer<'_> {
506507 . map ( move |( x, pixel) | ( x as u32 , y as u32 , pixel) )
507508 } )
508509 }
510+
511+ /// Convert the alpha mode of the buffer in place.
512+ ///
513+ /// # Examples
514+ ///
515+ /// Write to the buffer as-if it was [`AlphaMode::Ignored`], and convert afterwards if
516+ /// necessary.
517+ ///
518+ /// ```no_run
519+ /// # let buffer: Buffer<'_> = unimplemented!();
520+ ///
521+ /// let needs_alpha_conversion = surface.supports_alpha_mode(AlphaMode::Ignored) {
522+ /// surface.set_alpha_mode(AlphaMode::Ignored);
523+ /// false
524+ /// } else {
525+ /// surface.set_alpha_mode(AlphaMode::Opaque);
526+ /// true
527+ /// };
528+ ///
529+ /// for row in buffer.pixel_rows() {
530+ /// for pixel in row {
531+ /// // Write red pixels with an arbitrary alpha value.
532+ /// pixel = Pixel::new_rgba(0xff, 0x00, 0x00, 0x7f);
533+ /// }
534+ /// }
535+ ///
536+ /// if needs_alpha_conversion {
537+ /// buffer.make_pixels_opaque();
538+ /// }
539+ ///
540+ /// // Alpha value is ignored, either by compositor () or by us above.
541+ /// buffer.present();
542+ /// ```
543+ #[ inline]
544+ pub fn make_pixels_opaque ( & mut self ) {
545+ for row in self . pixel_rows ( ) {
546+ for pixel in row {
547+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
548+ pixel. a = 0xff ;
549+ }
550+ }
551+ }
552+
553+ /// Multiply pixel color components by the alpha component.
554+ #[ inline]
555+ pub fn premultiply_pixels ( & mut self ) {
556+ for row in self . pixel_rows ( ) {
557+ for pixel in row {
558+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
559+ let a = pixel. a ;
560+ pixel. r = convert:: premultiply ( pixel. r , a) ;
561+ pixel. g = convert:: premultiply ( pixel. g , a) ;
562+ pixel. b = convert:: premultiply ( pixel. b , a) ;
563+ }
564+ }
565+ }
566+
567+ /// Divide pixel color components by the alpha component.
568+ #[ inline]
569+ pub fn unpremultiply_pixels ( & mut self ) {
570+ for row in self . pixel_rows ( ) {
571+ for pixel in row {
572+ // TODO: SIMD-optimize this somehow? Or maybe autovectorization is good enough.
573+ let a = pixel. a ;
574+ pixel. r = convert:: unpremultiply ( pixel. r , a) ;
575+ pixel. g = convert:: unpremultiply ( pixel. g , a) ;
576+ pixel. b = convert:: unpremultiply ( pixel. b , a) ;
577+ }
578+ }
579+ }
509580}
510581
511582/// Specifies how the alpha channel of the surface should be handled by the compositor.
0 commit comments