From 0329b4a5cb1d14d8074e96a729835fbae6fad075 Mon Sep 17 00:00:00 2001 From: Marshall Bowers Date: Fri, 15 Mar 2024 17:35:10 -0400 Subject: [PATCH] Allow loading "Segoe Fluent Icons" font on macOS (#9421) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR updates the `TextSystem` on macOS to allow loading the "Segoe Fluent Icons" font. We're using this font in the Storybook to render the `TitleBar` as it would appear on Windows despite us running it on macOS. This is to make things easier for iterating on UI design without needing to test on each individual platform. However, the "Segoe Fluent Icons" font does not have a glyph for the `m` character, causing it to run afoul of a precautionary check added in #4029, which ultimately results in the font not being loaded (and thus rendering as a missing glyph). We work around this by simply ignoring this check if the font we're trying to load is specifically "Segoe Fluent Icons". I think longer-term we'll need to revisit the behavior in the editor that is causing the panics when the `m` glyph is missing from the font, but that's a problem for a different day. #### Before Screenshot 2024-03-15 at 3 34 38 PM #### After Screenshot 2024-03-15 at 5 12 36 PM Note that you currently need to install the "Segoe Fluent Icons" font yourself—either installing it globally or placing the `.ttf` file in the `assets/fonts` directory—in order to see the icons rendered. I'd like to look into getting this, but there are restrictions on the distribution of the font on non-Windows platforms that will need to be followed. Release Notes: - N/A --- crates/gpui/src/platform/mac/text_system.rs | 31 +++++++++++++++++-- .../title_bar/windows_window_controls.rs | 4 +-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/crates/gpui/src/platform/mac/text_system.rs b/crates/gpui/src/platform/mac/text_system.rs index 083e9cc1d89ced19c6b0e43e9d8adb13f429a8b7..d5bb7230127927c0cd16e489af07d3bce5f2901f 100644 --- a/crates/gpui/src/platform/mac/text_system.rs +++ b/crates/gpui/src/platform/mac/text_system.rs @@ -233,9 +233,34 @@ impl MacTextSystemState { let mut font = font.load()?; open_type::apply_features(&mut font, features); - let Some(_) = font.glyph_for_char('m') else { - continue; - }; + + // This block contains a precautionary fix to guard against loading fonts + // that might cause panics due to `.unwrap()`s up the chain. + { + // We use the 'm' character for text measurements in various spots + // (e.g., the editor). However, at time of writing some of those usages + // will panic if the font has no 'm' glyph. + // + // Therefore, we check up front that the font has the necessary glyph. + let has_m_glyph = font.glyph_for_char('m').is_some(); + + // HACK: The 'Segoe Fluent Icons' font does not have an 'm' glyph, + // but we need to be able to load it for rendering Windows icons in + // the Storybook (on macOS). + let is_segoe_fluent_icons = font.full_name() == "Segoe Fluent Icons"; + + if !has_m_glyph && !is_segoe_fluent_icons { + // I spent far too long trying to track down why a font missing the 'm' + // character wasn't loading. This log statement will hopefully save + // someone else from suffering the same fate. + log::warn!( + "font '{}' has no 'm' character and was not loaded", + font.full_name() + ); + continue; + } + } + // We've seen a number of panics in production caused by calling font.properties() // which unwraps a downcast to CFNumber. This is an attempt to avoid the panic, // and to try and identify the incalcitrant font. diff --git a/crates/ui/src/components/title_bar/windows_window_controls.rs b/crates/ui/src/components/title_bar/windows_window_controls.rs index 504a849d20e3168d8745340c559a17a4cc10a83e..4f478878500e91cb18ea955f6bbb2d0da1587188 100644 --- a/crates/ui/src/components/title_bar/windows_window_controls.rs +++ b/crates/ui/src/components/title_bar/windows_window_controls.rs @@ -45,8 +45,6 @@ impl RenderOnce for WindowsWindowControls { .content_stretch() .max_h(self.button_height) .min_h(self.button_height) - .font("Segoe Fluent Icons") - .text_size(px(10.0)) .child(WindowsCaptionButton::new( "minimize", WindowsCaptionButtonIcon::Minimize, @@ -110,6 +108,8 @@ impl RenderOnce for WindowsCaptionButton { .content_center() .w(width) .h_full() + .font("Segoe Fluent Icons") + .text_size(px(10.0)) .hover(|style| style.bg(self.hover_background_color)) .active(|style| { let mut active_color = self.hover_background_color;