1use glyphon::Metrics;
2use glyphon::cosmic_text::Align;
3
4pub type ClipRect = (f32, f32, f32, f32);
6
7#[derive(Clone, Copy)]
8pub struct QuadCommand {
9 pub rect: (f32, f32, f32, f32),
10 pub color: [f32; 4],
11 pub border_radius: f32,
12 pub border_width: f32,
13 pub border_color: [f32; 4],
14 pub clip: Option<ClipRect>,
15}
16
17pub struct TextCommand {
18 pub text: String,
19 pub pos: (f32, f32),
20 pub color: [u8; 3],
21 pub bounds: (f32, f32),
22 pub metrics: Metrics,
23 pub align: Align,
24 pub clip: Option<ClipRect>,
25 pub font_family: Option<String>,
26 pub measure_chars: Vec<usize>,
29}
30
31pub struct Renderer {
32 pub quad_commands: Vec<QuadCommand>,
33 pub text_commands: Vec<TextCommand>,
34 pub text_measures: Vec<Vec<f32>>,
37 clip_stack: Vec<ClipRect>,
38 pub overlay_quad_commands: Vec<QuadCommand>,
40 pub overlay_text_commands: Vec<TextCommand>,
41}
42
43impl Renderer {
44 pub fn new() -> Self {
45 Self {
46 quad_commands: Vec::new(),
47 text_commands: Vec::new(),
48 text_measures: Vec::new(),
49 clip_stack: Vec::new(),
50 overlay_quad_commands: Vec::new(),
51 overlay_text_commands: Vec::new(),
52 }
53 }
54
55 pub fn clear(&mut self) {
56 self.quad_commands.clear();
57 self.text_commands.clear();
58 self.text_measures.clear();
59 self.clip_stack.clear();
60 self.overlay_quad_commands.clear();
61 self.overlay_text_commands.clear();
62 }
63
64 pub fn overlay_fill_rect_styled(
66 &mut self,
67 rect: (f32, f32, f32, f32),
68 color: [f32; 4],
69 border_radius: f32,
70 border_width: f32,
71 border_color: [f32; 4],
72 ) {
73 self.overlay_quad_commands.push(QuadCommand {
74 rect,
75 color,
76 border_radius,
77 border_width,
78 border_color,
79 clip: None,
80 });
81 }
82
83 pub fn overlay_draw_text(
85 &mut self,
86 text: &str,
87 pos: (f32, f32),
88 color: [u8; 3],
89 bounds: (f32, f32),
90 metrics: Metrics,
91 align: Align,
92 ) {
93 self.overlay_text_commands.push(TextCommand {
94 text: text.to_string(),
95 pos,
96 color,
97 bounds,
98 metrics,
99 align,
100 clip: None,
101 font_family: None,
102 measure_chars: vec![],
103 });
104 }
105
106 pub fn overlay_draw_text_with_font(
108 &mut self,
109 text: &str,
110 pos: (f32, f32),
111 color: [u8; 3],
112 bounds: (f32, f32),
113 metrics: Metrics,
114 align: Align,
115 font_family: &str,
116 ) {
117 self.overlay_text_commands.push(TextCommand {
118 text: text.to_string(),
119 pos,
120 color,
121 bounds,
122 metrics,
123 align,
124 clip: None,
125 font_family: Some(font_family.to_string()),
126 measure_chars: vec![],
127 });
128 }
129
130 pub fn push_clip(&mut self, clip: ClipRect) {
131 self.clip_stack.push(clip);
132 }
133
134 pub fn pop_clip(&mut self) {
135 self.clip_stack.pop();
136 }
137
138 fn current_clip(&self) -> Option<ClipRect> {
139 self.clip_stack.last().copied()
140 }
141
142 pub fn fill_rect(&mut self, rect: (f32, f32, f32, f32), color: [f32; 3]) {
143 self.quad_commands.push(QuadCommand {
144 rect,
145 color: [color[0], color[1], color[2], 1.0],
146 border_radius: 0.0,
147 border_width: 0.0,
148 border_color: [0.0; 4],
149 clip: self.current_clip(),
150 });
151 }
152
153 pub fn fill_rect_rounded(
154 &mut self,
155 rect: (f32, f32, f32, f32),
156 color: [f32; 4],
157 border_radius: f32,
158 ) {
159 self.quad_commands.push(QuadCommand {
160 rect,
161 color,
162 border_radius,
163 border_width: 0.0,
164 border_color: [0.0; 4],
165 clip: self.current_clip(),
166 });
167 }
168
169 pub fn fill_rect_styled(
170 &mut self,
171 rect: (f32, f32, f32, f32),
172 color: [f32; 4],
173 border_radius: f32,
174 border_width: f32,
175 border_color: [f32; 4],
176 ) {
177 self.quad_commands.push(QuadCommand {
178 rect,
179 color,
180 border_radius,
181 border_width,
182 border_color,
183 clip: self.current_clip(),
184 });
185 }
186
187 pub fn draw_text(
188 &mut self,
189 text: &str,
190 pos: (f32, f32),
191 color: [u8; 3],
192 bounds: (f32, f32),
193 metrics: Metrics,
194 align: Align,
195 ) {
196 self.text_commands.push(TextCommand {
197 text: text.to_string(),
198 pos,
199 color,
200 bounds,
201 metrics,
202 align,
203 clip: self.current_clip(),
204 font_family: None,
205 measure_chars: vec![],
206 });
207 }
208
209 pub fn draw_text_with_font(
210 &mut self,
211 text: &str,
212 pos: (f32, f32),
213 color: [u8; 3],
214 bounds: (f32, f32),
215 metrics: Metrics,
216 align: Align,
217 font_family: &str,
218 ) {
219 self.text_commands.push(TextCommand {
220 text: text.to_string(),
221 pos,
222 color,
223 bounds,
224 metrics,
225 align,
226 clip: self.current_clip(),
227 font_family: Some(font_family.to_string()),
228 measure_chars: vec![],
229 });
230 }
231
232 pub fn draw_text_measured(
233 &mut self,
234 text: &str,
235 pos: (f32, f32),
236 color: [u8; 3],
237 bounds: (f32, f32),
238 metrics: Metrics,
239 align: Align,
240 measure_chars: Vec<usize>,
241 ) -> usize {
242 let idx = self.text_commands.len();
243 self.text_commands.push(TextCommand {
244 text: text.to_string(),
245 pos,
246 color,
247 bounds,
248 metrics,
249 align,
250 clip: self.current_clip(),
251 font_family: None,
252 measure_chars,
253 });
254 idx
255 }
256}