Skip to main content

easyofd_core/graphics2d/
ofd_shapes.rs

1//! OFD 形状集合。
2//!
3//! 对应 Java: org.ofdrw.graphics2d.OFDShapes
4//!
5//! Java 版提供 `java.awt.Shape` 实现集合(矩形、椭圆、圆弧等)。
6//! Rust 版提供简化枚举,列出常用形状类型。
7
8/// 形状类型枚举。
9///
10/// 对应 Java: org.ofdrw.graphics2d.OFDShapes
11///
12/// 列出 OFD 绘图中常用的 2D 形状类型。
13/// Java 版每个变体是独立的 `Shape` 实现类;Rust 版合并为枚举。
14#[derive(Debug, Clone, PartialEq)]
15#[allow(missing_docs)]
16pub enum OfdShape {
17    /// 矩形。
18    Rect { x: f64, y: f64, w: f64, h: f64 },
19    /// 椭圆。
20    Ellipse { cx: f64, cy: f64, rx: f64, ry: f64 },
21    /// 圆。
22    Circle { cx: f64, cy: f64, r: f64 },
23    /// 线段。
24    Line { x1: f64, y1: f64, x2: f64, y2: f64 },
25    /// 圆弧。
26    Arc {
27        cx: f64,
28        cy: f64,
29        rx: f64,
30        ry: f64,
31        start_angle: f64,
32        extent: f64,
33    },
34}
35
36/// OFD 形状集合容器。
37///
38/// 对应 Java: org.ofdrw.graphics2d.OFDShapes
39///
40/// 持有一组待绘制的形状。
41#[derive(Debug, Clone, Default)]
42pub struct OfdShapes {
43    /// 形状列表。
44    shapes: Vec<OfdShape>,
45}
46
47impl OfdShapes {
48    /// 创建空形状集合。
49    #[must_use]
50    pub fn new() -> Self {
51        Self::default()
52    }
53
54    /// 添加形状。
55    pub fn push(&mut self, shape: OfdShape) {
56        self.shapes.push(shape);
57    }
58
59    /// 链式添加形状。
60    #[must_use]
61    pub fn with(mut self, shape: OfdShape) -> Self {
62        self.shapes.push(shape);
63        self
64    }
65
66    /// 获取形状数量。
67    #[must_use]
68    pub fn len(&self) -> usize {
69        self.shapes.len()
70    }
71
72    /// 是否为空。
73    #[must_use]
74    pub fn is_empty(&self) -> bool {
75        self.shapes.is_empty()
76    }
77
78    /// 获取形状列表引用。
79    #[must_use]
80    pub fn shapes(&self) -> &[OfdShape] {
81        &self.shapes
82    }
83}
84
85#[cfg(test)]
86mod tests {
87    use super::*;
88
89    #[test]
90    fn test_empty() {
91        let s = OfdShapes::new();
92        assert!(s.is_empty());
93        assert_eq!(s.len(), 0);
94    }
95
96    #[test]
97    fn test_push_and_len() {
98        let mut s = OfdShapes::new();
99        s.push(OfdShape::Rect {
100            x: 0.0,
101            y: 0.0,
102            w: 10.0,
103            h: 20.0,
104        });
105        s.push(OfdShape::Circle {
106            cx: 5.0,
107            cy: 5.0,
108            r: 3.0,
109        });
110        assert_eq!(s.len(), 2);
111        assert!(!s.is_empty());
112    }
113
114    #[test]
115    fn test_with_chain() {
116        let s = OfdShapes::new()
117            .with(OfdShape::Line {
118                x1: 0.0,
119                y1: 0.0,
120                x2: 10.0,
121                y2: 10.0,
122            })
123            .with(OfdShape::Ellipse {
124                cx: 5.0,
125                cy: 5.0,
126                rx: 3.0,
127                ry: 2.0,
128            });
129        assert_eq!(s.len(), 2);
130    }
131
132    #[test]
133    fn test_shape_variants() {
134        let rect = OfdShape::Rect {
135            x: 1.0,
136            y: 2.0,
137            w: 3.0,
138            h: 4.0,
139        };
140        let ellipse = OfdShape::Ellipse {
141            cx: 0.0,
142            cy: 0.0,
143            rx: 5.0,
144            ry: 3.0,
145        };
146        let circle = OfdShape::Circle {
147            cx: 1.0,
148            cy: 1.0,
149            r: 2.0,
150        };
151        let line = OfdShape::Line {
152            x1: 0.0,
153            y1: 0.0,
154            x2: 1.0,
155            y2: 1.0,
156        };
157        let arc = OfdShape::Arc {
158            cx: 0.0,
159            cy: 0.0,
160            rx: 1.0,
161            ry: 1.0,
162            start_angle: 0.0,
163            extent: 90.0,
164        };
165        // 验证 Debug 不 panic
166        let _ = format!("{rect:?} {ellipse:?} {circle:?} {line:?} {arc:?}");
167    }
168
169    #[test]
170    fn test_clone_eq() {
171        let s = OfdShapes::new().with(OfdShape::Rect {
172            x: 0.0,
173            y: 0.0,
174            w: 1.0,
175            h: 1.0,
176        });
177        let s2 = s.clone();
178        assert_eq!(s.len(), s2.len());
179        assert_eq!(s.shapes(), s2.shapes());
180    }
181}