aboutsummaryrefslogtreecommitdiff
path: root/alacritty/src/renderer/rects.rs
diff options
context:
space:
mode:
Diffstat (limited to 'alacritty/src/renderer/rects.rs')
-rw-r--r--alacritty/src/renderer/rects.rs201
1 files changed, 187 insertions, 14 deletions
diff --git a/alacritty/src/renderer/rects.rs b/alacritty/src/renderer/rects.rs
index 77c22011..25ae93d6 100644
--- a/alacritty/src/renderer/rects.rs
+++ b/alacritty/src/renderer/rects.rs
@@ -62,7 +62,18 @@ impl RenderLine {
end: Point<usize>,
color: Rgb,
) {
- let (position, thickness) = match flag {
+ 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;
@@ -78,22 +89,181 @@ impl RenderLine {
color,
));
- (bottom_pos, metrics.underline_thickness)
+ rects.push(Self::create_rect(
+ size,
+ metrics.descent,
+ start,
+ end,
+ bottom_pos,
+ metrics.underline_thickness,
+ color,
+ ));
+ },
+ Flags::UNDERLINE => {
+ rects.push(Self::create_rect(
+ size,
+ metrics.descent,
+ start,
+ end,
+ metrics.underline_position + 1.,
+ metrics.underline_thickness,
+ color,
+ ));
},
- Flags::UNDERLINE => (metrics.underline_position, metrics.underline_thickness),
- Flags::STRIKEOUT => (metrics.strikeout_position, metrics.strikeout_thickness),
+ Flags::OVERLINE => {
+ let start_x = start.column.0 as f32 * size.cell_width();
+ 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()) + (size.cell_height() / 8.),
+ end_x - start_x,
+ metrics.underline_thickness,
+ color,
+ 1.,
+ ));
+ },
+ Flags::STRIKEOUT => {
+ rects.push(Self::create_rect(
+ size,
+ metrics.descent,
+ start,
+ end,
+ metrics.strikeout_position,
+ metrics.strikeout_thickness,
+ color,
+ ));
+ },
+ Flags::DOTTED_UNDERLINE => {
+ Self::push_dotted_underline_rects(
+ rects,
+ size,
+ metrics.descent,
+ start,
+ end,
+ metrics.underline_position + 1.,
+ metrics.underline_thickness,
+ color)
+ }
_ => unimplemented!("Invalid flag for cell line drawing specified"),
};
+ }
- rects.push(Self::create_rect(
- size,
- metrics.descent,
- start,
- end,
- position,
- thickness,
- color,
- ));
+ fn push_undercurl_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 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 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() + fl,
+ 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.,
+ 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;
+ }
}
/// Create a line's rect at a position relative to the baseline.
@@ -161,6 +331,9 @@ impl RenderLines {
self.update_flag(cell, Flags::UNDERLINE);
self.update_flag(cell, Flags::DOUBLE_UNDERLINE);
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.
@@ -188,7 +361,7 @@ impl RenderLines {
}
// Start new line if there currently is none.
- let line = RenderLine { start: cell.point, end, color: cell.fg };
+ let line = RenderLine { start: cell.point, end, color: cell.sp };
match self.inner.get_mut(&flag) {
Some(lines) => lines.push(line),
None => {