From 932c7e23c8863fce83cb85cc5677ee421fb192b1 Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Sat, 16 Nov 2024 22:53:57 +0800 Subject: [PATCH] gpui: Fix SVG color render, when color have alpha (#20537) Release Notes: - N/A ## Demo - [Source SVG](https://github.com/user-attachments/assets/1c681e01-baba-4613-a3e7-ea5cb3015406) click here open in browser. | Before | After | | --- | --- | | image | image | --------- Co-authored-by: Floyd Wang --- crates/gpui/examples/image/color.svg | 6 +++--- crates/gpui/src/color.rs | 11 +++++++++++ crates/gpui/src/elements/img.rs | 11 +++++------ crates/gpui/src/platform/mac/text_system.rs | 13 +++++-------- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/crates/gpui/examples/image/color.svg b/crates/gpui/examples/image/color.svg index 84e9809d09492a7280e757554bc3c2ccb1e3f8b3..a080681b0e6fe1dc9167bc9a9a7db94159dc31cc 100644 --- a/crates/gpui/examples/image/color.svg +++ b/crates/gpui/examples/image/color.svg @@ -6,8 +6,8 @@ - + - - \ No newline at end of file + + diff --git a/crates/gpui/src/color.rs b/crates/gpui/src/color.rs index 6a1f375b651d4263650c434a498f7a9765858c59..9c831d0875588cf54d647badf96ef66953b73a9b 100644 --- a/crates/gpui/src/color.rs +++ b/crates/gpui/src/color.rs @@ -22,6 +22,17 @@ pub fn rgba(hex: u32) -> Rgba { Rgba { r, g, b, a } } +/// Swap from RGBA with premultiplied alpha to BGRA +pub(crate) fn swap_rgba_pa_to_bgra(color: &mut [u8]) { + color.swap(0, 2); + if color[3] > 0 { + let a = color[3] as f32 / 255.; + color[0] = (color[0] as f32 / a) as u8; + color[1] = (color[1] as f32 / a) as u8; + color[2] = (color[2] as f32 / a) as u8; + } +} + /// An RGBA color #[derive(PartialEq, Clone, Copy, Default)] pub struct Rgba { diff --git a/crates/gpui/src/elements/img.rs b/crates/gpui/src/elements/img.rs index 4e326720955f6a561dd1a464c6299449dd4b8dd7..895904c8012cb837ae641c307e3d2f147675dc2f 100644 --- a/crates/gpui/src/elements/img.rs +++ b/crates/gpui/src/elements/img.rs @@ -1,8 +1,8 @@ use crate::{ - px, AbsoluteLength, AnyElement, AppContext, Asset, AssetLogger, Bounds, DefiniteLength, - Element, ElementId, GlobalElementId, Hitbox, Image, InteractiveElement, Interactivity, - IntoElement, LayoutId, Length, ObjectFit, Pixels, RenderImage, Resource, SharedString, - SharedUri, StyleRefinement, Styled, SvgSize, Task, WindowContext, + px, swap_rgba_pa_to_bgra, AbsoluteLength, AnyElement, AppContext, Asset, AssetLogger, Bounds, + DefiniteLength, Element, ElementId, GlobalElementId, Hitbox, Image, InteractiveElement, + Interactivity, IntoElement, LayoutId, Length, ObjectFit, Pixels, RenderImage, Resource, + SharedString, SharedUri, StyleRefinement, Styled, SvgSize, Task, WindowContext, }; use anyhow::{anyhow, Result}; @@ -564,9 +564,8 @@ impl Asset for ImageAssetLoader { let mut buffer = ImageBuffer::from_raw(pixmap.width(), pixmap.height(), pixmap.take()).unwrap(); - // Convert from RGBA to BGRA. for pixel in buffer.chunks_exact_mut(4) { - pixel.swap(0, 2); + swap_rgba_pa_to_bgra(pixel); } RenderImage::new(SmallVec::from_elem(Frame::new(buffer), 1)) diff --git a/crates/gpui/src/platform/mac/text_system.rs b/crates/gpui/src/platform/mac/text_system.rs index 3db1bf9bcd52b31575915cef13f309ec3c63bc14..560c78ffb29f40406fe556908aea636d2781012a 100644 --- a/crates/gpui/src/platform/mac/text_system.rs +++ b/crates/gpui/src/platform/mac/text_system.rs @@ -1,7 +1,8 @@ use crate::{ - point, px, size, Bounds, DevicePixels, Font, FontFallbacks, FontFeatures, FontId, FontMetrics, - FontRun, FontStyle, FontWeight, GlyphId, LineLayout, Pixels, PlatformTextSystem, Point, - RenderGlyphParams, Result, ShapedGlyph, ShapedRun, SharedString, Size, SUBPIXEL_VARIANTS, + point, px, size, swap_rgba_pa_to_bgra, Bounds, DevicePixels, Font, FontFallbacks, FontFeatures, + FontId, FontMetrics, FontRun, FontStyle, FontWeight, GlyphId, LineLayout, Pixels, + PlatformTextSystem, Point, RenderGlyphParams, Result, ShapedGlyph, ShapedRun, SharedString, + Size, SUBPIXEL_VARIANTS, }; use anyhow::anyhow; use cocoa::appkit::CGFloat; @@ -418,11 +419,7 @@ impl MacTextSystemState { if params.is_emoji { // Convert from RGBA with premultiplied alpha to BGRA with straight alpha. for pixel in bytes.chunks_exact_mut(4) { - pixel.swap(0, 2); - let a = pixel[3] as f32 / 255.; - pixel[0] = (pixel[0] as f32 / a) as u8; - pixel[1] = (pixel[1] as f32 / a) as u8; - pixel[2] = (pixel[2] as f32 / a) as u8; + swap_rgba_pa_to_bgra(pixel); } }