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:
Emil Ernerfeldt 2021-08-15 20:15:14 +02:00
parent 96c45716be
commit 5dd68337c4
42 changed files with 285 additions and 371 deletions

View file

@ -11,7 +11,7 @@ pub struct Frame {
pub margin: Vec2,
pub corner_radius: f32,
pub shadow: Shadow,
pub fill: Color32,
pub fill: Rgba,
pub stroke: Stroke,
}
@ -85,7 +85,7 @@ impl Frame {
Self {
margin: Vec2::new(10.0, 10.0),
corner_radius: style.visuals.widgets.noninteractive.corner_radius,
fill: Color32::from_black_alpha(250),
fill: Color32::from_black_alpha(250).into(),
stroke: style.visuals.window_stroke(),
..Default::default()
}
@ -93,7 +93,7 @@ impl Frame {
}
impl Frame {
pub fn fill(mut self, fill: Color32) -> Self {
pub fn fill(mut self, fill: Rgba) -> Self {
self.fill = fill;
self
}
@ -120,9 +120,9 @@ impl Frame {
}
pub fn multiply_with_opacity(mut self, opacity: f32) -> Self {
self.fill = self.fill.linear_multiply(opacity);
self.stroke.color = self.stroke.color.linear_multiply(opacity);
self.shadow.color = self.shadow.color.linear_multiply(opacity);
self.fill = self.fill * opacity;
self.stroke.color = self.stroke.color * opacity;
self.shadow.color = self.shadow.color * opacity;
self
}
}

View file

@ -303,12 +303,12 @@ impl Resize {
if ui.ctx().style().debug.show_resize {
ui.ctx().debug_painter().debug_rect(
Rect::from_min_size(content_ui.min_rect().left_top(), state.desired_size),
Color32::GREEN,
Rgba::GREEN,
"desired_size",
);
ui.ctx().debug_painter().debug_rect(
Rect::from_min_size(content_ui.min_rect().left_top(), state.last_content_size),
Color32::LIGHT_BLUE,
Rgba::LIGHT_BLUE,
"last_content_size",
);
}

View file

@ -888,7 +888,7 @@ impl Context {
{
ui.ctx()
.debug_painter()
.debug_rect(area.rect(), Color32::RED, "");
.debug_rect(area.rect(), Rgba::RED, "");
}
}
}

View file

@ -20,11 +20,7 @@ impl Widget for &epaint::Texture {
}
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
let mut mesh = Mesh::default();
mesh.add_rect_with_uv(
rect,
[pos2(0.0, 0.0), pos2(1.0, 1.0)].into(),
Color32::WHITE,
);
mesh.add_rect_with_uv(rect, [pos2(0.0, 0.0), pos2(1.0, 1.0)].into(), Rgba::WHITE);
ui.painter().add(Shape::mesh(mesh));
let (tex_w, tex_h) = (self.width as f32, self.height as f32);
@ -46,7 +42,7 @@ impl Widget for &epaint::Texture {
pos2((u + texel_radius) / tex_w, (v + texel_radius) / tex_h),
);
let mut mesh = Mesh::default();
mesh.add_rect_with_uv(zoom_rect, uv_rect, Color32::WHITE);
mesh.add_rect_with_uv(zoom_rect, uv_rect, Rgba::WHITE);
ui.painter().add(Shape::mesh(mesh));
}
});

View file

@ -43,11 +43,11 @@ pub fn bar<R>(ui: &mut Ui, add_contents: impl FnOnce(&mut Ui) -> R) -> InnerResp
ui.horizontal(|ui| {
let mut style = (**ui.style()).clone();
style.spacing.button_padding = vec2(2.0, 0.0);
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
// style.visuals.widgets.active.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.active.bg_stroke = Stroke::none();
// style.visuals.widgets.hovered.bg_fill = Color32::TRANSPARENT;
// style.visuals.widgets.hovered.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.hovered.bg_stroke = Stroke::none();
style.visuals.widgets.inactive.bg_fill = Color32::TRANSPARENT;
style.visuals.widgets.inactive.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.inactive.bg_stroke = Stroke::none();
ui.set_style(style);
@ -114,11 +114,11 @@ fn menu_impl<'c, R>(
.show(ui, |ui| {
let mut style = (**ui.style()).clone();
style.spacing.button_padding = vec2(2.0, 0.0);
// style.visuals.widgets.active.bg_fill = Color32::TRANSPARENT;
// style.visuals.widgets.active.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.active.bg_stroke = Stroke::none();
// style.visuals.widgets.hovered.bg_fill = Color32::TRANSPARENT;
// style.visuals.widgets.hovered.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.hovered.bg_stroke = Stroke::none();
style.visuals.widgets.inactive.bg_fill = Color32::TRANSPARENT;
style.visuals.widgets.inactive.bg_fill = Rgba::TRANSPARENT;
style.visuals.widgets.inactive.bg_stroke = Stroke::none();
ui.set_style(style);
ui.with_layout(Layout::top_down_justified(Align::LEFT), add_contents)

View file

@ -1,7 +1,7 @@
use crate::{
emath::{Align2, Pos2, Rect, Vec2},
layers::{LayerId, PaintList, ShapeIdx},
Color32, CtxRef,
Color32, CtxRef, Rgba,
};
use epaint::{
mutex::Mutex,
@ -28,7 +28,7 @@ pub struct Painter {
/// If set, all shapes will have their colors modified to be closer to this.
/// This is used to implement grayed out interfaces.
fade_to_color: Option<Color32>,
fade_to_color: Option<Rgba>,
}
impl Painter {
@ -62,17 +62,17 @@ impl Painter {
}
/// If set, colors will be modified to look like this
pub(crate) fn set_fade_to_color(&mut self, fade_to_color: Option<Color32>) {
pub(crate) fn set_fade_to_color(&mut self, fade_to_color: Option<Rgba>) {
self.fade_to_color = fade_to_color;
}
pub(crate) fn visible(&self) -> bool {
self.fade_to_color != Some(Color32::TRANSPARENT)
self.fade_to_color != Some(Rgba::TRANSPARENT)
}
/// If `false`, nothing added to the painter will be visible
pub(crate) fn set_invisible(&mut self) {
self.fade_to_color = Some(Color32::TRANSPARENT)
self.fade_to_color = Some(Rgba::TRANSPARENT)
}
/// Create a painter for a sub-region of this `Painter`.
@ -155,7 +155,7 @@ impl Painter {
/// Can be used for free painting.
/// NOTE: all coordinates are screen coordinates!
pub fn add(&self, mut shape: Shape) -> ShapeIdx {
if self.fade_to_color == Some(Color32::TRANSPARENT) {
if self.fade_to_color == Some(Rgba::TRANSPARENT) {
self.paint_list.lock().add(self.clip_rect, Shape::Noop)
} else {
self.transform_shape(&mut shape);
@ -167,7 +167,7 @@ impl Painter {
///
/// Calling this once is generally faster than calling [`Self::add`] multiple times.
pub fn extend(&self, mut shapes: Vec<Shape>) {
if self.fade_to_color == Some(Color32::TRANSPARENT) {
if self.fade_to_color == Some(Rgba::TRANSPARENT) {
return;
}
if !shapes.is_empty() {
@ -183,7 +183,7 @@ impl Painter {
/// Modify an existing [`Shape`].
pub fn set(&self, idx: ShapeIdx, mut shape: Shape) {
if self.fade_to_color == Some(Color32::TRANSPARENT) {
if self.fade_to_color == Some(Rgba::TRANSPARENT) {
return;
}
self.transform_shape(&mut shape);
@ -194,7 +194,7 @@ impl Painter {
/// ## Debug painting
impl Painter {
#[allow(clippy::needless_pass_by_value)]
pub fn debug_rect(&mut self, rect: Rect, color: Color32, text: impl ToString) {
pub fn debug_rect(&mut self, rect: Rect, color: Rgba, text: impl ToString) {
self.rect_stroke(rect, 0.0, (1.0, color));
let text_style = TextStyle::Monospace;
self.text(
@ -207,18 +207,12 @@ impl Painter {
}
pub fn error(&self, pos: Pos2, text: impl std::fmt::Display) -> Rect {
self.debug_text(pos, Align2::LEFT_TOP, Color32::RED, format!("🔥 {}", text))
self.debug_text(pos, Align2::LEFT_TOP, Rgba::RED, format!("🔥 {}", text))
}
/// text with a background
#[allow(clippy::needless_pass_by_value)]
pub fn debug_text(
&self,
pos: Pos2,
anchor: Align2,
color: Color32,
text: impl ToString,
) -> Rect {
pub fn debug_text(&self, pos: Pos2, anchor: Align2, color: Rgba, text: impl ToString) -> Rect {
let galley = self
.fonts()
.layout_no_wrap(TextStyle::Monospace, text.to_string());
@ -227,7 +221,7 @@ impl Painter {
self.add(Shape::Rect {
rect: frame_rect,
corner_radius: 0.0,
fill: Color32::from_black_alpha(240),
fill: Color32::from_black_alpha(240).into(),
// stroke: Stroke::new(1.0, color),
stroke: Default::default(),
});
@ -249,7 +243,7 @@ impl Painter {
&self,
center: Pos2,
radius: f32,
fill_color: impl Into<Color32>,
fill_color: impl Into<Rgba>,
stroke: impl Into<Stroke>,
) {
self.add(Shape::Circle {
@ -260,7 +254,7 @@ impl Painter {
});
}
pub fn circle_filled(&self, center: Pos2, radius: f32, fill_color: impl Into<Color32>) {
pub fn circle_filled(&self, center: Pos2, radius: f32, fill_color: impl Into<Rgba>) {
self.add(Shape::Circle {
center,
radius,
@ -282,7 +276,7 @@ impl Painter {
&self,
rect: Rect,
corner_radius: f32,
fill_color: impl Into<Color32>,
fill_color: impl Into<Rgba>,
stroke: impl Into<Stroke>,
) {
self.add(Shape::Rect {
@ -293,7 +287,7 @@ impl Painter {
});
}
pub fn rect_filled(&self, rect: Rect, corner_radius: f32, fill_color: impl Into<Color32>) {
pub fn rect_filled(&self, rect: Rect, corner_radius: f32, fill_color: impl Into<Rgba>) {
self.add(Shape::Rect {
rect,
corner_radius,
@ -341,7 +335,7 @@ impl Painter {
anchor: Align2,
text: impl ToString,
text_style: TextStyle,
text_color: Color32,
text_color: Rgba,
) -> Rect {
let galley = self.layout_no_wrap(text_style, text.to_string());
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size));
@ -377,7 +371,7 @@ impl Painter {
///
/// You can create the `Galley` with [`Self::layout_no_wrap`] or [`Self::layout_multiline`].
#[inline(always)]
pub fn galley(&self, pos: Pos2, galley: std::sync::Arc<Galley>, color: Color32) {
pub fn galley(&self, pos: Pos2, galley: std::sync::Arc<Galley>, color: Rgba) {
self.galley_with_italics(pos, galley, color, false)
}
@ -385,7 +379,7 @@ impl Painter {
&self,
pos: Pos2,
galley: std::sync::Arc<Galley>,
color: Color32,
color: Rgba,
fake_italics: bool,
) {
if !galley.is_empty() {
@ -399,8 +393,8 @@ impl Painter {
}
}
fn tint_shape_towards(shape: &mut Shape, target: Color32) {
fn tint_shape_towards(shape: &mut Shape, target: Rgba) {
epaint::shape_transform::adjust_colors(shape, &|color| {
*color = crate::color::tint_color_towards(*color, target);
*color = crate::color::tint_rgba_towards(*color, target);
});
}

View file

@ -189,7 +189,7 @@ pub struct Visuals {
/// so that `visuals.text_color` is always used,
/// but its alpha may be different based on whether or not
/// it is disabled, non-interactive, hovered etc.
pub override_text_color: Option<Color32>,
pub override_text_color: Option<Rgba>,
/// Visual styles of widgets
pub widgets: Widgets,
@ -197,19 +197,19 @@ pub struct Visuals {
pub selection: Selection,
/// The color used for `Hyperlink`,
pub hyperlink_color: Color32,
pub hyperlink_color: Rgba,
/// Something just barely different from the background color.
/// Used for [`crate::Grid::striped`].
pub faint_bg_color: Color32,
pub faint_bg_color: Rgba,
/// Very dark or light color (for corresponding theme).
/// Used as the background of text edits, scroll bars and others things
/// that needs to look different from other interactive stuff.
pub extreme_bg_color: Color32,
pub extreme_bg_color: Rgba,
/// Background color behind code-styled monospaced labels.
pub code_bg_color: Color32,
pub code_bg_color: Rgba,
pub window_corner_radius: f32,
pub window_shadow: Shadow,
@ -237,20 +237,20 @@ impl Visuals {
&self.widgets.noninteractive
}
pub fn text_color(&self) -> Color32 {
pub fn text_color(&self) -> Rgba {
self.override_text_color
.unwrap_or_else(|| self.widgets.noninteractive.text_color())
}
pub fn weak_text_color(&self) -> Color32 {
crate::color::tint_color_towards(self.text_color(), self.window_fill())
pub fn weak_text_color(&self) -> Rgba {
crate::color::tint_rgba_towards(self.text_color(), self.window_fill())
}
pub fn strong_text_color(&self) -> Color32 {
pub fn strong_text_color(&self) -> Rgba {
self.widgets.active.text_color()
}
pub fn window_fill(&self) -> Color32 {
pub fn window_fill(&self) -> Rgba {
self.widgets.noninteractive.bg_fill
}
@ -264,7 +264,7 @@ impl Visuals {
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
#[cfg_attr(feature = "persistence", serde(default))]
pub struct Selection {
pub bg_fill: Color32,
pub bg_fill: Rgba,
pub stroke: Stroke,
}
@ -307,7 +307,7 @@ impl Widgets {
#[cfg_attr(feature = "persistence", derive(serde::Deserialize, serde::Serialize))]
pub struct WidgetVisuals {
/// Background color of widget.
pub bg_fill: Color32,
pub bg_fill: Rgba,
/// For surrounding rectangle of things that need it,
/// like buttons, the box of the checkbox, etc.
@ -325,7 +325,7 @@ pub struct WidgetVisuals {
}
impl WidgetVisuals {
pub fn text_color(&self) -> Color32 {
pub fn text_color(&self) -> Rgba {
self.fg_stroke.color
}
}
@ -398,10 +398,10 @@ impl Visuals {
override_text_color: None,
widgets: Widgets::default(),
selection: Selection::default(),
hyperlink_color: Color32::from_rgb(90, 170, 255),
faint_bg_color: Color32::from_gray(24),
extreme_bg_color: Color32::from_gray(10),
code_bg_color: Color32::from_gray(64),
hyperlink_color: Color32::from_rgb(90, 170, 255).into(),
faint_bg_color: Color32::from_gray(24).into(),
extreme_bg_color: Color32::from_gray(10).into(),
code_bg_color: Color32::from_gray(64).into(),
window_corner_radius: 6.0,
window_shadow: Shadow::big_dark(),
popup_shadow: Shadow::small_dark(),
@ -420,10 +420,10 @@ impl Visuals {
dark_mode: false,
widgets: Widgets::light(),
selection: Selection::light(),
hyperlink_color: Color32::from_rgb(0, 155, 255),
faint_bg_color: Color32::from_gray(240),
extreme_bg_color: Color32::from_gray(250),
code_bg_color: Color32::from_gray(200),
hyperlink_color: Color32::from_rgb(0, 155, 255).into(),
faint_bg_color: Color32::from_gray(240).into(),
extreme_bg_color: Color32::from_gray(250).into(),
code_bg_color: Color32::from_gray(200).into(),
window_shadow: Shadow::big_light(),
popup_shadow: Shadow::small_light(),
..Self::dark()
@ -440,13 +440,13 @@ impl Default for Visuals {
impl Selection {
fn dark() -> Self {
Self {
bg_fill: Color32::from_rgb(0, 92, 128),
bg_fill: Color32::from_rgb(0, 92, 128).into(),
stroke: Stroke::new(1.0, Color32::from_rgb(192, 222, 255)),
}
}
fn light() -> Self {
Self {
bg_fill: Color32::from_rgb(144, 209, 255),
bg_fill: Color32::from_rgb(144, 209, 255).into(),
stroke: Stroke::new(1.0, Color32::from_rgb(0, 83, 125)),
}
}
@ -462,35 +462,35 @@ impl Widgets {
pub fn dark() -> Self {
Self {
noninteractive: WidgetVisuals {
bg_fill: Color32::from_gray(27), // window background
bg_fill: Color32::from_gray(27).into(), // window background
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines, windows outlines
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color
corner_radius: 2.0,
expansion: 0.0,
},
inactive: WidgetVisuals {
bg_fill: Color32::from_gray(60), // button background
bg_fill: Color32::from_gray(60).into(), // button background
bg_stroke: Default::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text
corner_radius: 2.0,
expansion: 0.0,
},
hovered: WidgetVisuals {
bg_fill: Color32::from_gray(70),
bg_fill: Color32::from_gray(70).into(),
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
corner_radius: 3.0,
expansion: 1.0,
},
active: WidgetVisuals {
bg_fill: Color32::from_gray(55),
bg_stroke: Stroke::new(1.0, Color32::WHITE),
fg_stroke: Stroke::new(2.0, Color32::WHITE),
bg_fill: Color32::from_gray(55).into(),
bg_stroke: Stroke::new(1.0, Rgba::WHITE),
fg_stroke: Stroke::new(2.0, Rgba::WHITE),
corner_radius: 2.0,
expansion: 1.0,
},
open: WidgetVisuals {
bg_fill: Color32::from_gray(27),
bg_fill: Color32::from_gray(27).into(),
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)),
fg_stroke: Stroke::new(1.0, Color32::from_gray(210)),
corner_radius: 2.0,
@ -502,37 +502,37 @@ impl Widgets {
pub fn light() -> Self {
Self {
noninteractive: WidgetVisuals {
bg_fill: Color32::from_gray(235), // window background
bg_fill: Color32::from_gray(235).into(), // window background
bg_stroke: Stroke::new(1.0, Color32::from_gray(190)), // separators, indentation lines, windows outlines
fg_stroke: Stroke::new(1.0, Color32::from_gray(100)), // normal text color
corner_radius: 2.0,
expansion: 0.0,
},
inactive: WidgetVisuals {
bg_fill: Color32::from_gray(215), // button background
bg_fill: Color32::from_gray(215).into(), // button background
bg_stroke: Default::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(80)), // button text
corner_radius: 2.0,
expansion: 0.0,
},
hovered: WidgetVisuals {
bg_fill: Color32::from_gray(210),
bg_fill: Color32::from_gray(210).into(),
bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button
fg_stroke: Stroke::new(1.5, Color32::BLACK),
fg_stroke: Stroke::new(1.5, Rgba::BLACK),
corner_radius: 3.0,
expansion: 1.0,
},
active: WidgetVisuals {
bg_fill: Color32::from_gray(165),
bg_stroke: Stroke::new(1.0, Color32::BLACK),
fg_stroke: Stroke::new(2.0, Color32::BLACK),
bg_fill: Color32::from_gray(165).into(),
bg_stroke: Stroke::new(1.0, Rgba::BLACK),
fg_stroke: Stroke::new(2.0, Rgba::BLACK),
corner_radius: 2.0,
expansion: 1.0,
},
open: WidgetVisuals {
bg_fill: Color32::from_gray(220),
bg_fill: Color32::from_gray(220).into(),
bg_stroke: Stroke::new(1.0, Color32::from_gray(160)),
fg_stroke: Stroke::new(1.0, Color32::BLACK),
fg_stroke: Stroke::new(1.0, Rgba::BLACK),
corner_radius: 2.0,
expansion: 0.0,
},
@ -934,9 +934,9 @@ fn slider_vec2<'a>(
}
}
fn ui_color(ui: &mut Ui, srgba: &mut Color32, text: impl Into<Label>) -> Response {
fn ui_color(ui: &mut Ui, rgba: &mut Rgba, text: impl Into<Label>) -> Response {
ui.horizontal(|ui| {
ui.color_edit_button_srgba(srgba);
ui.color_edit_button_rgba(rgba);
ui.label(text);
})
.response

View file

@ -945,11 +945,7 @@ impl Ui {
}
/// Shortcut for `add(Label::new(text).text_color(color))`
pub fn colored_label(
&mut self,
color: impl Into<Color32>,
label: impl Into<Label>,
) -> Response {
pub fn colored_label(&mut self, color: impl Into<Rgba>, label: impl Into<Label>) -> Response {
label.into().text_color(color).ui(self)
}
@ -1172,6 +1168,12 @@ impl Ui {
/// # Colors
impl Ui {
/// Shows a button with the given color.
/// If the user clicks the button, a full color picker is shown.
pub fn color_edit_button_rgba(&mut self, rgba: &mut Rgba) -> Response {
color_picker::color_edit_button_rgba(self, rgba, color_picker::Alpha::BlendOrAdditive)
}
/// Shows a button with the given color.
/// If the user clicks the button, a full color picker is shown.
pub fn color_edit_button_srgba(&mut self, srgba: &mut Color32) -> Response {

View file

@ -14,10 +14,10 @@ use crate::*;
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Button {
text: String,
text_color: Option<Color32>,
text_color: Option<Rgba>,
text_style: Option<TextStyle>,
/// None means default for interact
fill: Option<Color32>,
fill: Option<Rgba>,
stroke: Option<Stroke>,
sense: Sense,
small: bool,
@ -43,12 +43,12 @@ impl Button {
}
}
pub fn text_color(mut self, text_color: Color32) -> Self {
self.text_color = Some(text_color);
pub fn text_color(mut self, text_color: impl Into<Rgba>) -> Self {
self.text_color = Some(text_color.into());
self
}
pub fn text_color_opt(mut self, text_color: Option<Color32>) -> Self {
pub fn text_color_opt(mut self, text_color: Option<Rgba>) -> Self {
self.text_color = text_color;
self
}
@ -60,7 +60,7 @@ impl Button {
/// Override background fill color. Note that this will override any on-hover effects.
/// Calling this will also turn on the frame.
pub fn fill(mut self, fill: impl Into<Color32>) -> Self {
pub fn fill(mut self, fill: impl Into<Rgba>) -> Self {
self.fill = Some(fill.into());
self.frame = Some(true);
self
@ -229,7 +229,7 @@ impl Widget for Button {
pub struct Checkbox<'a> {
checked: &'a mut bool,
text: String,
text_color: Option<Color32>,
text_color: Option<Rgba>,
text_style: Option<TextStyle>,
}
@ -244,7 +244,7 @@ impl<'a> Checkbox<'a> {
}
}
pub fn text_color(mut self, text_color: Color32) -> Self {
pub fn text_color(mut self, text_color: Rgba) -> Self {
self.text_color = Some(text_color);
self
}
@ -351,7 +351,7 @@ impl<'a> Widget for Checkbox<'a> {
pub struct RadioButton {
checked: bool,
text: String,
text_color: Option<Color32>,
text_color: Option<Rgba>,
text_style: Option<TextStyle>,
}
@ -366,7 +366,7 @@ impl RadioButton {
}
}
pub fn text_color(mut self, text_color: Color32) -> Self {
pub fn text_color(mut self, text_color: Rgba) -> Self {
self.text_color = Some(text_color);
self
}
@ -475,7 +475,7 @@ impl ImageButton {
}
/// Multiply image color with this. Default is WHITE (no tint).
pub fn tint(mut self, tint: impl Into<Color32>) -> Self {
pub fn tint(mut self, tint: impl Into<Rgba>) -> Self {
self.image = self.image.tint(tint);
self
}

View file

@ -23,8 +23,8 @@ fn background_checkers(painter: &Painter, rect: Rect) {
return;
}
let mut top_color = Color32::from_gray(128);
let mut bottom_color = Color32::from_gray(32);
let mut top_color = Color32::from_gray(128).into();
let mut bottom_color = Color32::from_gray(32).into();
let checker_size = Vec2::splat(rect.height() / 2.0);
let n = (rect.width() / checker_size.x).round() as u32;
@ -92,7 +92,7 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response {
response
}
fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color32) -> Response {
fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Rgba) -> Response {
#![allow(clippy::identity_op)]
let desired_size = vec2(
@ -151,7 +151,7 @@ fn color_slider_2d(
ui: &mut Ui,
x_value: &mut f32,
y_value: &mut f32,
color_at: impl Fn(f32, f32) -> Color32,
color_at: impl Fn(f32, f32) -> Rgba,
) -> Response {
let desired_size = Vec2::splat(ui.spacing().slider_width);
let (rect, response) = ui.allocate_at_least(desired_size, Sense::click_and_drag());
@ -211,7 +211,7 @@ pub enum Alpha {
BlendOrAdditive,
}
fn color_text_ui(ui: &mut Ui, color: impl Into<Color32>) {
fn color_text_ui(ui: &mut Ui, color: impl Into<Rgba>) {
let color = color.into();
ui.horizontal(|ui| {
let [r, g, b, a] = color.to_array();
@ -368,6 +368,17 @@ pub fn color_edit_button_hsva(ui: &mut Ui, hsva: &mut Hsva, alpha: Alpha) -> Res
button_response
}
/// Shows a button with the given color.
/// If the user clicks the button, a full color picker is shown.
pub fn color_edit_button_rgba(ui: &mut Ui, rgba: &mut Rgba, alpha: Alpha) -> Response {
let mut srgba = (*rgba).into();
let response = color_edit_button_srgba(ui, &mut srgba, alpha);
if response.changed() {
*rgba = srgba.into();
}
response
}
/// Shows a button with the given color.
/// If the user clicks the button, a full color picker is shown.
pub fn color_edit_button_srgba(ui: &mut Ui, srgba: &mut Color32, alpha: Alpha) -> Response {

View file

@ -18,8 +18,8 @@ pub struct Image {
texture_id: TextureId,
uv: Rect,
size: Vec2,
bg_fill: Color32,
tint: Color32,
bg_fill: Rgba,
tint: Rgba,
sense: Sense,
}
@ -30,7 +30,7 @@ impl Image {
uv: Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
size: size.into(),
bg_fill: Default::default(),
tint: Color32::WHITE,
tint: Rgba::WHITE,
sense: Sense::hover(),
}
}
@ -42,13 +42,13 @@ impl Image {
}
/// A solid color to put behind the image. Useful for transparent images.
pub fn bg_fill(mut self, bg_fill: impl Into<Color32>) -> Self {
pub fn bg_fill(mut self, bg_fill: impl Into<Rgba>) -> Self {
self.bg_fill = bg_fill.into();
self
}
/// Multiply image color with this. Default is WHITE (no tint).
pub fn tint(mut self, tint: impl Into<Color32>) -> Self {
pub fn tint(mut self, tint: impl Into<Rgba>) -> Self {
self.tint = tint.into();
self
}

View file

@ -8,7 +8,7 @@ use std::sync::Arc;
/// # let ui = &mut egui::Ui::__test();
/// ui.label("Equivalent");
/// ui.add(egui::Label::new("Equivalent"));
/// ui.add(egui::Label::new("With Options").text_color(egui::Color32::RED));
/// ui.add(egui::Label::new("With Options").text_color(egui::Rgba::RED));
/// ```
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
pub struct Label {
@ -16,8 +16,8 @@ pub struct Label {
pub(crate) text: String,
pub(crate) wrap: Option<bool>,
pub(crate) text_style: Option<TextStyle>,
pub(crate) background_color: Color32,
pub(crate) text_color: Option<Color32>,
pub(crate) background_color: Rgba,
pub(crate) text_color: Option<Rgba>,
code: bool,
strong: bool,
weak: bool,
@ -35,7 +35,7 @@ impl Label {
text: text.to_string(),
wrap: None,
text_style: None,
background_color: Color32::TRANSPARENT,
background_color: Rgba::TRANSPARENT,
text_color: None,
code: false,
strong: false,
@ -135,12 +135,12 @@ impl Label {
}
/// Fill-color behind the text
pub fn background_color(mut self, background_color: impl Into<Color32>) -> Self {
pub fn background_color(mut self, background_color: impl Into<Rgba>) -> Self {
self.background_color = background_color.into();
self
}
pub fn text_color(mut self, text_color: impl Into<Color32>) -> Self {
pub fn text_color(mut self, text_color: impl Into<Rgba>) -> Self {
self.text_color = Some(text_color.into());
self
}
@ -206,7 +206,7 @@ impl Label {
pos: Pos2,
galley: Arc<Galley>,
has_focus: bool,
response_color: Color32,
response_color: Rgba,
) {
let Self {
mut background_color,
@ -238,11 +238,11 @@ impl Label {
let mut lines = vec![];
if strikethrough || underline || background_color != Color32::TRANSPARENT {
if strikethrough || underline || background_color != Rgba::TRANSPARENT {
for row in &galley.rows {
let rect = row.rect().translate(pos.to_vec2());
if background_color != Color32::TRANSPARENT {
if background_color != Rgba::TRANSPARENT {
let rect = rect.expand(1.0); // looks better
ui.painter().rect_filled(rect, 0.0, background_color);
}

View file

@ -97,7 +97,7 @@ pub fn stroke_ui(ui: &mut crate::Ui, stroke: &mut epaint::Stroke, text: &str) {
ui.horizontal(|ui| {
ui.add(DragValue::new(width).speed(0.1).clamp_range(0.0..=5.0))
.on_hover_text("Width");
ui.color_edit_button_srgba(color);
ui.color_edit_button_rgba(color);
ui.label(text);
// stroke preview:
@ -118,6 +118,6 @@ pub(crate) fn shadow_ui(ui: &mut Ui, shadow: &mut epaint::Shadow, text: &str) {
.clamp_range(0.0..=100.0),
)
.on_hover_text("Extrusion");
ui.color_edit_button_srgba(color);
ui.color_edit_button_rgba(color);
});
}

View file

@ -135,7 +135,7 @@ impl HLine {
pub fn new(y: impl Into<f64>) -> Self {
Self {
y: y.into(),
stroke: Stroke::new(1.0, Color32::TRANSPARENT),
stroke: Stroke::new(1.0, Rgba::TRANSPARENT),
name: String::default(),
highlight: false,
style: LineStyle::Solid,
@ -160,8 +160,8 @@ impl HLine {
self
}
/// Stroke color. Default is `Color32::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
/// Stroke color. Default is `Rgba::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.stroke.color = color.into();
self
}
@ -207,7 +207,7 @@ impl PlotItem for HLine {
&self.name
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.stroke.color
}
@ -245,7 +245,7 @@ impl VLine {
pub fn new(x: impl Into<f64>) -> Self {
Self {
x: x.into(),
stroke: Stroke::new(1.0, Color32::TRANSPARENT),
stroke: Stroke::new(1.0, Rgba::TRANSPARENT),
name: String::default(),
highlight: false,
style: LineStyle::Solid,
@ -270,8 +270,8 @@ impl VLine {
self
}
/// Stroke color. Default is `Color32::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
/// Stroke color. Default is `Rgba::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.stroke.color = color.into();
self
}
@ -317,7 +317,7 @@ impl PlotItem for VLine {
&self.name
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.stroke.color
}
@ -346,7 +346,7 @@ pub(super) trait PlotItem {
fn get_shapes(&self, ui: &mut Ui, transform: &ScreenTransform, shapes: &mut Vec<Shape>);
fn initialize(&mut self, x_range: RangeInclusive<f64>);
fn name(&self) -> &str;
fn color(&self) -> Color32;
fn color(&self) -> Rgba;
fn highlight(&mut self);
fn highlighted(&self) -> bool;
fn values(&self) -> Option<&Values>;
@ -552,7 +552,7 @@ impl Line {
pub fn new(series: Values) -> Self {
Self {
series,
stroke: Stroke::new(1.0, Color32::TRANSPARENT),
stroke: Stroke::new(1.0, Rgba::TRANSPARENT),
name: Default::default(),
highlight: false,
fill: None,
@ -578,8 +578,8 @@ impl Line {
self
}
/// Stroke color. Default is `Color32::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
/// Stroke color. Default is `Rgba::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.stroke.color = color.into();
self
}
@ -684,7 +684,7 @@ impl PlotItem for Line {
self.name.as_str()
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.stroke.color
}
@ -719,7 +719,7 @@ impl Polygon {
pub fn new(series: Values) -> Self {
Self {
series,
stroke: Stroke::new(1.0, Color32::TRANSPARENT),
stroke: Stroke::new(1.0, Rgba::TRANSPARENT),
name: Default::default(),
highlight: false,
fill_alpha: DEFAULT_FILL_ALPHA,
@ -746,8 +746,8 @@ impl Polygon {
self
}
/// Stroke color. Default is `Color32::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
/// Stroke color. Default is `Rgba::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.stroke.color = color.into();
self
}
@ -819,7 +819,7 @@ impl PlotItem for Polygon {
self.name.as_str()
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.stroke.color
}
@ -847,7 +847,7 @@ pub struct Text {
pub(super) position: Value,
pub(super) name: String,
pub(super) highlight: bool,
pub(super) color: Color32,
pub(super) color: Rgba,
pub(super) anchor: Align2,
}
@ -860,7 +860,7 @@ impl Text {
position,
name: Default::default(),
highlight: false,
color: Color32::TRANSPARENT,
color: Rgba::TRANSPARENT,
anchor: Align2::CENTER_CENTER,
}
}
@ -877,8 +877,8 @@ impl Text {
self
}
/// Text color. Default is `Color32::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
/// Text color. Default is `Rgba::TRANSPARENT` which means a color will be auto-assigned.
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.color = color.into();
self
}
@ -904,7 +904,7 @@ impl Text {
impl PlotItem for Text {
fn get_shapes(&self, ui: &mut Ui, transform: &ScreenTransform, shapes: &mut Vec<Shape>) {
let color = if self.color == Color32::TRANSPARENT {
let color = if self.color == Rgba::TRANSPARENT {
ui.style().visuals.text_color()
} else {
self.color
@ -937,7 +937,7 @@ impl PlotItem for Text {
self.name.as_str()
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.color
}
@ -964,8 +964,8 @@ impl PlotItem for Text {
pub struct Points {
pub(super) series: Values,
pub(super) shape: MarkerShape,
/// Color of the marker. `Color32::TRANSPARENT` means that it will be picked automatically.
pub(super) color: Color32,
/// Color of the marker. `Rgba::TRANSPARENT` means that it will be picked automatically.
pub(super) color: Rgba,
/// Whether to fill the marker. Does not apply to all types.
pub(super) filled: bool,
/// The maximum extent of the marker from its center.
@ -980,7 +980,7 @@ impl Points {
Self {
series,
shape: MarkerShape::Circle,
color: Color32::TRANSPARENT,
color: Rgba::TRANSPARENT,
filled: true,
radius: 1.0,
name: Default::default(),
@ -1002,7 +1002,7 @@ impl Points {
}
/// Set the marker's color.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.color = color.into();
self
}
@ -1200,7 +1200,7 @@ impl PlotItem for Points {
self.name.as_str()
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.color
}
@ -1225,7 +1225,7 @@ impl PlotItem for Points {
pub struct Arrows {
pub(super) origins: Values,
pub(super) tips: Values,
pub(super) color: Color32,
pub(super) color: Rgba,
pub(super) name: String,
pub(super) highlight: bool,
}
@ -1235,7 +1235,7 @@ impl Arrows {
Self {
origins,
tips,
color: Color32::TRANSPARENT,
color: Rgba::TRANSPARENT,
name: Default::default(),
highlight: false,
}
@ -1248,7 +1248,7 @@ impl Arrows {
}
/// Set the arrows' color.
pub fn color(mut self, color: impl Into<Color32>) -> Self {
pub fn color(mut self, color: impl Into<Rgba>) -> Self {
self.color = color.into();
self
}
@ -1315,7 +1315,7 @@ impl PlotItem for Arrows {
self.name.as_str()
}
fn color(&self) -> Color32 {
fn color(&self) -> Rgba {
self.color
}
@ -1342,8 +1342,8 @@ pub struct PlotImage {
pub(super) texture_id: TextureId,
pub(super) uv: Rect,
pub(super) size: Vec2,
pub(super) bg_fill: Color32,
pub(super) tint: Color32,
pub(super) bg_fill: Rgba,
pub(super) tint: Rgba,
pub(super) highlight: bool,
pub(super) name: String,
}
@ -1359,7 +1359,7 @@ impl PlotImage {
uv: Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)),
size: size.into(),
bg_fill: Default::default(),
tint: Color32::WHITE,
tint: Rgba::WHITE,
}
}
@ -1376,13 +1376,13 @@ impl PlotImage {
}
/// A solid color to put behind the image. Useful for transparent images.
pub fn bg_fill(mut self, bg_fill: impl Into<Color32>) -> Self {
pub fn bg_fill(mut self, bg_fill: impl Into<Rgba>) -> Self {
self.bg_fill = bg_fill.into();
self
}
/// Multiply image color with this. Default is WHITE (no tint).
pub fn tint(mut self, tint: impl Into<Color32>) -> Self {
pub fn tint(mut self, tint: impl Into<Rgba>) -> Self {
self.tint = tint.into();
self
}
@ -1445,8 +1445,8 @@ impl PlotItem for PlotImage {
self.name.as_str()
}
fn color(&self) -> Color32 {
Color32::TRANSPARENT
fn color(&self) -> Rgba {
Rgba::TRANSPARENT
}
fn highlight(&mut self) {

View file

@ -69,13 +69,13 @@ impl Legend {
#[derive(Clone)]
struct LegendEntry {
color: Color32,
color: Rgba,
checked: bool,
hovered: bool,
}
impl LegendEntry {
fn new(color: Color32, checked: bool) -> Self {
fn new(color: Rgba, checked: bool) -> Self {
Self {
color,
checked,
@ -122,7 +122,7 @@ impl LegendEntry {
});
if *checked {
let fill = if *color == Color32::TRANSPARENT {
let fill = if *color == Rgba::TRANSPARENT {
ui.visuals().noninteractive().fg_stroke.color
} else {
*color
@ -179,7 +179,7 @@ impl LegendWidget {
.and_modify(|entry| {
if entry.color != item.color() {
// Multiple items with different colors
entry.color = Color32::TRANSPARENT;
entry.color = Rgba::TRANSPARENT;
}
})
.or_insert_with(|| {

View file

@ -101,7 +101,7 @@ impl Plot {
}
}
fn auto_color(&mut self) -> Color32 {
fn auto_color(&mut self) -> Rgba {
let i = self.next_auto_color_idx;
self.next_auto_color_idx += 1;
let golden_ratio = (5.0_f32.sqrt() - 1.0) / 2.0; // 0.61803398875
@ -116,7 +116,7 @@ impl Plot {
};
// Give the stroke an automatic color if no color has been assigned.
if line.stroke.color == Color32::TRANSPARENT {
if line.stroke.color == Rgba::TRANSPARENT {
line.stroke.color = self.auto_color();
}
self.items.push(Box::new(line));
@ -130,7 +130,7 @@ impl Plot {
};
// Give the stroke an automatic color if no color has been assigned.
if polygon.stroke.color == Color32::TRANSPARENT {
if polygon.stroke.color == Rgba::TRANSPARENT {
polygon.stroke.color = self.auto_color();
}
self.items.push(Box::new(polygon));
@ -154,7 +154,7 @@ impl Plot {
};
// Give the points an automatic color if no color has been assigned.
if points.color == Color32::TRANSPARENT {
if points.color == Rgba::TRANSPARENT {
points.color = self.auto_color();
}
self.items.push(Box::new(points));
@ -168,7 +168,7 @@ impl Plot {
};
// Give the arrows an automatic color if no color has been assigned.
if arrows.color == Color32::TRANSPARENT {
if arrows.color == Rgba::TRANSPARENT {
arrows.color = self.auto_color();
}
self.items.push(Box::new(arrows));
@ -185,7 +185,7 @@ impl Plot {
/// Can be useful e.g. to show min/max bounds or similar.
/// Always fills the full width of the plot.
pub fn hline(mut self, mut hline: HLine) -> Self {
if hline.stroke.color == Color32::TRANSPARENT {
if hline.stroke.color == Rgba::TRANSPARENT {
hline.stroke.color = self.auto_color();
}
self.items.push(Box::new(hline));
@ -196,7 +196,7 @@ impl Plot {
/// Can be useful e.g. to show min/max bounds or similar.
/// Always fills the full height of the plot.
pub fn vline(mut self, mut vline: VLine) -> Self {
if vline.stroke.color == Color32::TRANSPARENT {
if vline.stroke.color == Rgba::TRANSPARENT {
vline.stroke.color = self.auto_color();
}
self.items.push(Box::new(vline));
@ -634,7 +634,7 @@ impl Prepared {
}
}
fn color_from_alpha(ui: &Ui, alpha: f32) -> Color32 {
fn color_from_alpha(ui: &Ui, alpha: f32) -> Rgba {
if ui.visuals().dark_mode {
Rgba::from_white_alpha(alpha).into()
} else {

View file

@ -94,7 +94,7 @@ impl Widget for ProgressBar {
ui.painter().rect(
inner_rect,
corner_radius,
Color32::from(Rgba::from(visuals.selection.bg_fill) * color_factor as f32),
Rgba::from(visuals.selection.bg_fill) * color_factor as f32,
Stroke::none(),
);
@ -115,7 +115,7 @@ impl Widget for ProgressBar {
ui.painter().add(Shape::Path {
points,
closed: false,
fill: Color32::TRANSPARENT,
fill: Rgba::TRANSPARENT,
stroke: Stroke::new(2.0, visuals.faint_bg_color),
});
}

View file

@ -61,7 +61,7 @@ pub struct Slider<'a> {
prefix: String,
suffix: String,
text: String,
text_color: Option<Color32>,
text_color: Option<Rgba>,
min_decimals: usize,
max_decimals: Option<usize>,
}
@ -180,7 +180,7 @@ impl<'a> Slider<'a> {
self
}
pub fn text_color(mut self, text_color: Color32) -> Self {
pub fn text_color(mut self, text_color: Rgba) -> Self {
self.text_color = Some(text_color);
self
}

View file

@ -229,7 +229,7 @@ pub struct TextEdit<'t, S: TextBuffer = String> {
id: Option<Id>,
id_source: Option<Id>,
text_style: Option<TextStyle>,
text_color: Option<Color32>,
text_color: Option<Rgba>,
password: bool,
frame: bool,
multiline: bool,
@ -329,12 +329,12 @@ impl<'t, S: TextBuffer> TextEdit<'t, S> {
self
}
pub fn text_color(mut self, text_color: Color32) -> Self {
pub fn text_color(mut self, text_color: Rgba) -> Self {
self.text_color = Some(text_color);
self
}
pub fn text_color_opt(mut self, text_color: Option<Color32>) -> Self {
pub fn text_color_opt(mut self, text_color: Option<Rgba>) -> Self {
self.text_color = text_color;
self
}

View file

@ -90,7 +90,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
fonts.texture().size(),
egui::Pos2::ZERO,
&galley,
egui::Color32::WHITE,
egui::Rgba::WHITE,
fake_italics,
&mut mesh,
);

View file

@ -303,7 +303,7 @@ fn vertex_gradient(ui: &mut Ui, bg_fill: Color32, gradient: &Gradient) -> Respon
let (rect, response) = ui.allocate_at_least(GRADIENT_SIZE, Sense::hover());
if bg_fill != Default::default() {
let mut mesh = Mesh::default();
mesh.add_colored_rect(rect, bg_fill);
mesh.add_colored_rect(rect, bg_fill.into());
ui.painter().add(Shape::mesh(mesh));
}
{
@ -313,8 +313,8 @@ fn vertex_gradient(ui: &mut Ui, bg_fill: Color32, gradient: &Gradient) -> Respon
for (i, &color) in gradient.0.iter().enumerate() {
let t = i as f32 / (n as f32 - 1.0);
let x = lerp(rect.x_range(), t);
mesh.colored_vertex(pos2(x, rect.top()), color);
mesh.colored_vertex(pos2(x, rect.bottom()), color);
mesh.colored_vertex(pos2(x, rect.top()), color.into());
mesh.colored_vertex(pos2(x, rect.bottom()), color.into());
if i < n - 1 {
let i = i as u32;
mesh.add_triangle(2 * i, 2 * i + 1, 2 * i + 2);
@ -333,9 +333,11 @@ impl Gradient {
pub fn one_color(srgba: Color32) -> Self {
Self(vec![srgba, srgba])
}
pub fn texture_gradient(left: Color32, right: Color32) -> Self {
Self(vec![left, right])
}
pub fn ground_truth_linear_gradient(left: Color32, right: Color32) -> Self {
let left = Rgba::from(left);
let right = Rgba::from(right);
@ -350,6 +352,7 @@ impl Gradient {
.collect(),
)
}
/// This is how a bad person blends `sRGBA`
pub fn ground_truth_bad_srgba_gradient(left: Color32, right: Color32) -> Self {
let n = 255;

View file

@ -199,7 +199,7 @@ impl DemoWindows {
// Native: WrapApp uses a transparent window, so let's show that off:
// NOTE: the OS compositor assumes "normal" blending, so we need to hack it:
let [r, g, b, _] = fill.to_array();
fill = egui::Color32::from_rgba_premultiplied(r, g, b, 180);
fill = egui::Rgba::from_rgba_premultiplied(r, g, b, 0.70);
}
let frame = egui::Frame::none().fill(fill);
egui::CentralPanel::default().frame(frame).show(ctx, |_| {});

View file

@ -59,8 +59,8 @@ pub fn drop_target<R>(
let mut stroke = style.bg_stroke;
if is_being_dragged && !can_accept_what_is_being_dragged {
// gray out:
fill = color::tint_color_towards(fill, ui.visuals().window_fill());
stroke.color = color::tint_color_towards(stroke.color, ui.visuals().window_fill());
fill = color::tint_rgba_towards(fill, ui.visuals().window_fill());
stroke.color = color::tint_rgba_towards(stroke.color, ui.visuals().window_fill());
}
ui.painter().set(

View file

@ -363,7 +363,7 @@ impl Tree {
fn children_ui(&mut self, ui: &mut Ui, depth: usize) -> Action {
if depth > 0
&& ui
.add(Button::new("delete").text_color(Color32::RED))
.add(Button::new("delete").text_color(Rgba::RED))
.clicked()
{
return Action::Delete;

View file

@ -504,7 +504,7 @@ impl EguiGlium {
pub fn on_event(&mut self, event: &glium::glutin::event::WindowEvent<'_>) {
crate::input_to_egui(
self.egui_ctx.pixels_per_point(),
&event,
event,
self.clipboard.as_mut(),
&mut self.input_state,
);

View file

@ -127,9 +127,9 @@ impl Painter {
struct Vertex {
a_pos: [f32; 2],
a_tc: [f32; 2],
a_srgba: [u8; 4],
a_rgba: [f32; 4],
}
implement_vertex!(Vertex, a_pos, a_tc, a_srgba);
implement_vertex!(Vertex, a_pos, a_tc, a_rgba);
let vertices: Vec<Vertex> = mesh
.vertices
@ -137,7 +137,7 @@ impl Painter {
.map(|v| Vertex {
a_pos: [v.pos.x, v.pos.y],
a_tc: [v.uv.x, v.uv.y],
a_srgba: v.color.to_array(),
a_rgba: v.color.to_array(),
})
.collect();

View file

@ -4,21 +4,10 @@ precision mediump float;
uniform vec2 u_screen_size;
attribute vec2 a_pos;
attribute vec2 a_tc;
attribute vec4 a_srgba;
varying vec4 v_rgba;
attribute vec4 a_rgba; // 0-1
varying vec4 v_rgba; // 0-1
varying vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, vec3(cutoff));
}
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
@ -26,7 +15,6 @@ void main() {
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_srgba;
v_tc = a_tc;
}

View file

@ -2,30 +2,17 @@
uniform vec2 u_screen_size;
attribute vec2 a_pos;
attribute vec4 a_srgba; // 0-255 sRGB
attribute vec2 a_tc;
varying vec4 v_rgba;
attribute vec4 a_rgba; // 0-1
varying vec4 v_rgba; // 0-1
varying vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, vec3(cutoff));
}
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
2.0 * a_pos.x / u_screen_size.x - 1.0,
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_rgba;
v_tc = a_tc;
}

View file

@ -2,30 +2,17 @@
uniform vec2 u_screen_size;
in vec2 a_pos;
in vec4 a_srgba; // 0-255 sRGB
in vec2 a_tc;
out vec4 v_rgba;
in vec4 a_rgba; // 0-1
out vec4 v_rgba; // 0-1
out vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, cutoff);
}
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
2.0 * a_pos.x / u_screen_size.x - 1.0,
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_rgba;
v_tc = a_tc;
}

View file

@ -4,29 +4,16 @@ precision mediump float;
uniform vec2 u_screen_size;
attribute vec2 a_pos;
attribute vec2 a_tc;
attribute vec4 a_srgba;
varying vec4 v_rgba;
attribute vec4 a_rgba; // 0-1
varying vec4 v_rgba; // 0-1
varying vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, vec3(cutoff));
}
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
2.0 * a_pos.x / u_screen_size.x - 1.0,
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_rgba;
v_tc = a_tc;
}

View file

@ -2,30 +2,16 @@ precision mediump float;
uniform vec2 u_screen_size;
attribute vec2 a_pos;
attribute vec2 a_tc;
attribute vec4 a_srgba;
varying vec4 v_rgba;
attribute vec4 a_rgba; // 0-1
varying vec4 v_rgba; // 0-1
varying vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, vec3(cutoff));
}
// 0-1 linear from 0-255 sRGBA
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
2.0 * a_pos.x / u_screen_size.x - 1.0,
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_rgba;
v_tc = a_tc;
}

View file

@ -2,30 +2,16 @@ precision mediump float;
uniform vec2 u_screen_size;
attribute vec2 a_pos;
attribute vec2 a_tc;
attribute vec4 a_srgba;
varying vec4 v_rgba;
attribute vec4 a_rgba; // 0-1
varying vec4 v_rgba; // 0-1
varying vec2 v_tc;
// 0-1 linear from 0-255 sRGB
vec3 linear_from_srgb(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(10.31475));
vec3 lower = srgb / vec3(3294.6);
vec3 higher = pow((srgb + vec3(14.025)) / vec3(269.025), vec3(2.4));
return mix(higher, lower, vec3(cutoff));
}
// 0-1 linear from 0-255 sRGBA
vec4 linear_from_srgba(vec4 srgba) {
return vec4(linear_from_srgb(srgba.rgb), srgba.a / 255.0);
}
void main() {
gl_Position = vec4(
2.0 * a_pos.x / u_screen_size.x - 1.0,
1.0 - 2.0 * a_pos.y / u_screen_size.y,
0.0,
1.0);
// egui encodes vertex colors in gamma spaces, so we must decode the colors here:
v_rgba = linear_from_srgba(a_srgba);
v_rgba = a_rgba;
v_tc = a_tc;
}

View file

@ -210,7 +210,7 @@ impl WebGlPainter {
let mut positions: Vec<f32> = Vec::with_capacity(2 * mesh.vertices.len());
let mut tex_coords: Vec<f32> = Vec::with_capacity(2 * mesh.vertices.len());
let mut colors: Vec<u8> = Vec::with_capacity(4 * mesh.vertices.len());
let mut colors: Vec<f32> = Vec::with_capacity(4 * mesh.vertices.len());
for v in &mesh.vertices {
positions.push(v.pos.x);
positions.push(v.pos.y);
@ -289,29 +289,22 @@ impl WebGlPainter {
let colors_memory_buffer = wasm_bindgen::memory()
.dyn_into::<WebAssembly::Memory>()?
.buffer();
let colors_ptr = colors.as_ptr() as u32;
let colors_ptr = colors.as_ptr() as u32 / 4;
let colors_array = js_sys::Uint8Array::new(&colors_memory_buffer)
.subarray(colors_ptr, colors_ptr + colors.len() as u32);
gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&self.color_buffer));
gl.buffer_data_with_array_buffer_view(Gl::ARRAY_BUFFER, &colors_array, Gl::STREAM_DRAW);
let a_srgba_loc = gl.get_attrib_location(&self.program, "a_srgba");
assert!(a_srgba_loc >= 0);
let a_srgba_loc = a_srgba_loc as u32;
let a_rgba_loc = gl.get_attrib_location(&self.program, "a_rgba");
assert!(a_rgba_loc >= 0);
let a_rgba_loc = a_rgba_loc as u32;
let normalize = false;
let stride = 0;
let offset = 0;
gl.vertex_attrib_pointer_with_i32(
a_srgba_loc,
4,
Gl::UNSIGNED_BYTE,
normalize,
stride,
offset,
);
gl.enable_vertex_attrib_array(a_srgba_loc);
gl.vertex_attrib_pointer_with_i32(a_rgba_loc, 4, Gl::FLOAT, normalize, stride, offset);
gl.enable_vertex_attrib_array(a_rgba_loc);
// --------------------------------------------------------------------

View file

@ -211,7 +211,7 @@ impl WebGl2Painter {
let mut positions: Vec<f32> = Vec::with_capacity(2 * mesh.vertices.len());
let mut tex_coords: Vec<f32> = Vec::with_capacity(2 * mesh.vertices.len());
let mut colors: Vec<u8> = Vec::with_capacity(4 * mesh.vertices.len());
let mut colors: Vec<f32> = Vec::with_capacity(4 * mesh.vertices.len());
for v in &mesh.vertices {
positions.push(v.pos.x);
positions.push(v.pos.y);
@ -290,29 +290,22 @@ impl WebGl2Painter {
let colors_memory_buffer = wasm_bindgen::memory()
.dyn_into::<WebAssembly::Memory>()?
.buffer();
let colors_ptr = colors.as_ptr() as u32;
let colors_ptr = colors.as_ptr() as u32 / 4;
let colors_array = js_sys::Uint8Array::new(&colors_memory_buffer)
.subarray(colors_ptr, colors_ptr + colors.len() as u32);
gl.bind_buffer(Gl::ARRAY_BUFFER, Some(&self.color_buffer));
gl.buffer_data_with_array_buffer_view(Gl::ARRAY_BUFFER, &colors_array, Gl::STREAM_DRAW);
let a_srgba_loc = gl.get_attrib_location(&self.program, "a_srgba");
assert!(a_srgba_loc >= 0);
let a_srgba_loc = a_srgba_loc as u32;
let a_rgba_loc = gl.get_attrib_location(&self.program, "a_rgba");
assert!(a_rgba_loc >= 0);
let a_rgba_loc = a_rgba_loc as u32;
let normalize = false;
let stride = 0;
let offset = 0;
gl.vertex_attrib_pointer_with_i32(
a_srgba_loc,
4,
Gl::UNSIGNED_BYTE,
normalize,
stride,
offset,
);
gl.enable_vertex_attrib_array(a_srgba_loc);
gl.vertex_attrib_pointer_with_i32(a_rgba_loc, 4, Gl::FLOAT, normalize, stride, offset);
gl.enable_vertex_attrib_array(a_rgba_loc);
// --------------------------------------------------------------------

View file

@ -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::*;

View file

@ -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,
}

View file

@ -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)
}

View file

@ -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(),
}
}

View file

@ -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;

View file

@ -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 => {}

View file

@ -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)

View file

@ -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(