aboutsummaryrefslogtreecommitdiff
path: root/font/src/ft/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'font/src/ft/mod.rs')
-rw-r--r--font/src/ft/mod.rs175
1 files changed, 81 insertions, 94 deletions
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 6bcda2a1..bc6d6d89 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -13,19 +13,18 @@
// limitations under the License.
//
//! Rasterization powered by FreeType and FontConfig
-use std::collections::HashMap;
use std::cmp::min;
-use std::path::PathBuf;
+use std::collections::HashMap;
use std::fmt;
+use std::path::PathBuf;
use freetype::tt_os2::TrueTypeOS2Table;
use freetype::{self, Library};
use libc::c_uint;
-
pub mod fc;
-use super::{FontDesc, RasterizedGlyph, Metrics, Size, FontKey, GlyphKey, Weight, Slant, Style};
+use super::{FontDesc, FontKey, GlyphKey, Metrics, RasterizedGlyph, Size, Slant, Style, Weight};
struct FixedSize {
pixelsize: f64,
@@ -37,7 +36,7 @@ struct Face {
load_flags: freetype::face::LoadFlag,
render_mode: freetype::RenderMode,
lcd_filter: c_uint,
- non_scalable: Option<FixedSize>
+ non_scalable: Option<FixedSize>,
}
impl fmt::Debug for Face {
@@ -46,14 +45,17 @@ impl fmt::Debug for Face {
.field("ft_face", &self.ft_face)
.field("key", &self.key)
.field("load_flags", &self.load_flags)
- .field("render_mode", &match self.render_mode {
- freetype::RenderMode::Normal => "Normal",
- freetype::RenderMode::Light => "Light",
- freetype::RenderMode::Mono => "Mono",
- freetype::RenderMode::Lcd => "Lcd",
- freetype::RenderMode::LcdV => "LcdV",
- freetype::RenderMode::Max => "Max",
- })
+ .field(
+ "render_mode",
+ &match self.render_mode {
+ freetype::RenderMode::Normal => "Normal",
+ freetype::RenderMode::Light => "Light",
+ freetype::RenderMode::Mono => "Mono",
+ freetype::RenderMode::Lcd => "Lcd",
+ freetype::RenderMode::LcdV => "LcdV",
+ freetype::RenderMode::Max => "Max",
+ },
+ )
.field("lcd_filter", &self.lcd_filter)
.finish()
}
@@ -87,9 +89,7 @@ impl ::Rasterize for FreeTypeRasterizer {
}
fn metrics(&self, key: FontKey, _size: Size) -> Result<Metrics, Error> {
- let face = self.faces
- .get(&key)
- .ok_or(Error::FontNotLoaded)?;
+ let face = self.faces.get(&key).ok_or(Error::FontNotLoaded)?;
let full = self.full_metrics(key)?;
let height = (full.size_metrics.height / 64) as f64;
@@ -108,20 +108,19 @@ impl ::Rasterize for FreeTypeRasterizer {
// Get strikeout position and thickness in device pixels
let (strikeout_position, strikeout_thickness) =
- match TrueTypeOS2Table::from_face(&mut face.ft_face.clone())
- {
- Some(os2) => {
- let strikeout_position = f32::from(os2.y_strikeout_position()) * x_scale / 64.;
- let strikeout_thickness = f32::from(os2.y_strikeout_size()) * x_scale / 64.;
- (strikeout_position, strikeout_thickness)
- },
- _ => {
- // Fallback if font doesn't provide info about strikeout
- trace!("Using fallback strikeout metrics");
- let strikeout_position = height as f32 / 2. + descent;
- (strikeout_position, underline_thickness)
- },
- };
+ match TrueTypeOS2Table::from_face(&mut face.ft_face.clone()) {
+ Some(os2) => {
+ let strikeout_position = f32::from(os2.y_strikeout_position()) * x_scale / 64.;
+ let strikeout_thickness = f32::from(os2.y_strikeout_size()) * x_scale / 64.;
+ (strikeout_position, strikeout_thickness)
+ },
+ _ => {
+ // Fallback if font doesn't provide info about strikeout
+ trace!("Using fallback strikeout metrics");
+ let strikeout_position = height as f32 / 2. + descent;
+ (strikeout_position, underline_thickness)
+ },
+ };
Ok(Metrics {
average_advance: full.cell_width,
@@ -154,6 +153,7 @@ pub trait IntoFontconfigType {
impl IntoFontconfigType for Slant {
type FcType = fc::Slant;
+
fn into_fontconfig_type(&self) -> Self::FcType {
match *self {
Slant::Normal => fc::Slant::Roman,
@@ -176,7 +176,7 @@ impl IntoFontconfigType for Weight {
struct FullMetrics {
size_metrics: freetype::ffi::FT_Size_Metrics,
- cell_width: f64
+ cell_width: f64,
}
impl FreeTypeRasterizer {
@@ -189,31 +189,25 @@ impl FreeTypeRasterizer {
Style::Description { slant, weight } => {
// Match nearest font
self.get_matching_face(&desc, slant, weight, size)
- }
+ },
Style::Specific(ref style) => {
// If a name was specified, try and load specifically that font.
self.get_specific_face(&desc, &style, size)
- }
+ },
}
}
fn full_metrics(&self, key: FontKey) -> Result<FullMetrics, Error> {
- let face = self.faces
- .get(&key)
- .ok_or(Error::FontNotLoaded)?;
+ let face = self.faces.get(&key).ok_or(Error::FontNotLoaded)?;
- let size_metrics = face.ft_face.size_metrics()
- .ok_or(Error::MissingSizeMetrics)?;
+ let size_metrics = face.ft_face.size_metrics().ok_or(Error::MissingSizeMetrics)?;
let width = match face.ft_face.load_char('0' as usize, face.load_flags) {
- Ok(_) => face.ft_face.glyph().metrics().horiAdvance / 64,
- Err(_) => size_metrics.max_advance / 64
+ Ok(_) => face.ft_face.glyph().metrics().horiAdvance / 64,
+ Err(_) => size_metrics.max_advance / 64,
} as f64;
- Ok(FullMetrics {
- size_metrics,
- cell_width: width
- })
+ Ok(FullMetrics { size_metrics, cell_width: width })
}
fn get_matching_face(
@@ -232,12 +226,9 @@ impl FreeTypeRasterizer {
let font = fc::font_match(fc::Config::get_current(), &mut pattern)
.ok_or_else(|| Error::MissingFont(desc.to_owned()))?;
- self.face_from_pattern(&font)
- .and_then(|pattern| {
- pattern
- .map(Ok)
- .unwrap_or_else(|| Err(Error::MissingFont(desc.to_owned())))
- })
+ self.face_from_pattern(&font).and_then(|pattern| {
+ pattern.map(Ok).unwrap_or_else(|| Err(Error::MissingFont(desc.to_owned())))
+ })
}
fn get_specific_face(
@@ -253,12 +244,9 @@ impl FreeTypeRasterizer {
let font = fc::font_match(fc::Config::get_current(), &mut pattern)
.ok_or_else(|| Error::MissingFont(desc.to_owned()))?;
- self.face_from_pattern(&font)
- .and_then(|pattern| {
- pattern
- .map(Ok)
- .unwrap_or_else(|| Err(Error::MissingFont(desc.to_owned())))
- })
+ self.face_from_pattern(&font).and_then(|pattern| {
+ pattern.map(Ok).unwrap_or_else(|| Err(Error::MissingFont(desc.to_owned())))
+ })
}
fn face_from_pattern(&mut self, pattern: &fc::Pattern) -> Result<Option<FontKey>, Error> {
@@ -277,9 +265,7 @@ impl FreeTypeRasterizer {
let mut pixelsize = pattern.pixelsize();
debug!("pixelsizes: {:?}", pixelsize);
- Some(FixedSize {
- pixelsize: pixelsize.next().expect("has 1+ pixelsize"),
- })
+ Some(FixedSize { pixelsize: pixelsize.next().expect("has 1+ pixelsize") })
};
let face = Face {
@@ -303,7 +289,11 @@ impl FreeTypeRasterizer {
}
}
- fn face_for_glyph(&mut self, glyph_key: GlyphKey, have_recursed: bool) -> Result<FontKey, Error> {
+ fn face_for_glyph(
+ &mut self,
+ glyph_key: GlyphKey,
+ have_recursed: bool,
+ ) -> Result<FontKey, Error> {
let c = glyph_key.c;
let use_initial_face = if let Some(face) = self.faces.get(&glyph_key.font_key) {
@@ -322,8 +312,7 @@ impl FreeTypeRasterizer {
}
}
- fn get_rendered_glyph(&mut self, glyph_key: GlyphKey)
- -> Result<RasterizedGlyph, Error> {
+ fn get_rendered_glyph(&mut self, glyph_key: GlyphKey) -> Result<RasterizedGlyph, Error> {
// Render a custom symbol for the underline and beam cursor
match glyph_key.c {
super::UNDERLINE_CURSOR_CHAR => {
@@ -370,9 +359,10 @@ impl FreeTypeRasterizer {
let face = &self.faces[&font_key];
let index = face.ft_face.get_char_index(glyph_key.c as usize);
- let size = face.non_scalable.as_ref()
- .map(|v| v.pixelsize as f32)
- .unwrap_or_else(|| glyph_key.size.as_f32_pts() * self.device_pixel_ratio * 96. / 72.);
+ let size =
+ face.non_scalable.as_ref().map(|v| v.pixelsize as f32).unwrap_or_else(|| {
+ glyph_key.size.as_f32_pts() * self.device_pixel_ratio * 96. / 72.
+ });
face.ft_face.set_char_size(to_freetype_26_6(size), 0, 0, 0)?;
@@ -405,7 +395,7 @@ impl FreeTypeRasterizer {
use freetype::face::LoadFlag;
match (antialias, hinting, rgba) {
(false, fc::HintStyle::None, _) => LoadFlag::NO_HINTING | LoadFlag::MONOCHROME,
- (false, _, _) => LoadFlag::TARGET_MONO | LoadFlag::MONOCHROME,
+ (false, ..) => LoadFlag::TARGET_MONO | LoadFlag::MONOCHROME,
(true, fc::HintStyle::None, _) => LoadFlag::NO_HINTING | LoadFlag::TARGET_NORMAL,
// hintslight does *not* use LCD hinting even when a subpixel mode
// is selected.
@@ -459,7 +449,9 @@ impl FreeTypeRasterizer {
/// Given a FreeType `Bitmap`, returns packed buffer with 1 byte per LCD channel.
///
/// The i32 value in the return type is the number of pixels per row.
- fn normalize_buffer(bitmap: &freetype::bitmap::Bitmap) -> freetype::FtResult<(i32, i32, Vec<u8>)> {
+ fn normalize_buffer(
+ bitmap: &freetype::bitmap::Bitmap,
+ ) -> freetype::FtResult<(i32, i32, Vec<u8>)> {
use freetype::bitmap::PixelMode;
let buf = bitmap.buffer();
@@ -475,7 +467,7 @@ impl FreeTypeRasterizer {
Ok((bitmap.rows(), bitmap.width() / 3, packed))
},
PixelMode::LcdV => {
- for i in 0..bitmap.rows()/3 {
+ for i in 0..bitmap.rows() / 3 {
for j in 0..bitmap.width() {
for k in 0..3 {
let offset = ((i as usize) * 3 + k) * pitch + (j as usize);
@@ -529,14 +521,11 @@ impl FreeTypeRasterizer {
}
Ok((bitmap.rows(), bitmap.width(), packed))
},
- mode => panic!("unhandled pixel mode: {:?}", mode)
+ mode => panic!("unhandled pixel mode: {:?}", mode),
}
}
- fn load_face_with_glyph(
- &mut self,
- glyph: char,
- ) -> Result<FontKey, Error> {
+ fn load_face_with_glyph(&mut self, glyph: char) -> Result<FontKey, Error> {
let mut charset = fc::CharSet::new();
charset.add(glyph);
let mut pattern = fc::Pattern::new();
@@ -560,19 +549,19 @@ impl FreeTypeRasterizer {
// and index above.
let key = self.face_from_pattern(&pattern)?.unwrap();
Ok(key)
- }
+ },
}
- }
- else {
- Err(Error::MissingFont(
- FontDesc::new("fallback-without-path", Style::Specific(glyph.to_string()))))
+ } else {
+ Err(Error::MissingFont(FontDesc::new(
+ "fallback-without-path",
+ Style::Specific(glyph.to_string()),
+ )))
}
},
- None => {
- Err(Error::MissingFont(
- FontDesc::new("no-fallback-for", Style::Specific(glyph.to_string()))
- ))
- }
+ None => Err(Error::MissingFont(FontDesc::new(
+ "no-fallback-for",
+ Style::Specific(glyph.to_string()),
+ ))),
}
}
}
@@ -614,19 +603,17 @@ impl ::std::error::Error for Error {
impl ::std::fmt::Display for Error {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
match *self {
- Error::FreeType(ref err) => {
- err.fmt(f)
- },
- Error::MissingFont(ref desc) => {
- write!(f, "Couldn't find a font with {}\
- \n\tPlease check the font config in your alacritty.yml.", desc)
- },
- Error::FontNotLoaded => {
- f.write_str("Tried to use a font that hasn't been loaded")
- },
+ Error::FreeType(ref err) => err.fmt(f),
+ Error::MissingFont(ref desc) => write!(
+ f,
+ "Couldn't find a font with {}\n\tPlease check the font config in your \
+ alacritty.yml.",
+ desc
+ ),
+ Error::FontNotLoaded => f.write_str("Tried to use a font that hasn't been loaded"),
Error::MissingSizeMetrics => {
f.write_str("Tried to get size metrics from a face without a size")
- }
+ },
}
}
}