ratex_types/
display_item.rs1use serde::{Deserialize, Serialize};
2
3use crate::color::Color;
4use crate::path_command::PathCommand;
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct DisplayList {
10 pub items: Vec<DisplayItem>,
11 pub width: f64,
12 pub height: f64,
13 pub depth: f64,
14}
15
16#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
18#[serde(tag = "type")]
19pub enum DisplayItem {
20 GlyphPath {
22 x: f64,
23 y: f64,
24 scale: f64,
25 font: String,
26 char_code: u32,
27 #[serde(skip_serializing, default)]
31 commands: Vec<PathCommand>,
32 color: Color,
33 },
34 Line {
36 x: f64,
37 y: f64,
38 width: f64,
39 thickness: f64,
40 color: Color,
41 #[serde(default)]
43 dashed: bool,
44 },
45 Rect {
47 x: f64,
48 y: f64,
49 width: f64,
50 height: f64,
51 color: Color,
52 },
53 Path {
55 x: f64,
56 y: f64,
57 commands: Vec<PathCommand>,
58 fill: bool,
59 color: Color,
60 },
61}
62
63impl DisplayList {
64 pub fn new() -> Self {
65 Self {
66 items: Vec::new(),
67 width: 0.0,
68 height: 0.0,
69 depth: 0.0,
70 }
71 }
72
73 pub fn total_height(&self) -> f64 {
74 self.height + self.depth
75 }
76}
77
78impl Default for DisplayList {
79 fn default() -> Self {
80 Self::new()
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_display_list_new() {
90 let dl = DisplayList::new();
91 assert!(dl.items.is_empty());
92 assert!((dl.width - 0.0).abs() < f64::EPSILON);
93 assert!((dl.total_height() - 0.0).abs() < f64::EPSILON);
94 }
95
96 #[test]
97 fn test_serde_roundtrip() {
98 let dl = DisplayList {
99 items: vec![
100 DisplayItem::Line {
101 x: 0.0,
102 y: 5.0,
103 width: 10.0,
104 thickness: 0.04,
105 color: Color::BLACK,
106 dashed: false,
107 },
108 DisplayItem::Rect {
109 x: 0.0,
110 y: 0.0,
111 width: 10.0,
112 height: 10.0,
113 color: Color::rgb(1.0, 0.0, 0.0),
114 },
115 DisplayItem::Path {
116 x: 0.0,
117 y: 0.0,
118 commands: vec![
119 PathCommand::MoveTo { x: 0.0, y: 0.0 },
120 PathCommand::LineTo { x: 5.0, y: 5.0 },
121 PathCommand::Close,
122 ],
123 fill: false,
124 color: Color::BLACK,
125 },
126 ],
127 width: 10.0,
128 height: 5.0,
129 depth: 5.0,
130 };
131
132 let json = serde_json::to_string(&dl).unwrap();
133 let dl2: DisplayList = serde_json::from_str(&json).unwrap();
134
135 assert_eq!(dl.items.len(), dl2.items.len());
136 assert!((dl.width - dl2.width).abs() < f64::EPSILON);
137 assert!((dl.height - dl2.height).abs() < f64::EPSILON);
138 assert!((dl.depth - dl2.depth).abs() < f64::EPSILON);
139 }
140
141 #[test]
142 fn test_total_height() {
143 let dl = DisplayList {
144 items: vec![],
145 width: 10.0,
146 height: 3.0,
147 depth: 2.0,
148 };
149 assert!((dl.total_height() - 5.0).abs() < f64::EPSILON);
150 }
151}