From 20a93f6195ca8e9f0a748038317a5efe1be3e482 Mon Sep 17 00:00:00 2001 From: Ankan Misra Date: Tue, 7 Jul 2026 14:29:55 +0530 Subject: [PATCH] gpui_macos: Fix glyph rendering when fonts share a PostScript name (#57250) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS, `load_family` was inserting every font into `font_ids_by_postscript_name` without checking for duplicates. When two installed font files claim the same PostScript name — typically an older Geist Mono left behind alongside the current brew cask — the second insert overwrote the first. After shaping, `id_for_native_font` looked up that PostScript name and got back the *other* font's `FontId`, so the rasterizer drew glyphs from the wrong table See #55472 for the screenshot This adds a local `HashSet` to dedup within a single `load_family` call. Scoping it to one call (rather than the global map) matters: the same family gets reloaded under different `FontKey`s when `FontFeatures` or `FontFallbacks` change, and a global check would skip every font on the reload and break weight selection. Cross-family PostScript name collisions and CoreText fallback substitutions that re-introduce a conflict are out of scope here Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed glyph rendering when fonts share a PostScript name on macOS --------- Co-authored-by: Lukas Wirth --- crates/gpui_macos/src/text_system.rs | 32 ++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/crates/gpui_macos/src/text_system.rs b/crates/gpui_macos/src/text_system.rs index 2808e535ad5..fbc48864ce5 100644 --- a/crates/gpui_macos/src/text_system.rs +++ b/crates/gpui_macos/src/text_system.rs @@ -1,6 +1,6 @@ use anyhow::anyhow; use cocoa::appkit::CGFloat; -use collections::HashMap; +use collections::{HashMap, HashSet}; use core_foundation::{ array::{CFArray, CFArrayRef}, attributed_string::CFMutableAttributedString, @@ -282,6 +282,7 @@ impl MacTextSystemState { let name = gpui::font_name_with_fallbacks(name, ".AppleSystemUIFont"); let mut font_ids = SmallVec::new(); + let mut postscript_names_seen = HashSet::default(); let family = self .memory_source .select_family_by_name(name) @@ -340,15 +341,38 @@ impl MacTextSystemState { .is_some()) } { log::error!( - "Failed to read traits for font {:?}", - font.postscript_name().unwrap() + "Failed to read traits for font {:?} (PostScript name {:?})", + font.full_name(), + font.postscript_name(), ); continue; } + let Some(postscript_name) = font.postscript_name() else { + log::warn!( + "font {:?} in family {:?} has no PostScript name; skipping", + font.full_name(), + name, + ); + continue; + }; + // Dedup is scoped to this single `load_family` call (issue #55472). + // The same family can be reloaded later under a different `FontKey` + // (different features/fallbacks); a global check against + // `font_ids_by_postscript_name` would skip every already-registered + // font and leave the second call's `font_ids` empty. + if !postscript_names_seen.insert(postscript_name.clone()) { + log::warn!( + "skipping duplicate font {:?} with PostScript name {:?} \ + in family {:?}", + font.full_name(), + postscript_name, + name, + ); + continue; + } let font_id = FontId(self.fonts.len()); font_ids.push(font_id); - let postscript_name = font.postscript_name().unwrap(); self.font_ids_by_postscript_name .insert(postscript_name.clone(), font_id); self.postscript_names_by_font_id