From 66ec0fc0e16e304497e92cc59996369d981bc9c2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Thu, 23 Oct 2025 21:22:28 +0200 Subject: [PATCH] Revert zero-width non-joiner insertion in text shaping (#41043) Reverts parts of https://github.com/zed-industries/zed/pull/39928 Closes https://github.com/zed-industries/zed/issues/40987 Release Notes: - Fixed some fonts rendering with absurd spacing on MacOS --- crates/gpui/src/platform/mac/text_system.rs | 29 --------------------- 1 file changed, 29 deletions(-) diff --git a/crates/gpui/src/platform/mac/text_system.rs b/crates/gpui/src/platform/mac/text_system.rs index 3d89ba79f316ca526af03eb274290d7d30aa190c..a0f90587d862d885e85b2052ce4f55f3cd5da55d 100644 --- a/crates/gpui/src/platform/mac/text_system.rs +++ b/crates/gpui/src/platform/mac/text_system.rs @@ -67,8 +67,6 @@ struct MacTextSystemState { font_ids_by_postscript_name: HashMap, font_ids_by_font_key: HashMap>, postscript_names_by_font_id: HashMap, - /// UTF-16 indices of ZWNJS - zwnjs_scratch_space: Vec, } impl MacTextSystem { @@ -81,7 +79,6 @@ impl MacTextSystem { font_ids_by_postscript_name: HashMap::default(), font_ids_by_font_key: HashMap::default(), postscript_names_by_font_id: HashMap::default(), - zwnjs_scratch_space: Vec::new(), })) } } @@ -431,11 +428,6 @@ impl MacTextSystemState { } fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout { - const ZWNJ: char = '\u{200C}'; - const ZWNJ_STR: &str = "\u{200C}"; - const ZWNJ_SIZE_16: usize = ZWNJ.len_utf16(); - - self.zwnjs_scratch_space.clear(); // Construct the attributed string, converting UTF8 ranges to UTF16 ranges. let mut string = CFMutableAttributedString::new(); let mut max_ascent = 0.0f32; @@ -443,26 +435,14 @@ impl MacTextSystemState { { let mut ix_converter = StringIndexConverter::new(&text); - let mut last_font_run = None; for run in font_runs { let text = &text[ix_converter.utf8_ix..][..run.len]; - // if the fonts are the same, we need to disconnect the text with a ZWNJ - // to prevent core text from forming ligatures between them - let needs_zwnj = last_font_run.replace(run.font_id) == Some(run.font_id); let utf16_start = string.char_len(); // insert at end of string ix_converter.advance_to_utf8_ix(ix_converter.utf8_ix + run.len); // note: replace_str may silently ignore codepoints it dislikes (e.g., BOM at start of string) string.replace_str(&CFString::new(text), CFRange::init(utf16_start, 0)); - if needs_zwnj { - let zwnjs_pos = string.char_len(); - self.zwnjs_scratch_space.push(zwnjs_pos as usize); - string.replace_str( - &CFString::from_static_string(ZWNJ_STR), - CFRange::init(zwnjs_pos, 0), - ); - } let utf16_end = string.char_len(); let cf_range = CFRange::init(utf16_start, utf16_end - utf16_start); @@ -514,15 +494,6 @@ impl MacTextSystemState { .zip(run.string_indices().iter()) { let mut glyph_utf16_ix = usize::try_from(glyph_utf16_ix).unwrap(); - let r = self - .zwnjs_scratch_space - .binary_search_by(|&it| it.cmp(&glyph_utf16_ix)); - match r { - // this glyph is a ZWNJ, skip it - Ok(_) => continue, - // adjust the index to account for the ZWNJs we've inserted - Err(idx) => glyph_utf16_ix -= idx * ZWNJ_SIZE_16, - } if ix_converter.utf16_ix > glyph_utf16_ix { // We cannot reuse current index converter, as it can only seek forward. Restart the search. ix_converter = StringIndexConverter::new(text);