Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix scaling for offset and glyph offset #7145

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 10 additions & 6 deletions alacritty/src/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,10 +400,10 @@ impl Display {
let rasterizer = Rasterizer::new(scale_factor)?;

debug!("Loading \"{}\" font", &config.font.normal().family);
let mut glyph_cache = GlyphCache::new(rasterizer, &config.font)?;
let mut glyph_cache = GlyphCache::new(rasterizer, &config.font, window.scale_factor)?;

let metrics = glyph_cache.font_metrics();
let (cell_width, cell_height) = compute_cell_size(config, &metrics);
let (cell_width, cell_height) = compute_cell_size(config, &metrics, window.scale_factor);

// Resize the window to account for the user configured size.
if let Some(dimensions) = config.window.dimensions() {
Expand Down Expand Up @@ -575,7 +575,7 @@ impl Display {
let _ = glyph_cache.update_font_size(font, scale_factor);

// Compute new cell sizes.
compute_cell_size(config, &glyph_cache.font_metrics())
compute_cell_size(config, &glyph_cache.font_metrics(), scale_factor)
}

/// Reset glyph cache.
Expand Down Expand Up @@ -1610,12 +1610,16 @@ impl FrameTimer {
///
/// This will return a tuple of the cell width and height.
#[inline]
fn compute_cell_size(config: &UiConfig, metrics: &crossfont::Metrics) -> (f32, f32) {
fn compute_cell_size(
config: &UiConfig,
metrics: &crossfont::Metrics,
scale_factor: f64,
) -> (f32, f32) {
let offset_x = f64::from(config.font.offset.x);
let offset_y = f64::from(config.font.offset.y);
(
(metrics.average_advance + offset_x).floor().max(1.) as f32,
(metrics.line_height + offset_y).floor().max(1.) as f32,
(metrics.average_advance + offset_x * scale_factor).floor().max(1.) as f32,
(metrics.line_height + offset_y * scale_factor).floor().max(1.) as f32,
)
}

Expand Down
26 changes: 17 additions & 9 deletions alacritty/src/renderer/text/builtin_font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,33 @@ pub fn builtin_glyph(
metrics: &Metrics,
offset: &Delta<i8>,
glyph_offset: &Delta<i8>,
scale_factor: f64,
) -> Option<RasterizedGlyph> {
let mut glyph = match character {
// Box drawing characters and block elements.
'\u{2500}'..='\u{259f}' => box_drawing(character, metrics, offset),
'\u{2500}'..='\u{259f}' => box_drawing(character, metrics, offset, scale_factor),
_ => return None,
};

// Since we want to ignore `glyph_offset` for the built-in font, subtract it to compensate its
// addition when loading glyphs in the renderer.
glyph.left -= glyph_offset.x as i32;
glyph.top -= glyph_offset.y as i32;
glyph.left -= ((glyph_offset.x as f64) * scale_factor) as i32;
glyph.top -= ((glyph_offset.y as f64) * scale_factor) as i32;

Some(glyph)
}

fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> RasterizedGlyph {
fn box_drawing(
character: char,
metrics: &Metrics,
offset: &Delta<i8>,
scale_factor: f64,
) -> RasterizedGlyph {
// Ensure that width and height is at least one.
let height = (metrics.line_height as i32 + offset.y as i32).max(1) as usize;
let width = (metrics.average_advance as i32 + offset.x as i32).max(1) as usize;
let offset_y = ((offset.y as f64) * scale_factor) as i32;
let offset_x = ((offset.x as f64) * scale_factor) as i32;
let height = (metrics.line_height as i32 + offset_y).max(1) as usize;
let width = (metrics.average_advance as i32 + offset_x).max(1) as usize;
// 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;
Expand Down Expand Up @@ -482,7 +490,7 @@ fn box_drawing(character: char, metrics: &Metrics, offset: &Delta<i8>) -> Raster
_ => unreachable!(),
}

let top = height as i32 + metrics.descent as i32;
let top = height as i32 + ((metrics.descent as f64) * scale_factor) as i32;
let buffer = BitmapBuffer::Rgb(canvas.into_raw());
RasterizedGlyph {
character,
Expand Down Expand Up @@ -825,11 +833,11 @@ mod tests {

// Test coverage of box drawing characters.
for character in '\u{2500}'..='\u{259f}' {
assert!(builtin_glyph(character, &metrics, &offset, &glyph_offset).is_some());
assert!(builtin_glyph(character, &metrics, &offset, &glyph_offset, 1.0).is_some());
}

for character in ('\u{2450}'..'\u{2500}').chain('\u{25a0}'..'\u{2600}') {
assert!(builtin_glyph(character, &metrics, &offset, &glyph_offset).is_none());
assert!(builtin_glyph(character, &metrics, &offset, &glyph_offset, 1.0).is_none());
}
}
}
16 changes: 13 additions & 3 deletions alacritty/src/renderer/text/glyph_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,17 @@ pub struct GlyphCache {

/// Whether to use the built-in font for box drawing characters.
builtin_box_drawing: bool,

/// Display scale factor
scale_factor: f64,
}

impl GlyphCache {
pub fn new(mut rasterizer: Rasterizer, font: &Font) -> Result<GlyphCache, crossfont::Error> {
pub fn new(
mut rasterizer: Rasterizer,
font: &Font,
scale_factor: f64,
) -> Result<GlyphCache, crossfont::Error> {
let (regular, bold, italic, bold_italic) = Self::compute_font_keys(font, &mut rasterizer)?;

// Need to load at least one glyph for the face before calling metrics.
Expand All @@ -101,6 +108,7 @@ impl GlyphCache {
glyph_offset: font.glyph_offset,
metrics,
builtin_box_drawing: font.builtin_box_drawing,
scale_factor,
})
}

Expand Down Expand Up @@ -211,6 +219,7 @@ impl GlyphCache {
&self.metrics,
&self.font_offset,
&self.glyph_offset,
self.scale_factor,
)
})
.flatten()
Expand Down Expand Up @@ -246,8 +255,8 @@ impl GlyphCache {
where
L: LoadGlyph,
{
glyph.left += i32::from(self.glyph_offset.x);
glyph.top += i32::from(self.glyph_offset.y);
glyph.left += ((self.glyph_offset.x as f64) * self.scale_factor) as i32;
glyph.top += ((self.glyph_offset.y as f64) * self.scale_factor) as i32;
glyph.top -= self.metrics.descent as i32;

// The metrics of zero-width characters are based on rendering
Expand Down Expand Up @@ -284,6 +293,7 @@ impl GlyphCache {
self.rasterizer.update_dpr(scale_factor as f32);
self.font_offset = font.offset;
self.glyph_offset = font.glyph_offset;
self.scale_factor = scale_factor;

// Recompute font keys.
let (regular, bold, italic, bold_italic) =
Expand Down