summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKirill Chibisov <contact@kchibisov.com>2022-01-30 15:46:02 +0300
committerKirill Chibisov <contact@kchibisov.com>2022-02-10 03:17:21 +0300
commit5bab2ad2d0b1f3827f55665fe7b1bac98b4726b6 (patch)
tree62c78d31b2a1073e05b579191fe68ee47655c828
parentcd0e5c2a17012ddaf273ed1841e4ca546257a6fd (diff)
downloadalacritty-5bab2ad2d0b1f3827f55665fe7b1bac98b4726b6.tar.gz
alacritty-5bab2ad2d0b1f3827f55665fe7b1bac98b4726b6.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.md5
-rw-r--r--alacritty/src/renderer/builtin_font.rs60
2 files changed, 58 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f48967f..fce012a9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Option `font.builtin_box_drawing` to disable the built-in font for drawing box characters
+### Changed
+
+- Builtin font thickness is now based on cell width instead of underline thickness
+
### Fixed
- OSC 4 not handling `?`
@@ -18,6 +22,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.,