epaint/
shape_transform.rs

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