mirror of
https://github.com/wez/wezterm.git
synced 2024-12-23 21:32:13 +03:00
wezterm-font: remove font-loader dependency
This commit replaces it with the underlying core text calls on macos. refs: #337
This commit is contained in:
parent
9ca428c4e1
commit
30cc10d4cf
131
Cargo.lock
generated
131
Cargo.lock
generated
@ -656,15 +656,6 @@ dependencies = [
|
||||
"bitflags 1.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e56268c17a6248366d66d4a47a3381369d068cce8409bb1716ed77ea32163bb"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.20.2"
|
||||
@ -780,16 +771,6 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.6.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.7.0"
|
||||
@ -801,10 +782,14 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.6.2"
|
||||
name = "core-foundation"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b"
|
||||
checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62"
|
||||
dependencies = [
|
||||
"core-foundation-sys 0.8.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
@ -813,16 +798,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
version = "0.14.0"
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e54c4ab33705fa1fc8af375bb7929d68e1c1546c1ecef408966d8c3e49a1d84a"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1",
|
||||
"core-foundation 0.6.4",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b"
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics"
|
||||
@ -837,25 +816,38 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-text"
|
||||
version = "10.0.0"
|
||||
name = "core-graphics"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81f59bff773954e5cd058a3f5983406b52bec7cc65202bef340ba64a0c40ac91"
|
||||
checksum = "fc239bba52bab96649441699533a68de294a101533b0270b2d65aa402b29a7f9"
|
||||
dependencies = [
|
||||
"core-foundation 0.6.4",
|
||||
"core-graphics 0.14.0",
|
||||
"bitflags 1.2.1",
|
||||
"core-foundation 0.9.1",
|
||||
"core-graphics-types",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-graphics-types"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1",
|
||||
"core-foundation 0.9.1",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-text"
|
||||
version = "15.0.0"
|
||||
version = "19.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "131b3fd1f8bd5db9f2b398fa4fdb6008c64afc04d447c306ac2c7e98fba2a61d"
|
||||
checksum = "d2c7f46e8b820fd5f4b28528104b28b0a91cbe9e9c5bde8017087fb44bc93a60"
|
||||
dependencies = [
|
||||
"core-foundation 0.7.0",
|
||||
"core-graphics 0.19.2",
|
||||
"core-foundation 0.9.1",
|
||||
"core-graphics 0.22.1",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
]
|
||||
@ -1150,16 +1142,6 @@ dependencies = [
|
||||
"smallvec 0.6.13",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "expat-sys"
|
||||
version = "2.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
@ -1239,19 +1221,6 @@ version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "font-loader"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ece0e8a5dd99a65f8de977b4a3f89e3b5a5259e15ae610952cdb894e96f5e2e"
|
||||
dependencies = [
|
||||
"core-foundation 0.6.4",
|
||||
"core-text 10.0.0",
|
||||
"libc",
|
||||
"servo-fontconfig",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fontconfig"
|
||||
version = "0.1.0"
|
||||
@ -3332,37 +3301,6 @@ dependencies = [
|
||||
"serial-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo-fontconfig"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a088f8d775a5c5314aae09bd77340bc9c67d72b9a45258be34c83548b4814cd9"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"servo-fontconfig-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo-fontconfig-sys"
|
||||
version = "4.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0aa080856db55f188aaf36f01cae8c03448a6056552adb77d461179e44e1a14"
|
||||
dependencies = [
|
||||
"expat-sys",
|
||||
"pkg-config",
|
||||
"servo-freetype-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "servo-freetype-sys"
|
||||
version = "4.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9232032c2e85118c0282c6562c84cab12316e655491ba0a5d1905b2320060d1b"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
@ -4348,11 +4286,10 @@ dependencies = [
|
||||
"allsorts",
|
||||
"anyhow",
|
||||
"config",
|
||||
"core-foundation 0.7.0",
|
||||
"core-text 15.0.0",
|
||||
"core-foundation 0.9.1",
|
||||
"core-text",
|
||||
"dwrote",
|
||||
"euclid 0.20.14",
|
||||
"font-loader",
|
||||
"fontconfig",
|
||||
"freetype",
|
||||
"harfbuzz",
|
||||
|
@ -227,9 +227,8 @@ pub enum FontLocatorSelection {
|
||||
FontConfig,
|
||||
/// Use the EnumFontFamilies call on win32 systems
|
||||
EnumFontFamilies,
|
||||
/// Use the fontloader crate to use a system specific method of
|
||||
/// resolving fonts
|
||||
FontLoader,
|
||||
/// Use CoreText on macOS
|
||||
CoreText,
|
||||
/// Use only the font_dirs configuration to locate fonts
|
||||
ConfigDirsOnly,
|
||||
}
|
||||
@ -243,7 +242,7 @@ impl Default for FontLocatorSelection {
|
||||
if cfg!(windows) {
|
||||
FontLocatorSelection::EnumFontFamilies
|
||||
} else if cfg!(target_os = "macos") {
|
||||
FontLocatorSelection::FontLoader
|
||||
FontLocatorSelection::CoreText
|
||||
} else {
|
||||
FontLocatorSelection::FontConfig
|
||||
}
|
||||
@ -264,7 +263,7 @@ impl FontLocatorSelection {
|
||||
pub fn variants() -> Vec<&'static str> {
|
||||
vec![
|
||||
"FontConfig",
|
||||
"FontLoader",
|
||||
"CoreText",
|
||||
"ConfigDirsOnly",
|
||||
"EnumFontFamilies",
|
||||
]
|
||||
@ -276,7 +275,7 @@ impl std::str::FromStr for FontLocatorSelection {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_ref() {
|
||||
"fontconfig" => Ok(Self::FontConfig),
|
||||
"fontloader" => Ok(Self::FontLoader),
|
||||
"coretext" => Ok(Self::CoreText),
|
||||
"configdirsonly" => Ok(Self::ConfigDirsOnly),
|
||||
"enumfontfamilies" => Ok(Self::EnumFontFamilies),
|
||||
_ => Err(anyhow!(
|
||||
|
@ -34,8 +34,5 @@ dwrote = "0.9"
|
||||
winapi = "0.3"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
core-foundation = "0.7"
|
||||
core-text = "15.0"
|
||||
# on linux, font-loader pulls in servo-font* crates which conflict with
|
||||
# our newer font related deps, so we avoid it on linux
|
||||
font-loader = { version = "0.8" }
|
||||
core-foundation = "0.9"
|
||||
core-text = "19.0"
|
||||
|
93
wezterm-font/src/locator/core_text.rs
Normal file
93
wezterm-font/src/locator/core_text.rs
Normal file
@ -0,0 +1,93 @@
|
||||
#![cfg(target_os="macos")]
|
||||
|
||||
use crate::locator::{FontDataHandle, FontLocator};
|
||||
use config::FontAttributes;
|
||||
use core_foundation::base::{CFType, TCFType};
|
||||
use core_foundation::dictionary::CFDictionary;
|
||||
use core_foundation::number::CFNumber;
|
||||
use core_foundation::string::CFString;
|
||||
use core_foundation::url::CFURL;
|
||||
use core_text::font_descriptor::*;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// A FontLocator implemented using the system font loading
|
||||
/// functions provided by the font-loader crate.
|
||||
pub struct CoreTextFontLocator {}
|
||||
|
||||
fn descriptor_from_attr(attr: &FontAttributes) -> anyhow::Result<CTFontDescriptor> {
|
||||
let family_name = attr
|
||||
.family
|
||||
.parse::<CFString>()
|
||||
.map_err(|_| anyhow::anyhow!("failed to parse family name {} as CFString", attr.family))?;
|
||||
|
||||
let symbolic_traits: CTFontSymbolicTraits = kCTFontMonoSpaceTrait
|
||||
| if attr.bold { kCTFontBoldTrait } else { 0 }
|
||||
| if attr.italic { kCTFontItalicTrait } else { 0 };
|
||||
|
||||
let family_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontFamilyNameAttribute) };
|
||||
let traits_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontTraitsAttribute) };
|
||||
let symbolic_traits_attr: CFString =
|
||||
unsafe { TCFType::wrap_under_get_rule(kCTFontSymbolicTrait) };
|
||||
|
||||
let traits = CFDictionary::from_CFType_pairs(&[(
|
||||
symbolic_traits_attr.as_CFType(),
|
||||
CFNumber::from(symbolic_traits as i32).as_CFType(),
|
||||
)]);
|
||||
|
||||
let attributes = CFDictionary::from_CFType_pairs(&[
|
||||
(traits_attr, traits.as_CFType()),
|
||||
(family_attr, family_name.as_CFType()),
|
||||
]);
|
||||
Ok(core_text::font_descriptor::new_from_attributes(&attributes))
|
||||
}
|
||||
|
||||
fn font_path_from_descriptor(descriptor: &CTFontDescriptor) -> anyhow::Result<PathBuf> {
|
||||
let url: CFURL;
|
||||
unsafe {
|
||||
let value =
|
||||
CTFontDescriptorCopyAttribute(descriptor.as_concrete_TypeRef(), kCTFontURLAttribute);
|
||||
|
||||
if value.is_null() {
|
||||
return Err(anyhow::anyhow!("font descriptor has no URL"));
|
||||
}
|
||||
|
||||
let value: CFType = TCFType::wrap_under_get_rule(value);
|
||||
if !value.instance_of::<CFURL>() {
|
||||
return Err(anyhow::anyhow!("font descriptor URL is not a CFURL"));
|
||||
}
|
||||
url = TCFType::wrap_under_get_rule(std::mem::transmute(value.as_CFTypeRef()));
|
||||
}
|
||||
if let Some(path) = url.to_path() {
|
||||
Ok(path)
|
||||
} else {
|
||||
Err(anyhow::anyhow!("font descriptor URL is not a path"))
|
||||
}
|
||||
}
|
||||
|
||||
impl FontLocator for CoreTextFontLocator {
|
||||
fn load_fonts(
|
||||
&self,
|
||||
fonts_selection: &[FontAttributes],
|
||||
loaded: &mut HashSet<FontAttributes>,
|
||||
) -> anyhow::Result<Vec<FontDataHandle>> {
|
||||
let mut fonts = vec![];
|
||||
|
||||
for attr in fonts_selection {
|
||||
if let Ok(descriptor) = descriptor_from_attr(attr) {
|
||||
if let Ok(path) = font_path_from_descriptor(&descriptor) {
|
||||
let handle = FontDataHandle::OnDisk { path, index: 0 };
|
||||
|
||||
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
||||
if crate::parser::font_info_matches(attr, parsed.names()) {
|
||||
fonts.push(handle);
|
||||
loaded.insert(attr.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(fonts)
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@ impl FontLocator for FontConfigFontLocator {
|
||||
loaded: &mut HashSet<FontAttributes>,
|
||||
) -> anyhow::Result<Vec<FontDataHandle>> {
|
||||
let mut fonts = vec![];
|
||||
let mut fallback = vec![];
|
||||
|
||||
for attr in fonts_selection {
|
||||
let mut pattern = FontPattern::new()?;
|
||||
@ -55,8 +54,6 @@ impl FontLocator for FontConfigFontLocator {
|
||||
}
|
||||
}
|
||||
|
||||
fonts.append(&mut fallback);
|
||||
|
||||
Ok(fonts)
|
||||
}
|
||||
}
|
||||
|
@ -1,62 +0,0 @@
|
||||
use crate::locator::{FontDataHandle, FontLocator};
|
||||
use ::font_loader::system_fonts;
|
||||
use config::FontAttributes;
|
||||
use std::collections::HashSet;
|
||||
|
||||
/// A FontLocator implemented using the system font loading
|
||||
/// functions provided by the font-loader crate.
|
||||
pub struct FontLoaderFontLocator {}
|
||||
|
||||
impl FontLocator for FontLoaderFontLocator {
|
||||
fn load_fonts(
|
||||
&self,
|
||||
fonts_selection: &[FontAttributes],
|
||||
loaded: &mut HashSet<FontAttributes>,
|
||||
) -> anyhow::Result<Vec<FontDataHandle>> {
|
||||
let mut fonts = Vec::new();
|
||||
for font_attr in fonts_selection {
|
||||
if cfg!(windows) && font_attr.family.len() > 31 {
|
||||
// Avoid a super painful panic in the upstream library:
|
||||
// https://github.com/MSleepyPanda/rust-font-loader/blob/2b264974fe080955d341ce8a163035bdce24ff2f/src/win32.rs#L87
|
||||
log::error!(
|
||||
"font-loader would panic for font family `{}`",
|
||||
font_attr.family
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let mut font_props = system_fonts::FontPropertyBuilder::new()
|
||||
.family(&font_attr.family)
|
||||
.monospace();
|
||||
font_props = if font_attr.bold {
|
||||
font_props.bold()
|
||||
} else {
|
||||
font_props
|
||||
};
|
||||
font_props = if font_attr.italic {
|
||||
font_props.italic()
|
||||
} else {
|
||||
font_props
|
||||
};
|
||||
let font_props = font_props.build();
|
||||
|
||||
if let Some((data, index)) = system_fonts::get(&font_props) {
|
||||
let handle = FontDataHandle::Memory {
|
||||
data,
|
||||
index: index as u32,
|
||||
name: font_attr.family.clone(),
|
||||
};
|
||||
|
||||
// The system may just decide to give us its fallback,
|
||||
// eg: Consolas, so we need to parse the returned font
|
||||
// here to see if we got what we asked for.
|
||||
if let Ok(parsed) = crate::parser::ParsedFont::from_locator(&handle) {
|
||||
if crate::parser::font_info_matches(font_attr, parsed.names()) {
|
||||
fonts.push(handle);
|
||||
loaded.insert(font_attr.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(fonts)
|
||||
}
|
||||
}
|
@ -2,11 +2,10 @@ use config::FontAttributes;
|
||||
use std::collections::HashSet;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub mod core_text;
|
||||
pub mod enum_font_families;
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
pub mod font_config;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod font_loader;
|
||||
|
||||
/// Represents the data behind a font.
|
||||
/// This may be a font file that we can read off disk,
|
||||
@ -64,11 +63,11 @@ pub fn new_locator(locator: FontLocatorSelection) -> Box<dyn FontLocator> {
|
||||
#[cfg(not(all(unix, not(target_os = "macos"))))]
|
||||
panic!("fontconfig not compiled in");
|
||||
}
|
||||
FontLocatorSelection::FontLoader => {
|
||||
FontLocatorSelection::CoreText => {
|
||||
#[cfg(target_os = "macos")]
|
||||
return Box::new(font_loader::FontLoaderFontLocator {});
|
||||
return Box::new(core_text::CoreTextFontLocator {});
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
panic!("fontloader not compiled in");
|
||||
panic!("CoreText not compiled in");
|
||||
}
|
||||
FontLocatorSelection::EnumFontFamilies => {
|
||||
#[cfg(windows)]
|
||||
|
@ -551,7 +551,7 @@ pub fn font_info_matches(attr: &FontAttributes, names: &Names) -> bool {
|
||||
Some("Italic") if attr.italic && !attr.bold => true,
|
||||
Some("Bold") if attr.bold && !attr.italic => true,
|
||||
Some("Bold Italic") if attr.bold && attr.italic => true,
|
||||
Some("Regular") | None if !attr.italic && !attr.bold => true,
|
||||
Some("Medium") | Some("Regular") | None if !attr.italic && !attr.bold => true,
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user