summaryrefslogtreecommitdiffstats
path: root/vendor/plotters/src/style/font/font_desc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/plotters/src/style/font/font_desc.rs')
-rw-r--r--vendor/plotters/src/style/font/font_desc.rs220
1 files changed, 220 insertions, 0 deletions
diff --git a/vendor/plotters/src/style/font/font_desc.rs b/vendor/plotters/src/style/font/font_desc.rs
new file mode 100644
index 000000000..a101a5d8b
--- /dev/null
+++ b/vendor/plotters/src/style/font/font_desc.rs
@@ -0,0 +1,220 @@
+use super::{FontData, FontDataInternal};
+use crate::style::text_anchor::Pos;
+use crate::style::{Color, TextStyle};
+
+use std::convert::From;
+
+pub use plotters_backend::{FontFamily, FontStyle, FontTransform};
+
+/// The error type for the font implementation
+pub type FontError = <FontDataInternal as FontData>::ErrorType;
+
+/// The type we used to represent a result of any font operations
+pub type FontResult<T> = Result<T, FontError>;
+
+/// Describes a font
+#[derive(Clone)]
+pub struct FontDesc<'a> {
+ size: f64,
+ family: FontFamily<'a>,
+ data: FontResult<FontDataInternal>,
+ transform: FontTransform,
+ style: FontStyle,
+}
+
+impl<'a> FontDesc<'a> {
+ /// Create a new font
+ ///
+ /// - `family`: The font family name
+ /// - `size`: The size of the font
+ /// - `style`: The font variations
+ /// - **returns** The newly created font description
+ pub fn new(family: FontFamily<'a>, size: f64, style: FontStyle) -> Self {
+ Self {
+ size,
+ family,
+ data: FontDataInternal::new(family, style),
+ transform: FontTransform::None,
+ style,
+ }
+ }
+
+ /// Create a new font desc with the same font but different size
+ ///
+ /// - `size`: The new size to set
+ /// - **returns** The newly created font descriptor with a new size
+ pub fn resize(&self, size: f64) -> Self {
+ Self {
+ size,
+ family: self.family,
+ data: self.data.clone(),
+ transform: self.transform.clone(),
+ style: self.style,
+ }
+ }
+
+ /// Set the style of the font
+ ///
+ /// - `style`: The new style
+ /// - **returns** The new font description with this style applied
+ pub fn style(&self, style: FontStyle) -> Self {
+ Self {
+ size: self.size,
+ family: self.family,
+ data: self.data.clone(),
+ transform: self.transform.clone(),
+ style,
+ }
+ }
+
+ /// Set the font transformation
+ ///
+ /// - `trans`: The new transformation
+ /// - **returns** The new font description with this font transformation applied
+ pub fn transform(&self, trans: FontTransform) -> Self {
+ Self {
+ size: self.size,
+ family: self.family,
+ data: self.data.clone(),
+ transform: trans,
+ style: self.style,
+ }
+ }
+
+ /// Get the font transformation description
+ pub fn get_transform(&self) -> FontTransform {
+ self.transform.clone()
+ }
+
+ /** Returns a new text style object with the specified `color`.
+
+ # Example
+
+ ```
+ use plotters::prelude::*;
+ let text_style = ("sans-serif", 20).into_font().color(&RED);
+ let drawing_area = SVGBackend::new("font_desc_color.svg", (200, 100)).into_drawing_area();
+ drawing_area.fill(&WHITE).unwrap();
+ drawing_area.draw_text("This is a big red label", &text_style, (10, 50));
+ ```
+
+ The result is a text label colorized accordingly:
+
+ ![](https://cdn.jsdelivr.net/gh/facorread/plotters-doc-data@f030ed3/apidoc/font_desc_color.svg)
+
+ # See also
+
+ [`IntoTextStyle::with_color()`](crate::style::IntoTextStyle::with_color)
+
+ [`IntoTextStyle::into_text_style()`](crate::style::IntoTextStyle::into_text_style) for a more succinct example
+
+ */
+ pub fn color<C: Color>(&self, color: &C) -> TextStyle<'a> {
+ TextStyle {
+ font: self.clone(),
+ color: color.to_backend_color(),
+ pos: Pos::default(),
+ }
+ }
+
+ /// Returns the font family
+ pub fn get_family(&self) -> FontFamily {
+ self.family
+ }
+
+ /// Get the name of the font
+ pub fn get_name(&self) -> &str {
+ self.family.as_str()
+ }
+
+ /// Get the name of the style
+ pub fn get_style(&self) -> FontStyle {
+ self.style
+ }
+
+ /// Get the size of font
+ pub fn get_size(&self) -> f64 {
+ self.size
+ }
+
+ /// Get the size of the text if rendered in this font
+ ///
+ /// For a TTF type, zero point of the layout box is the left most baseline char of the string
+ /// Thus the upper bound of the box is most likely be negative
+ pub fn layout_box(&self, text: &str) -> FontResult<((i32, i32), (i32, i32))> {
+ match &self.data {
+ Ok(ref font) => font.estimate_layout(self.size, text),
+ Err(e) => Err(e.clone()),
+ }
+ }
+
+ /// Get the size of the text if rendered in this font.
+ /// This is similar to `layout_box` function, but it apply the font transformation
+ /// and estimate the overall size of the font
+ pub fn box_size(&self, text: &str) -> FontResult<(u32, u32)> {
+ let ((min_x, min_y), (max_x, max_y)) = self.layout_box(text)?;
+ let (w, h) = self.get_transform().transform(max_x - min_x, max_y - min_y);
+ Ok((w.unsigned_abs(), h.unsigned_abs()))
+ }
+
+ /// Actually draws a font with a drawing function
+ pub fn draw<E, DrawFunc: FnMut(i32, i32, f32) -> Result<(), E>>(
+ &self,
+ text: &str,
+ (x, y): (i32, i32),
+ draw: DrawFunc,
+ ) -> FontResult<Result<(), E>> {
+ match &self.data {
+ Ok(ref font) => font.draw((x, y), self.size, text, draw),
+ Err(e) => Err(e.clone()),
+ }
+ }
+}
+
+impl<'a> From<&'a str> for FontDesc<'a> {
+ fn from(from: &'a str) -> FontDesc<'a> {
+ FontDesc::new(from.into(), 12.0, FontStyle::Normal)
+ }
+}
+
+impl<'a> From<FontFamily<'a>> for FontDesc<'a> {
+ fn from(family: FontFamily<'a>) -> FontDesc<'a> {
+ FontDesc::new(family, 12.0, FontStyle::Normal)
+ }
+}
+
+impl<'a, T: Into<f64>> From<(FontFamily<'a>, T)> for FontDesc<'a> {
+ fn from((family, size): (FontFamily<'a>, T)) -> FontDesc<'a> {
+ FontDesc::new(family, size.into(), FontStyle::Normal)
+ }
+}
+
+impl<'a, T: Into<f64>> From<(&'a str, T)> for FontDesc<'a> {
+ fn from((typeface, size): (&'a str, T)) -> FontDesc<'a> {
+ FontDesc::new(typeface.into(), size.into(), FontStyle::Normal)
+ }
+}
+
+impl<'a, T: Into<f64>, S: Into<FontStyle>> From<(FontFamily<'a>, T, S)> for FontDesc<'a> {
+ fn from((family, size, style): (FontFamily<'a>, T, S)) -> FontDesc<'a> {
+ FontDesc::new(family, size.into(), style.into())
+ }
+}
+
+impl<'a, T: Into<f64>, S: Into<FontStyle>> From<(&'a str, T, S)> for FontDesc<'a> {
+ fn from((typeface, size, style): (&'a str, T, S)) -> FontDesc<'a> {
+ FontDesc::new(typeface.into(), size.into(), style.into())
+ }
+}
+
+/// The trait that allows some type turns into a font description
+pub trait IntoFont<'a> {
+ /// Make the font description from the source type
+ fn into_font(self) -> FontDesc<'a>;
+}
+
+impl<'a, T: Into<FontDesc<'a>>> IntoFont<'a> for T {
+ fn into_font(self) -> FontDesc<'a> {
+ self.into()
+ }
+}