windows: Support all OpenType
font features (#10756)
Release Notes: - Added support for all `OpenType` font features to DirectWrite. https://github.com/zed-industries/zed/assets/14981363/cb2848cd-9178-4d87-881a-54dc646b2b61 --------- Co-authored-by: Mikayla Maki <mikayla@zed.dev>
This commit is contained in:
parent
268cb948a7
commit
11dc3c2582
17 changed files with 114 additions and 25 deletions
|
@ -1,3 +1,7 @@
|
|||
#[cfg(target_os = "windows")]
|
||||
use crate::SharedString;
|
||||
#[cfg(target_os = "windows")]
|
||||
use itertools::Itertools;
|
||||
use schemars::{
|
||||
schema::{InstanceType, Schema, SchemaObject, SingleOrVec},
|
||||
JsonSchema,
|
||||
|
@ -7,10 +11,14 @@ macro_rules! create_definitions {
|
|||
($($(#[$meta:meta])* ($name:ident, $idx:expr)),* $(,)?) => {
|
||||
|
||||
/// The OpenType features that can be configured for a given font.
|
||||
#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
#[derive(Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct FontFeatures {
|
||||
enabled: u64,
|
||||
disabled: u64,
|
||||
#[cfg(target_os = "windows")]
|
||||
other_enabled: SharedString,
|
||||
#[cfg(target_os = "windows")]
|
||||
other_disabled: SharedString,
|
||||
}
|
||||
|
||||
impl FontFeatures {
|
||||
|
@ -47,6 +55,14 @@ macro_rules! create_definitions {
|
|||
}
|
||||
}
|
||||
)*
|
||||
{
|
||||
for name in self.other_enabled.as_ref().chars().chunks(4).into_iter() {
|
||||
result.push((name.collect::<String>(), true));
|
||||
}
|
||||
for name in self.other_disabled.as_ref().chars().chunks(4).into_iter() {
|
||||
result.push((name.collect::<String>(), false));
|
||||
}
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
@ -59,6 +75,15 @@ macro_rules! create_definitions {
|
|||
debug.field(stringify!($name), &value);
|
||||
};
|
||||
)*
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
for name in self.other_enabled.as_ref().chars().chunks(4).into_iter() {
|
||||
debug.field(name.collect::<String>().as_str(), &true);
|
||||
}
|
||||
for name in self.other_disabled.as_ref().chars().chunks(4).into_iter() {
|
||||
debug.field(name.collect::<String>().as_str(), &false);
|
||||
}
|
||||
}
|
||||
debug.finish()
|
||||
}
|
||||
}
|
||||
|
@ -80,6 +105,7 @@ macro_rules! create_definitions {
|
|||
formatter.write_str("a map of font features")
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
|
@ -100,6 +126,54 @@ macro_rules! create_definitions {
|
|||
}
|
||||
Ok(FontFeatures { enabled, disabled })
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
|
||||
where
|
||||
M: MapAccess<'de>,
|
||||
{
|
||||
let mut enabled: u64 = 0;
|
||||
let mut disabled: u64 = 0;
|
||||
let mut other_enabled = "".to_owned();
|
||||
let mut other_disabled = "".to_owned();
|
||||
|
||||
while let Some((key, value)) = access.next_entry::<String, Option<bool>>()? {
|
||||
let idx = match key.as_str() {
|
||||
$(stringify!($name) => Some($idx),)*
|
||||
other_feature => {
|
||||
if other_feature.len() != 4 || !other_feature.is_ascii() {
|
||||
log::error!("Incorrect feature name: {}", other_feature);
|
||||
continue;
|
||||
}
|
||||
None
|
||||
},
|
||||
};
|
||||
if let Some(idx) = idx {
|
||||
match value {
|
||||
Some(true) => enabled |= 1 << idx,
|
||||
Some(false) => disabled |= 1 << idx,
|
||||
None => {}
|
||||
};
|
||||
} else {
|
||||
match value {
|
||||
Some(true) => other_enabled.push_str(key.as_str()),
|
||||
Some(false) => other_disabled.push_str(key.as_str()),
|
||||
None => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
let other_enabled = if other_enabled.is_empty() {
|
||||
"".into()
|
||||
} else {
|
||||
other_enabled.into()
|
||||
};
|
||||
let other_disabled = if other_disabled.is_empty() {
|
||||
"".into()
|
||||
} else {
|
||||
other_disabled.into()
|
||||
};
|
||||
Ok(FontFeatures { enabled, disabled, other_enabled, other_disabled })
|
||||
}
|
||||
}
|
||||
|
||||
let features = deserializer.deserialize_map(FontFeaturesVisitor)?;
|
||||
|
@ -125,6 +199,16 @@ macro_rules! create_definitions {
|
|||
}
|
||||
)*
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
for name in self.other_enabled.as_ref().chars().chunks(4).into_iter() {
|
||||
map.serialize_entry(name.collect::<String>().as_str(), &true)?;
|
||||
}
|
||||
for name in self.other_disabled.as_ref().chars().chunks(4).into_iter() {
|
||||
map.serialize_entry(name.collect::<String>().as_str(), &false)?;
|
||||
}
|
||||
}
|
||||
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue