diff options
author | Joe Wilm <joe@jwilm.com> | 2017-01-02 18:52:41 -0800 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2017-01-02 19:49:38 -0800 |
commit | 86301856391b05047f1fd9f2e8999d61b26d982e (patch) | |
tree | 2163b2fead9d1c45bb72670b32558cb781f2d4a5 /font/src/darwin/mod.rs | |
parent | 04d69e3c2902bca56605ad59e60b2ae1e5ce91a3 (diff) | |
download | alacritty-86301856391b05047f1fd9f2e8999d61b26d982e.tar.gz alacritty-86301856391b05047f1fd9f2e8999d61b26d982e.zip |
Rework font loading
This work started because we wanted to be able to simply say "monospace"
on Linux and have it give us some sort of font. The config format for
fonts changed to accomodate this new paradigm. As a result, italic and
bold can have different families from the normal (roman) face.
The fontconfig based font resolution probably works a lot better than
the CoreText version at this point. With CoreText, we simply iterate
over fonts and check it they match the requested properties. What's
worse is that the CoreText version requires a valid family. With
fontconfig, it will just provide the closest matching thing and use it
(unless a specific style is requested).
Diffstat (limited to 'font/src/darwin/mod.rs')
-rw-r--r-- | font/src/darwin/mod.rs | 63 |
1 files changed, 57 insertions, 6 deletions
diff --git a/font/src/darwin/mod.rs b/font/src/darwin/mod.rs index 99f080ab..35336df9 100644 --- a/font/src/darwin/mod.rs +++ b/font/src/darwin/mod.rs @@ -19,6 +19,8 @@ use std::collections::HashMap; use std::ptr; +use ::{Slant, Weight, Style}; + use core_foundation::base::TCFType; use core_foundation::string::{CFString, CFStringRef}; use core_foundation::array::CFIndex; @@ -36,6 +38,7 @@ use core_text::font_descriptor::kCTFontDefaultOrientation; use core_text::font_descriptor::kCTFontHorizontalOrientation; use core_text::font_descriptor::kCTFontVerticalOrientation; use core_text::font_descriptor::{CTFontDescriptor, CTFontDescriptorRef, CTFontOrientation}; +use core_text::font_descriptor::SymbolicTraitAccessors; use libc::{size_t, c_int}; @@ -166,10 +169,15 @@ impl ::Rasterize for Rasterizer { } impl Rasterizer { - fn get_font(&mut self, desc: &FontDesc, size: Size) -> Result<Font, Error> { + fn get_specific_face( + &mut self, + desc: &FontDesc, + style: &str, + size: Size + ) -> Result<Font, Error> { let descriptors = descriptors_for_family(&desc.name[..]); for descriptor in descriptors { - if descriptor.style_name == desc.style { + if descriptor.style_name == style { // Found the font we want let scaled_size = size.as_f32_pts() as f64 * self.device_pixel_ratio as f64; let font = descriptor.to_font(scaled_size); @@ -179,6 +187,44 @@ impl Rasterizer { Err(Error::MissingFont(desc.to_owned())) } + + fn get_matching_face( + &mut self, + desc: &FontDesc, + slant: Slant, + weight: Weight, + size: Size + ) -> Result<Font, Error> { + let bold = match weight { + Weight::Bold => true, + _ => false + }; + let italic = match slant { + Slant::Normal => false, + _ => true, + }; + let scaled_size = size.as_f32_pts() as f64 * self.device_pixel_ratio as f64; + + let descriptors = descriptors_for_family(&desc.name[..]); + for descriptor in descriptors { + let font = descriptor.to_font(scaled_size); + if font.is_bold() == bold && font.is_italic() == italic { + // Found the font we want + return Ok(font); + } + } + + Err(Error::MissingFont(desc.to_owned())) + } + + fn get_font(&mut self, desc: &FontDesc, size: Size) -> Result<Font, Error> { + match desc.style { + Style::Specific(ref style) => self.get_specific_face(desc, style, size), + Style::Description { slant, weight } => { + self.get_matching_face(desc, slant, weight, size) + }, + } + } } /// Specifies the intended rendering orientation of the font for obtaining glyph metrics @@ -290,6 +336,14 @@ impl Font { } } + pub fn is_bold(&self) -> bool { + self.ct_font.symbolic_traits().is_bold() + } + + pub fn is_italic(&self) -> bool { + self.ct_font.symbolic_traits().is_italic() + } + fn glyph_advance(&self, character: char) -> f64 { let index = self.glyph_index(character).unwrap(); @@ -539,12 +593,9 @@ mod tests { .collect::<Vec<_>>(); for font in fonts { - // Check deref - println!("family: {}", font.family_name()); - // Get a glyph for c in &['a', 'b', 'c', 'd'] { - let glyph = font.get_glyph(*c, 72.); + let glyph = font.get_glyph(*c, 72.).unwrap(); // Debug the glyph.. sigh for row in 0..glyph.height { |