Skip to content

Commit

Permalink
Render the various underline styles
Browse files Browse the repository at this point in the history
```
$ printf "\x1b[58;2;255;0;0m\x1b[4msingle\x1b[21mdouble\x1b[60mcurly\x1b[61mdotted\x1b[62mdashed\x1b[0m"
```

refs: #415
  • Loading branch information
wez committed Jan 6, 2021
1 parent 9357669 commit 697d41a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 12 deletions.
99 changes: 89 additions & 10 deletions wezterm-gui/src/gui/glyphcache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -353,16 +353,96 @@ impl<T: Texture2d> GlyphCache<T> {
}
};

let draw_dotted = |buffer: &mut Image| {
for row in 0..self.metrics.underline_height {
let y = (cell_rect.origin.y + self.metrics.descender_row + row) as usize;
if y >= self.metrics.cell_size.height as usize {
break;
}

let mut color = white;
let segment_length = (self.metrics.cell_size.width / 4) as usize;
let mut count = segment_length;
let range =
buffer.horizontal_pixel_range_mut(0, self.metrics.cell_size.width as usize, y);
for c in range.iter_mut() {
*c = color.0;
count -= 1;
if count == 0 {
color = if color == white { black } else { white };
count = segment_length;
}
}
}
};

let draw_dashed = |buffer: &mut Image| {
for row in 0..self.metrics.underline_height {
let y = (cell_rect.origin.y + self.metrics.descender_row + row) as usize;
if y >= self.metrics.cell_size.height as usize {
break;
}
let mut color = white;
let third = (self.metrics.cell_size.width / 3) as usize + 1;
let mut count = third;
let range =
buffer.horizontal_pixel_range_mut(0, self.metrics.cell_size.width as usize, y);
for c in range.iter_mut() {
*c = color.0;
count -= 1;
if count == 0 {
color = if color == white { black } else { white };
count = third;
}
}
}
};

let draw_curly = |buffer: &mut Image| {
let max_y = self.metrics.cell_size.height as usize - 1;
let x_factor = (2. * std::f32::consts::PI) / self.metrics.cell_size.width as f32;

// Have the wave go from the descender to the bottom of the cell
let wave_height =
self.metrics.cell_size.height - (cell_rect.origin.y + self.metrics.descender_row);

let half_height = (wave_height as f32 / 2.).max(1.);
let y =
(cell_rect.origin.y + self.metrics.descender_row) as usize - half_height as usize;

fn add(x: usize, y: usize, val: u8, max_y: usize, buffer: &mut Image) {
let y = y.min(max_y);
let pixel = buffer.pixel_mut(x, y);
let (current, _, _, _) = Color(*pixel).as_rgba();
let value = current.saturating_add(val);
*pixel = Color::rgb(value, value, value).0;
}

for x in 0..self.metrics.cell_size.width as usize {
let vertical = wave_height as f32 * (x as f32 * x_factor).cos();
let v1 = vertical.floor();
let v2 = vertical.ceil();

for row in 0..self.metrics.underline_height as usize {
let value = (255. * (vertical - v1).abs()) as u8;
add(x, row + y + v1 as usize, 255 - value, max_y, buffer);
add(x, row + y + v2 as usize, value, max_y, buffer);
}
}
};

let draw_double = |buffer: &mut Image| {
let first_line = self
.metrics
.descender_row
.min(self.metrics.descender_plus_two - 2 * self.metrics.underline_height);

for row in 0..self.metrics.underline_height {
buffer.draw_line(
Point::new(
cell_rect.origin.x,
cell_rect.origin.y + self.metrics.descender_row + row,
),
Point::new(cell_rect.origin.x, cell_rect.origin.y + first_line + row),
Point::new(
cell_rect.origin.x + self.metrics.cell_size.width,
cell_rect.origin.y + self.metrics.descender_row + row,
cell_rect.origin.y + first_line + row,
),
white,
Operator::Source,
Expand Down Expand Up @@ -419,11 +499,10 @@ impl<T: Texture2d> GlyphCache<T> {
}
match key.underline {
Underline::None => {}
Underline::Single |
// FIXME: these extra styles need to be rendered separately!
Underline::Curly | Underline::Dotted | Underline::Dashed => {
draw_single(&mut buffer)
}
Underline::Single => draw_single(&mut buffer),
Underline::Curly => draw_curly(&mut buffer),
Underline::Dashed => draw_dashed(&mut buffer),
Underline::Dotted => draw_dotted(&mut buffer),
Underline::Double => draw_double(&mut buffer),
}
if key.strike_through {
Expand Down
2 changes: 1 addition & 1 deletion wezterm-gui/src/gui/utilsprites.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl RenderMetrics {
let descender_row =
(cell_height as f64 + (metrics.descender - metrics.underline_position).get()) as isize;
let descender_plus_two =
(2 * underline_height + descender_row).min(cell_height as isize - 1);
(2 * underline_height + descender_row).min(cell_height as isize - underline_height);
let strike_row = descender_row / 2;

Self {
Expand Down
2 changes: 1 addition & 1 deletion window/src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ fn srgb8_to_linear_f32(val: u8) -> f32 {
}

/// A color stored as big endian bgra32
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct Color(pub u32);

impl From<LinSrgba> for Color {
Expand Down

0 comments on commit 697d41a

Please sign in to comment.