aboutsummaryrefslogtreecommitdiff
path: root/src/config/font.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/config/font.rs')
-rw-r--r--src/config/font.rs212
1 files changed, 212 insertions, 0 deletions
diff --git a/src/config/font.rs b/src/config/font.rs
new file mode 100644
index 00000000..2d3ae310
--- /dev/null
+++ b/src/config/font.rs
@@ -0,0 +1,212 @@
+// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+use serde_yaml;
+use serde::{de, Deserialize};
+
+use config::{Delta, failure_default};
+use font::{Size, FontKey, Slant};
+
+// Global and local font configuration
+#[derive(Deserialize, Debug)]
+pub struct FontConfiguration {
+ #[serde(default, deserialize_with="failure_default")]
+ options: GlobalOptions,
+ #[serde(default, deserialize_with="deserialize_font_collection")]
+ fonts: Vec<Font>,
+}
+
+impl FontConfiguration {
+ pub fn font_by_char(&self, c: char, weight: Slant) -> FontKey {
+ for font in fonts {
+ let options = font.options();
+
+ // Skip font if font slant does not match requested slant
+ if options.unwrap_or(self.options as Options).style.unwrap_or(self.options.style) != weight {
+ continue;
+ }
+
+ let is_match = match options {
+ Some(options) => {
+ for range in options.ranges {
+ if range.start < c && range.end > c {
+ return true;
+ }
+ }
+ false
+ },
+ None => {
+ true
+ },
+ };
+
+ if is_match {
+ // TODO: Check if this font contains the char
+ }
+ }
+ }
+}
+
+impl Default for FontConfiguration {
+ fn default() -> Self {
+ Self {
+ fonts: vec!(Font::default()),
+ ..Default::default()
+ }
+ }
+}
+
+// Information about a font
+#[derive(Deserialize, Debug)]
+pub struct Font {
+ family: String,
+ #[serde(deserialize_with="failure_default")]
+ options: Option<Options>,
+}
+
+// Default font config in case of failure or missing config
+impl Default for Font {
+ #[cfg(target_os = "macos")]
+ fn default() -> Self {
+ Font {
+ family: "Menlo".into(),
+ options: None,
+ }
+ }
+
+ #[cfg(not(target_os = "macos"))]
+ fn default() -> Self {
+ Font {
+ family: "monospace".into(),
+ options: None,
+ }
+ }
+}
+
+// Options for a font
+#[derive(Deserialize, Debug)]
+pub struct Options {
+ #[serde(deserialize_with="deserialize_size")]
+ size: Option<Size>,
+ #[serde(deserialize_with="failure_default")]
+ thin_strokes: Option<bool>,
+ #[serde(deserialize_with="failure_default")]
+ antialias: Option<AntiAlias>,
+ #[serde(deserialize_with="failure_default")]
+ hinting: Option<bool>,
+ #[serde(deserialize_with="failure_default")]
+ style: Option<String>,
+ #[serde(deserialize_with="failure_default")]
+ offset: Option<Delta>,
+ #[serde(deserialize_with="failure_default")]
+ ranges: Vec<FontRange>,
+}
+
+impl Default for Options {
+ fn default() -> Self {
+ Options {
+ size: None,
+ thin_strokes: None,
+ antialias: None,
+ hinting: None,
+ style: None,
+ offset: None,
+ ranges: Vec::new(),
+ }
+ }
+}
+
+#[derive(Deserialize, Debug)]
+pub struct GlobalOptions(Options);
+impl Default for GlobalOptions {
+ fn default() -> Self {
+ GlobalOptions(Options {
+ size: Some(Size::new(12.0)),
+ thin_strokes: Some(true),
+ antialias: Some(AntiAlias::LCD),
+ hinting: Some(true),
+ style: Some("normal".into()),
+ offset: Some(Delta::default()),
+ ranges: Vec::new(),
+ })
+ }
+}
+
+// AntiAliasing settings for fonts
+#[derive(Deserialize, Debug)]
+pub enum AntiAlias {
+ LCD,
+ LCDV,
+ GRAY,
+ DISABLED,
+}
+
+// Range for which a specific font should be used
+#[derive(Deserialize, Debug)]
+pub struct FontRange {
+ #[serde(deserialize_with="failure_default")]
+ start: char,
+ #[serde(deserialize_with="failure_default")]
+ end: char,
+}
+
+// Deserialize the font vector
+fn deserialize_font_collection<'a, D>(deserializer: D)
+ -> ::std::result::Result<Vec<Font>, D::Error>
+ where D: de::Deserializer<'a>,
+{
+ // Deserialize vector as generic yaml value
+ let mut value = match serde_yaml::Value::deserialize(deserializer) {
+ Ok(value) => value,
+ Err(err) => {
+ eprintln!("problem with config: {}; Using default fonts", err);
+ return Ok(vec!(Font::default()));
+ },
+ };
+
+ // Get value as sequence
+ let sequence = match value.as_sequence_mut() {
+ Some(sequence) => sequence,
+ None => return Ok(vec!(Font::default())),
+ };
+
+ // Deserialize each element in the sequence
+ let mut font_collection = Vec::new();
+ for i in 0..sequence.len() {
+ match Font::deserialize(sequence.remove(i)) {
+ Ok(font) => font_collection.push(font),
+ // TODO: Print line or something like that?
+ Err(err) => eprintln!("problem with config: Malformed font; Skipping"),
+ }
+ }
+
+ // Return defaults if collection contains no font
+ if font_collection.is_empty() {
+ Ok(vec!(Font::default()))
+ } else {
+ Ok(font_collection)
+ }
+}
+
+// Deserialize font size
+fn deserialize_size<'a, D>(deserializer: D)
+ -> ::std::result::Result<Option<Size>, D::Error>
+ where D: de::Deserializer<'a>,
+{
+ match f32::deserialize(deserializer) {
+ Ok(value) => Ok(Some(Size::new(value))),
+ _ => {
+ Ok(None)
+ },
+ }
+}