Skip to main content

smooth_frame/input/rect/
mod.rs

1mod axis;
2mod corner;
3mod path_builder;
4
5use crate::output::path::SmoothPath;
6use crate::utils::clamp01;
7
8use path_builder::build_rect_path;
9
10/// 矩形便捷封装。
11#[derive(Debug, Clone, Copy, PartialEq)]
12pub struct SmoothRect {
13    width: f64,
14    height: f64,
15    radius: f64,
16    smoothing: f64,
17}
18
19impl SmoothRect {
20    /// 创建矩形便捷封装。
21    ///
22    /// 宽高为非有限数、负数或零时会退化为单点闭合路径。
23    #[must_use]
24    pub fn new(width: f64, height: f64) -> Self {
25        Self {
26            width,
27            height,
28            radius: 0.0,
29            smoothing: 0.0,
30        }
31    }
32
33    /// 设置矩形角半径。
34    ///
35    /// 负数或非有限数会按 0 处理,过大的半径会 clamp 到短边的一半。
36    #[must_use]
37    pub fn with_radius(mut self, radius: f64) -> Self {
38        self.radius = radius;
39        self
40    }
41
42    /// 设置 Sketch-like smoothing。
43    ///
44    /// 有限数会 clamp 到 `[0, 1]`,非有限数会按 0 处理。
45    #[must_use]
46    pub fn with_smoothing(mut self, smoothing: f64) -> Self {
47        self.smoothing = smoothing;
48        self
49    }
50
51    /// 生成矩形 smooth corner 路径。
52    #[must_use]
53    pub fn to_path(&self) -> SmoothPath {
54        let width = sanitize_dimension(self.width);
55        let height = sanitize_dimension(self.height);
56        let requested_radius = sanitize_dimension(self.radius);
57        let radius = requested_radius.min(width.min(height) / 2.0);
58        let smoothing = if self.smoothing.is_finite() {
59            clamp01(self.smoothing)
60        } else {
61            0.0
62        };
63
64        build_rect_path(width, height, radius, smoothing)
65    }
66}
67
68// 将负数或非有限尺寸按 0 处理。
69fn sanitize_dimension(value: f64) -> f64 {
70    if value.is_finite() && value > 0.0 {
71        value
72    } else {
73        0.0
74    }
75}