mirror of
https://github.com/emilk/egui.git
synced 2026-08-30 13:20:05 -04:00
Use u8 in Rounding, and introduce Roundingf (#5563)
* Part of https://github.com/emilk/egui/issues/4019 As part of the work on adding a custom `Border` to everything, I want to make sure that the size of `RectShape`, `Frame` and the future `Border` is kept small (for performance reasons). This PR changes the storage of the corner radius of rectangles from four `f32` (one for each corner) into four `u8`. This mean the corner radius can only be an integer in the range 0-255 (in ui points). This should be enough for most people. If you want to manipulate rounding using `f32`, there is a new `Roundingf` to fill that niche.
This commit is contained in:
@@ -29,6 +29,8 @@ pub mod image;
|
||||
mod margin;
|
||||
mod mesh;
|
||||
pub mod mutex;
|
||||
mod rounding;
|
||||
mod roundingf;
|
||||
mod shadow;
|
||||
mod shape;
|
||||
pub mod shape_transform;
|
||||
@@ -47,10 +49,12 @@ pub use self::{
|
||||
image::{ColorImage, FontImage, ImageData, ImageDelta},
|
||||
margin::Margin,
|
||||
mesh::{Mesh, Mesh16, Vertex},
|
||||
rounding::Rounding,
|
||||
roundingf::Roundingf,
|
||||
shadow::Shadow,
|
||||
shape::{
|
||||
CircleShape, EllipseShape, PaintCallback, PaintCallbackInfo, PathShape, RectShape,
|
||||
Rounding, Shape, TextShape,
|
||||
CircleShape, EllipseShape, PaintCallback, PaintCallbackInfo, PathShape, RectShape, Shape,
|
||||
TextShape,
|
||||
},
|
||||
stats::PaintStats,
|
||||
stroke::{PathStroke, Stroke, StrokeKind},
|
||||
|
||||
220
crates/epaint/src/rounding.rs
Normal file
220
crates/epaint/src/rounding.rs
Normal file
@@ -0,0 +1,220 @@
|
||||
/// 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: u8,
|
||||
|
||||
/// Radius of the rounding of the North-East (right top) corner.
|
||||
pub ne: u8,
|
||||
|
||||
/// Radius of the rounding of the South-West (left bottom) corner.
|
||||
pub sw: u8,
|
||||
|
||||
/// Radius of the rounding of the South-East (right bottom) corner.
|
||||
pub se: u8,
|
||||
}
|
||||
|
||||
impl Default for Rounding {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u8> for Rounding {
|
||||
#[inline]
|
||||
fn from(radius: u8) -> Self {
|
||||
Self::same(radius)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Rounding {
|
||||
#[inline]
|
||||
fn from(radius: f32) -> Self {
|
||||
Self::same(radius.round() as u8)
|
||||
}
|
||||
}
|
||||
|
||||
impl Rounding {
|
||||
/// No rounding on any corner.
|
||||
pub const ZERO: Self = Self {
|
||||
nw: 0,
|
||||
ne: 0,
|
||||
sw: 0,
|
||||
se: 0,
|
||||
};
|
||||
|
||||
/// Same rounding on all four corners.
|
||||
#[inline]
|
||||
pub const fn same(radius: u8) -> 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: u8) -> 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: u8) -> Self {
|
||||
Self {
|
||||
nw: self.nw.min(max),
|
||||
ne: self.ne.min(max),
|
||||
sw: self.sw.min(max),
|
||||
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 {
|
||||
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 Rounding {
|
||||
#[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<u8> for Rounding {
|
||||
#[inline]
|
||||
fn add_assign(&mut self, rhs: u8) {
|
||||
*self = Self {
|
||||
nw: self.nw.saturating_add(rhs),
|
||||
ne: self.ne.saturating_add(rhs),
|
||||
sw: self.sw.saturating_add(rhs),
|
||||
se: self.se.saturating_add(rhs),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Sub for Rounding {
|
||||
type Output = Self;
|
||||
#[inline]
|
||||
fn sub(self, rhs: Self) -> Self {
|
||||
Self {
|
||||
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 {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: Self) {
|
||||
*self = Self {
|
||||
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<u8> for Rounding {
|
||||
#[inline]
|
||||
fn sub_assign(&mut self, rhs: u8) {
|
||||
*self = Self {
|
||||
nw: self.nw.saturating_sub(rhs),
|
||||
ne: self.ne.saturating_sub(rhs),
|
||||
sw: self.sw.saturating_sub(rhs),
|
||||
se: self.se.saturating_sub(rhs),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Div<f32> for Rounding {
|
||||
type Output = Self;
|
||||
#[inline]
|
||||
fn div(self, rhs: f32) -> Self {
|
||||
Self {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DivAssign<f32> for Rounding {
|
||||
#[inline]
|
||||
fn div_assign(&mut self, rhs: f32) {
|
||||
*self = Self {
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<f32> for Rounding {
|
||||
type Output = Self;
|
||||
#[inline]
|
||||
fn mul(self, rhs: f32) -> Self {
|
||||
Self {
|
||||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::MulAssign<f32> for Rounding {
|
||||
#[inline]
|
||||
fn mul_assign(&mut self, rhs: f32) {
|
||||
*self = Self {
|
||||
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,
|
||||
};
|
||||
}
|
||||
}
|
||||
236
crates/epaint/src/roundingf.rs
Normal file
236
crates/epaint/src/roundingf.rs
Normal file
@@ -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<Rounding> 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<Roundingf> 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<f32> 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<f32> 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<f32> 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<f32> 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<f32> 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<f32> 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<f32> 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,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::{any::Any, sync::Arc};
|
||||
use crate::{
|
||||
stroke::PathStroke,
|
||||
text::{FontId, Fonts, Galley},
|
||||
Color32, Mesh, Stroke, TextureId,
|
||||
Color32, Mesh, Rounding, Stroke, TextureId,
|
||||
};
|
||||
use emath::{pos2, Align2, Pos2, Rangef, Rect, TSTransform, Vec2};
|
||||
|
||||
@@ -779,214 +779,6 @@ impl From<RectShape> for Shape {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
/// How rounded the corners of things should be
|
||||
pub struct Rounding {
|
||||
/// 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 Default for Rounding {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Rounding {
|
||||
#[inline]
|
||||
fn from(radius: f32) -> Self {
|
||||
Self {
|
||||
nw: radius,
|
||||
ne: radius,
|
||||
sw: radius,
|
||||
se: radius,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Rounding {
|
||||
/// No rounding on any corner.
|
||||
pub const ZERO: Self = Self {
|
||||
nw: 0.0,
|
||||
ne: 0.0,
|
||||
sw: 0.0,
|
||||
se: 0.0,
|
||||
};
|
||||
|
||||
#[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 Rounding {
|
||||
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 Rounding {
|
||||
#[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<f32> for Rounding {
|
||||
#[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 Rounding {
|
||||
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 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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::SubAssign<f32> for Rounding {
|
||||
#[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<f32> for Rounding {
|
||||
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<f32> 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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Mul<f32> for Rounding {
|
||||
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<f32> 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,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/// How to paint some text on screen.
|
||||
|
||||
@@ -525,7 +525,7 @@ impl Path {
|
||||
|
||||
pub mod path {
|
||||
//! Helpers for constructing paths
|
||||
use crate::shape::Rounding;
|
||||
use crate::Rounding;
|
||||
use emath::{pos2, Pos2, Rect};
|
||||
|
||||
/// overwrites existing points
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user