epaint/shapes/
text_shape.rs

1use std::sync::Arc;
2
3use crate::*;
4
5/// How to paint some text on screen.
6///
7/// This needs to be recreated if `pixels_per_point` (dpi scale) changes.
8#[derive(Clone, Debug, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10pub struct TextShape {
11    /// Top left corner of the first character.
12    pub pos: Pos2,
13
14    /// The laid out text, from [`Fonts::layout_job`].
15    pub galley: Arc<Galley>,
16
17    /// Add this underline to the whole text.
18    /// You can also set an underline when creating the galley.
19    pub underline: Stroke,
20
21    /// Any [`Color32::PLACEHOLDER`] in the galley will be replaced by the given color.
22    /// Affects everything: backgrounds, glyphs, strikethrough, underline, etc.
23    pub fallback_color: Color32,
24
25    /// If set, the text color in the galley will be ignored and replaced
26    /// with the given color.
27    ///
28    /// This only affects the glyphs and will NOT replace background color nor strikethrough/underline color.
29    pub override_text_color: Option<Color32>,
30
31    /// If set, the text will be rendered with the given opacity in gamma space
32    /// Affects everything: backgrounds, glyphs, strikethrough, underline, etc.
33    pub opacity_factor: f32,
34
35    /// Rotate text by this many radians clockwise.
36    /// The pivot is `pos` (the upper left corner of the text).
37    pub angle: f32,
38}
39
40impl TextShape {
41    /// The given fallback color will be used for any uncolored part of the galley (using [`Color32::PLACEHOLDER`]).
42    ///
43    /// Any non-placeholder color in the galley takes precedence over this fallback color.
44    #[inline]
45    pub fn new(pos: Pos2, galley: Arc<Galley>, fallback_color: Color32) -> Self {
46        Self {
47            pos,
48            galley,
49            underline: Stroke::NONE,
50            fallback_color,
51            override_text_color: None,
52            opacity_factor: 1.0,
53            angle: 0.0,
54        }
55    }
56
57    /// The visual bounding rectangle
58    #[inline]
59    pub fn visual_bounding_rect(&self) -> Rect {
60        self.galley.mesh_bounds.translate(self.pos.to_vec2())
61    }
62
63    #[inline]
64    pub fn with_underline(mut self, underline: Stroke) -> Self {
65        self.underline = underline;
66        self
67    }
68
69    /// Use the given color for the text, regardless of what color is already in the galley.
70    #[inline]
71    pub fn with_override_text_color(mut self, override_text_color: Color32) -> Self {
72        self.override_text_color = Some(override_text_color);
73        self
74    }
75
76    /// Rotate text by this many radians clockwise.
77    /// The pivot is `pos` (the upper left corner of the text).
78    #[inline]
79    pub fn with_angle(mut self, angle: f32) -> Self {
80        self.angle = angle;
81        self
82    }
83
84    /// Render text with this opacity in gamma space
85    #[inline]
86    pub fn with_opacity_factor(mut self, opacity_factor: f32) -> Self {
87        self.opacity_factor = opacity_factor;
88        self
89    }
90}
91
92impl From<TextShape> for Shape {
93    #[inline(always)]
94    fn from(shape: TextShape) -> Self {
95        Self::Text(shape)
96    }
97}