Introduce web-colors feature flag to enable sRGB linear blending
This is how browsers perform color management. They treat gamma-corrected sRGB colors as if they were linear RGB. Correctness aside, this mode is introduced for legacy reasons. Most UI/UX tooling uses this color management as well, and many have created an intuition about how color should behave from interacting with a browser. This feature flag should facilitate application development with `iced` in those cases. More details: https://webcolorisstillbroken.com/
This commit is contained in:
parent
b5f102c558
commit
faa7627ea4
16 changed files with 99 additions and 30 deletions
|
|
@ -11,6 +11,7 @@ repository = "https://github.com/iced-rs/iced"
|
|||
geometry = ["iced_graphics/geometry", "lyon"]
|
||||
image = ["iced_graphics/image"]
|
||||
svg = ["resvg"]
|
||||
web-colors = ["iced_graphics/web-colors"]
|
||||
|
||||
[dependencies]
|
||||
wgpu = "0.16"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use crate::core;
|
||||
use crate::core::{Color, Font, Point, Size};
|
||||
use crate::graphics::backend;
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::{Primitive, Transformation, Viewport};
|
||||
use crate::quad;
|
||||
use crate::text;
|
||||
|
|
@ -239,7 +240,7 @@ impl Backend {
|
|||
load: match clear_color {
|
||||
Some(background_color) => wgpu::LoadOp::Clear({
|
||||
let [r, g, b, a] =
|
||||
background_color.into_linear();
|
||||
color::pack(background_color).components();
|
||||
|
||||
wgpu::Color {
|
||||
r: f64::from(r),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
//! Build and draw geometry.
|
||||
use crate::core::{Point, Rectangle, Size, Vector};
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::geometry::fill::{self, Fill};
|
||||
use crate::graphics::geometry::{
|
||||
LineCap, LineDash, LineJoin, Path, Stroke, Style, Text,
|
||||
|
|
@ -68,7 +69,7 @@ impl BufferStack {
|
|||
(Style::Solid(color), Buffer::Solid(buffer)) => {
|
||||
Box::new(tessellation::BuffersBuilder::new(
|
||||
buffer,
|
||||
TriangleVertex2DBuilder(color.into_linear()),
|
||||
TriangleVertex2DBuilder(color::pack(*color)),
|
||||
))
|
||||
}
|
||||
(Style::Gradient(gradient), Buffer::Gradient(buffer)) => {
|
||||
|
|
@ -91,7 +92,7 @@ impl BufferStack {
|
|||
(Style::Solid(color), Buffer::Solid(buffer)) => {
|
||||
Box::new(tessellation::BuffersBuilder::new(
|
||||
buffer,
|
||||
TriangleVertex2DBuilder(color.into_linear()),
|
||||
TriangleVertex2DBuilder(color::pack(*color)),
|
||||
))
|
||||
}
|
||||
(Style::Gradient(gradient), Buffer::Gradient(buffer)) => {
|
||||
|
|
@ -526,7 +527,7 @@ impl tessellation::StrokeVertexConstructor<primitive::GradientVertex2D>
|
|||
}
|
||||
}
|
||||
|
||||
struct TriangleVertex2DBuilder([f32; 4]);
|
||||
struct TriangleVertex2DBuilder(color::Packed);
|
||||
|
||||
impl tessellation::FillVertexConstructor<primitive::ColoredVertex2D>
|
||||
for TriangleVertex2DBuilder
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ pub use text::Text;
|
|||
use crate::core;
|
||||
use crate::core::alignment;
|
||||
use crate::core::{Color, Font, Point, Rectangle, Size, Vector};
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::{Primitive, Viewport};
|
||||
use crate::quad::{self, Quad};
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ impl<'a> Layer<'a> {
|
|||
bounds.y + translation.y,
|
||||
],
|
||||
size: [bounds.width, bounds.height],
|
||||
border_color: border_color.into_linear(),
|
||||
border_color: color::pack(*border_color),
|
||||
border_radius: *border_radius,
|
||||
border_width: *border_width,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ use gradient::Gradient;
|
|||
use solid::Solid;
|
||||
|
||||
use crate::core::{Background, Rectangle};
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::{self, Transformation};
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
|
|
@ -217,7 +218,7 @@ pub struct Quad {
|
|||
pub size: [f32; 2],
|
||||
|
||||
/// The border color of the [`Quad`], in __linear RGB__.
|
||||
pub border_color: [f32; 4],
|
||||
pub border_color: color::Packed,
|
||||
|
||||
/// The border radii of the [`Quad`].
|
||||
pub border_radius: [f32; 4],
|
||||
|
|
@ -250,7 +251,7 @@ impl Batch {
|
|||
let kind = match background {
|
||||
Background::Color(color) => {
|
||||
self.solids.push(Solid {
|
||||
color: color.into_linear(),
|
||||
color: color::pack(*color),
|
||||
quad,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
use crate::graphics::color;
|
||||
use crate::quad::{self, Quad};
|
||||
use crate::Buffer;
|
||||
|
||||
|
|
@ -9,7 +10,7 @@ use std::ops::Range;
|
|||
#[repr(C)]
|
||||
pub struct Solid {
|
||||
/// The background color data of the quad.
|
||||
pub color: [f32; 4],
|
||||
pub color: color::Packed,
|
||||
|
||||
/// The [`Quad`] data of the [`Solid`].
|
||||
pub quad: Quad,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ use crate::core::alignment;
|
|||
use crate::core::font::{self, Font};
|
||||
use crate::core::text::{Hit, LineHeight, Shaping};
|
||||
use crate::core::{Pixels, Point, Rectangle, Size};
|
||||
use crate::graphics::color;
|
||||
use crate::layer::Text;
|
||||
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
|
@ -155,7 +156,8 @@ impl Pipeline {
|
|||
bottom: (clip_bounds.y + clip_bounds.height) as i32,
|
||||
},
|
||||
default_color: {
|
||||
let [r, g, b, a] = section.color.into_linear();
|
||||
let [r, g, b, a] =
|
||||
color::pack(section.color).components();
|
||||
|
||||
glyphon::Color::rgba(
|
||||
(r * 255.0) as u8,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
//! Connect a window with a renderer.
|
||||
use crate::core::Color;
|
||||
use crate::graphics;
|
||||
use crate::graphics::color;
|
||||
use crate::graphics::compositor;
|
||||
use crate::graphics::{Error, Primitive, Viewport};
|
||||
use crate::{Backend, Renderer, Settings};
|
||||
|
|
@ -69,16 +70,19 @@ impl<Theme> Compositor<Theme> {
|
|||
let format = compatible_surface.as_ref().and_then(|surface| {
|
||||
let capabilities = surface.get_capabilities(&adapter);
|
||||
|
||||
capabilities
|
||||
.formats
|
||||
.iter()
|
||||
.copied()
|
||||
.find(wgpu::TextureFormat::is_srgb)
|
||||
.or_else(|| {
|
||||
log::warn!("No sRGB format found!");
|
||||
let mut formats = capabilities.formats.iter().copied();
|
||||
|
||||
capabilities.formats.first().copied()
|
||||
})
|
||||
let format = if color::GAMMA_CORRECTION {
|
||||
formats.find(wgpu::TextureFormat::is_srgb)
|
||||
} else {
|
||||
formats.find(|format| !wgpu::TextureFormat::is_srgb(format))
|
||||
};
|
||||
|
||||
format.or_else(|| {
|
||||
log::warn!("No format found!");
|
||||
|
||||
capabilities.formats.first().copied()
|
||||
})
|
||||
})?;
|
||||
|
||||
log::info!("Selected format: {:?}", format);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue