aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <rahm@google.com>2021-09-27 23:45:48 -0600
committerJosh Rahm <rahm@google.com>2021-09-27 23:45:48 -0600
commit505bbdb0aa09350a2c52ede96cbacc6e9cf084a2 (patch)
tree8fa20678a35f674617e6ae030eaf941d7560d31d
parent843583e2246a2404999b6c36293d7966cfb84334 (diff)
downloadr-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.rs8
-rw-r--r--alacritty/src/renderer/rects.rs106
-rw-r--r--alacritty_terminal/src/ansi.rs6
-rw-r--r--alacritty_terminal/src/term/cell.rs4
-rw-r--r--alacritty_terminal/src/term/mod.rs14
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);