mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Use Rgba (4xf32) instead of Color32 in all interfaces
This simplifies a few things, but some benchmarks gets worse, probably due to the increased memory use (and thus more cache misses). I don't plan to merge this, but leave it here as an experiment
This commit is contained in:
@@ -201,6 +201,7 @@ impl Rgba {
|
||||
pub const RED: Rgba = Rgba::from_rgb(1.0, 0.0, 0.0);
|
||||
pub const GREEN: Rgba = Rgba::from_rgb(0.0, 1.0, 0.0);
|
||||
pub const BLUE: Rgba = Rgba::from_rgb(0.0, 0.0, 1.0);
|
||||
pub const LIGHT_BLUE: Rgba = Rgba::from_rgb(0.26, 0.35, 1.0);
|
||||
|
||||
#[inline(always)]
|
||||
pub const fn from_rgba_premultiplied(r: f32, g: f32, b: f32, a: f32) -> Self {
|
||||
@@ -753,10 +754,11 @@ impl From<Hsva> for HsvaGamma {
|
||||
|
||||
/// Cheap and ugly.
|
||||
/// Made for graying out disabled `Ui`:s.
|
||||
pub fn tint_color_towards(color: Color32, target: Color32) -> Color32 {
|
||||
pub fn tint_color32_towards(color: Color32, target: Color32) -> Color32 {
|
||||
let [mut r, mut g, mut b, mut a] = color.to_array();
|
||||
|
||||
if a == 0 {
|
||||
// Additive color.
|
||||
r /= 2;
|
||||
g /= 2;
|
||||
b /= 2;
|
||||
@@ -776,6 +778,11 @@ pub fn tint_color_towards(color: Color32, target: Color32) -> Color32 {
|
||||
Color32::from_rgba_premultiplied(r, g, b, a)
|
||||
}
|
||||
|
||||
pub fn tint_rgba_towards(color: Rgba, target: Rgba) -> Rgba {
|
||||
// sRGBA (gamma) is more of a perceptual color space, so we use that
|
||||
tint_color32_towards(color.into(), target.into()).into()
|
||||
}
|
||||
|
||||
#[cfg(feature = "cint")]
|
||||
mod impl_cint {
|
||||
use super::*;
|
||||
|
||||
@@ -134,7 +134,7 @@ pub(crate) struct PaintRect {
|
||||
pub rect: emath::Rect,
|
||||
/// How rounded the corners are. Use `0.0` for no rounding.
|
||||
pub corner_radius: f32,
|
||||
pub fill: Color32,
|
||||
pub fill: Rgba,
|
||||
pub stroke: Stroke,
|
||||
}
|
||||
|
||||
|
||||
@@ -9,15 +9,15 @@ use emath::*;
|
||||
pub struct Vertex {
|
||||
/// Logical pixel coordinates (points).
|
||||
/// (0,0) is the top left corner of the screen.
|
||||
pub pos: Pos2, // 64 bit
|
||||
pub pos: Pos2, // 2xf32 (64 bit)
|
||||
|
||||
/// Normalized texture coordinates.
|
||||
/// (0, 0) is the top left corner of the texture.
|
||||
/// (1, 1) is the bottom right corner of the texture.
|
||||
pub uv: Pos2, // 64 bit
|
||||
pub uv: Pos2, // 2xf32 (64 bit)
|
||||
|
||||
/// sRGBA with premultiplied alpha
|
||||
pub color: Color32, // 32 bit
|
||||
/// Linear RGBA with premultiplied alpha
|
||||
pub color: Rgba, // 4xf32 (128 bit)
|
||||
}
|
||||
|
||||
/// Textured triangles in two dimensions.
|
||||
@@ -93,7 +93,7 @@ impl Mesh {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn colored_vertex(&mut self, pos: Pos2, color: Color32) {
|
||||
pub fn colored_vertex(&mut self, pos: Pos2, color: Rgba) {
|
||||
crate::epaint_assert!(self.texture_id == TextureId::Egui);
|
||||
self.vertices.push(Vertex {
|
||||
pos,
|
||||
@@ -125,7 +125,7 @@ impl Mesh {
|
||||
}
|
||||
|
||||
/// Rectangle with a texture and color.
|
||||
pub fn add_rect_with_uv(&mut self, rect: Rect, uv: Rect, color: Color32) {
|
||||
pub fn add_rect_with_uv(&mut self, rect: Rect, uv: Rect, color: Rgba) {
|
||||
#![allow(clippy::identity_op)]
|
||||
|
||||
let idx = self.vertices.len() as u32;
|
||||
@@ -156,7 +156,7 @@ impl Mesh {
|
||||
|
||||
/// Uniformly colored rectangle.
|
||||
#[inline(always)]
|
||||
pub fn add_colored_rect(&mut self, rect: Rect, color: Color32) {
|
||||
pub fn add_colored_rect(&mut self, rect: Rect, color: Rgba) {
|
||||
crate::epaint_assert!(self.texture_id == TextureId::Egui);
|
||||
self.add_rect_with_uv(rect, [WHITE_UV, WHITE_UV].into(), color)
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pub struct Shadow {
|
||||
pub extrusion: f32,
|
||||
|
||||
/// Color of the opaque center of the shadow.
|
||||
pub color: Color32,
|
||||
pub color: Rgba,
|
||||
}
|
||||
|
||||
impl Shadow {
|
||||
@@ -18,7 +18,7 @@ impl Shadow {
|
||||
pub fn small_dark() -> Self {
|
||||
Self {
|
||||
extrusion: 16.0,
|
||||
color: Color32::from_black_alpha(96),
|
||||
color: Color32::from_black_alpha(96).into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ impl Shadow {
|
||||
pub fn small_light() -> Self {
|
||||
Self {
|
||||
extrusion: 16.0,
|
||||
color: Color32::from_black_alpha(32),
|
||||
color: Color32::from_black_alpha(32).into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ impl Shadow {
|
||||
pub fn big_dark() -> Self {
|
||||
Self {
|
||||
extrusion: 32.0,
|
||||
color: Color32::from_black_alpha(96),
|
||||
color: Color32::from_black_alpha(96).into(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ impl Shadow {
|
||||
pub fn big_light() -> Self {
|
||||
Self {
|
||||
extrusion: 32.0,
|
||||
color: Color32::from_black_alpha(40),
|
||||
color: Color32::from_black_alpha(40).into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
text::{Fonts, Galley, TextStyle},
|
||||
Color32, Mesh, Stroke,
|
||||
Mesh, Rgba, Stroke,
|
||||
};
|
||||
use emath::*;
|
||||
|
||||
@@ -17,7 +17,7 @@ pub enum Shape {
|
||||
Circle {
|
||||
center: Pos2,
|
||||
radius: f32,
|
||||
fill: Color32,
|
||||
fill: Rgba,
|
||||
stroke: Stroke,
|
||||
},
|
||||
LineSegment {
|
||||
@@ -30,14 +30,14 @@ pub enum Shape {
|
||||
/// This is required if `fill != TRANSPARENT`.
|
||||
closed: bool,
|
||||
/// Fill is only supported for convex polygons.
|
||||
fill: Color32,
|
||||
fill: Rgba,
|
||||
stroke: Stroke,
|
||||
},
|
||||
Rect {
|
||||
rect: Rect,
|
||||
/// How rounded the corners are. Use `0.0` for no rounding.
|
||||
corner_radius: f32,
|
||||
fill: Color32,
|
||||
fill: Rgba,
|
||||
stroke: Stroke,
|
||||
},
|
||||
Text {
|
||||
@@ -46,7 +46,7 @@ pub enum Shape {
|
||||
/// The layed out text.
|
||||
galley: std::sync::Arc<Galley>,
|
||||
/// Text color (foreground).
|
||||
color: Color32,
|
||||
color: Rgba,
|
||||
/// If true, tilt the letters for a hacky italics effect.
|
||||
fake_italics: bool,
|
||||
},
|
||||
@@ -89,7 +89,7 @@ impl Shape {
|
||||
/// Turn a line into equally spaced dots.
|
||||
pub fn dotted_line(
|
||||
points: &[Pos2],
|
||||
color: impl Into<Color32>,
|
||||
color: impl Into<Rgba>,
|
||||
spacing: f32,
|
||||
radius: f32,
|
||||
) -> Vec<Self> {
|
||||
@@ -113,7 +113,7 @@ impl Shape {
|
||||
/// A convex polygon with a fill and optional stroke.
|
||||
pub fn convex_polygon(
|
||||
points: Vec<Pos2>,
|
||||
fill: impl Into<Color32>,
|
||||
fill: impl Into<Rgba>,
|
||||
stroke: impl Into<Stroke>,
|
||||
) -> Self {
|
||||
Self::Path {
|
||||
@@ -125,11 +125,11 @@ impl Shape {
|
||||
}
|
||||
|
||||
#[deprecated = "Renamed convex_polygon"]
|
||||
pub fn polygon(points: Vec<Pos2>, fill: impl Into<Color32>, stroke: impl Into<Stroke>) -> Self {
|
||||
pub fn polygon(points: Vec<Pos2>, fill: impl Into<Rgba>, stroke: impl Into<Stroke>) -> Self {
|
||||
Self::convex_polygon(points, fill, stroke)
|
||||
}
|
||||
|
||||
pub fn circle_filled(center: Pos2, radius: f32, fill_color: impl Into<Color32>) -> Self {
|
||||
pub fn circle_filled(center: Pos2, radius: f32, fill_color: impl Into<Rgba>) -> Self {
|
||||
Self::Circle {
|
||||
center,
|
||||
radius,
|
||||
@@ -147,7 +147,7 @@ impl Shape {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rect_filled(rect: Rect, corner_radius: f32, fill_color: impl Into<Color32>) -> Self {
|
||||
pub fn rect_filled(rect: Rect, corner_radius: f32, fill_color: impl Into<Rgba>) -> Self {
|
||||
Self::Rect {
|
||||
rect,
|
||||
corner_radius,
|
||||
@@ -172,7 +172,7 @@ impl Shape {
|
||||
anchor: Align2,
|
||||
text: impl ToString,
|
||||
text_style: TextStyle,
|
||||
color: Color32,
|
||||
color: Rgba,
|
||||
) -> Self {
|
||||
let galley = fonts.layout_multiline(text_style, text.to_string(), f32::INFINITY);
|
||||
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||
@@ -190,7 +190,7 @@ fn points_from_line(
|
||||
line: &[Pos2],
|
||||
spacing: f32,
|
||||
radius: f32,
|
||||
color: Color32,
|
||||
color: Rgba,
|
||||
shapes: &mut Vec<Shape>,
|
||||
) {
|
||||
let mut position_on_segment = 0.0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::*;
|
||||
|
||||
pub fn adjust_colors(shape: &mut Shape, adjust_color: &impl Fn(&mut Color32)) {
|
||||
pub fn adjust_colors(shape: &mut Shape, adjust_color: &impl Fn(&mut Rgba)) {
|
||||
#![allow(clippy::match_same_arms)]
|
||||
match shape {
|
||||
Shape::Noop => {}
|
||||
|
||||
@@ -7,16 +7,16 @@ use super::*;
|
||||
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct Stroke {
|
||||
pub width: f32,
|
||||
pub color: Color32,
|
||||
pub color: Rgba,
|
||||
}
|
||||
|
||||
impl Stroke {
|
||||
/// Same as [`Stroke::default`].
|
||||
pub fn none() -> Self {
|
||||
Self::new(0.0, Color32::TRANSPARENT)
|
||||
Self::new(0.0, Rgba::TRANSPARENT)
|
||||
}
|
||||
|
||||
pub fn new(width: impl Into<f32>, color: impl Into<Color32>) -> Self {
|
||||
pub fn new(width: impl Into<f32>, color: impl Into<Rgba>) -> Self {
|
||||
Self {
|
||||
width: width.into(),
|
||||
color: color.into(),
|
||||
@@ -26,7 +26,7 @@ impl Stroke {
|
||||
|
||||
impl<Color> From<(f32, Color)> for Stroke
|
||||
where
|
||||
Color: Into<Color32>,
|
||||
Color: Into<Rgba>,
|
||||
{
|
||||
fn from((width, color): (f32, Color)) -> Stroke {
|
||||
Stroke::new(width, color)
|
||||
|
||||
@@ -272,13 +272,8 @@ impl TessellationOptions {
|
||||
}
|
||||
|
||||
/// Tessellate the given convex area into a polygon.
|
||||
fn fill_closed_path(
|
||||
path: &[PathPoint],
|
||||
color: Color32,
|
||||
options: TessellationOptions,
|
||||
out: &mut Mesh,
|
||||
) {
|
||||
if color == Color32::TRANSPARENT {
|
||||
fn fill_closed_path(path: &[PathPoint], color: Rgba, options: TessellationOptions, out: &mut Mesh) {
|
||||
if color == Rgba::TRANSPARENT {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -286,7 +281,7 @@ fn fill_closed_path(
|
||||
if options.anti_alias {
|
||||
out.reserve_triangles(3 * n as usize);
|
||||
out.reserve_vertices(2 * n as usize);
|
||||
let color_outer = Color32::TRANSPARENT;
|
||||
let color_outer = Rgba::TRANSPARENT;
|
||||
let idx_inner = out.vertices.len() as u32;
|
||||
let idx_outer = idx_inner + 1;
|
||||
for i in 2..n {
|
||||
@@ -324,7 +319,7 @@ fn stroke_path(
|
||||
options: TessellationOptions,
|
||||
out: &mut Mesh,
|
||||
) {
|
||||
if stroke.width <= 0.0 || stroke.color == Color32::TRANSPARENT {
|
||||
if stroke.width <= 0.0 || stroke.color == Rgba::TRANSPARENT {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -333,7 +328,7 @@ fn stroke_path(
|
||||
|
||||
if options.anti_alias {
|
||||
let color_inner = stroke.color;
|
||||
let color_outer = Color32::TRANSPARENT;
|
||||
let color_outer = Rgba::TRANSPARENT;
|
||||
|
||||
let thin_line = stroke.width <= options.aa_size;
|
||||
if thin_line {
|
||||
@@ -346,7 +341,7 @@ fn stroke_path(
|
||||
|
||||
// Fade out as it gets thinner:
|
||||
let color_inner = mul_color(color_inner, stroke.width / options.aa_size);
|
||||
if color_inner == Color32::TRANSPARENT {
|
||||
if color_inner == Rgba::TRANSPARENT {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -438,7 +433,7 @@ fn stroke_path(
|
||||
// Fade out thin lines rather than making them thinner
|
||||
let radius = options.aa_size / 2.0;
|
||||
let color = mul_color(stroke.color, stroke.width / options.aa_size);
|
||||
if color == Color32::TRANSPARENT {
|
||||
if color == Rgba::TRANSPARENT {
|
||||
return;
|
||||
}
|
||||
for p in path {
|
||||
@@ -455,11 +450,10 @@ fn stroke_path(
|
||||
}
|
||||
}
|
||||
|
||||
fn mul_color(color: Color32, factor: f32) -> Color32 {
|
||||
#[inline]
|
||||
fn mul_color(color: Rgba, factor: f32) -> Rgba {
|
||||
crate::epaint_assert!(0.0 <= factor && factor <= 1.0);
|
||||
// As an unfortunate side-effect of using premultiplied alpha
|
||||
// we need a somewhat expensive conversion to linear space and back.
|
||||
color.linear_multiply(factor)
|
||||
color * factor
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@@ -552,7 +546,7 @@ impl Tessellator {
|
||||
path.add_open_points(&points);
|
||||
}
|
||||
|
||||
if fill != Color32::TRANSPARENT {
|
||||
if fill != Rgba::TRANSPARENT {
|
||||
crate::epaint_assert!(
|
||||
closed,
|
||||
"You asked to fill a path that is not closed. That makes no sense."
|
||||
@@ -634,11 +628,11 @@ impl Tessellator {
|
||||
tex_size: [usize; 2],
|
||||
pos: Pos2,
|
||||
galley: &super::Galley,
|
||||
color: Color32,
|
||||
color: Rgba,
|
||||
fake_italics: bool,
|
||||
out: &mut Mesh,
|
||||
) {
|
||||
if color == Color32::TRANSPARENT || galley.is_empty() {
|
||||
if color == Rgba::TRANSPARENT || galley.is_empty() {
|
||||
return;
|
||||
}
|
||||
if cfg!(any(
|
||||
|
||||
Reference in New Issue
Block a user