mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 18:41:10 +00:00
Set *_font_fallbacks
default to None
(#16941)
Some checks are pending
CI / Check formatting and spelling (push) Waiting to run
CI / (macOS) Run Clippy and tests (push) Waiting to run
CI / (Linux) Run Clippy and tests (push) Waiting to run
CI / (Windows) Run Clippy and tests (push) Waiting to run
CI / Create a macOS bundle (push) Blocked by required conditions
CI / Create a Linux bundle (push) Blocked by required conditions
CI / Create arm64 Linux bundle (push) Blocked by required conditions
Deploy Docs / Deploy Docs (push) Waiting to run
Docs / Check formatting (push) Waiting to run
Some checks are pending
CI / Check formatting and spelling (push) Waiting to run
CI / (macOS) Run Clippy and tests (push) Waiting to run
CI / (Linux) Run Clippy and tests (push) Waiting to run
CI / (Windows) Run Clippy and tests (push) Waiting to run
CI / Create a macOS bundle (push) Blocked by required conditions
CI / Create a Linux bundle (push) Blocked by required conditions
CI / Create arm64 Linux bundle (push) Blocked by required conditions
Deploy Docs / Deploy Docs (push) Waiting to run
Docs / Check formatting (push) Waiting to run
In the current `default.json`, `*_font_fallbacks=[]`, which results in the `fallbacks` value in the `Font` struct always being `Some(...)`. This PR introduces the following improvements: 1. Changed `*_font_fallbacks = []` to `*_font_fallbacks = null` in `default.json`. 2. Enhanced the macOS and Windows implementations. Release Notes: - N/A
This commit is contained in:
parent
6c8836ec21
commit
64fa7a5234
3 changed files with 89 additions and 83 deletions
|
@ -28,7 +28,7 @@
|
|||
"buffer_font_family": "Zed Plex Mono",
|
||||
// Set the buffer text's font fallbacks, this will be merged with
|
||||
// the platform's default fallbacks.
|
||||
"buffer_font_fallbacks": [],
|
||||
"buffer_font_fallbacks": null,
|
||||
// The OpenType features to enable for text in the editor.
|
||||
"buffer_font_features": {
|
||||
// Disable ligatures:
|
||||
|
@ -54,7 +54,7 @@
|
|||
"ui_font_family": "Zed Plex Sans",
|
||||
// Set the UI's font fallbacks, this will be merged with the platform's
|
||||
// default font fallbacks.
|
||||
"ui_font_fallbacks": [],
|
||||
"ui_font_fallbacks": null,
|
||||
// The OpenType features to enable for text in the UI
|
||||
"ui_font_features": {
|
||||
// Disable ligatures:
|
||||
|
|
|
@ -35,50 +35,25 @@ pub fn apply_features_and_fallbacks(
|
|||
fallbacks: Option<&FontFallbacks>,
|
||||
) -> anyhow::Result<()> {
|
||||
unsafe {
|
||||
let fallback_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
|
||||
let mut keys = vec![kCTFontFeatureSettingsAttribute];
|
||||
let mut values = vec![generate_feature_array(features)];
|
||||
if let Some(fallbacks) = fallbacks {
|
||||
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);
|
||||
CFArrayAppendValue(fallback_array, fallback_desc as _);
|
||||
CFRelease(fallback_desc as _);
|
||||
if !fallbacks.fallback_list().is_empty() {
|
||||
keys.push(kCTFontCascadeListAttribute);
|
||||
values.push(generate_fallback_array(
|
||||
fallbacks,
|
||||
font.native_font().as_concrete_TypeRef(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let preferred_languages: CFArray<CFString> =
|
||||
CFArray::wrap_under_create_rule(CFLocaleCopyPreferredLanguages());
|
||||
|
||||
let default_fallbacks = CTFontCopyDefaultCascadeListForLanguages(
|
||||
font.native_font().as_concrete_TypeRef(),
|
||||
preferred_languages.as_concrete_TypeRef(),
|
||||
);
|
||||
let default_fallbacks: CFArray<CTFontDescriptor> =
|
||||
CFArray::wrap_under_create_rule(default_fallbacks);
|
||||
|
||||
default_fallbacks
|
||||
.iter()
|
||||
.filter(|desc| desc.font_path().is_some())
|
||||
.map(|desc| {
|
||||
CFArrayAppendValue(fallback_array, desc.as_concrete_TypeRef() as _);
|
||||
});
|
||||
}
|
||||
|
||||
let feature_array = generate_feature_array(features);
|
||||
let keys = [kCTFontFeatureSettingsAttribute, kCTFontCascadeListAttribute];
|
||||
let values = [feature_array, fallback_array];
|
||||
let attrs = CFDictionaryCreate(
|
||||
kCFAllocatorDefault,
|
||||
keys.as_ptr() as _,
|
||||
values.as_ptr() as _,
|
||||
2,
|
||||
keys.len() as isize,
|
||||
&kCFTypeDictionaryKeyCallBacks,
|
||||
&kCFTypeDictionaryValueCallBacks,
|
||||
);
|
||||
CFRelease(feature_array as *const _ as _);
|
||||
CFRelease(fallback_array as *const _ as _);
|
||||
let new_descriptor = CTFontDescriptorCreateWithAttributes(attrs);
|
||||
CFRelease(attrs as _);
|
||||
let new_descriptor = CTFontDescriptor::wrap_under_create_rule(new_descriptor);
|
||||
|
@ -97,8 +72,7 @@ pub fn apply_features_and_fallbacks(
|
|||
|
||||
fn generate_feature_array(features: &FontFeatures) -> CFMutableArrayRef {
|
||||
unsafe {
|
||||
let mut feature_array =
|
||||
CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
let feature_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||
for (tag, value) in features.tag_value_list() {
|
||||
let keys = [kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue];
|
||||
let values = [
|
||||
|
@ -121,6 +95,42 @@ fn generate_feature_array(features: &FontFeatures) -> CFMutableArrayRef {
|
|||
}
|
||||
}
|
||||
|
||||
fn generate_fallback_array(fallbacks: &FontFallbacks, font_ref: CTFontRef) -> CFMutableArrayRef {
|
||||
unsafe {
|
||||
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);
|
||||
CFArrayAppendValue(fallback_array, fallback_desc as _);
|
||||
CFRelease(fallback_desc as _);
|
||||
}
|
||||
append_system_fallbacks(fallback_array, font_ref);
|
||||
fallback_array
|
||||
}
|
||||
}
|
||||
|
||||
fn append_system_fallbacks(fallback_array: CFMutableArrayRef, font_ref: CTFontRef) {
|
||||
unsafe {
|
||||
let preferred_languages: CFArray<CFString> =
|
||||
CFArray::wrap_under_create_rule(CFLocaleCopyPreferredLanguages());
|
||||
|
||||
let default_fallbacks = CTFontCopyDefaultCascadeListForLanguages(
|
||||
font_ref,
|
||||
preferred_languages.as_concrete_TypeRef(),
|
||||
);
|
||||
let default_fallbacks: CFArray<CTFontDescriptor> =
|
||||
CFArray::wrap_under_create_rule(default_fallbacks);
|
||||
|
||||
default_fallbacks
|
||||
.iter()
|
||||
.filter(|desc| desc.font_path().is_some())
|
||||
.map(|desc| {
|
||||
CFArrayAppendValue(fallback_array, desc.as_concrete_TypeRef() as _);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[link(name = "CoreText", kind = "framework")]
|
||||
extern "C" {
|
||||
static kCTFontOpenTypeFeatureTag: CFStringRef;
|
||||
|
|
|
@ -275,54 +275,52 @@ impl DirectWriteState {
|
|||
|
||||
fn generate_font_fallbacks(
|
||||
&self,
|
||||
fallbacks: Option<&FontFallbacks>,
|
||||
fallbacks: &FontFallbacks,
|
||||
) -> Result<Option<IDWriteFontFallback>> {
|
||||
if fallbacks.is_some_and(|fallbacks| fallbacks.fallback_list().is_empty()) {
|
||||
if fallbacks.fallback_list().is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
unsafe {
|
||||
let builder = self.components.factory.CreateFontFallbackBuilder()?;
|
||||
let font_set = &self.system_font_collection.GetFontSet()?;
|
||||
if let Some(fallbacks) = fallbacks {
|
||||
for family_name in fallbacks.fallback_list() {
|
||||
let Some(fonts) = font_set
|
||||
.GetMatchingFonts(
|
||||
&HSTRING::from(family_name),
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
)
|
||||
.log_err()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if fonts.GetFontCount() == 0 {
|
||||
log::error!("No matching font found for {}", family_name);
|
||||
continue;
|
||||
}
|
||||
let font = fonts.GetFontFaceReference(0)?.CreateFontFace()?;
|
||||
let mut count = 0;
|
||||
font.GetUnicodeRanges(None, &mut count).ok();
|
||||
if count == 0 {
|
||||
continue;
|
||||
}
|
||||
let mut unicode_ranges = vec![DWRITE_UNICODE_RANGE::default(); count as usize];
|
||||
let Some(_) = font
|
||||
.GetUnicodeRanges(Some(&mut unicode_ranges), &mut count)
|
||||
.log_err()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let target_family_name = HSTRING::from(family_name);
|
||||
builder.AddMapping(
|
||||
&unicode_ranges,
|
||||
&[target_family_name.as_ptr()],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
1.0,
|
||||
)?;
|
||||
for family_name in fallbacks.fallback_list() {
|
||||
let Some(fonts) = font_set
|
||||
.GetMatchingFonts(
|
||||
&HSTRING::from(family_name),
|
||||
DWRITE_FONT_WEIGHT_NORMAL,
|
||||
DWRITE_FONT_STRETCH_NORMAL,
|
||||
DWRITE_FONT_STYLE_NORMAL,
|
||||
)
|
||||
.log_err()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if fonts.GetFontCount() == 0 {
|
||||
log::error!("No matching font found for {}", family_name);
|
||||
continue;
|
||||
}
|
||||
let font = fonts.GetFontFaceReference(0)?.CreateFontFace()?;
|
||||
let mut count = 0;
|
||||
font.GetUnicodeRanges(None, &mut count).ok();
|
||||
if count == 0 {
|
||||
continue;
|
||||
}
|
||||
let mut unicode_ranges = vec![DWRITE_UNICODE_RANGE::default(); count as usize];
|
||||
let Some(_) = font
|
||||
.GetUnicodeRanges(Some(&mut unicode_ranges), &mut count)
|
||||
.log_err()
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let target_family_name = HSTRING::from(family_name);
|
||||
builder.AddMapping(
|
||||
&unicode_ranges,
|
||||
&[target_family_name.as_ptr()],
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
1.0,
|
||||
)?;
|
||||
}
|
||||
let system_fallbacks = self.components.factory.GetSystemFontFallback()?;
|
||||
builder.AddMappings(&system_fallbacks)?;
|
||||
|
@ -378,10 +376,8 @@ impl DirectWriteState {
|
|||
else {
|
||||
continue;
|
||||
};
|
||||
let fallbacks = self
|
||||
.generate_font_fallbacks(font_fallbacks)
|
||||
.log_err()
|
||||
.unwrap_or_default();
|
||||
let fallbacks = font_fallbacks
|
||||
.and_then(|fallbacks| self.generate_font_fallbacks(fallbacks).log_err().flatten());
|
||||
let font_info = FontInfo {
|
||||
font_family: family_name.to_owned(),
|
||||
font_face,
|
||||
|
|
Loading…
Reference in a new issue