mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-28 01:26:48 +00:00
Fix the fonts panic
co-authored-by: Piotr <piotr@zed.dev>
This commit is contained in:
parent
2bfbd72483
commit
a75fa35a08
1 changed files with 41 additions and 4 deletions
|
@ -81,13 +81,11 @@ impl PlatformTextSystem for MacTextSystem {
|
|||
fn all_font_names(&self) -> Vec<String> {
|
||||
let collection = core_text::font_collection::create_for_all_families();
|
||||
let Some(descriptors) = collection.get_descriptors() else {
|
||||
return vec![];
|
||||
return Vec::new();
|
||||
};
|
||||
let mut names = BTreeSet::new();
|
||||
for descriptor in descriptors.into_iter() {
|
||||
names.insert(descriptor.font_name());
|
||||
names.insert(descriptor.family_name());
|
||||
names.insert(descriptor.style_name());
|
||||
names.extend(lenient_font_attributes::family_name(&descriptor));
|
||||
}
|
||||
if let Ok(fonts_in_memory) = self.0.read().memory_source.all_families() {
|
||||
names.extend(fonts_in_memory);
|
||||
|
@ -612,6 +610,45 @@ impl From<FontStyle> for FontkitStyle {
|
|||
}
|
||||
}
|
||||
|
||||
// Some fonts may have no attributest despite `core_text` requiring them (and panicking).
|
||||
// This is the same version as `core_text` has without `expect` calls.
|
||||
mod lenient_font_attributes {
|
||||
use core_foundation::{
|
||||
base::{CFRetain, CFType, TCFType},
|
||||
string::{CFString, CFStringRef},
|
||||
};
|
||||
use core_text::font_descriptor::{
|
||||
kCTFontFamilyNameAttribute, CTFontDescriptor, CTFontDescriptorCopyAttribute,
|
||||
};
|
||||
|
||||
pub fn family_name(descriptor: &CTFontDescriptor) -> Option<String> {
|
||||
unsafe { get_string_attribute(descriptor, kCTFontFamilyNameAttribute) }
|
||||
}
|
||||
|
||||
fn get_string_attribute(
|
||||
descriptor: &CTFontDescriptor,
|
||||
attribute: CFStringRef,
|
||||
) -> Option<String> {
|
||||
unsafe {
|
||||
let value = CTFontDescriptorCopyAttribute(descriptor.as_concrete_TypeRef(), attribute);
|
||||
if value.is_null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let value = CFType::wrap_under_create_rule(value);
|
||||
assert!(value.instance_of::<CFString>());
|
||||
let s = wrap_under_get_rule(value.as_CFTypeRef() as CFStringRef);
|
||||
Some(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn wrap_under_get_rule(reference: CFStringRef) -> CFString {
|
||||
assert!(!reference.is_null(), "Attempted to create a NULL object.");
|
||||
let reference = CFRetain(reference as *const ::std::os::raw::c_void) as CFStringRef;
|
||||
TCFType::wrap_under_create_rule(reference)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{font, px, FontRun, MacTextSystem, PlatformTextSystem};
|
||||
|
|
Loading…
Reference in a new issue