mirror of
https://github.com/zed-industries/zed.git
synced 2024-11-07 20:39:04 +03:00
windows: Let the OS decide which font to use as the UI font (#10877)
On my computer, I get `Yahei UI`, which makes sense since I'm using a Chinese operating system, and `Yahei UI` includes Chinese codepoints. On an English operating system, `Segoe UI` should be used instead. Edit: I also choose to use the UI font selected by the system as the fallback font, rather than hard-coding the `Arial` font. Release Notes: - N/A
This commit is contained in:
parent
9e88155a48
commit
06d2d9da5f
@ -16,9 +16,11 @@ use windows::{
|
||||
Direct2D::{Common::*, *},
|
||||
DirectWrite::*,
|
||||
Dxgi::Common::*,
|
||||
Gdi::LOGFONTW,
|
||||
Imaging::{D2D::IWICImagingFactory2, *},
|
||||
},
|
||||
System::{Com::*, SystemServices::LOCALE_NAME_MAX_LENGTH},
|
||||
UI::WindowsAndMessaging::*,
|
||||
},
|
||||
};
|
||||
|
||||
@ -51,6 +53,7 @@ unsafe impl Send for DirectWriteComponent {}
|
||||
|
||||
struct DirectWriteState {
|
||||
components: DirectWriteComponent,
|
||||
system_ui_font_name: SharedString,
|
||||
system_font_collection: IDWriteFontCollection1,
|
||||
custom_font_collection: IDWriteFontCollection1,
|
||||
fonts: Vec<FontInfo>,
|
||||
@ -106,9 +109,11 @@ impl DirectWriteTextSystem {
|
||||
.factory
|
||||
.CreateFontCollectionFromFontSet(&custom_font_set)?
|
||||
};
|
||||
let system_ui_font_name = get_system_ui_font_name();
|
||||
|
||||
Ok(Self(RwLock::new(DirectWriteState {
|
||||
components,
|
||||
system_ui_font_name,
|
||||
system_font_collection,
|
||||
custom_font_collection,
|
||||
fonts: Vec::new(),
|
||||
@ -309,53 +314,55 @@ impl DirectWriteState {
|
||||
}
|
||||
|
||||
fn select_font(&mut self, target_font: &Font) -> FontId {
|
||||
let family_name = if target_font.family == ".SystemUIFont" {
|
||||
// https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-fonts
|
||||
// Segoe UI is the Windows font intended for user interface text strings.
|
||||
"Segoe UI"
|
||||
} else {
|
||||
target_font.family.as_ref()
|
||||
};
|
||||
unsafe {
|
||||
// try to find target font in custom font collection first
|
||||
self.get_font_id_from_font_collection(
|
||||
family_name,
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
false,
|
||||
)
|
||||
.or_else(|| {
|
||||
self.get_font_id_from_font_collection(
|
||||
family_name,
|
||||
if target_font.family == ".SystemUIFont" {
|
||||
let family = self.system_ui_font_name.clone();
|
||||
self.find_font_id(
|
||||
family.as_ref(),
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
true,
|
||||
)
|
||||
.unwrap()
|
||||
} else {
|
||||
self.find_font_id(
|
||||
target_font.family.as_ref(),
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
)
|
||||
.unwrap_or_else(|| {
|
||||
let family = self.system_ui_font_name.clone();
|
||||
log::error!("{} not found, use {} instead.", target_font.family, family);
|
||||
self.get_font_id_from_font_collection(
|
||||
family.as_ref(),
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
true,
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn find_font_id(
|
||||
&mut self,
|
||||
family_name: &str,
|
||||
weight: FontWeight,
|
||||
style: FontStyle,
|
||||
features: &FontFeatures,
|
||||
) -> Option<FontId> {
|
||||
// try to find target font in custom font collection first
|
||||
self.get_font_id_from_font_collection(family_name, weight, style, features, false)
|
||||
.or_else(|| {
|
||||
self.get_font_id_from_font_collection(family_name, weight, style, features, true)
|
||||
})
|
||||
.or_else(|| {
|
||||
self.update_system_font_collection();
|
||||
self.get_font_id_from_font_collection(
|
||||
family_name,
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
true,
|
||||
)
|
||||
self.get_font_id_from_font_collection(family_name, weight, style, features, true)
|
||||
})
|
||||
.or_else(|| {
|
||||
log::error!("{} not found, use Arial instead.", family_name);
|
||||
self.get_font_id_from_font_collection(
|
||||
"Arial",
|
||||
target_font.weight,
|
||||
target_font.style,
|
||||
&target_font.features,
|
||||
false,
|
||||
)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn layout_line(&mut self, text: &str, font_size: Pixels, font_runs: &[FontRun]) -> LineLayout {
|
||||
@ -1271,6 +1278,29 @@ fn translate_color(color: &DWRITE_COLOR_F) -> D2D1_COLOR_F {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_system_ui_font_name() -> SharedString {
|
||||
unsafe {
|
||||
let mut info: LOGFONTW = std::mem::zeroed();
|
||||
let font_family = if SystemParametersInfoW(
|
||||
SPI_GETICONTITLELOGFONT,
|
||||
std::mem::size_of::<LOGFONTW>() as u32,
|
||||
Some(&mut info as *mut _ as _),
|
||||
SYSTEM_PARAMETERS_INFO_UPDATE_FLAGS(0),
|
||||
)
|
||||
.log_err()
|
||||
.is_none()
|
||||
{
|
||||
// https://learn.microsoft.com/en-us/windows/win32/uxguide/vis-fonts
|
||||
// Segoe UI is the Windows font intended for user interface text strings.
|
||||
"Segoe UI".into()
|
||||
} else {
|
||||
String::from_utf16_lossy(&info.lfFaceName).into()
|
||||
};
|
||||
log::info!("Use {} as UI font.", font_family);
|
||||
font_family
|
||||
}
|
||||
}
|
||||
|
||||
const DEFAULT_LOCALE_NAME: PCWSTR = windows::core::w!("en-US");
|
||||
const BRUSH_COLOR: D2D1_COLOR_F = D2D1_COLOR_F {
|
||||
r: 1.0,
|
||||
|
Loading…
Reference in New Issue
Block a user