plotters_unstable/style/
text.rs1use super::color::Color;
2use super::font::{FontDesc, FontError, FontFamily, FontStyle, FontTransform};
3use super::size::{HasDimension, SizeDesc};
4use super::BLACK;
5pub use plotters_backend::text_anchor;
6use plotters_backend::{BackendColor, BackendCoord, BackendStyle, BackendTextStyle};
7
8#[derive(Clone)]
10pub struct TextStyle<'a> {
11 pub font: FontDesc<'a>,
13 pub color: BackendColor,
15 pub pos: text_anchor::Pos,
17}
18
19pub trait IntoTextStyle<'a> {
20 fn into_text_style<P: HasDimension>(self, parent: &P) -> TextStyle<'a>;
21}
22
23impl<'a> IntoTextStyle<'a> for FontDesc<'a> {
24 fn into_text_style<P: HasDimension>(self, _: &P) -> TextStyle<'a> {
25 self.into()
26 }
27}
28
29impl<'a> IntoTextStyle<'a> for TextStyle<'a> {
30 fn into_text_style<P: HasDimension>(self, _: &P) -> TextStyle<'a> {
31 self
32 }
33}
34
35impl<'a> IntoTextStyle<'a> for FontFamily<'a> {
36 fn into_text_style<P: HasDimension>(self, _: &P) -> TextStyle<'a> {
37 self.into()
38 }
39}
40
41impl<'a, T: SizeDesc> IntoTextStyle<'a> for (&'a str, T) {
42 fn into_text_style<P: HasDimension>(self, parent: &P) -> TextStyle<'a> {
43 (self.0, self.1.in_pixels(parent)).into()
44 }
45}
46
47impl<'a, T: SizeDesc> IntoTextStyle<'a> for (FontFamily<'a>, T) {
48 fn into_text_style<P: HasDimension>(self, parent: &P) -> TextStyle<'a> {
49 (self.0, self.1.in_pixels(parent)).into()
50 }
51}
52
53impl<'a, T: SizeDesc> IntoTextStyle<'a> for (&'a str, T, FontStyle) {
54 fn into_text_style<P: HasDimension>(self, parent: &P) -> TextStyle<'a> {
55 Into::<FontDesc>::into((self.0, self.1.in_pixels(parent), self.2)).into()
56 }
57}
58
59impl<'a, T: SizeDesc> IntoTextStyle<'a> for (FontFamily<'a>, T, FontStyle) {
60 fn into_text_style<P: HasDimension>(self, parent: &P) -> TextStyle<'a> {
61 Into::<FontDesc>::into((self.0, self.1.in_pixels(parent), self.2)).into()
62 }
63}
64
65impl<'a> TextStyle<'a> {
66 pub fn color<C: Color>(&self, color: &'a C) -> Self {
77 Self {
78 font: self.font.clone(),
79 color: color.color(),
80 pos: self.pos,
81 }
82 }
83
84 pub fn transform(&self, trans: FontTransform) -> Self {
95 Self {
96 font: self.font.clone().transform(trans),
97 color: self.color,
98 pos: self.pos,
99 }
100 }
101
102 pub fn pos(&self, pos: text_anchor::Pos) -> Self {
115 Self {
116 font: self.font.clone(),
117 color: self.color,
118 pos,
119 }
120 }
121}
122
123impl<'a, 'b: 'a> Into<TextStyle<'a>> for &'b TextStyle<'a> {
125 fn into(self) -> TextStyle<'a> {
126 self.clone()
127 }
128}
129
130impl<'a, T: Into<FontDesc<'a>>> From<T> for TextStyle<'a> {
131 fn from(font: T) -> Self {
132 Self {
133 font: font.into(),
134 color: BLACK.color(),
135 pos: text_anchor::Pos::default(),
136 }
137 }
138}
139
140impl<'a> BackendTextStyle for TextStyle<'a> {
141 type FontError = FontError;
142 fn color(&self) -> BackendColor {
143 self.color.color()
144 }
145
146 fn size(&self) -> f64 {
147 self.font.get_size()
148 }
149
150 fn transform(&self) -> FontTransform {
151 self.font.get_transform()
152 }
153
154 fn style(&self) -> FontStyle {
155 self.font.get_style()
156 }
157
158 #[allow(clippy::type_complexity)]
159 fn layout_box(&self, text: &str) -> Result<((i32, i32), (i32, i32)), Self::FontError> {
160 self.font.layout_box(text)
161 }
162
163 fn anchor(&self) -> text_anchor::Pos {
164 self.pos
165 }
166
167 fn family(&self) -> FontFamily {
168 self.font.get_family()
169 }
170
171 fn draw<E, DrawFunc: FnMut(i32, i32, BackendColor) -> Result<(), E>>(
172 &self,
173 text: &str,
174 pos: BackendCoord,
175 mut draw: DrawFunc,
176 ) -> Result<Result<(), E>, Self::FontError> {
177 let color = self.color.color();
178 self.font.draw(text, pos, move |x, y, a| {
179 let mix_color = color.mix(a as f64);
180 draw(x, y, mix_color)
181 })
182 }
183}