1
1
mirror of https://github.com/wez/wezterm.git synced 2024-09-20 03:09:06 +03:00

config: cursor_thickness, strikethrough_position, underline_position, underline_thickness

refs: https://github.com/wez/wezterm/issues/2326
refs: https://github.com/wez/wezterm/issues/2505
This commit is contained in:
Wez Furlong 2022-09-10 18:32:51 -07:00
parent 72674f5d28
commit 295677ed52
9 changed files with 147 additions and 9 deletions

View File

@ -57,6 +57,18 @@ pub struct Config {
#[dynamic(default = "default_one_point_oh_f64")]
pub cell_width: f64,
#[dynamic(try_from = "crate::units::OptPixelUnit", default)]
pub cursor_thickness: Option<Dimension>,
#[dynamic(try_from = "crate::units::OptPixelUnit", default)]
pub underline_thickness: Option<Dimension>,
#[dynamic(try_from = "crate::units::OptPixelUnit", default)]
pub underline_position: Option<Dimension>,
#[dynamic(try_from = "crate::units::OptPixelUnit", default)]
pub strikethrough_position: Option<Dimension>,
#[dynamic(default)]
pub allow_square_glyphs_to_overflow_width: AllowSquareGlyphOverflow,

View File

@ -18,6 +18,12 @@ As features stabilize some brief notes about them will accumulate here.
* [normalize_to_nfc](config/lua/config/normalize_to_nfc.md) option to normalize
terminal output to Unicode NFC prior to applying it to the terminal model.
[#2482](https://github.com/wez/wezterm/issues/2482)
* [cursor_thickness](config/lua/config/cursor_thickness.md),
[underline_thickness](config/lua/config/underline_thickness.md),
[underline_position](config/lua/config/underline_position.md) and
[strikethrough_position](config/lua/config/strikethrough_position.md) options
to fine tune appearance. [#2505](https://github.com/wez/wezterm/issues/2505)
[#2326](https://github.com/wez/wezterm/issues/2326)
#### Fixed
* Wayland: key repeat gets stuck after pressing two keys in quick succession.

View File

@ -0,0 +1,16 @@
# cursor_thickness
*Since: nightly builds only*
If specified, overrides the base thickness of the lines used to
render the textual cursor glyph.
The default is to use the [underline_thickness](underline_thickness.md).
This config option accepts different units that have slightly different interpretations:
* `2`, `2.0` or `"2px"` all specify a thickness of 2 pixels
* `"2pt"` specifies a thickness of 2 points, which scales according to the DPI of the window
* `"200%"` takes the `underline_thickness` and multiplies it by 2 to arrive at a thickness double the normal size
* `"0.1cell"` takes the cell height, scales it by `0.1` and uses that as the thickness

View File

@ -0,0 +1,16 @@
# strikethrough_position
*Since: nightly builds only*
If specified, overrides the position of strikethrough lines.
The default is derived from the underline position metric specified by the designer
of the primary font.
This config option accepts different units that have slightly different interpretations:
* `2`, `2.0` or `"2px"` all specify a position of 2 pixels
* `"2pt"` specifies a position of 2 points, which scales according to the DPI of the window
* `"200%"` takes the font-specified `underline_position` and multiplies it by 2
* `"0.5cell"` takes the cell height, scales it by `0.5` and uses that as the position

View File

@ -0,0 +1,19 @@
# underline_position
*Since: nightly builds only*
If specified, overrides the position of underlines.
The default is to use the underline position metric specified by the designer
of the primary font.
This config option accepts different units that have slightly different interpretations:
* `2`, `2.0` or `"2px"` all specify a position of 2 pixels
* `"2pt"` specifies a position of 2 points, which scales according to the DPI of the window
* `"200%"` takes the font-specified `underline_position` and multiplies it by 2
* `"0.1cell"` takes the cell height, scales it by `0.1` and uses that as the position
Note that the `underline_position` is often a small negative number like `-2`
or `-4` and specifies an offset from the baseline of the font.

View File

@ -0,0 +1,19 @@
# underline_thickness
*Since: nightly builds only*
If specified, overrides the base thickness of underlines. The underline
thickness is also used for rendering split pane dividers and a number of other
lines in custom glyphs.
The default is to use the underline thickness metric specified by the designer
of the primary font.
This config option accepts different units that have slightly different interpretations:
* `2`, `2.0` or `"2px"` all specify a thickness of 2 pixels
* `"2pt"` specifies a thickness of 2 points, which scales according to the DPI of the window
* `"200%"` takes the font-specified `underline_thickness` and multiplies it by 2 to arrive at a thickness double the normal size
* `"0.1cell"` takes the cell height, scales it by `0.1` and uses that as the thickness

View File

@ -2,6 +2,7 @@ use crate::glyphcache::{GlyphCache, SizedBlockKey};
use crate::utilsprites::RenderMetrics;
use ::window::bitmaps::atlas::Sprite;
use ::window::color::{LinearRgba, SrgbaPixel};
use config::DimensionContext;
use std::ops::Range;
use termwiz::surface::CursorShape;
use tiny_skia::{FillRule, Paint, Path, PathBuilder, PixmapMut, Stroke, Transform};
@ -3707,7 +3708,14 @@ impl<T: Texture2d> GlyphCache<T> {
return Ok(sprite.clone());
}
let metrics = metrics.scale_cell_width(width as f64);
let mut metrics = metrics.scale_cell_width(width as f64);
if let Some(d) = &self.fonts.config().cursor_thickness {
metrics.underline_height = d.evaluate_as_pixels(DimensionContext {
dpi: self.fonts.get_dpi() as f32,
pixel_max: metrics.underline_height as f32,
pixel_cell: metrics.cell_size.height as f32,
}) as isize;
}
let mut buffer = Image::new(
metrics.cell_size.width as usize,

View File

@ -248,7 +248,7 @@ impl DecodedImage {
pub struct GlyphCache<T: Texture2d> {
glyph_cache: HashMap<GlyphKey, Rc<CachedGlyph<T>>>,
pub atlas: Atlas<T>,
fonts: Rc<FontConfiguration>,
pub fonts: Rc<FontConfiguration>,
pub image_cache: LfuCacheU64<DecodedImage>,
frame_cache: HashMap<[u8; 32], Sprite<T>>,
line_glyphs: HashMap<LineKey, Sprite<T>>,
@ -402,6 +402,7 @@ impl<T: Texture2d> GlyphCache<T> {
pub fn config_changed(&mut self) {
let config = self.fonts.config();
self.image_cache.update_config(&config);
self.cursor_glyphs.clear();
}
/// Perform the load and render of a glyph
@ -783,7 +784,8 @@ impl<T: Texture2d> GlyphCache<T> {
metrics.cell_size.height - (cell_rect.origin.y + metrics.descender_row);
let half_height = (wave_height as f32 / 4.).max(1.);
let y = (cell_rect.origin.y + metrics.descender_row) as usize - half_height as usize;
let y = ((cell_rect.origin.y + metrics.descender_row) as usize)
.saturating_sub(half_height as usize);
fn add(x: usize, y: usize, val: u8, max_y: usize, buffer: &mut Image) {
let y = y.min(max_y);
@ -800,8 +802,20 @@ impl<T: Texture2d> GlyphCache<T> {
for row in 0..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);
add(
x,
row.saturating_add(y).saturating_add(v1 as usize),
255u8.saturating_sub(value),
max_y,
buffer,
);
add(
x,
row.saturating_add(y).saturating_add(v2 as usize),
value,
max_y,
buffer,
);
}
}
};

View File

@ -4,6 +4,7 @@ use ::window::bitmaps::{BitmapImage, Image, Texture2d};
use ::window::color::SrgbaPixel;
use ::window::{Point, Rect, Size};
use anyhow::Context;
use config::DimensionContext;
use std::rc::Rc;
use wezterm_font::units::*;
use wezterm_font::{FontConfiguration, FontMetrics};
@ -84,14 +85,41 @@ impl RenderMetrics {
// such that we are horizontally centered.
let line_height_y_adjust = (cell_height as f64 - metrics.cell_height.get().ceil()) / 2.;
let underline_height = metrics.underline_thickness.get().round().max(1.) as isize;
let config = fonts.config();
let underline_height = match &config.underline_thickness {
None => metrics.underline_thickness.get().round().max(1.) as isize,
Some(d) => d
.evaluate_as_pixels(DimensionContext {
dpi: fonts.get_dpi() as f32,
pixel_max: metrics.underline_thickness.get() as f32,
pixel_cell: cell_height as f32,
})
.max(1.) as isize,
};
let descender_row = (cell_height as f64
+ (metrics.descender - metrics.underline_position).get()
let underline_position = match &config.underline_position {
None => metrics.underline_position.get(),
Some(d) => d.evaluate_as_pixels(DimensionContext {
dpi: fonts.get_dpi() as f32,
pixel_max: metrics.underline_position.get() as f32,
pixel_cell: cell_height as f32,
}) as f64,
};
let descender_row = (cell_height as f64 + (metrics.descender.get() - underline_position)
- line_height_y_adjust) as isize;
let descender_plus_two =
(2 * underline_height + descender_row).min(cell_height as isize - underline_height);
let strike_row = descender_row / 2;
let strike_row = match &config.strikethrough_position {
None => descender_row / 2,
Some(d) => d
.evaluate_as_pixels(DimensionContext {
dpi: fonts.get_dpi() as f32,
pixel_max: descender_row as f32 / 2.,
pixel_cell: cell_height as f32,
})
.round() as isize,
};
Ok(Self {
descender: metrics.descender - PixelLength::new(line_height_y_adjust),