diff options
Diffstat (limited to 'font/src/ft/mod.rs')
-rw-r--r-- | font/src/ft/mod.rs | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs index 1d3f64bd..03e8bb31 100644 --- a/font/src/ft/mod.rs +++ b/font/src/ft/mod.rs @@ -18,6 +18,7 @@ use std::cmp::min; use std::path::PathBuf; use std::fmt; +use freetype::tt_os2::TrueTypeOS2Table; use freetype::{self, Library}; use libc::c_uint; @@ -86,15 +87,50 @@ 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 full = self.full_metrics(key)?; let height = (full.size_metrics.height / 64) as f64; let descent = (full.size_metrics.descender / 64) as f32; + // Get underline position and thickness in device pixels + let x_scale = full.size_metrics.x_scale as f32 / 65536.0; + let underline_position = + (f32::from(face.ft_face.underline_position()) * x_scale / 64.).round(); + let underline_thickness = + (f32::from(face.ft_face.underline_thickness()) * x_scale / 64.) + .round() + .max(1.); + + // 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.).round(); + let strikeout_thickness = + (f32::from(os2.y_strikeout_size()) * x_scale / 64.).round(); + (strikeout_position, strikeout_thickness) + }, + _ => { + // Fallback if font doesn't provide info about strikeout + trace!("No strikeout data available for font, using fallback."); + let strikeout_position = height as f32 / 2. + descent; + (strikeout_position, underline_thickness) + }, + }; + Ok(Metrics { average_advance: full.cell_width, line_height: height, descent, + underline_position, + underline_thickness, + strikeout_position, + strikeout_thickness, }) } |