aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2018-12-31 17:01:06 +0000
committerGitHub <noreply@github.com>2018-12-31 17:01:06 +0000
commit7275ecc282d29d1c67f700c01a399582ba052853 (patch)
tree836ccd5bc47c7f40cd22816f6a5b3376dd371661
parent9ffaac8ee7c5586f0faa62401b9de76cff81130f (diff)
downloadalacritty-7275ecc282d29d1c67f700c01a399582ba052853.tar.gz
alacritty-7275ecc282d29d1c67f700c01a399582ba052853.zip
Fix line metrics
Since bitmap fonts do not provide their own underline metrics, the self-calculated metrics which have been used for rusttype are now also used for bitmap fonts with freetype. The rusttype and bitmap fallback metrics have incorrectly offset the underline by the underline height. Since the position is already defined as the center point, that is not necessary. All rounding and clamping has also been removed from the font library, so that the raw values are reported now. The clamping and rounding is now done in the line renderer.
-rw-r--r--font/src/darwin/mod.rs16
-rw-r--r--font/src/ft/mod.rs20
-rw-r--r--font/src/rusttype/mod.rs8
-rw-r--r--src/renderer/lines.rs9
4 files changed, 26 insertions, 27 deletions
diff --git a/font/src/darwin/mod.rs b/font/src/darwin/mod.rs
index ca784ae6..0e694f16 100644
--- a/font/src/darwin/mod.rs
+++ b/font/src/darwin/mod.rs
@@ -430,21 +430,17 @@ impl Font {
let leading = self.ct_font.leading() as f64;
let line_height = (ascent + descent + leading + 0.5).floor();
- // Strikeout and underline metrics
- // CoreText doesn't provide strikeout so we provide our own
- let underline_position =
- (self.ct_font.underline_position() - descent)
- .round() as f32;
- let underline_thickness = self.ct_font.underline_thickness()
- .round()
- .max(1.) as f32;
- let strikeout_position = (line_height as f32 / 2. - descent as f32).round();
+ // Strikeout and underline metrics.
+ // CoreText doesn't provide strikeout so we provide our own.
+ let underline_position = (self.ct_font.underline_position() - descent) as f32;
+ let underline_thickness = self.ct_font.underline_thickness() as f32;
+ let strikeout_position = (line_height / 2. - descent) as f32;
let strikeout_thickness = underline_thickness;
Metrics {
average_advance,
line_height,
- descent: -(self.ct_font.descent() as f32),
+ descent: -(descent as f32),
underline_position,
underline_thickness,
strikeout_position,
diff --git a/font/src/ft/mod.rs b/font/src/ft/mod.rs
index 03e8bb31..1d375295 100644
--- a/font/src/ft/mod.rs
+++ b/font/src/ft/mod.rs
@@ -97,22 +97,22 @@ impl ::Rasterize for FreeTypeRasterizer {
// 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.);
+ let mut underline_position = f32::from(face.ft_face.underline_position()) * x_scale / 64.;
+ let mut underline_thickness = f32::from(face.ft_face.underline_thickness()) * x_scale / 64.;
+
+ // Fallback for bitmap fonts which do not provide underline metrics
+ if underline_position == 0. {
+ underline_thickness = (descent / 5.).round();
+ underline_position = descent / 2.;
+ }
// 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();
+ 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)
},
_ => {
diff --git a/font/src/rusttype/mod.rs b/font/src/rusttype/mod.rs
index 2d28a8bd..bd4b8df1 100644
--- a/font/src/rusttype/mod.rs
+++ b/font/src/rusttype/mod.rs
@@ -38,11 +38,11 @@ impl crate::Rasterize for RustTypeRasterizer {
let average_advance = f64::from(hmetrics.advance_width);
let descent = vmetrics.descent;
- // Strikeout and underline metrics
- // RustType doesn't support these, so we make up our own
+ // Strikeout and underline metrics.
+ // RustType doesn't support these, so we make up our own.
let thickness = (descent / 5.).round();
- let underline_position = descent / 2. + thickness / 2.;
- let strikeout_position = (line_height as f32 / 2. - descent).round();
+ let underline_position = descent / 2.;
+ let strikeout_position = line_height as f32 / 2. - descent;
Ok(Metrics {
descent,
diff --git a/src/renderer/lines.rs b/src/renderer/lines.rs
index 99d1f28f..3c250caf 100644
--- a/src/renderer/lines.rs
+++ b/src/renderer/lines.rs
@@ -122,12 +122,15 @@ fn create_rect(
let end_x = (end.column.0 + 1) as f32 * size.cell_width;
let width = end_x - start_x;
- let (position, height) = match flag {
+ let (position, mut height) = match flag {
Flags::UNDERLINE => (metrics.underline_position, metrics.underline_thickness),
Flags::STRIKEOUT => (metrics.strikeout_position, metrics.strikeout_thickness),
_ => unimplemented!("Invalid flag for cell line drawing specified"),
};
+ // Make sure lines are always visible
+ height = height.max(1.);
+
let cell_bottom = (start.line.0 as f32 + 1.) * size.cell_height;
let baseline = cell_bottom + metrics.descent;
@@ -139,9 +142,9 @@ fn create_rect(
let rect = Rect::new(
start_x + size.padding_x,
- y + size.padding_y,
+ y.round() + size.padding_y,
width,
- height,
+ height.round(),
);
(rect, start.fg)