summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml2
-rw-r--r--examples/geometry/src/main.rs19
-rw-r--r--graphics/Cargo.toml1
-rw-r--r--graphics/src/color.rs46
-rw-r--r--graphics/src/gradient.rs8
-rw-r--r--graphics/src/lib.rs1
-rw-r--r--graphics/src/primitive.rs3
-rw-r--r--renderer/Cargo.toml1
-rw-r--r--wgpu/Cargo.toml1
-rw-r--r--wgpu/src/backend.rs3
-rw-r--r--wgpu/src/geometry.rs7
-rw-r--r--wgpu/src/layer.rs3
-rw-r--r--wgpu/src/quad.rs5
-rw-r--r--wgpu/src/quad/solid.rs3
-rw-r--r--wgpu/src/text.rs4
-rw-r--r--wgpu/src/window/compositor.rs22
16 files changed, 99 insertions, 30 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 479830ac..070cd0ce 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -37,6 +37,8 @@ smol = ["iced_futures/smol"]
palette = ["iced_core/palette"]
# Enables querying system information
system = ["iced_winit/system"]
+# Enables broken "sRGB linear" blending to reproduce color management of the Web
+web-colors = ["iced_renderer/web-colors"]
# Enables the advanced module
advanced = []
diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs
index 5cb41184..a4183db9 100644
--- a/examples/geometry/src/main.rs
+++ b/examples/geometry/src/main.rs
@@ -3,6 +3,7 @@
mod rainbow {
use iced_graphics::primitive::{ColoredVertex2D, Primitive};
+ use iced::advanced::graphics::color;
use iced::advanced::layout::{self, Layout};
use iced::advanced::renderer;
use iced::advanced::widget::{self, Widget};
@@ -84,39 +85,39 @@ mod rainbow {
vertices: vec![
ColoredVertex2D {
position: posn_center,
- color: [1.0, 1.0, 1.0, 1.0],
+ color: color::pack([1.0, 1.0, 1.0, 1.0]),
},
ColoredVertex2D {
position: posn_tl,
- color: color_r,
+ color: color::pack(color_r),
},
ColoredVertex2D {
position: posn_t,
- color: color_o,
+ color: color::pack(color_o),
},
ColoredVertex2D {
position: posn_tr,
- color: color_y,
+ color: color::pack(color_y),
},
ColoredVertex2D {
position: posn_r,
- color: color_g,
+ color: color::pack(color_g),
},
ColoredVertex2D {
position: posn_br,
- color: color_gb,
+ color: color::pack(color_gb),
},
ColoredVertex2D {
position: posn_b,
- color: color_b,
+ color: color::pack(color_b),
},
ColoredVertex2D {
position: posn_bl,
- color: color_i,
+ color: color::pack(color_i),
},
ColoredVertex2D {
position: posn_l,
- color: color_v,
+ color: color::pack(color_v),
},
],
indices: vec![
diff --git a/graphics/Cargo.toml b/graphics/Cargo.toml
index 903a2069..0e22227d 100644
--- a/graphics/Cargo.toml
+++ b/graphics/Cargo.toml
@@ -14,6 +14,7 @@ categories = ["gui"]
geometry = ["lyon_path"]
opengl = []
image = ["dep:image", "kamadak-exif"]
+web-colors = []
[dependencies]
glam = "0.24"
diff --git a/graphics/src/color.rs b/graphics/src/color.rs
new file mode 100644
index 00000000..92448a68
--- /dev/null
+++ b/graphics/src/color.rs
@@ -0,0 +1,46 @@
+//! Manage colors for shaders.
+use crate::core::Color;
+
+use bytemuck::{Pod, Zeroable};
+
+/// A color packed as 4 floats representing RGBA channels.
+#[derive(Debug, Clone, Copy, PartialEq, Zeroable, Pod)]
+#[repr(C)]
+pub struct Packed([f32; 4]);
+
+impl Packed {
+ /// Returns the internal components of the [`Packed`] color.
+ pub fn components(self) -> [f32; 4] {
+ self.0
+ }
+}
+
+/// A flag that indicates whether the renderer should perform gamma correction.
+pub const GAMMA_CORRECTION: bool = internal::GAMMA_CORRECTION;
+
+/// Packs a [`Color`].
+pub fn pack(color: impl Into<Color>) -> Packed {
+ Packed(internal::pack(color.into()))
+}
+
+#[cfg(not(feature = "web-colors"))]
+mod internal {
+ use crate::core::Color;
+
+ pub const GAMMA_CORRECTION: bool = true;
+
+ pub fn pack(color: Color) -> [f32; 4] {
+ color.into_linear()
+ }
+}
+
+#[cfg(feature = "web-colors")]
+mod internal {
+ use crate::core::Color;
+
+ pub const GAMMA_CORRECTION: bool = false;
+
+ pub fn pack(color: Color) -> [f32; 4] {
+ [color.r, color.g, color.b, color.a]
+ }
+}
diff --git a/graphics/src/gradient.rs b/graphics/src/gradient.rs
index d3eabb6f..d26b5665 100644
--- a/graphics/src/gradient.rs
+++ b/graphics/src/gradient.rs
@@ -3,8 +3,10 @@
//! For a gradient that you can use as a background variant for a widget, see [`Gradient`].
//!
//! [`Gradient`]: crate::core::Gradient;
+use crate::color;
use crate::core::gradient::ColorStop;
use crate::core::{self, Color, Point, Rectangle};
+
use std::cmp::Ordering;
#[derive(Debug, Clone, PartialEq)]
@@ -101,7 +103,8 @@ impl Linear {
for (index, stop) in self.stops.iter().enumerate() {
let [r, g, b, a] =
- stop.map_or(Color::default(), |s| s.color).into_linear();
+ color::pack(stop.map_or(Color::default(), |s| s.color))
+ .components();
data[index * 4] = r;
data[(index * 4) + 1] = g;
@@ -133,7 +136,8 @@ pub fn pack(gradient: &core::Gradient, bounds: Rectangle) -> Packed {
for (index, stop) in linear.stops.iter().enumerate() {
let [r, g, b, a] =
- stop.map_or(Color::default(), |s| s.color).into_linear();
+ color::pack(stop.map_or(Color::default(), |s| s.color))
+ .components();
data[index * 4] = r;
data[(index * 4) + 1] = g;
diff --git a/graphics/src/lib.rs b/graphics/src/lib.rs
index bfaac19f..f6bc87fb 100644
--- a/graphics/src/lib.rs
+++ b/graphics/src/lib.rs
@@ -27,6 +27,7 @@ mod transformation;
mod viewport;
pub mod backend;
+pub mod color;
pub mod compositor;
pub mod damage;
pub mod gradient;
diff --git a/graphics/src/primitive.rs b/graphics/src/primitive.rs
index 2d4f5511..187c6c6c 100644
--- a/graphics/src/primitive.rs
+++ b/graphics/src/primitive.rs
@@ -1,4 +1,5 @@
//! Draw using different graphical primitives.
+use crate::color;
use crate::core::alignment;
use crate::core::image;
use crate::core::svg;
@@ -248,7 +249,7 @@ pub struct ColoredVertex2D {
pub position: [f32; 2],
/// The color of the vertex in __linear__ RGBA.
- pub color: [f32; 4],
+ pub color: color::Packed,
}
/// A vertex which contains 2D position & packed gradient data.
diff --git a/renderer/Cargo.toml b/renderer/Cargo.toml
index 640ac996..ddfb6445 100644
--- a/renderer/Cargo.toml
+++ b/renderer/Cargo.toml
@@ -9,6 +9,7 @@ image = ["iced_tiny_skia/image", "iced_wgpu?/image"]
svg = ["iced_tiny_skia/svg", "iced_wgpu?/svg"]
geometry = ["iced_graphics/geometry", "iced_tiny_skia/geometry", "iced_wgpu?/geometry"]
tracing = ["iced_wgpu?/tracing"]
+web-colors = ["iced_wgpu?/web-colors"]
[dependencies]
raw-window-handle = "0.5"
diff --git a/wgpu/Cargo.toml b/wgpu/Cargo.toml
index b5401626..badd165b 100644
--- a/wgpu/Cargo.toml
+++ b/wgpu/Cargo.toml
@@ -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"
diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs
index 844987f2..b524c615 100644
--- a/wgpu/src/backend.rs
+++ b/wgpu/src/backend.rs
@@ -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),
diff --git a/wgpu/src/geometry.rs b/wgpu/src/geometry.rs
index 740ec20c..f81b5b2f 100644
--- a/wgpu/src/geometry.rs
+++ b/wgpu/src/geometry.rs
@@ -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
diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs
index 1a870c15..71570e3d 100644
--- a/wgpu/src/layer.rs
+++ b/wgpu/src/layer.rs
@@ -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,
};
diff --git a/wgpu/src/quad.rs b/wgpu/src/quad.rs
index 9c5ed05f..37d0c623 100644
--- a/wgpu/src/quad.rs
+++ b/wgpu/src/quad.rs
@@ -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,
});
diff --git a/wgpu/src/quad/solid.rs b/wgpu/src/quad/solid.rs
index f667c42c..f8f1e3a5 100644
--- a/wgpu/src/quad/solid.rs
+++ b/wgpu/src/quad/solid.rs
@@ -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,
diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs
index 714e0400..a12bc9f7 100644
--- a/wgpu/src/text.rs
+++ b/wgpu/src/text.rs
@@ -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,
diff --git a/wgpu/src/window/compositor.rs b/wgpu/src/window/compositor.rs
index 500458e8..2eaafde0 100644
--- a/wgpu/src/window/compositor.rs
+++ b/wgpu/src/window/compositor.rs
@@ -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);