gpui_macos: Initialize fallback fonts with primary font weight and style (#56771)
This PR fixes an issue where font properties like bolds and italics would be lost when falling back to a fallback font. The problem we identified was that when loading the fallback fonts, we were just loading them by name. This meant that when the original font had a different font weight (e.g., bold) or style applied to it this would not cascade to the fallback font. To reproduce the problem, we used the following text in a Markdown file: ```md **한글 bold** ``` With the following font configuration in Zed: ```json "buffer_font_family": "Victor Mono", "buffer_font_fallbacks": [ "D2Coding" ] ``` The fonts can be obtained from their respective locations: - [Victor Mono](https://rubjo.github.io/victor-mono/) - [D2Coding](https://github.com/naver/d2codingfont) #### Before <img width="168" height="46" alt="Screenshot 2026-05-14 at 1 15 15 PM" src="https://github.com/user-attachments/assets/f6883e4b-8f2b-4285-a110-0e18d562c51d" /> #### After <img width="176" height="53" alt="Screenshot 2026-05-14 at 1 16 04 PM" src="https://github.com/user-attachments/assets/88d67207-6711-473b-8027-e0acfa58c258" /> Closes #51460. Release Notes: - macOS: Fixed fallback fonts missing weight/style. --------- Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
1 parent
80ee76412e
commit
7f74def4b5
1 file changed
+46
-7
@@ -15,6 +15,10 @@ use core_foundation::{
|
||||
};
|
||||
use core_foundation_sys::locale::CFLocaleCopyPreferredLanguages;
|
||||
use core_graphics::{display::CFDictionary, geometry::CGAffineTransform};
|
||||
use core_text::font_descriptor::{
|
||||
TraitAccessors, kCTFontFamilyNameAttribute, kCTFontItalicTrait, kCTFontSlantTrait,
|
||||
kCTFontTraitsAttribute, kCTFontWeightTrait, kCTFontWidthTrait,
|
||||
};
|
||||
use core_text::{
|
||||
font::{CTFont, CTFontRef, cascade_list_for_languages},
|
||||
font_descriptor::{
|
||||
@@ -39,10 +43,7 @@ pub fn apply_features_and_fallbacks(
|
||||
&& !fallbacks.fallback_list().is_empty()
|
||||
{
|
||||
keys.push(kCTFontCascadeListAttribute);
|
||||
values.push(generate_fallback_array(
|
||||
fallbacks,
|
||||
font.native_font().as_concrete_TypeRef(),
|
||||
));
|
||||
values.push(generate_fallback_array(fallbacks, font));
|
||||
}
|
||||
let attrs = CFDictionaryCreate(
|
||||
kCFAllocatorDefault,
|
||||
@@ -98,16 +99,54 @@ fn generate_feature_array(features: &FontFeatures) -> CFMutableArrayRef {
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_fallback_array(fallbacks: &FontFallbacks, font_ref: CTFontRef) -> CFMutableArrayRef {
|
||||
fn generate_fallback_array(fallbacks: &FontFallbacks, font: &mut FontKitFont) -> CFMutableArrayRef {
|
||||
unsafe {
|
||||
let symbolic_traits = font.native_font().symbolic_traits();
|
||||
let all_traits = font.native_font().all_traits();
|
||||
|
||||
let fallback_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
for user_fallback in fallbacks.fallback_list() {
|
||||
let name = CFString::from(user_fallback.as_str());
|
||||
let fallback_desc =
|
||||
CTFontDescriptorCreateWithNameAndSize(name.as_concrete_TypeRef(), 0.0);
|
||||
|
||||
let traits_keys = [kCTFontWeightTrait, kCTFontSlantTrait];
|
||||
let weight_value = CFNumber::from(all_traits.normalized_weight());
|
||||
let slant_value = CFNumber::from(if (symbolic_traits & kCTFontItalicTrait) != 0 {
|
||||
1.0
|
||||
} else {
|
||||
0.0
|
||||
});
|
||||
let traits_values = [weight_value.as_CFTypeRef(), slant_value.as_CFTypeRef()];
|
||||
let traits = CFDictionaryCreate(
|
||||
kCFAllocatorDefault,
|
||||
&traits_keys as *const _ as _,
|
||||
&traits_values as *const _ as _,
|
||||
traits_keys.len() as isize,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks,
|
||||
);
|
||||
drop(weight_value);
|
||||
drop(slant_value);
|
||||
|
||||
let attr_keys = [kCTFontFamilyNameAttribute, kCTFontTraitsAttribute];
|
||||
let attr_values = [name.as_CFTypeRef(), traits as _];
|
||||
let attrs = CFDictionaryCreate(
|
||||
kCFAllocatorDefault,
|
||||
&attr_keys as *const _ as _,
|
||||
&attr_values as *const _ as _,
|
||||
attr_keys.len() as isize,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks,
|
||||
);
|
||||
CFRelease(traits as _);
|
||||
|
||||
let fallback_desc = CTFontDescriptorCreateWithAttributes(attrs);
|
||||
CFRelease(attrs as _);
|
||||
|
||||
CFArrayAppendValue(fallback_array, fallback_desc as _);
|
||||
CFRelease(fallback_desc as _);
|
||||
}
|
||||
|
||||
let font_ref = font.native_font().as_concrete_TypeRef();
|
||||
append_system_fallbacks(fallback_array, font_ref);
|
||||
fallback_array
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user