Skip to main content

easyofd_core/model/
point.rs

1//! 坐标点。
2//!
3//! 对应 Java: org.ofdrw.core.basicType.Point
4
5use crate::page_description::color::CT_Color;
6
7/// 坐标点(ofd:Point),含可选边缘标志与颜色。
8///
9/// 对应 Java: ofdrw Point。
10#[derive(Debug, Clone, PartialEq)]
11pub struct Point {
12    /// X 坐标。
13    pub x: f64,
14    /// Y 坐标。
15    pub y: f64,
16    /// 边缘标志(0 或 1,可选)。
17    pub edge_flag: Option<u8>,
18    /// 颜色(可选)。
19    pub color: Option<CT_Color>,
20}
21
22/// 边缘标志值。
23pub mod edge_flag {
24    /// 闭合路径边缘点。
25    pub const CLOSED: u8 = 0;
26    /// 非闭合路径边缘点。
27    pub const OPEN: u8 = 1;
28}
29
30impl Point {
31    /// 创建坐标点。
32    #[must_use]
33    pub fn new(x: f64, y: f64) -> Self {
34        Self {
35            x,
36            y,
37            edge_flag: None,
38            color: None,
39        }
40    }
41
42    /// 设置边缘标志。
43    #[must_use]
44    pub fn with_edge_flag(mut self, flag: u8) -> Self {
45        self.edge_flag = Some(flag);
46        self
47    }
48
49    /// 设置颜色。
50    #[must_use]
51    pub fn with_color(mut self, color: CT_Color) -> Self {
52        self.color = Some(color);
53        self
54    }
55
56    /// 设置 X 坐标(对应 Java: Point#setX)。
57    #[must_use]
58    pub fn set_x(mut self, x: f64) -> Self {
59        self.x = x;
60        self
61    }
62
63    /// 设置 Y 坐标(对应 Java: Point#setY)。
64    #[must_use]
65    pub fn set_y(mut self, y: f64) -> Self {
66        self.y = y;
67        self
68    }
69}
70
71impl From<(f64, f64)> for Point {
72    fn from((x, y): (f64, f64)) -> Self {
73        Self::new(x, y)
74    }
75}
76
77impl std::fmt::Display for Point {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        write!(f, "{} {}", self.x, self.y)
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use super::*;
86
87    fn approx(a: f64, b: f64) -> bool {
88        (a - b).abs() < f64::EPSILON
89    }
90
91    #[test]
92    fn test_point_new() {
93        let p = Point::new(1.5, 2.5);
94        assert!(approx(p.x, 1.5));
95        assert!(approx(p.y, 2.5));
96        assert!(p.edge_flag.is_none());
97    }
98
99    #[test]
100    fn test_builders() {
101        let p = Point::new(0.0, 0.0)
102            .with_edge_flag(edge_flag::OPEN)
103            .set_x(10.0)
104            .set_y(20.0);
105        assert!(approx(p.x, 10.0));
106        assert_eq!(p.edge_flag, Some(1));
107        assert!(p.color.is_none());
108    }
109
110    #[test]
111    fn test_from_tuple_and_display() {
112        let p = Point::from((3.0, 4.0));
113        assert_eq!(p.to_string(), "3 4");
114    }
115}