summaryrefslogtreecommitdiff
path: root/alacritty_terminal/src/config/font.rs
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2019-05-10 11:36:16 +0000
committerGitHub <noreply@github.com>2019-05-10 11:36:16 +0000
commit5d173f6df3b20308eb318cef4b58147b2197d5f9 (patch)
tree05638837bef25d65a818253814331a4f429f57ac /alacritty_terminal/src/config/font.rs
parent7738c52ed4eb177ead9f43d14207ecb129cfe617 (diff)
downloadalacritty-5d173f6df3b20308eb318cef4b58147b2197d5f9.tar.gz
alacritty-5d173f6df3b20308eb318cef4b58147b2197d5f9.zip
Refactor config parsing files
This is a large refactor of the config parsing structure, attempting to reduce the size of the file a bit by splitting it up into different modules with more specific purposes. This also fixes #2279.
Diffstat (limited to 'alacritty_terminal/src/config/font.rs')
-rw-r--r--alacritty_terminal/src/config/font.rs200
1 files changed, 200 insertions, 0 deletions
diff --git a/alacritty_terminal/src/config/font.rs b/alacritty_terminal/src/config/font.rs
new file mode 100644
index 00000000..3c78ad29
--- /dev/null
+++ b/alacritty_terminal/src/config/font.rs
@@ -0,0 +1,200 @@
+use std::fmt;
+
+use font::Size;
+use serde::de::Visitor;
+use serde::{Deserialize, Deserializer};
+
+#[cfg(target_os = "macos")]
+use crate::config::DefaultTrueBool;
+use crate::config::{failure_default, Delta};
+
+/// Font config
+///
+/// Defaults are provided at the level of this struct per platform, but not per
+/// field in this struct. It might be nice in the future to have defaults for
+/// each value independently. Alternatively, maybe erroring when the user
+/// doesn't provide complete config is Ok.
+#[serde(default)]
+#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
+pub struct Font {
+ /// Normal font face
+ #[serde(deserialize_with = "failure_default")]
+ normal: FontDescription,
+
+ /// Bold font face
+ #[serde(deserialize_with = "failure_default")]
+ italic: SecondaryFontDescription,
+
+ /// Italic font face
+ #[serde(deserialize_with = "failure_default")]
+ bold: SecondaryFontDescription,
+
+ /// Font size in points
+ #[serde(deserialize_with = "DeserializeSize::deserialize")]
+ pub size: Size,
+
+ /// Extra spacing per character
+ #[serde(deserialize_with = "failure_default")]
+ pub offset: Delta<i8>,
+
+ /// Glyph offset within character cell
+ #[serde(deserialize_with = "failure_default")]
+ pub glyph_offset: Delta<i8>,
+
+ #[cfg(target_os = "macos")]
+ #[serde(deserialize_with = "failure_default")]
+ use_thin_strokes: DefaultTrueBool,
+}
+
+impl Default for Font {
+ fn default() -> Font {
+ Font {
+ size: default_font_size(),
+ normal: Default::default(),
+ bold: Default::default(),
+ italic: Default::default(),
+ glyph_offset: Default::default(),
+ offset: Default::default(),
+ #[cfg(target_os = "macos")]
+ use_thin_strokes: Default::default(),
+ }
+ }
+}
+
+impl Font {
+ /// Get a font clone with a size modification
+ pub fn with_size(self, size: Size) -> Font {
+ Font { size, ..self }
+ }
+
+ // Get normal font description
+ pub fn normal(&self) -> &FontDescription {
+ &self.normal
+ }
+
+ // Get italic font description
+ pub fn italic(&self) -> FontDescription {
+ self.italic.desc(&self.normal)
+ }
+
+ // Get bold font description
+ pub fn bold(&self) -> FontDescription {
+ self.bold.desc(&self.normal)
+ }
+
+ #[cfg(target_os = "macos")]
+ pub fn use_thin_strokes(&self) -> bool {
+ self.use_thin_strokes.0
+ }
+
+ #[cfg(not(target_os = "macos"))]
+ pub fn use_thin_strokes(&self) -> bool {
+ false
+ }
+}
+
+fn default_font_size() -> Size {
+ Size::new(11.)
+}
+
+/// Description of the normal font
+#[serde(default)]
+#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
+pub struct FontDescription {
+ #[serde(deserialize_with = "failure_default")]
+ pub family: String,
+ #[serde(deserialize_with = "failure_default")]
+ pub style: Option<String>,
+}
+
+impl Default for FontDescription {
+ fn default() -> FontDescription {
+ FontDescription {
+ #[cfg(not(any(target_os = "macos", windows)))]
+ family: "monospace".into(),
+ #[cfg(target_os = "macos")]
+ family: "Menlo".into(),
+ #[cfg(windows)]
+ family: "Consolas".into(),
+ style: None,
+ }
+ }
+}
+
+/// Description of the italic and bold font
+#[serde(default)]
+#[derive(Debug, Default, Deserialize, Clone, PartialEq, Eq)]
+pub struct SecondaryFontDescription {
+ #[serde(deserialize_with = "failure_default")]
+ family: Option<String>,
+ #[serde(deserialize_with = "failure_default")]
+ style: Option<String>,
+}
+
+impl SecondaryFontDescription {
+ pub fn desc(&self, fallback: &FontDescription) -> FontDescription {
+ FontDescription {
+ family: self.family.clone().unwrap_or_else(|| fallback.family.clone()),
+ style: self.style.clone(),
+ }
+ }
+}
+
+trait DeserializeSize: Sized {
+ fn deserialize<'a, D>(_: D) -> ::std::result::Result<Self, D::Error>
+ where
+ D: serde::de::Deserializer<'a>;
+}
+
+impl DeserializeSize for Size {
+ fn deserialize<'a, D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
+ where
+ D: serde::de::Deserializer<'a>,
+ {
+ use std::marker::PhantomData;
+
+ struct NumVisitor<__D> {
+ _marker: PhantomData<__D>,
+ }
+
+ impl<'a, __D> Visitor<'a> for NumVisitor<__D>
+ where
+ __D: serde::de::Deserializer<'a>,
+ {
+ type Value = f64;
+
+ fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str("f64 or u64")
+ }
+
+ fn visit_f64<E>(self, value: f64) -> ::std::result::Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(value)
+ }
+
+ fn visit_u64<E>(self, value: u64) -> ::std::result::Result<Self::Value, E>
+ where
+ E: ::serde::de::Error,
+ {
+ Ok(value as f64)
+ }
+ }
+
+ let value = serde_yaml::Value::deserialize(deserializer)?;
+ let size = value
+ .deserialize_any(NumVisitor::<D> { _marker: PhantomData })
+ .map(|v| Size::new(v as _));
+
+ // Use default font size as fallback
+ match size {
+ Ok(size) => Ok(size),
+ Err(err) => {
+ let size = default_font_size();
+ error!("Problem with config: {}; using size {}", err, size.as_f32_pts());
+ Ok(size)
+ },
+ }
+ }
+}