1use super::*;
12use agg_gui::draw_ctx::DrawCtx;
13use agg_gui::text::{measure_text_metrics, TextMetrics};
14use agg_gui::CompOp;
15use agg_rust::arc::Arc as AggArc;
16use agg_rust::basics::PATH_FLAGS_NONE;
17use agg_rust::rounded_rect::RoundedRect;
18
19impl DrawCtx for WgpuGfxCtx {
20 fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
21 Some(self as &mut dyn std::any::Any)
22 }
23
24 fn set_fill_color(&mut self, c: Color) {
27 self.fill_color = c;
28 self.fill_linear_gradient = None;
29 self.fill_radial_gradient = None;
30 }
31
32 fn set_fill_linear_gradient(&mut self, gradient: LinearGradientPaint) {
33 self.fill_linear_gradient = Some(gradient);
34 self.fill_radial_gradient = None;
35 }
36
37 fn supports_fill_linear_gradient(&self) -> bool {
38 true
39 }
40
41 fn set_fill_radial_gradient(&mut self, gradient: RadialGradientPaint) {
42 self.fill_linear_gradient = None;
43 self.fill_radial_gradient = Some(gradient);
44 }
45
46 fn supports_fill_radial_gradient(&self) -> bool {
47 true
48 }
49
50 fn set_stroke_color(&mut self, c: Color) {
51 self.stroke_color = c;
52 self.stroke_linear_gradient = None;
53 self.stroke_radial_gradient = None;
54 }
55
56 fn set_stroke_linear_gradient(&mut self, gradient: LinearGradientPaint) {
57 self.stroke_linear_gradient = Some(gradient);
58 self.stroke_radial_gradient = None;
59 }
60
61 fn supports_stroke_linear_gradient(&self) -> bool {
62 true
63 }
64
65 fn set_stroke_radial_gradient(&mut self, gradient: RadialGradientPaint) {
66 self.stroke_linear_gradient = None;
67 self.stroke_radial_gradient = Some(gradient);
68 }
69
70 fn supports_stroke_radial_gradient(&self) -> bool {
71 true
72 }
73
74 fn set_line_width(&mut self, w: f64) {
75 self.line_width = w;
76 }
77
78 fn set_line_join(&mut self, j: LineJoin) {
79 self.line_join = j;
80 }
81
82 fn set_line_cap(&mut self, c: LineCap) {
83 self.line_cap = c;
84 }
85
86 fn set_miter_limit(&mut self, limit: f64) {
87 self.miter_limit = limit.max(1.0);
88 }
89
90 fn set_line_dash(&mut self, dashes: &[f64], offset: f64) {
91 self.line_dash.clear();
92 self.line_dash
93 .extend(dashes.iter().copied().filter(|v| *v > 0.0));
94 self.dash_offset = offset;
95 }
96
97 fn set_blend_mode(&mut self, _mode: CompOp) {
98 }
101
102 fn set_global_alpha(&mut self, a: f64) {
103 self.global_alpha = a;
104 }
105
106 fn set_fill_rule(&mut self, rule: agg_gui::draw_ctx::FillRule) {
107 self.fill_rule = rule;
108 }
109
110 fn set_font(&mut self, font: std::sync::Arc<Font>) {
113 self.font = Some(font);
114 }
115
116 fn set_font_size(&mut self, size: f64) {
117 self.font_size = size;
118 }
119
120 fn clip_rect(&mut self, x: f64, y: f64, w: f64, h: f64) {
123 let (mut x0, mut y0) = (x, y);
125 let (mut x1, mut y1) = (x + w, y + h);
126 self.ctm().transform(&mut x0, &mut y0);
127 self.ctm().transform(&mut x1, &mut y1);
128 let (lx, rx) = if x0 < x1 { (x0, x1) } else { (x1, x0) };
129 let (by, ty) = if y0 < y1 { (y0, y1) } else { (y1, y0) };
130 let [nx, ny, nw, nh] = Self::compute_scissor(lx, by, rx, ty);
131
132 let [ix, iy, iw, ih] = if let Some([ex, ey, ew, eh]) = self.current_clip() {
134 let nx2 = nx.saturating_add(nw).min(ex.saturating_add(ew));
135 let ny2 = ny.saturating_add(nh).min(ey.saturating_add(eh));
136 let rx2 = nx.max(ex);
137 let ry2 = ny.max(ey);
138 [
139 rx2,
140 ry2,
141 nx2.saturating_sub(rx2).max(0),
142 ny2.saturating_sub(ry2).max(0),
143 ]
144 } else {
145 [nx, ny, nw, nh]
146 };
147
148 self.state_stack.last_mut().unwrap().1 = Some([ix, iy, iw, ih]);
149 }
150
151 fn reset_clip(&mut self) {
152 self.state_stack.last_mut().unwrap().1 = None;
153 }
154
155 fn clear(&mut self, color: Color) {
158 self.commands.push(DrawCommand::Clear(color));
159 }
160
161 fn begin_path(&mut self) {
164 self.path = PathStorage::new();
165 }
166
167 fn move_to(&mut self, x: f64, y: f64) {
168 self.path.move_to(x, y);
169 }
170
171 fn line_to(&mut self, x: f64, y: f64) {
172 self.path.line_to(x, y);
173 }
174
175 fn cubic_to(&mut self, cx1: f64, cy1: f64, cx2: f64, cy2: f64, x: f64, y: f64) {
176 self.path.curve4(cx1, cy1, cx2, cy2, x, y);
177 }
178
179 fn quad_to(&mut self, cx: f64, cy: f64, x: f64, y: f64) {
180 self.path.curve3(cx, cy, x, y);
181 }
182
183 fn arc_to(&mut self, cx: f64, cy: f64, r: f64, start_angle: f64, end_angle: f64, ccw: bool) {
184 let mut arc = AggArc::new(cx, cy, r, r, start_angle, end_angle, ccw);
185 self.path.concat_path(&mut arc, 0);
186 }
187
188 fn circle(&mut self, cx: f64, cy: f64, r: f64) {
189 self.arc_to(cx, cy, r, 0.0, std::f64::consts::TAU, true);
190 self.path.close_polygon(PATH_FLAGS_NONE);
191 }
192
193 fn rect(&mut self, x: f64, y: f64, w: f64, h: f64) {
194 self.path.move_to(x, y);
195 self.path.line_to(x + w, y);
196 self.path.line_to(x + w, y + h);
197 self.path.line_to(x, y + h);
198 self.path.close_polygon(PATH_FLAGS_NONE);
199 }
200
201 fn rounded_rect(&mut self, x: f64, y: f64, w: f64, h: f64, r: f64) {
202 let r = r.min(w * 0.5).min(h * 0.5).max(0.0);
203 let mut rr = RoundedRect::new(x, y, x + w, y + h, r);
204 rr.normalize_radius();
205 self.path.concat_path(&mut rr, 0);
206 }
207
208 fn close_path(&mut self) {
209 self.path.close_polygon(PATH_FLAGS_NONE);
210 }
211
212 fn fill(&mut self) {
215 self.do_fill();
216 }
217
218 fn stroke(&mut self) {
219 self.do_stroke();
220 }
221
222 fn fill_and_stroke(&mut self) {
223 self.do_fill();
225 self.do_stroke();
226 }
227
228 fn draw_triangles_aa(&mut self, vertices: &[[f32; 3]], indices: &[u32], color: Color) {
229 if vertices.is_empty() || indices.is_empty() {
230 return;
231 }
232 let ctm = *self.ctm();
234 let transformed: Vec<[f32; 3]> = vertices
235 .iter()
236 .map(|v| {
237 let (mut x, mut y) = (v[0] as f64, v[1] as f64);
238 ctm.transform(&mut x, &mut y);
239 [x as f32, y as f32, v[2]]
240 })
241 .collect();
242 self.commands.push(DrawCommand::AaSolid {
243 verts: transformed,
244 indices: indices.to_vec(),
245 color,
246 global_alpha: self.global_alpha as f32,
247 clip: self.current_clip(),
248 });
249 }
250
251 fn fill_text(&mut self, text: &str, x: f64, y: f64) {
254 self.fill_text_impl(text, x, y);
255 }
256
257 fn fill_text_gsv(&mut self, _text: &str, _x: f64, _y: f64, _size: f64) {
258 }
261
262 fn measure_text(&self, text: &str) -> Option<TextMetrics> {
263 let font = self.font.as_ref()?;
264 Some(measure_text_metrics(font, text, self.font_size))
265 }
266
267 fn has_image_blit(&self) -> bool {
270 true
271 }
272
273 fn draw_image_rgba(
274 &mut self,
275 data: &[u8],
276 img_w: u32,
277 img_h: u32,
278 dst_x: f64,
279 dst_y: f64,
280 dst_w: f64,
281 dst_h: f64,
282 ) {
283 self.draw_image_rgba_slice_impl(data, img_w, img_h, dst_x, dst_y, dst_w, dst_h);
284 }
285
286 fn draw_image_rgba_arc(
287 &mut self,
288 data: &std::sync::Arc<Vec<u8>>,
289 img_w: u32,
290 img_h: u32,
291 dst_x: f64,
292 dst_y: f64,
293 dst_w: f64,
294 dst_h: f64,
295 ) {
296 self.draw_image_rgba_arc_impl(data, img_w, img_h, dst_x, dst_y, dst_w, dst_h);
297 }
298
299 fn draw_image_rgba_corners(
300 &mut self,
301 data: &std::sync::Arc<Vec<u8>>,
302 img_w: u32,
303 img_h: u32,
304 corners: [(f64, f64); 4],
305 ) {
306 self.draw_image_rgba_corners_impl(data, img_w, img_h, corners);
307 }
308
309 fn has_lcd_mask_composite(&self) -> bool {
310 true
311 }
312
313 fn draw_lcd_mask(
314 &mut self,
315 mask: &[u8],
316 mask_w: u32,
317 mask_h: u32,
318 src_color: agg_gui::Color,
319 dst_x: f64,
320 dst_y: f64,
321 ) {
322 self.draw_lcd_mask_slice_impl(mask, mask_w, mask_h, src_color, dst_x, dst_y);
323 }
324
325 fn draw_lcd_mask_arc(
326 &mut self,
327 mask: &std::sync::Arc<Vec<u8>>,
328 mask_w: u32,
329 mask_h: u32,
330 src_color: agg_gui::Color,
331 dst_x: f64,
332 dst_y: f64,
333 ) {
334 self.draw_lcd_mask_arc_impl(mask, mask_w, mask_h, src_color, dst_x, dst_y);
335 }
336
337 fn draw_lcd_backbuffer_arc(
338 &mut self,
339 color: &std::sync::Arc<Vec<u8>>,
340 alpha: &std::sync::Arc<Vec<u8>>,
341 content_version: u64,
342 w: u32,
343 h: u32,
344 dst_x: f64,
345 dst_y: f64,
346 dst_w: f64,
347 dst_h: f64,
348 ) {
349 self.draw_lcd_backbuffer_arc_impl(
350 color,
351 alpha,
352 content_version,
353 w,
354 h,
355 dst_x,
356 dst_y,
357 dst_w,
358 dst_h,
359 );
360 }
361
362 fn transform(&self) -> TransAffine {
365 *self.ctm()
366 }
367
368 fn root_transform(&self) -> TransAffine {
369 let mut t = *self.ctm();
370 for layer in self.layer_stack.iter().rev() {
371 t.premultiply(&TransAffine::new_translation(
372 layer.origin_x,
373 layer.origin_y,
374 ));
375 }
376 t
377 }
378
379 fn save(&mut self) {
380 let top = *self.state_stack.last().unwrap();
381 self.state_stack.push(top);
382 }
383
384 fn restore(&mut self) {
385 if self.state_stack.len() > 1 {
386 self.state_stack.pop();
387 self.apply_scissor();
389 }
390 }
391
392 fn translate(&mut self, tx: f64, ty: f64) {
393 self.ctm_mut()
394 .premultiply(&TransAffine::new_translation(tx, ty));
395 }
396
397 fn rotate(&mut self, radians: f64) {
398 self.ctm_mut()
399 .premultiply(&TransAffine::new_rotation(radians));
400 }
401
402 fn scale(&mut self, sx: f64, sy: f64) {
403 self.ctm_mut()
404 .premultiply(&TransAffine::new_scaling(sx, sy));
405 }
406
407 fn set_transform(&mut self, m: TransAffine) {
408 *self.ctm_mut() = m;
409 }
410
411 fn reset_transform(&mut self) {
412 *self.ctm_mut() = TransAffine::new();
413 }
414
415 fn supports_compositing_layers(&self) -> bool {
418 true
419 }
420
421 fn supports_retained_layers(&self) -> bool {
422 true
423 }
424
425 fn push_layer(&mut self, width: f64, height: f64) {
426 self.push_layer_with_alpha_impl(width, height, 1.0, None);
427 }
428
429 fn push_layer_with_alpha(&mut self, width: f64, height: f64, alpha: f64) {
430 self.push_layer_with_alpha_impl(width, height, alpha, None);
431 }
432
433 fn pop_layer(&mut self) {
434 self.pop_layer_impl();
435 }
436
437 fn set_layer_rounded_clip(&mut self, x: f64, y: f64, w: f64, h: f64, r: f64) {
438 self.set_layer_rounded_clip_impl(x, y, w, h, r);
439 }
440
441 fn set_layer_opaque_backdrop(&mut self, opaque: bool) {
442 self.set_layer_opaque_backdrop_impl(opaque);
443 }
444
445 fn composite_retained_layer(&mut self, key: u64, width: f64, height: f64, alpha: f64) -> bool {
446 self.composite_retained_layer_impl(key, width, height, alpha)
447 }
448
449 fn push_retained_layer_with_alpha(&mut self, key: u64, width: f64, height: f64, alpha: f64) {
450 self.push_layer_with_alpha_impl(width, height, alpha, Some(key));
451 }
452
453 fn gl_paint(&mut self, _screen_rect: agg_gui::Rect, _painter: &mut dyn agg_gui::GlPaint) {
456 }
475
476 fn capture_screenshot(&mut self) -> bool {
479 self.capture_screenshot_impl()
480 }
481
482 fn has_captured_screenshot(&self) -> bool {
483 self.capture_texture.is_some()
484 }
485
486 fn captured_screenshot_size(&self) -> Option<(u32, u32)> {
487 self.capture_texture.as_ref().map(|(_, _, w, h)| (*w, *h))
488 }
489
490 fn draw_captured_screenshot(&mut self, dst_x: f64, dst_y: f64, dst_w: f64, dst_h: f64) -> bool {
491 self.draw_captured_screenshot_impl(dst_x, dst_y, dst_w, dst_h)
492 }
493
494 fn read_captured_screenshot(&mut self) -> (Vec<u8>, u32, u32) {
495 self.read_captured_screenshot_impl()
496 }
497}