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
This commit is contained in:
Lukas Wirth
2025-10-23 19:22:28 +00:00
committed by GitHub
parent 435eab6896
commit 66ec0fc0e1
@@ -67,8 +67,6 @@ struct MacTextSystemState {
font_ids_by_postscript_name: HashMap<String, FontId>,
font_ids_by_font_key: HashMap<FontKey, SmallVec<[FontId; 4]>>,
postscript_names_by_font_id: HashMap<FontId, String>,
/// UTF-16 indices of ZWNJS
zwnjs_scratch_space: Vec<usize>,
}
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);