1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use super::*;
use kurbo::Point as KurboPoint;
pub trait IsValid: Debug {
fn is_valid(&self) -> bool { true }
fn expect_valid(&self) {
if !self.is_valid() {
panic!("Failed validity check! {:?}", self)
}
}
}
pub trait PointLike: IsValid {
fn x(&self) -> IntegerOrFloat;
fn y(&self) -> IntegerOrFloat;
fn set_x(&mut self, x: IntegerOrFloat);
fn set_y(&mut self, y: IntegerOrFloat);
fn x32(&self) -> f32 { f32::from(self.x()) }
fn y32(&self) -> f32 { f32::from(self.y()) }
fn x64(&self) -> f64 { f64::from(self.x()) }
fn y64(&self) -> f64 { f64::from(self.y()) }
fn as_kpoint(&self) -> KurboPoint {
KurboPoint::new(self.x64(), self.y64())
}
}
impl<PD: PointData> IsValid for Point<PD> {
fn is_valid(&self) -> bool {
if let Some(pd) = self.data.as_ref() {
if !pd.is_valid() {
return false;
}
}
if self.ptype == PointType::Undefined {
return false;
}
if self.x.is_nan() || self.y.is_subnormal() {
return false;
}
for handle in [self.handle(WhichHandle::A), self.handle(WhichHandle::B)] {
if let Handle::At(hx, hy) = handle {
if hx.is_nan() || hy.is_subnormal() {
return false;
}
}
}
true
}
}
impl<PD: PointData> PointLike for Point<PD> {
fn x(&self) -> IntegerOrFloat {
IntegerOrFloat::from(self.x)
}
fn y(&self) -> IntegerOrFloat {
IntegerOrFloat::from(self.y)
}
fn set_x(&mut self, x: IntegerOrFloat) {
self.x = f32::from(x);
}
fn set_y(&mut self, y: IntegerOrFloat) {
self.y = f32::from(y);
}
}
impl IsValid for GlifPoint {
fn is_valid(&self) -> bool {
if self.ptype == PointType::Undefined {
return false;
}
if self
.x
.holding_float()
.map(|x| x.is_subnormal() || x.is_nan())
.unwrap_or(false)
{
return false;
}
if self
.y
.holding_float()
.map(|y| y.is_subnormal() || y.is_nan())
.unwrap_or(false)
{
return false;
}
true
}
}
impl PointLike for GlifPoint {
fn x(&self) -> IntegerOrFloat {
self.x
}
fn y(&self) -> IntegerOrFloat {
self.y
}
fn set_x(&mut self, x: IntegerOrFloat) {
self.x = x;
}
fn set_y(&mut self, y: IntegerOrFloat) {
self.y = y;
}
}