epaint/
shape_transform.rs

1use std::sync::Arc;
2
3use crate::*;
4
5/// Remember to handle [`Color32::PLACEHOLDER`] specially!
6pub fn adjust_colors(
7    shape: &mut Shape,
8    adjust_color: impl Fn(&mut Color32) + Send + Sync + Copy + 'static,
9) {
10    #![allow(clippy::match_same_arms)]
11    match shape {
12        Shape::Noop => {}
13
14        Shape::Vec(shapes) => {
15            for shape in shapes {
16                adjust_colors(shape, adjust_color);
17            }
18        }
19
20        Shape::LineSegment { stroke, points: _ } => {
21            adjust_color_mode(&mut stroke.color, adjust_color);
22        }
23
24        Shape::Path(PathShape {
25            points: _,
26            closed: _,
27            fill,
28            stroke,
29        })
30        | Shape::QuadraticBezier(QuadraticBezierShape {
31            points: _,
32            closed: _,
33            fill,
34            stroke,
35        })
36        | Shape::CubicBezier(CubicBezierShape {
37            points: _,
38            closed: _,
39            fill,
40            stroke,
41        }) => {
42            adjust_color(fill);
43            adjust_color_mode(&mut stroke.color, adjust_color);
44        }
45
46        Shape::Circle(CircleShape {
47            center: _,
48            radius: _,
49            fill,
50            stroke,
51        })
52        | Shape::Ellipse(EllipseShape {
53            center: _,
54            radius: _,
55            fill,
56            stroke,
57        })
58        | Shape::Rect(RectShape {
59            rect: _,
60            rounding: _,
61            fill,
62            stroke,
63            blur_width: _,
64            fill_texture_id: _,
65            uv: _,
66        }) => {
67            adjust_color(fill);
68            adjust_color(&mut stroke.color);
69        }
70
71        Shape::Text(TextShape {
72            pos: _,
73            galley,
74            underline,
75            fallback_color,
76            override_text_color,
77            opacity_factor: _,
78            angle: _,
79        }) => {
80            adjust_color(&mut underline.color);
81            adjust_color(fallback_color);
82            if let Some(override_text_color) = override_text_color {
83                adjust_color(override_text_color);
84            }
85
86            if !galley.is_empty() {
87                let galley = std::sync::Arc::make_mut(galley);
88                for row in &mut galley.rows {
89                    for vertex in &mut row.visuals.mesh.vertices {
90                        adjust_color(&mut vertex.color);
91                    }
92                }
93            }
94        }
95
96        Shape::Mesh(Mesh {
97            indices: _,
98            vertices,
99            texture_id: _,
100        }) => {
101            for v in vertices {
102                adjust_color(&mut v.color);
103            }
104        }
105
106        Shape::Callback(_) => {
107            // Can't tint user callback code
108        }
109    }
110}
111
112fn adjust_color_mode(
113    color_mode: &mut ColorMode,
114    adjust_color: impl Fn(&mut Color32) + Send + Sync + Copy + 'static,
115) {
116    match color_mode {
117        color::ColorMode::Solid(color) => adjust_color(color),
118        color::ColorMode::UV(callback) => {
119            let callback = callback.clone();
120            *color_mode = color::ColorMode::UV(Arc::new(Box::new(move |rect, pos| {
121                let mut color = callback(rect, pos);
122                adjust_color(&mut color);
123                color
124            })));
125        }
126    }
127}