dxf_tools_rs/types/
transparency.rs1use std::fmt;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
11pub struct Transparency(u8);
12
13impl Transparency {
14 pub const OPAQUE: Transparency = Transparency(0);
16
17 pub const TRANSPARENT: Transparency = Transparency(255);
19
20 pub const BY_LAYER: Transparency = Transparency(0);
22
23 pub const fn new(alpha: u8) -> Self {
25 Transparency(alpha)
26 }
27
28 pub fn from_percent(percent: f64) -> Self {
30 let alpha = (percent.clamp(0.0, 1.0) * 255.0) as u8;
31 Transparency(alpha)
32 }
33
34 pub fn from_alpha_value(value: u32) -> Self {
41 let type_byte = (value >> 24) as u8;
42 match type_byte {
43 0 => Transparency::BY_LAYER,
44 1 => Transparency::OPAQUE, 3 => Transparency((value & 0xFF) as u8),
46 _ => Transparency::OPAQUE,
47 }
48 }
49
50 pub const fn alpha(&self) -> u8 {
52 self.0
53 }
54
55 pub fn as_percent(&self) -> f64 {
57 self.0 as f64 / 255.0
58 }
59
60 pub const fn is_opaque(&self) -> bool {
62 self.0 == 0
63 }
64
65 pub const fn is_transparent(&self) -> bool {
67 self.0 == 255
68 }
69
70 pub const T_10: Transparency = Transparency(26); pub const T_20: Transparency = Transparency(51); pub const T_30: Transparency = Transparency(77); pub const T_40: Transparency = Transparency(102); pub const T_50: Transparency = Transparency(128); pub const T_60: Transparency = Transparency(153); pub const T_70: Transparency = Transparency(179); pub const T_80: Transparency = Transparency(204); pub const T_90: Transparency = Transparency(230); pub fn to_alpha_value(&self) -> i32 {
88 if self.0 == 0 {
89 0
91 } else {
92 ((3u32 << 24) | self.0 as u32) as i32
94 }
95 }
96}
97
98impl Default for Transparency {
99 fn default() -> Self {
100 Transparency::OPAQUE
101 }
102}
103
104impl From<u8> for Transparency {
105 fn from(alpha: u8) -> Self {
106 Transparency(alpha)
107 }
108}
109
110impl From<Transparency> for u8 {
111 fn from(transparency: Transparency) -> Self {
112 transparency.0
113 }
114}
115
116impl fmt::Display for Transparency {
117 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
118 write!(f, "{:.1}%", self.as_percent() * 100.0)
119 }
120}
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125
126 #[test]
127 fn test_transparency_creation() {
128 let t = Transparency::new(128);
129 assert_eq!(t.alpha(), 128);
130 }
131
132 #[test]
133 fn test_transparency_from_percent() {
134 let t = Transparency::from_percent(0.5);
135 assert_eq!(t.alpha(), 127);
137
138 let t = Transparency::from_percent(0.0);
139 assert_eq!(t.alpha(), 0);
140
141 let t = Transparency::from_percent(1.0);
142 assert_eq!(t.alpha(), 255);
143 }
144
145 #[test]
146 fn test_transparency_as_percent() {
147 assert_eq!(Transparency::OPAQUE.as_percent(), 0.0);
148 assert_eq!(Transparency::TRANSPARENT.as_percent(), 1.0);
149 assert!((Transparency::T_50.as_percent() - 0.5).abs() < 0.01);
150 }
151
152 #[test]
153 fn test_transparency_checks() {
154 assert!(Transparency::OPAQUE.is_opaque());
155 assert!(!Transparency::OPAQUE.is_transparent());
156 assert!(Transparency::TRANSPARENT.is_transparent());
157 assert!(!Transparency::TRANSPARENT.is_opaque());
158 }
159
160 #[test]
161 fn test_transparency_display() {
162 assert_eq!(Transparency::OPAQUE.to_string(), "0.0%");
163 assert_eq!(Transparency::TRANSPARENT.to_string(), "100.0%");
164 }
165
166 #[test]
167 fn test_transparency_conversion() {
168 let alpha: u8 = 100;
169 let t: Transparency = alpha.into();
170 let back: u8 = t.into();
171 assert_eq!(alpha, back);
172 }
173
174 #[test]
175 fn test_default_transparency() {
176 assert_eq!(Transparency::default(), Transparency::OPAQUE);
177 }
178}
179