From 47478d5a8a4b7a05b44f024404137c4c68b62b7e Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Tue, 21 Sep 2021 12:22:15 -0500 Subject: [PATCH] New ToPixel trait Use it where we convert GdkPixbuf pixels to our own Pixel for premultiplication. Part-of: Upstream-Status: Backport Signed-off-by: Alexander Kanavin --- src/surface_utils/mod.rs | 32 +++++++++++++++++++++++++++++ src/surface_utils/shared_surface.rs | 5 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/surface_utils/mod.rs b/src/surface_utils/mod.rs index 93d3b4f79..58953e6a0 100644 --- a/src/surface_utils/mod.rs +++ b/src/surface_utils/mod.rs @@ -25,6 +25,9 @@ pub type CairoARGB = ARGB8; /// GdkPixbuf's endian-independent RGBA8 pixel layout. pub type GdkPixbufRGBA = rgb::RGBA8; +/// GdkPixbuf's packed RGB pixel layout. +pub type GdkPixbufRGB = rgb::RGB8; + /// Analogous to `rgb::FromSlice`, to convert from `[T]` to `[CairoARGB]` #[allow(clippy::upper_case_acronyms)] pub trait AsCairoARGB { @@ -68,6 +71,11 @@ pub trait ToGdkPixbufRGBA { fn to_pixbuf_rgba(&self) -> GdkPixbufRGBA; } +/// Trait to convert pixels in various formats to our own Pixel layout. +pub trait ToPixel { + fn to_pixel(&self) -> Pixel; +} + impl ToGdkPixbufRGBA for Pixel { #[inline] fn to_pixbuf_rgba(&self) -> GdkPixbufRGBA { @@ -80,6 +88,30 @@ impl ToGdkPixbufRGBA for Pixel { } } +impl ToPixel for GdkPixbufRGBA { + #[inline] + fn to_pixel(&self) -> Pixel { + Pixel { + r: self.r, + g: self.g, + b: self.b, + a: self.a, + } + } +} + +impl ToPixel for GdkPixbufRGB { + #[inline] + fn to_pixel(&self) -> Pixel { + Pixel { + r: self.r, + g: self.g, + b: self.b, + a: 255, + } + } +} + /// Extension methods for `cairo::ImageSurfaceData`. pub trait ImageSurfaceDataExt: DerefMut { /// Sets the pixel at the given coordinates. Assumes the `ARgb32` format. diff --git a/src/surface_utils/shared_surface.rs b/src/surface_utils/shared_surface.rs index 476a6f776..9fa9a2e15 100644 --- a/src/surface_utils/shared_surface.rs +++ b/src/surface_utils/shared_surface.rs @@ -16,6 +16,7 @@ use crate::util::clamp; use super::{ iterators::{PixelRectangle, Pixels}, AsCairoARGB, CairoARGB, EdgeMode, ImageSurfaceDataExt, Pixel, PixelOps, ToGdkPixbufRGBA, + ToPixel, }; /// Types of pixel data in a `ImageSurface`. @@ -304,13 +305,13 @@ impl ImageSurface { .map(|row| row.as_rgba()) .zip(surf.rows_mut()) .flat_map(|(src_row, dest_row)| src_row.iter().zip(dest_row.iter_mut())) - .for_each(|(src, dest)| *dest = src.premultiply().into()); + .for_each(|(src, dest)| *dest = src.to_pixel().premultiply().into()); } else { pixbuf_rows .map(|row| row.as_rgb()) .zip(surf.rows_mut()) .flat_map(|(src_row, dest_row)| src_row.iter().zip(dest_row.iter_mut())) - .for_each(|(src, dest)| *dest = src.alpha(0xff).into()); + .for_each(|(src, dest)| *dest = src.to_pixel().into()); } if let (Some(content_type), Some(bytes)) = (content_type, mime_data) {