gpui: Fix ascent/descent calculation on macOS (#39886)
As you can see in the image, we were previously returning different `ascent`s/`descent`s when a line would/would not contain an Emoji. <img width="104" height="36" alt="image" src="https://github.com/user-attachments/assets/436aeda0-87c0-4dee-943b-6da83681d466" /> --- CoreTexts `CTLineGetTypographicBounds` seems to return a different ascent/descent depending on if an Emoji is there or not AFAIK it is not documented if this is intended behaviour or not. For us it is undesirable, as typing an Emoji causes the line to be shifted to the bottom, see here: https://github.com/user-attachments/assets/2ad1c82e-6297-48ac-a522-fb382ea56eea --- Instead of using `CTLineGetTypographicBounds` to resolve the ascent/descent, we look at every run and choose the maximum ascent/descent. This matches how it [works on Linux](https://github.com/zed-industries/zed/blob/f1d17fcfbef41690fdeb523f0fbddc7c406c5ad6/crates/gpui/src/platform/linux/text_system.rs#L452) Release Notes: - Fixed an issue on macOS where typing an emoji on a line would cause the line to shift downwards by a few pixels
This commit is contained in:
@@ -430,6 +430,8 @@ impl MacTextSystemState {
|
||||
fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
|
||||
// Construct the attributed string, converting UTF8 ranges to UTF16 ranges.
|
||||
let mut string = CFMutableAttributedString::new();
|
||||
let mut max_ascent = 0.0f32;
|
||||
let mut max_descent = 0.0f32;
|
||||
{
|
||||
string.replace_str(&CFString::new(text), CFRange::init(0, 0));
|
||||
let utf16_line_len = string.char_len() as usize;
|
||||
@@ -451,6 +453,11 @@ impl MacTextSystemState {
|
||||
|
||||
let font: &FontKitFont = &self.fonts[run.font_id.0];
|
||||
|
||||
let font_metrics = font.metrics();
|
||||
let font_scale = font_size.0 / font_metrics.units_per_em as f32;
|
||||
max_ascent = max_ascent.max(font_metrics.ascent * font_scale);
|
||||
max_descent = max_descent.max(-font_metrics.descent * font_scale);
|
||||
|
||||
unsafe {
|
||||
string.set_attribute(
|
||||
cf_range,
|
||||
@@ -508,8 +515,8 @@ impl MacTextSystemState {
|
||||
runs,
|
||||
font_size,
|
||||
width: typographic_bounds.width.into(),
|
||||
ascent: typographic_bounds.ascent.into(),
|
||||
descent: typographic_bounds.descent.into(),
|
||||
ascent: max_ascent.into(),
|
||||
descent: max_descent.into(),
|
||||
len: text.len(),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user