summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-01-30 15:46:02 +0300
committerGitHub <noreply@github.com>2022-01-30 15:46:02 +0300
commit5459492eaef9926419def7d85ad18b6c895a1568 (patch)
tree926eae76ba72579a1a36e0865b2db9f523a0b7dd
parentefae2cc80cb231081ce393fb922e6dcfc458260b (diff)
downloadalacritty-5459492eaef9926419def7d85ad18b6c895a1568.tar.gz
alacritty-5459492eaef9926419def7d85ad18b6c895a1568.zip
Use cell width to compute builtin font thickness
While using underline thickness could sound logical to draw other lines most fonts don't make underlines thick compared to cell bounding box if you increase font size. So instead we're using cell width to scale builtin font nicely. This commit also adjusts arcs drawing and alignment. Fixes #5826. Fixes #5821.
-rw-r--r--CHANGELOG.md2
-rw-r--r--alacritty/src/renderer/builtin_font.rs60
2 files changed, 55 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a397984c..edcdc07e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- The `--help` output was reworked with a new colorful syntax
+- Builtin font thickness is now based on cell width instead of underline thickness
### Fixed
@@ -26,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OSC 104 not clearing colors when second parameter is empty
- Builtin font lines not contiguous when `font.offset` is used
- `font.glyph_offset` is no longer applied on builtin font
+- Buili-in font arcs alignment
## 0.10.0
diff --git a/alacritty/src/renderer/builtin_font.rs b/alacritty/src/renderer/builtin_font.rs
index e905a1ef..f3dbe9bb 100644
--- a/alacritty/src/renderer/builtin_font.rs
+++ b/alacritty/src/renderer/builtin_font.rs
@@ -1,7 +1,7 @@
//! Hand-rolled drawing of unicode [box drawing](http://www.unicode.org/charts/PDF/U2500.pdf)
//! and [block elements](https://www.unicode.org/charts/PDF/U2580.pdf).
-use std::{cmp, mem};
+use std::{cmp, mem, ops};
use crossfont::{BitmapBuffer, Metrics, RasterizedGlyph};
@@ -39,8 +39,10 @@ pub fn builtin_glyph(
fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> RasterizedGlyph {
let height = (metrics.line_height as i32 + offset.y as i32) as usize;
let width = (metrics.average_advance as i32 + offset.x as i32) as usize;
- let stroke_size = cmp::max(metrics.underline_thickness as usize, 1);
- let heavy_stroke_size = stroke_size * 3;
+ // Use one eight of the cell width, since this is used as a step size for block elemenets.
+ let stroke_size = cmp::max((width as f32 / 8.).round() as usize, 1);
+ let heavy_stroke_size = stroke_size * 2;
+
// Certain symbols require larger canvas than the cell itself, since for proper contiguous
// lines they require drawing on neighbour cells. So treat them specially early on and handle
// 'normal' characters later.
@@ -66,7 +68,7 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> Raster
let from_x = 0.;
let to_x = x_end + 1.;
- for stroke_size in stroke_size..2 * stroke_size {
+ for stroke_size in 0..2 * stroke_size {
let stroke_size = stroke_size as f32 / 2.;
if character == '\u{2571}' || character == '\u{2573}' {
let h = y_end - stroke_size as f32;
@@ -341,7 +343,9 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> Raster
// Mirror `X` axis.
if character == '\u{256d}' || character == '\u{2570}' {
let center = canvas.x_center() as usize;
- let extra_offset = if width % 2 == 0 { 1 } else { 0 };
+
+ let extra_offset = if stroke_size % 2 == width % 2 { 0 } else { 1 };
+
let buffer = canvas.buffer_mut();
for y in 1..height {
let left = (y - 1) * width;
@@ -357,7 +361,9 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> Raster
// Mirror `Y` axis.
if character == '\u{256d}' || character == '\u{256e}' {
let center = canvas.y_center() as usize;
- let extra_offset = if height % 2 == 0 { 1 } else { 0 };
+
+ let extra_offset = if stroke_size % 2 == height % 2 { 0 } else { 1 };
+
let buffer = canvas.buffer_mut();
if extra_offset != 0 {
let bottom_row = (height - 1) * width;
@@ -483,6 +489,28 @@ impl Pixel {
}
}
+impl ops::Add for Pixel {
+ type Output = Pixel;
+
+ fn add(self, rhs: Pixel) -> Self::Output {
+ let _r = self._r.saturating_add(rhs._r);
+ let _g = self._g.saturating_add(rhs._g);
+ let _b = self._b.saturating_add(rhs._b);
+ Pixel { _r, _g, _b }
+ }
+}
+
+impl ops::Div<u8> for Pixel {
+ type Output = Pixel;
+
+ fn div(self, rhs: u8) -> Self::Output {
+ let _r = self._r / rhs;
+ let _g = self._g / rhs;
+ let _b = self._b / rhs;
+ Pixel { _r, _g, _b }
+ }
+}
+
/// Canvas which is used for simple line drawing operations.
///
/// The coordinate system is the following:
@@ -716,6 +744,24 @@ impl Canvas {
// Ensure the part closer to edges is properly filled.
self.draw_h_line(0., self.y_center(), stroke_size as f32, stroke_size);
self.draw_v_line(self.x_center(), 0., stroke_size as f32, stroke_size);
+
+ // Fill the resulted arc, since it could have gaps in-between.
+ for y in 0..self.height {
+ let row = y * self.width;
+ let left = match self.buffer[row..row + self.width].iter().position(|p| p._r != 0) {
+ Some(left) => row + left,
+ _ => continue,
+ };
+ let right = match self.buffer[row..row + self.width].iter().rposition(|p| p._r != 0) {
+ Some(right) => row + right,
+ _ => continue,
+ };
+
+ for index in left + 1..right {
+ self.buffer[index] =
+ self.buffer[index] + self.buffer[index - 1] / 2 + self.buffer[index + 1] / 2;
+ }
+ }
}
/// Fills the `Canvas` with the given `Color`.
@@ -744,7 +790,7 @@ mod test {
#[test]
fn builtin_line_drawing_glyphs_coverage() {
- // Dummy metrics values to test builtin glyphs coverage.
+ // Dummy metrics values to test built-in glyphs coverage.
let metrics = Metrics {
average_advance: 6.,
line_height: 16.,