Add logging for the font_descriptor panic (#7097)

Conrad Irwin created

Release Notes:

- Fixed a panic caused by an inconsistency in font metrics.

Change summary

crates/gpui/src/platform/mac/text_system.rs | 39 ++++++++++++++++++++++
1 file changed, 38 insertions(+), 1 deletion(-)

Detailed changes

crates/gpui/src/platform/mac/text_system.rs 🔗

@@ -10,6 +10,7 @@ use core_foundation::{
     array::CFIndex,
     attributed_string::{CFAttributedStringRef, CFMutableAttributedString},
     base::{CFRange, TCFType},
+    number::CFNumber,
     string::CFString,
 };
 use core_graphics::{
@@ -17,7 +18,14 @@ use core_graphics::{
     color_space::CGColorSpace,
     context::CGContext,
 };
-use core_text::{font::CTFont, line::CTLine, string_attributes::kCTFontAttributeName};
+use core_text::{
+    font::CTFont,
+    font_descriptor::{
+        kCTFontSlantTrait, kCTFontSymbolicTrait, kCTFontWeightTrait, kCTFontWidthTrait,
+    },
+    line::CTLine,
+    string_attributes::kCTFontAttributeName,
+};
 use font_kit::{
     font::Font as FontKitFont,
     handle::Handle,
@@ -219,6 +227,35 @@ impl MacTextSystemState {
             let Some(_) = font.glyph_for_char('m') else {
                 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.
+            let traits = font.native_font().all_traits();
+            if unsafe {
+                !(traits
+                    .get(kCTFontSymbolicTrait)
+                    .downcast::<CFNumber>()
+                    .is_some()
+                    && traits
+                        .get(kCTFontWidthTrait)
+                        .downcast::<CFNumber>()
+                        .is_some()
+                    && traits
+                        .get(kCTFontWeightTrait)
+                        .downcast::<CFNumber>()
+                        .is_some()
+                    && traits
+                        .get(kCTFontSlantTrait)
+                        .downcast::<CFNumber>()
+                        .is_some())
+            } {
+                log::error!(
+                    "Failed to read traits for font {:?}",
+                    font.postscript_name().unwrap()
+                );
+                continue;
+            }
+
             let font_id = FontId(self.fonts.len());
             font_ids.push(font_id);
             let postscript_name = font.postscript_name().unwrap();