diff --git a/crates/egui/src/containers/window.rs b/crates/egui/src/containers/window.rs index c48f6009915..f1c67300b8a 100644 --- a/crates/egui/src/containers/window.rs +++ b/crates/egui/src/containers/window.rs @@ -8,7 +8,9 @@ use crate::{ TextStyle, Ui, UiKind, Vec2b, WidgetInfo, WidgetRect, WidgetText, WidgetType, }; use emath::GuiRounding as _; -use epaint::{emath, pos2, vec2, Galley, Pos2, Rect, RectShape, Rounding, Shape, Stroke, Vec2}; +use epaint::{ + emath, pos2, vec2, Galley, Pos2, Rect, RectShape, Rounding, Roundingf, Shape, Stroke, Vec2, +}; use super::scroll_area::ScrollBarVisibility; use super::{area, resize, Area, Frame, Resize, ScrollArea}; @@ -486,8 +488,9 @@ impl<'open> Window<'open> { let style = ctx.style(); let spacing = window_margin.top + window_margin.bottom; let height = ctx.fonts(|f| title.font_height(f, &style)) + spacing; - window_frame.rounding.ne = window_frame.rounding.ne.clamp(0.0, height / 2.0); - window_frame.rounding.nw = window_frame.rounding.nw.clamp(0.0, height / 2.0); + let half_height = (height / 2.0).round() as _; + window_frame.rounding.ne = window_frame.rounding.ne.clamp(0, half_height); + window_frame.rounding.nw = window_frame.rounding.nw.clamp(0, half_height); (height, spacing) } else { (0.0, 0.0) @@ -603,8 +606,8 @@ impl<'open> Window<'open> { let mut round = window_frame.rounding; if !is_collapsed { - round.se = 0.0; - round.sw = 0.0; + round.se = 0; + round.sw = 0; } area_content_ui.painter().set( @@ -682,6 +685,7 @@ fn paint_resize_corner( }; // Adjust the corner offset to accommodate for window rounding + let radius = radius as f32; let offset = ((2.0_f32.sqrt() * (1.0 + radius) - radius) * 45.0_f32.to_radians().cos()).max(2.0); @@ -1022,7 +1026,7 @@ fn paint_frame_interaction(ui: &Ui, rect: Rect, interaction: ResizeInteraction) bottom = interaction.bottom.hover; } - let rounding = ui.visuals().window_rounding; + let rounding = Roundingf::from(ui.visuals().window_rounding); let Rect { min, max } = rect; let mut points = Vec::new(); diff --git a/crates/egui/src/style.rs b/crates/egui/src/style.rs index 33ab21a6837..af35972c4d6 100644 --- a/crates/egui/src/style.rs +++ b/crates/egui/src/style.rs @@ -1291,7 +1291,7 @@ impl Visuals { warn_fg_color: Color32::from_rgb(255, 143, 0), // orange error_fg_color: Color32::from_rgb(255, 0, 0), // red - window_rounding: Rounding::same(6.0), + window_rounding: Rounding::same(6), window_shadow: Shadow { offset: vec2(10.0, 20.0), blur: 15.0, @@ -1302,7 +1302,7 @@ impl Visuals { window_stroke: Stroke::new(1.0, Color32::from_gray(60)), window_highlight_topmost: true, - menu_rounding: Rounding::same(6.0), + menu_rounding: Rounding::same(6), panel_fill: Color32::from_gray(27), @@ -1412,7 +1412,7 @@ impl Widgets { bg_fill: Color32::from_gray(27), bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, inactive: WidgetVisuals { @@ -1420,7 +1420,7 @@ impl Widgets { bg_fill: Color32::from_gray(60), // checkbox background bg_stroke: Default::default(), fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, hovered: WidgetVisuals { @@ -1428,7 +1428,7 @@ impl Widgets { bg_fill: Color32::from_gray(70), 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)), - rounding: Rounding::same(3.0), + rounding: Rounding::same(3), expansion: 1.0, }, active: WidgetVisuals { @@ -1436,7 +1436,7 @@ impl Widgets { bg_fill: Color32::from_gray(55), bg_stroke: Stroke::new(1.0, Color32::WHITE), fg_stroke: Stroke::new(2.0, Color32::WHITE), - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 1.0, }, open: WidgetVisuals { @@ -1444,7 +1444,7 @@ impl Widgets { bg_fill: Color32::from_gray(27), bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), fg_stroke: Stroke::new(1.0, Color32::from_gray(210)), - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, } @@ -1457,7 +1457,7 @@ impl Widgets { bg_fill: Color32::from_gray(248), bg_stroke: Stroke::new(1.0, Color32::from_gray(190)), // separators, indentation lines fg_stroke: Stroke::new(1.0, Color32::from_gray(80)), // normal text color - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, inactive: WidgetVisuals { @@ -1465,7 +1465,7 @@ impl Widgets { bg_fill: Color32::from_gray(230), // checkbox background bg_stroke: Default::default(), fg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // button text - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, hovered: WidgetVisuals { @@ -1473,7 +1473,7 @@ impl Widgets { bg_fill: Color32::from_gray(220), 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), - rounding: Rounding::same(3.0), + rounding: Rounding::same(3), expansion: 1.0, }, active: WidgetVisuals { @@ -1481,7 +1481,7 @@ impl Widgets { bg_fill: Color32::from_gray(165), bg_stroke: Stroke::new(1.0, Color32::BLACK), fg_stroke: Stroke::new(2.0, Color32::BLACK), - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 1.0, }, open: WidgetVisuals { @@ -1489,7 +1489,7 @@ impl Widgets { bg_fill: Color32::from_gray(220), bg_stroke: Stroke::new(1.0, Color32::from_gray(160)), fg_stroke: Stroke::new(1.0, Color32::BLACK), - rounding: Rounding::same(2.0), + rounding: Rounding::same(2), expansion: 0.0, }, } @@ -2420,9 +2420,16 @@ impl Widget for &mut Rounding { // Apply the checkbox: if same { - *self = Rounding::same((self.nw + self.ne + self.sw + self.se) / 4.0); - } else if self.is_same() { - self.se *= 1.00001; // prevent collapsing into sameness + *self = Rounding::from(self.average()); + } else { + // Make sure we aren't same: + if self.is_same() { + if self.average() == 0.0 { + self.se = 1; + } else { + self.se -= 1; + } + } } response diff --git a/crates/egui/src/widgets/color_picker.rs b/crates/egui/src/widgets/color_picker.rs index 9a605905968..ea1b53aef9f 100644 --- a/crates/egui/src/widgets/color_picker.rs +++ b/crates/egui/src/widgets/color_picker.rs @@ -99,7 +99,7 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response { show_color_at(ui.painter(), color, rect); - let rounding = visuals.rounding.at_most(2.0); // Can't do more rounding because the background grid doesn't do any rounding + let rounding = visuals.rounding.at_most(2); // Can't do more rounding because the background grid doesn't do any rounding ui.painter() .rect_stroke(rect, rounding, (2.0, visuals.bg_fill)); // fill is intentional, because default style has no border } diff --git a/crates/egui/src/widgets/progress_bar.rs b/crates/egui/src/widgets/progress_bar.rs index 5e099f6a604..7f926d02b73 100644 --- a/crates/egui/src/widgets/progress_bar.rs +++ b/crates/egui/src/widgets/progress_bar.rs @@ -138,7 +138,8 @@ impl Widget for ProgressBar { let rounding = rounding.unwrap_or_else(|| corner_radius.into()); ui.painter() .rect(outer_rect, rounding, visuals.extreme_bg_color, Stroke::NONE); - let min_width = 2.0 * rounding.sw.at_least(rounding.nw).at_most(corner_radius); + let min_width = + 2.0 * f32::max(rounding.sw as _, rounding.nw as _).at_most(corner_radius); let filled_width = (outer_rect.width() * progress).at_least(min_width); let inner_rect = Rect::from_min_size(outer_rect.min, vec2(filled_width, outer_rect.height())); diff --git a/crates/egui/src/widgets/slider.rs b/crates/egui/src/widgets/slider.rs index 7dc3a5cd568..71f4c8499c0 100644 --- a/crates/egui/src/widgets/slider.rs +++ b/crates/egui/src/widgets/slider.rs @@ -780,10 +780,10 @@ impl<'a> Slider<'a> { // The trailing rect has to be drawn differently depending on the orientation. match self.orientation { SliderOrientation::Horizontal => { - trailing_rail_rect.max.x = center.x + rounding.nw; + trailing_rail_rect.max.x = center.x + rounding.nw as f32; } SliderOrientation::Vertical => { - trailing_rail_rect.min.y = center.y - rounding.se; + trailing_rail_rect.min.y = center.y - rounding.se as f32; } }; diff --git a/crates/egui_demo_lib/src/demo/pan_zoom.rs b/crates/egui_demo_lib/src/demo/pan_zoom.rs index f8411a740c0..421dc521a25 100644 --- a/crates/egui_demo_lib/src/demo/pan_zoom.rs +++ b/crates/egui_demo_lib/src/demo/pan_zoom.rs @@ -127,7 +127,7 @@ impl crate::View for PanZoom { .show(ui.ctx(), |ui| { ui.set_clip_rect(transform.inverse() * rect); egui::Frame::default() - .rounding(egui::Rounding::same(4.0)) + .rounding(egui::Rounding::same(4)) .inner_margin(egui::Margin::same(8.0)) .stroke(ui.ctx().style().visuals.window_stroke) .fill(ui.style().visuals.panel_fill) diff --git a/crates/epaint/src/lib.rs b/crates/epaint/src/lib.rs index f37e4a2fa71..1cc9e6c969c 100644 --- a/crates/epaint/src/lib.rs +++ b/crates/epaint/src/lib.rs @@ -30,6 +30,7 @@ mod margin; mod mesh; pub mod mutex; mod rounding; +mod roundingf; mod shadow; mod shape; pub mod shape_transform; @@ -49,6 +50,7 @@ pub use self::{ margin::Margin, mesh::{Mesh, Mesh16, Vertex}, rounding::Rounding, + roundingf::Roundingf, shadow::Shadow, shape::{ CircleShape, EllipseShape, PaintCallback, PaintCallbackInfo, PathShape, RectShape, Shape, diff --git a/crates/epaint/src/rounding.rs b/crates/epaint/src/rounding.rs index 43f37841778..12695f38717 100644 --- a/crates/epaint/src/rounding.rs +++ b/crates/epaint/src/rounding.rs @@ -1,18 +1,23 @@ -/// How rounded the corners of things should be -#[derive(Copy, Clone, Debug, PartialEq)] +/// How rounded the corners of things should be. +/// +/// The rounding uses `u8` to save space, +/// so the amount of rounding is limited to integers in the range `[0, 255]`. +/// +/// For calculations, you may want to use [`crate::Roundingf`] instead, which uses `f32`. +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] pub struct Rounding { /// Radius of the rounding of the North-West (left top) corner. - pub nw: f32, + pub nw: u8, /// Radius of the rounding of the North-East (right top) corner. - pub ne: f32, + pub ne: u8, /// Radius of the rounding of the South-West (left bottom) corner. - pub sw: f32, + pub sw: u8, /// Radius of the rounding of the South-East (right bottom) corner. - pub se: f32, + pub se: u8, } impl Default for Rounding { @@ -22,30 +27,32 @@ impl Default for Rounding { } } +impl From for Rounding { + #[inline] + fn from(radius: u8) -> Self { + Self::same(radius) + } +} + impl From for Rounding { #[inline] fn from(radius: f32) -> Self { - Self { - nw: radius, - ne: radius, - sw: radius, - se: radius, - } + Self::same(radius.round() as u8) } } impl Rounding { /// No rounding on any corner. pub const ZERO: Self = Self { - nw: 0.0, - ne: 0.0, - sw: 0.0, - se: 0.0, + nw: 0, + ne: 0, + sw: 0, + se: 0, }; /// Same rounding on all four corners. #[inline] - pub const fn same(radius: f32) -> Self { + pub const fn same(radius: u8) -> Self { Self { nw: radius, ne: radius, @@ -56,13 +63,13 @@ impl Rounding { /// Do all corners have the same rounding? #[inline] - pub fn is_same(&self) -> bool { + pub fn is_same(self) -> bool { self.nw == self.ne && self.nw == self.sw && self.nw == self.se } /// Make sure each corner has a rounding of at least this. #[inline] - pub fn at_least(&self, min: f32) -> Self { + pub fn at_least(self, min: u8) -> Self { Self { nw: self.nw.max(min), ne: self.ne.max(min), @@ -73,7 +80,7 @@ impl Rounding { /// Make sure each corner has a rounding of at most this. #[inline] - pub fn at_most(&self, max: f32) -> Self { + pub fn at_most(self, max: u8) -> Self { Self { nw: self.nw.min(max), ne: self.ne.min(max), @@ -81,6 +88,11 @@ impl Rounding { se: self.se.min(max), } } + + /// Average rounding of the corners. + pub fn average(&self) -> f32 { + (self.nw as f32 + self.ne as f32 + self.sw as f32 + self.se as f32) / 4.0 + } } impl std::ops::Add for Rounding { @@ -108,14 +120,14 @@ impl std::ops::AddAssign for Rounding { } } -impl std::ops::AddAssign for Rounding { +impl std::ops::AddAssign for Rounding { #[inline] - fn add_assign(&mut self, rhs: f32) { + fn add_assign(&mut self, rhs: u8) { *self = Self { - nw: self.nw + rhs, - ne: self.ne + rhs, - sw: self.sw + rhs, - se: self.se + rhs, + nw: self.nw.saturating_add(rhs), + ne: self.ne.saturating_add(rhs), + sw: self.sw.saturating_add(rhs), + se: self.se.saturating_add(rhs), }; } } @@ -125,10 +137,10 @@ impl std::ops::Sub for Rounding { #[inline] fn sub(self, rhs: Self) -> Self { Self { - nw: self.nw - rhs.nw, - ne: self.ne - rhs.ne, - sw: self.sw - rhs.sw, - se: self.se - rhs.se, + nw: self.nw.saturating_sub(rhs.nw), + ne: self.ne.saturating_sub(rhs.ne), + sw: self.sw.saturating_sub(rhs.sw), + se: self.se.saturating_sub(rhs.se), } } } @@ -137,22 +149,22 @@ impl std::ops::SubAssign for Rounding { #[inline] fn sub_assign(&mut self, rhs: Self) { *self = Self { - nw: self.nw - rhs.nw, - ne: self.ne - rhs.ne, - sw: self.sw - rhs.sw, - se: self.se - rhs.se, + nw: self.nw.saturating_sub(rhs.nw), + ne: self.ne.saturating_sub(rhs.ne), + sw: self.sw.saturating_sub(rhs.sw), + se: self.se.saturating_sub(rhs.se), }; } } -impl std::ops::SubAssign for Rounding { +impl std::ops::SubAssign for Rounding { #[inline] - fn sub_assign(&mut self, rhs: f32) { + fn sub_assign(&mut self, rhs: u8) { *self = Self { - nw: self.nw - rhs, - ne: self.ne - rhs, - sw: self.sw - rhs, - se: self.se - rhs, + nw: self.nw.saturating_sub(rhs), + ne: self.ne.saturating_sub(rhs), + sw: self.sw.saturating_sub(rhs), + se: self.se.saturating_sub(rhs), }; } } @@ -162,10 +174,10 @@ impl std::ops::Div for Rounding { #[inline] fn div(self, rhs: f32) -> Self { Self { - nw: self.nw / rhs, - ne: self.ne / rhs, - sw: self.sw / rhs, - se: self.se / rhs, + nw: (self.nw as f32 / rhs) as u8, + ne: (self.ne as f32 / rhs) as u8, + sw: (self.sw as f32 / rhs) as u8, + se: (self.se as f32 / rhs) as u8, } } } @@ -174,10 +186,10 @@ impl std::ops::DivAssign for Rounding { #[inline] fn div_assign(&mut self, rhs: f32) { *self = Self { - nw: self.nw / rhs, - ne: self.ne / rhs, - sw: self.sw / rhs, - se: self.se / rhs, + nw: (self.nw as f32 / rhs) as u8, + ne: (self.ne as f32 / rhs) as u8, + sw: (self.sw as f32 / rhs) as u8, + se: (self.se as f32 / rhs) as u8, }; } } @@ -187,10 +199,10 @@ impl std::ops::Mul for Rounding { #[inline] fn mul(self, rhs: f32) -> Self { Self { - nw: self.nw * rhs, - ne: self.ne * rhs, - sw: self.sw * rhs, - se: self.se * rhs, + nw: (self.nw as f32 * rhs) as u8, + ne: (self.ne as f32 * rhs) as u8, + sw: (self.sw as f32 * rhs) as u8, + se: (self.se as f32 * rhs) as u8, } } } @@ -199,10 +211,10 @@ impl std::ops::MulAssign for Rounding { #[inline] fn mul_assign(&mut self, rhs: f32) { *self = Self { - nw: self.nw * rhs, - ne: self.ne * rhs, - sw: self.sw * rhs, - se: self.se * rhs, + nw: (self.nw as f32 * rhs) as u8, + ne: (self.ne as f32 * rhs) as u8, + sw: (self.sw as f32 * rhs) as u8, + se: (self.se as f32 * rhs) as u8, }; } } diff --git a/crates/epaint/src/roundingf.rs b/crates/epaint/src/roundingf.rs new file mode 100644 index 00000000000..b49cbc77f80 --- /dev/null +++ b/crates/epaint/src/roundingf.rs @@ -0,0 +1,236 @@ +use crate::Rounding; + +/// How rounded the corners of things should be, in `f32`. +/// +/// This is used for calculations, but storage is usually done with the more compact [`Rounding`]. +#[derive(Copy, Clone, Debug, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] +pub struct Roundingf { + /// Radius of the rounding of the North-West (left top) corner. + pub nw: f32, + + /// Radius of the rounding of the North-East (right top) corner. + pub ne: f32, + + /// Radius of the rounding of the South-West (left bottom) corner. + pub sw: f32, + + /// Radius of the rounding of the South-East (right bottom) corner. + pub se: f32, +} + +impl From for Roundingf { + #[inline] + fn from(rounding: Rounding) -> Self { + Self { + nw: rounding.nw as f32, + ne: rounding.ne as f32, + sw: rounding.sw as f32, + se: rounding.se as f32, + } + } +} + +impl From for Rounding { + #[inline] + fn from(rounding: Roundingf) -> Self { + Self { + nw: rounding.nw.round() as u8, + ne: rounding.ne.round() as u8, + sw: rounding.sw.round() as u8, + se: rounding.se.round() as u8, + } + } +} + +impl Default for Roundingf { + #[inline] + fn default() -> Self { + Self::ZERO + } +} + +impl From for Roundingf { + #[inline] + fn from(radius: f32) -> Self { + Self { + nw: radius, + ne: radius, + sw: radius, + se: radius, + } + } +} + +impl Roundingf { + /// No rounding on any corner. + pub const ZERO: Self = Self { + nw: 0.0, + ne: 0.0, + sw: 0.0, + se: 0.0, + }; + + /// Same rounding on all four corners. + #[inline] + pub const fn same(radius: f32) -> Self { + Self { + nw: radius, + ne: radius, + sw: radius, + se: radius, + } + } + + /// Do all corners have the same rounding? + #[inline] + pub fn is_same(&self) -> bool { + self.nw == self.ne && self.nw == self.sw && self.nw == self.se + } + + /// Make sure each corner has a rounding of at least this. + #[inline] + pub fn at_least(&self, min: f32) -> Self { + Self { + nw: self.nw.max(min), + ne: self.ne.max(min), + sw: self.sw.max(min), + se: self.se.max(min), + } + } + + /// Make sure each corner has a rounding of at most this. + #[inline] + pub fn at_most(&self, max: f32) -> Self { + Self { + nw: self.nw.min(max), + ne: self.ne.min(max), + sw: self.sw.min(max), + se: self.se.min(max), + } + } +} + +impl std::ops::Add for Roundingf { + type Output = Self; + #[inline] + fn add(self, rhs: Self) -> Self { + Self { + nw: self.nw + rhs.nw, + ne: self.ne + rhs.ne, + sw: self.sw + rhs.sw, + se: self.se + rhs.se, + } + } +} + +impl std::ops::AddAssign for Roundingf { + #[inline] + fn add_assign(&mut self, rhs: Self) { + *self = Self { + nw: self.nw + rhs.nw, + ne: self.ne + rhs.ne, + sw: self.sw + rhs.sw, + se: self.se + rhs.se, + }; + } +} + +impl std::ops::AddAssign for Roundingf { + #[inline] + fn add_assign(&mut self, rhs: f32) { + *self = Self { + nw: self.nw + rhs, + ne: self.ne + rhs, + sw: self.sw + rhs, + se: self.se + rhs, + }; + } +} + +impl std::ops::Sub for Roundingf { + type Output = Self; + #[inline] + fn sub(self, rhs: Self) -> Self { + Self { + nw: self.nw - rhs.nw, + ne: self.ne - rhs.ne, + sw: self.sw - rhs.sw, + se: self.se - rhs.se, + } + } +} + +impl std::ops::SubAssign for Roundingf { + #[inline] + fn sub_assign(&mut self, rhs: Self) { + *self = Self { + nw: self.nw - rhs.nw, + ne: self.ne - rhs.ne, + sw: self.sw - rhs.sw, + se: self.se - rhs.se, + }; + } +} + +impl std::ops::SubAssign for Roundingf { + #[inline] + fn sub_assign(&mut self, rhs: f32) { + *self = Self { + nw: self.nw - rhs, + ne: self.ne - rhs, + sw: self.sw - rhs, + se: self.se - rhs, + }; + } +} + +impl std::ops::Div for Roundingf { + type Output = Self; + #[inline] + fn div(self, rhs: f32) -> Self { + Self { + nw: self.nw / rhs, + ne: self.ne / rhs, + sw: self.sw / rhs, + se: self.se / rhs, + } + } +} + +impl std::ops::DivAssign for Roundingf { + #[inline] + fn div_assign(&mut self, rhs: f32) { + *self = Self { + nw: self.nw / rhs, + ne: self.ne / rhs, + sw: self.sw / rhs, + se: self.se / rhs, + }; + } +} + +impl std::ops::Mul for Roundingf { + type Output = Self; + #[inline] + fn mul(self, rhs: f32) -> Self { + Self { + nw: self.nw * rhs, + ne: self.ne * rhs, + sw: self.sw * rhs, + se: self.se * rhs, + } + } +} + +impl std::ops::MulAssign for Roundingf { + #[inline] + fn mul_assign(&mut self, rhs: f32) { + *self = Self { + nw: self.nw * rhs, + ne: self.ne * rhs, + sw: self.sw * rhs, + se: self.se * rhs, + }; + } +} diff --git a/crates/epaint/src/shadow.rs b/crates/epaint/src/shadow.rs index bb386d21dc7..5a68e45baa1 100644 --- a/crates/epaint/src/shadow.rs +++ b/crates/epaint/src/shadow.rs @@ -47,7 +47,7 @@ impl Shadow { } = *self; let rect = rect.translate(offset).expand(spread); - let rounding = rounding.into() + Rounding::same(spread.abs()); + let rounding = rounding.into() + Rounding::from(spread.abs()); RectShape::filled(rect, rounding, color).with_blur_width(blur) } diff --git a/crates/epaint/src/tessellator.rs b/crates/epaint/src/tessellator.rs index bb0ed25e2ca..5e8b131cf71 100644 --- a/crates/epaint/src/tessellator.rs +++ b/crates/epaint/src/tessellator.rs @@ -548,6 +548,8 @@ pub mod path { // Duplicated vertices can happen when one side is all rounding, with no straight edge between. let eps = f32::EPSILON * rect.size().max_elem(); + let r = crate::Roundingf::from(r); + add_circle_quadrant(path, pos2(max.x - r.se, max.y - r.se), r.se, 0.0); // south east if rect.width() <= r.se + r.sw + eps { @@ -628,7 +630,7 @@ pub mod path { let half_width = rect.width() * 0.5; let half_height = rect.height() * 0.5; let max_cr = half_width.min(half_height); - rounding.at_most(max_cr).at_least(0.0) + rounding.at_most(max_cr.floor() as _).at_least(0) } } @@ -1741,7 +1743,7 @@ impl Tessellator { .at_most(rect.size().min_elem() - eps) .at_least(0.0); - rounding += Rounding::same(0.5 * blur_width); + rounding += Rounding::from(0.5 * blur_width); self.feathering = self.feathering.max(blur_width); }