Feature/fallback fonts (#15306)

Supersedes https://github.com/zed-industries/zed/pull/12090

fixes #5180
fixes #5055

See original PR for an example of the feature at work.

This PR changes the settings interface to be backwards compatible, and
adds the `ui_font_fallbacks`, `buffer_font_fallbacks`, and
`terminal.font_fallbacks` settings.

Release Notes:

- Added support for font fallbacks via three new settings:
`ui_font_fallbacks`, `buffer_font_fallbacks`, and
`terminal.font_fallbacks`.(#5180, #5055).

---------

Co-authored-by: Junkui Zhang <364772080@qq.com>
This commit is contained in:
Mikayla Maki 2024-07-26 16:42:21 -07:00 committed by GitHub
parent 3e31955b7f
commit a1bd7a1297
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 444 additions and 136 deletions

View file

@ -3,10 +3,11 @@ use crate::{Appearance, SyntaxTheme, Theme, ThemeRegistry, ThemeStyleContent};
use anyhow::Result;
use derive_more::{Deref, DerefMut};
use gpui::{
px, AppContext, Font, FontFeatures, FontStyle, FontWeight, Global, Pixels, Subscription,
ViewContext, WindowContext,
px, AppContext, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels,
Subscription, ViewContext, WindowContext,
};
use refineable::Refineable;
use schemars::schema::ArrayValidation;
use schemars::{
gen::SchemaGenerator,
schema::{InstanceType, Schema, SchemaObject},
@ -244,6 +245,9 @@ pub struct ThemeSettingsContent {
/// The name of a font to use for rendering in the UI.
#[serde(default)]
pub ui_font_family: Option<String>,
/// The font fallbacks to use for rendering in the UI.
#[serde(default)]
pub ui_font_fallbacks: Option<Vec<String>>,
/// The OpenType features to enable for text in the UI.
#[serde(default)]
pub ui_font_features: Option<FontFeatures>,
@ -253,6 +257,9 @@ pub struct ThemeSettingsContent {
/// The name of a font to use for rendering in text buffers.
#[serde(default)]
pub buffer_font_family: Option<String>,
/// The font fallbacks to use for rendering in text buffers.
#[serde(default)]
pub buffer_font_fallbacks: Option<Vec<String>>,
/// The default font size for rendering in text buffers.
#[serde(default)]
pub buffer_font_size: Option<f32>,
@ -510,14 +517,22 @@ impl settings::Settings for ThemeSettings {
let mut this = Self {
ui_font_size: defaults.ui_font_size.unwrap().into(),
ui_font: Font {
family: defaults.ui_font_family.clone().unwrap().into(),
family: defaults.ui_font_family.as_ref().unwrap().clone().into(),
features: defaults.ui_font_features.clone().unwrap(),
fallbacks: defaults
.ui_font_fallbacks
.as_ref()
.map(|fallbacks| FontFallbacks::from_fonts(fallbacks.clone())),
weight: defaults.ui_font_weight.map(FontWeight).unwrap(),
style: Default::default(),
},
buffer_font: Font {
family: defaults.buffer_font_family.clone().unwrap().into(),
family: defaults.buffer_font_family.as_ref().unwrap().clone().into(),
features: defaults.buffer_font_features.clone().unwrap(),
fallbacks: defaults
.buffer_font_fallbacks
.as_ref()
.map(|fallbacks| FontFallbacks::from_fonts(fallbacks.clone())),
weight: defaults.buffer_font_weight.map(FontWeight).unwrap(),
style: FontStyle::default(),
},
@ -543,7 +558,9 @@ impl settings::Settings for ThemeSettings {
if let Some(value) = value.buffer_font_features.clone() {
this.buffer_font.features = value;
}
if let Some(value) = value.buffer_font_fallbacks.clone() {
this.buffer_font.fallbacks = Some(FontFallbacks::from_fonts(value));
}
if let Some(value) = value.buffer_font_weight {
this.buffer_font.weight = FontWeight(value);
}
@ -554,6 +571,9 @@ impl settings::Settings for ThemeSettings {
if let Some(value) = value.ui_font_features.clone() {
this.ui_font.features = value;
}
if let Some(value) = value.ui_font_fallbacks.clone() {
this.ui_font.fallbacks = Some(FontFallbacks::from_fonts(value));
}
if let Some(value) = value.ui_font_weight {
this.ui_font.weight = FontWeight(value);
}
@ -605,15 +625,28 @@ impl settings::Settings for ThemeSettings {
.iter()
.cloned()
.map(Value::String)
.collect();
let fonts_schema = SchemaObject {
.collect::<Vec<_>>();
let font_family_schema = SchemaObject {
instance_type: Some(InstanceType::String.into()),
enum_values: Some(available_fonts),
..Default::default()
};
let font_fallback_schema = SchemaObject {
instance_type: Some(InstanceType::Array.into()),
array: Some(Box::new(ArrayValidation {
items: Some(schemars::schema::SingleOrVec::Single(Box::new(
font_family_schema.clone().into(),
))),
unique_items: Some(true),
..Default::default()
})),
..Default::default()
};
root_schema.definitions.extend([
("ThemeName".into(), theme_name_schema.into()),
("FontFamilies".into(), fonts_schema.into()),
("FontFamilies".into(), font_family_schema.into()),
("FontFallbacks".into(), font_fallback_schema.into()),
]);
root_schema
@ -627,10 +660,18 @@ impl settings::Settings for ThemeSettings {
"buffer_font_family".to_owned(),
Schema::new_ref("#/definitions/FontFamilies".into()),
),
(
"buffer_font_fallbacks".to_owned(),
Schema::new_ref("#/definitions/FontFallbacks".into()),
),
(
"ui_font_family".to_owned(),
Schema::new_ref("#/definitions/FontFamilies".into()),
),
(
"ui_font_fallbacks".to_owned(),
Schema::new_ref("#/definitions/FontFallbacks".into()),
),
]);
root_schema