diff options
author | 2023-09-19 23:00:20 +0200 | |
---|---|---|
committer | 2023-09-19 23:00:20 +0200 | |
commit | be340a8cd822be1ea0fe4c1b1f3a62ca66d705b4 (patch) | |
tree | 38f6d1dc01bc3c32859b46b20e136daa0f90754e | |
parent | 9af0a27e675b71164f32f8d82eb4cde9cdd459f3 (diff) | |
download | iced-be340a8cd822be1ea0fe4c1b1f3a62ca66d705b4.tar.gz iced-be340a8cd822be1ea0fe4c1b1f3a62ca66d705b4.tar.bz2 iced-be340a8cd822be1ea0fe4c1b1f3a62ca66d705b4.zip |
Fix gamma correction for colored glyphs in `iced_wgpu`
-rw-r--r-- | core/src/color.rs | 20 | ||||
-rw-r--r-- | graphics/src/text.rs | 12 | ||||
-rw-r--r-- | tiny_skia/src/text.rs | 14 | ||||
-rw-r--r-- | wgpu/src/text.rs | 13 |
4 files changed, 44 insertions, 15 deletions
diff --git a/core/src/color.rs b/core/src/color.rs index 1392f28b..cce8b340 100644 --- a/core/src/color.rs +++ b/core/src/color.rs @@ -89,6 +89,26 @@ impl Color { } } + /// Creates a [`Color`] from its linear RGBA components. + pub fn from_linear_rgba(r: f32, g: f32, b: f32, a: f32) -> Self { + // As described in: + // https://en.wikipedia.org/wiki/SRGB + fn gamma_component(u: f32) -> f32 { + if u < 0.0031308 { + 12.92 * u + } else { + 1.055 * u.powf(1.0 / 2.4) - 0.055 + } + } + + Self { + r: gamma_component(r), + g: gamma_component(g), + b: gamma_component(b), + a, + } + } + /// Converts the [`Color`] into its RGBA8 equivalent. #[must_use] pub fn into_rgba8(self) -> [u8; 4] { diff --git a/graphics/src/text.rs b/graphics/src/text.rs index 5fcfc699..c10eacad 100644 --- a/graphics/src/text.rs +++ b/graphics/src/text.rs @@ -8,6 +8,7 @@ pub use paragraph::Paragraph; pub use cosmic_text; +use crate::color; use crate::core::font::{self, Font}; use crate::core::text::Shaping; use crate::core::{Color, Size}; @@ -131,7 +132,12 @@ pub fn to_shaping(shaping: Shaping) -> cosmic_text::Shaping { } pub fn to_color(color: Color) -> cosmic_text::Color { - let [r, g, b, a] = color.into_rgba8(); - - cosmic_text::Color::rgba(r, g, b, a) + let [r, g, b, a] = color::pack(color).components(); + + cosmic_text::Color::rgba( + (r * 255.0) as u8, + (g * 255.0) as u8, + (b * 255.0) as u8, + (a * 255.0) as u8, + ) } diff --git a/tiny_skia/src/text.rs b/tiny_skia/src/text.rs index d1b33293..70e95d01 100644 --- a/tiny_skia/src/text.rs +++ b/tiny_skia/src/text.rs @@ -1,6 +1,7 @@ use crate::core::alignment; use crate::core::text::{LineHeight, Shaping}; use crate::core::{Color, Font, Pixels, Point, Rectangle}; +use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; use crate::graphics::text::editor; use crate::graphics::text::font_system; @@ -216,7 +217,18 @@ fn draw( fn from_color(color: cosmic_text::Color) -> Color { let [r, g, b, a] = color.as_rgba(); - Color::from_rgba8(r, g, b, a as f32 / 255.0) + if color::GAMMA_CORRECTION { + // `cosmic_text::Color` is linear RGB in this case, so we + // need to convert back to sRGB + Color::from_linear_rgba( + r as f32 / 255.0, + g as f32 / 255.0, + b as f32 / 255.0, + a as f32 / 255.0, + ) + } else { + Color::from_rgba8(r, g, b, a as f32 / 255.0) + } } #[derive(Debug, Clone, Default)] diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index 581df0cb..f746be63 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -2,7 +2,7 @@ use crate::core::alignment; use crate::core::{Rectangle, Size}; use crate::graphics::color; use crate::graphics::text::cache::{self, Cache}; -use crate::graphics::text::{font_system, Editor, Paragraph}; +use crate::graphics::text::{font_system, to_color, Editor, Paragraph}; use crate::layer::Text; use std::borrow::Cow; @@ -214,16 +214,7 @@ impl Pipeline { right: (clip_bounds.x + clip_bounds.width) as i32, bottom: (clip_bounds.y + clip_bounds.height) as i32, }, - default_color: { - let [r, g, b, a] = color::pack(color).components(); - - glyphon::Color::rgba( - (r * 255.0) as u8, - (g * 255.0) as u8, - (b * 255.0) as u8, - (a * 255.0) as u8, - ) - }, + default_color: to_color(color), }) }, ); |