diff options
author | Josh Rahm <rahm@google.com> | 2021-09-27 23:45:48 -0600 |
---|---|---|
committer | Josh Rahm <rahm@google.com> | 2021-09-27 23:45:48 -0600 |
commit | 505bbdb0aa09350a2c52ede96cbacc6e9cf084a2 (patch) | |
tree | 8fa20678a35f674617e6ae030eaf941d7560d31d | |
parent | 843583e2246a2404999b6c36293d7966cfb84334 (diff) | |
download | r-alacritty-505bbdb0aa09350a2c52ede96cbacc6e9cf084a2.tar.gz r-alacritty-505bbdb0aa09350a2c52ede96cbacc6e9cf084a2.tar.bz2 r-alacritty-505bbdb0aa09350a2c52ede96cbacc6e9cf084a2.zip |
Added a dotted underline feature and changed the undercurl feature to be
more antialiased.
-rw-r--r-- | alacritty/src/display/content.rs | 8 | ||||
-rw-r--r-- | alacritty/src/renderer/rects.rs | 106 | ||||
-rw-r--r-- | alacritty_terminal/src/ansi.rs | 6 | ||||
-rw-r--r-- | alacritty_terminal/src/term/cell.rs | 4 | ||||
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 14 |
5 files changed, 124 insertions, 14 deletions
diff --git a/alacritty/src/display/content.rs b/alacritty/src/display/content.rs index e5ff3780..6fef9574 100644 --- a/alacritty/src/display/content.rs +++ b/alacritty/src/display/content.rs @@ -278,7 +278,13 @@ impl RenderableCell { self.bg_alpha == 0. && self.character == ' ' && self.zerowidth.is_none() - && !self.flags.intersects(Flags::UNDERLINE | Flags::STRIKEOUT | Flags::DOUBLE_UNDERLINE | Flags::UNDERCURL | Flags::OVERLINE) + && !self.flags.intersects( + Flags::UNDERLINE | + Flags::STRIKEOUT | + Flags::DOUBLE_UNDERLINE | + Flags::UNDERCURL | + Flags::OVERLINE | + Flags::DOTTED_UNDERLINE) } /// Apply [`CellRgb`] colors to the cell's colors. diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs index 61ff91b7..25ae93d6 100644 --- a/alacritty/src/renderer/rects.rs +++ b/alacritty/src/renderer/rects.rs @@ -63,6 +63,17 @@ impl RenderLine { color: Rgb, ) { match flag { + Flags::UNDERCURL => { + Self::push_undercurl_rects( + rects, + size, + metrics.descent, + start, + end, + metrics.underline_position + 1., + metrics.underline_thickness, + color) + } Flags::DOUBLE_UNDERLINE => { // Position underlines so each one has 50% of descent available. let top_pos = 0.25 * metrics.descent; @@ -94,7 +105,7 @@ impl RenderLine { metrics.descent, start, end, - metrics.underline_position, + metrics.underline_position + 1., metrics.underline_thickness, color, )); @@ -104,7 +115,7 @@ impl RenderLine { let end_x = (end.column.0 + 1) as f32 * size.cell_width(); rects.push(RenderRect::new( start_x + size.padding_x(), - start.line as f32 * size.cell_height(), + (start.line as f32 * size.cell_height()) + (size.cell_height() / 8.), end_x - start_x, metrics.underline_thickness, color, @@ -122,14 +133,14 @@ impl RenderLine { color, )); }, - Flags::UNDERCURL => { - Self::push_undercurl_rects( + Flags::DOTTED_UNDERLINE => { + Self::push_dotted_underline_rects( rects, size, metrics.descent, start, end, - metrics.underline_position, + metrics.underline_position + 1., metrics.underline_thickness, color) } @@ -162,20 +173,94 @@ impl RenderLine { y = max_y; } + let period_div = 1.5 * (2. * std::f32::consts::PI) / size.cell_width(); + let amplitude_mul = size.cell_height() / 10.; + let mut x = start_x; let mut idx = 0; while x < end_x { let altr = [1., 0., -1., 0.][idx % 4]; - let rect = RenderRect::new( + let fl = (x * period_div).sin() * amplitude_mul; + let al = (fl.round() - fl).abs(); + + rects.push(RenderRect::new( x + size.padding_x(), - y + size.padding_y() + altr, + y + size.padding_y() + fl, 1., - thickness + 1., + thickness, color, + (1. - al).powf(2.), + )); + + let fl = (x * period_div).sin() * amplitude_mul - 0.5; + let al = (fl.round() - fl).abs(); + + rects.push(RenderRect::new( + x + size.padding_x(), + y + size.padding_y() + fl, 1., - ); - rects.push(rect); + thickness, + color, + (1. - al).powf(2.), + )); + + let fl = (x * period_div).sin() * amplitude_mul + 0.5; + let al = (fl.round() - fl).abs(); + + rects.push(RenderRect::new( + x + size.padding_x(), + y + size.padding_y() + fl, + 1., + thickness, + color, + (1. - al).powf(2.), + )); + + x += 1.; + idx += 1; + } + } + + fn push_dotted_underline_rects( + rects: &mut Vec<RenderRect>, + size: &SizeInfo, + descent: f32, + start: Point<usize>, + end: Point<usize>, + position: f32, + mut thickness: f32, + color: Rgb, + ) { + let start_x = start.column.0 as f32 * size.cell_width(); + let end_x = (end.column.0 + 1) as f32 * size.cell_width(); + + // Make sure lines are always visible. + thickness = thickness.max(1.); + + let line_bottom = (start.line as f32 + 1.) * size.cell_height(); + let baseline = line_bottom + descent; + + let mut y = (baseline - position - thickness / 2.).ceil(); + let max_y = line_bottom - thickness; + if y > max_y { + y = max_y; + } + + let mut x = start_x; + let mut idx = 0; + while x < end_x { + if idx % 4 == 0 { + let rect = RenderRect::new( + x + size.padding_x(), + y + size.padding_y(), + thickness + 1., + thickness + 1., + color, + 1., + ); + rects.push(rect); + } x += 1.; idx += 1; } @@ -248,6 +333,7 @@ impl RenderLines { self.update_flag(cell, Flags::STRIKEOUT); self.update_flag(cell, Flags::UNDERCURL); self.update_flag(cell, Flags::OVERLINE); + self.update_flag(cell, Flags::DOTTED_UNDERLINE); } /// Update the lines for a specific flag. diff --git a/alacritty_terminal/src/ansi.rs b/alacritty_terminal/src/ansi.rs index 51a3394e..d5574f59 100644 --- a/alacritty_terminal/src/ansi.rs +++ b/alacritty_terminal/src/ansi.rs @@ -768,8 +768,10 @@ pub enum Attr { Underline, /// Underlined twice. DoubleUnderline, - /// Underlined twice. + /// Undercurl twice. Undercurl, + /// Underlined with dots. + DottedUnderline, /// Blink cursor slowly. BlinkSlow, /// Blink cursor fast. @@ -971,6 +973,7 @@ where .trim() .to_owned(); self.handler.set_title(Some(title)); + return; } unhandled(params); @@ -1325,6 +1328,7 @@ fn attrs_from_sgr_parameters(params: &mut ParamsIter<'_>) -> Vec<Option<Attr>> { [4, 0] => Some(Attr::CancelUnderline), [4, 2] => Some(Attr::DoubleUnderline), [4, 3] => Some(Attr::Undercurl), + [4, 4] => Some(Attr::DottedUnderline), [4, ..] => Some(Attr::Underline), [5] => Some(Attr::BlinkSlow), [6] => Some(Attr::BlinkFast), diff --git a/alacritty_terminal/src/term/cell.rs b/alacritty_terminal/src/term/cell.rs index 4f5ac1e2..a393b332 100644 --- a/alacritty_terminal/src/term/cell.rs +++ b/alacritty_terminal/src/term/cell.rs @@ -25,7 +25,8 @@ bitflags! { const LEADING_WIDE_CHAR_SPACER = 0b0000_0100_0000_0000; const DOUBLE_UNDERLINE = 0b0000_1000_0000_0000; const UNDERCURL = 0b0001_0000_0000_0000; - const OVERLINE = 0b0010_0000_0000_0000; + const DOTTED_UNDERLINE = 0b0010_0000_0000_0000; + const OVERLINE = 0b0100_0000_0000_0000; } } @@ -125,6 +126,7 @@ impl GridCell for Cell { | Flags::UNDERLINE | Flags::DOUBLE_UNDERLINE | Flags::UNDERCURL + | Flags::DOTTED_UNDERLINE | Flags::OVERLINE | Flags::STRIKEOUT | Flags::WRAPLINE diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index 5a641a7b..ba170e32 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -1514,21 +1514,33 @@ impl<T: EventListener> Handler for Term<T> { Attr::Underline => { cursor.template.flags.remove(Flags::DOUBLE_UNDERLINE); cursor.template.flags.remove(Flags::UNDERCURL); + cursor.template.flags.remove(Flags::DOTTED_UNDERLINE); cursor.template.flags.insert(Flags::UNDERLINE); }, Attr::DoubleUnderline => { cursor.template.flags.remove(Flags::UNDERLINE); cursor.template.flags.remove(Flags::UNDERCURL); + cursor.template.flags.remove(Flags::DOTTED_UNDERLINE); cursor.template.flags.insert(Flags::DOUBLE_UNDERLINE); }, Attr::Undercurl => { cursor.template.flags.remove(Flags::UNDERLINE); cursor.template.flags.remove(Flags::DOUBLE_UNDERLINE); + cursor.template.flags.remove(Flags::DOTTED_UNDERLINE); cursor.template.flags.insert(Flags::UNDERCURL); }, + Attr::DottedUnderline => { + cursor.template.flags.remove(Flags::UNDERLINE); + cursor.template.flags.remove(Flags::DOUBLE_UNDERLINE); + cursor.template.flags.remove(Flags::UNDERCURL); + cursor.template.flags.insert(Flags::DOTTED_UNDERLINE); + }, Attr::CancelUnderline => { cursor.template.flags.remove( - Flags::UNDERLINE | Flags::DOUBLE_UNDERLINE | Flags::UNDERCURL); + Flags::UNDERLINE | + Flags::DOUBLE_UNDERLINE | + Flags::UNDERCURL | + Flags::DOTTED_UNDERLINE); }, Attr::Overline => { cursor.template.flags.insert(Flags::OVERLINE); |