diff --git a/Cargo.lock b/Cargo.lock index 0ff00b1c..42b0d862 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,15 +461,6 @@ dependencies = [ "objc2 0.5.2", ] -[[package]] -name = "block2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037" -dependencies = [ - "objc2 0.6.0", -] - [[package]] name = "blocking" version = "1.6.1" @@ -660,16 +651,6 @@ dependencies = [ "libc", ] -[[package]] -name = "core-foundation" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -683,21 +664,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" -dependencies = [ - "bitflags 2.8.0", - "core-foundation 0.10.0", - "core-graphics-types 0.2.0", + "core-foundation", + "core-graphics-types", "foreign-types", "libc", ] @@ -709,30 +677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" dependencies = [ "bitflags 1.3.2", - "core-foundation 0.9.4", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.8.0", - "core-foundation 0.10.0", - "libc", -] - -[[package]] -name = "core-text" -version = "21.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a593227b66cbd4007b2a050dfdd9e1d1318311409c8d600dc82ba1b15ca9c130" -dependencies = [ - "core-foundation 0.10.0", - "core-graphics 0.24.0", - "foreign-types", + "core-foundation", "libc", ] @@ -976,14 +921,14 @@ name = "fontique" version = "0.2.0" dependencies = [ "bytemuck", - "core-foundation 0.10.0", - "core-text", "core_maths", "fontconfig-cache-parser", "hashbrown", "icu_locid", "icu_properties", "memmap2", + "objc2-core-foundation", + "objc2-core-text", "objc2-foundation 0.3.0", "peniko", "read-fonts", @@ -1573,7 +1518,7 @@ checksum = "7ecfd3296f8c56b7c1f6fbac3c71cefa9d78ce009850c45000015f206dc7fa21" dependencies = [ "bitflags 2.8.0", "block", - "core-graphics-types 0.1.3", + "core-graphics-types", "foreign-types", "log", "objc", @@ -1734,7 +1679,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "libc", "objc2 0.5.2", "objc2-core-data", @@ -1750,7 +1695,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -1762,7 +1707,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ff520e9c33812fd374d8deecef01d4a840e7b41862d849513de77e44aa4889" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1774,7 +1719,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1786,7 +1731,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" dependencies = [ "bitflags 2.8.0", - "objc2 0.6.0", ] [[package]] @@ -1795,7 +1739,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", @@ -1807,12 +1751,22 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "000cfee34e683244f284252ee206a27953279d370e309649dc3ee317b37e5781" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-contacts", "objc2-foundation 0.2.2", ] +[[package]] +name = "objc2-core-text" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fde15abfe00bf9f1eda220addbdfa6c62b0e5595e98208e8cdbc2ec0f6970a6" +dependencies = [ + "bitflags 2.8.0", + "objc2-core-foundation", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -1826,7 +1780,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "dispatch", "libc", "objc2 0.5.2", @@ -1839,10 +1793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" dependencies = [ "bitflags 2.8.0", - "block2 0.6.0", - "libc", "objc2 0.6.0", - "objc2-core-foundation", ] [[package]] @@ -1851,7 +1802,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1a1ae721c5e35be65f01a03b6d2ac13a54cb4fa70d8a5da293d7b0020261398" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-app-kit", "objc2-foundation 0.2.2", @@ -1864,7 +1815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1876,7 +1827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-metal", @@ -1899,7 +1850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-cloud-kit", "objc2-core-data", @@ -1919,7 +1870,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44fa5f9748dbfe1ca6c0b79ad20725a11eca7c2218bceb4b005cb1be26273bfe" dependencies = [ - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-foundation 0.2.2", ] @@ -1931,7 +1882,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ "bitflags 2.8.0", - "block2 0.5.1", + "block2", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", @@ -3118,7 +3069,7 @@ dependencies = [ "block", "bytemuck", "cfg_aliases 0.1.1", - "core-graphics-types 0.1.3", + "core-graphics-types", "glow", "glutin_wgl_sys", "gpu-alloc", @@ -3479,13 +3430,13 @@ dependencies = [ "android-activity", "atomic-waker", "bitflags 2.8.0", - "block2 0.5.1", + "block2", "bytemuck", "calloop", "cfg_aliases 0.2.1", "concurrent-queue", - "core-foundation 0.9.4", - "core-graphics 0.23.2", + "core-foundation", + "core-graphics", "cursor-icon", "dpi", "js-sys", diff --git a/fontique/Cargo.toml b/fontique/Cargo.toml index 2d826751..d6f79e2b 100644 --- a/fontique/Cargo.toml +++ b/fontique/Cargo.toml @@ -25,7 +25,7 @@ unicode_script = ["dep:unicode-script"] system = [ "std", "dep:windows", "dep:windows-core", - "dep:core-text", "dep:core-foundation", "dep:objc2-foundation", + "dep:objc2-core-foundation", "dep:objc2-core-text", "dep:objc2-foundation", "dep:fontconfig-cache-parser", "dep:roxmltree", ] @@ -46,9 +46,9 @@ windows = { version = "0.58.0", features = ["implement", "Win32_Graphics_DirectW windows-core = { version = "0.58", optional = true } [target.'cfg(target_vendor = "apple")'.dependencies] -core-text = { version = "21.0.0", optional = true } -core-foundation = { version = "0.10.0", optional = true } -objc2-foundation = { version = "0.3.0", features = ["NSArray", "NSEnumerator", "NSPathUtilities", "NSString"], optional = true } +objc2-foundation = { version = "0.3.0", optional = true, default-features = false, features = ["alloc", "NSArray", "NSEnumerator", "NSPathUtilities", "NSString"] } +objc2-core-foundation = { version = "0.3.0", optional = true, default-features = false, features = ["CFBase"] } +objc2-core-text = { version = "0.3.0", optional = true, default-features = false, features = ["CTFont", "CTFontDescriptor"] } [target.'cfg(target_os = "linux")'.dependencies] fontconfig-cache-parser = { version = "0.2.0", optional = true } diff --git a/fontique/src/backend/coretext.rs b/fontique/src/backend/coretext.rs index d4d1058f..072bac20 100644 --- a/fontique/src/backend/coretext.rs +++ b/fontique/src/backend/coretext.rs @@ -5,21 +5,17 @@ use super::{ scan, FallbackKey, FamilyId, FamilyInfo, FamilyNameMap, GenericFamily, GenericFamilyMap, }; use alloc::sync::Arc; +use core::ptr::{null, null_mut}; use hashbrown::HashMap; +use objc2_core_foundation::{CFDictionaryCreate, CFRange, CFRetained, CFString, CFStringGetLength}; +use objc2_core_text::{ + CTFont, CTFontCopyFamilyName, CTFontCreateForString, CTFontCreateForStringWithLanguage, + CTFontCreateUIFontForLanguage, CTFontCreateWithFontDescriptor, + CTFontDescriptorCreateWithAttributes, CTFontUIFontType, +}; use objc2_foundation::{ NSSearchPathDirectory, NSSearchPathDomainMask, NSSearchPathForDirectoriesInDomains, }; -use { - core_foundation::{ - base::{CFRange, TCFType}, - dictionary::CFDictionary, - string::{CFString, CFStringRef}, - }, - core_text::{ - font::{self, kCTFontSystemFontType, CTFont, CTFontRef, CTFontUIFontType}, - font_descriptor, - }, -}; const DEFAULT_GENERIC_FAMILIES: &[(GenericFamily, &[&str])] = &[ (GenericFamily::Serif, &["Times", "Times New Roman"]), @@ -75,97 +71,45 @@ impl SystemFonts { pub(crate) fn fallback(&mut self, key: impl Into) -> Option { let key = key.into(); let sample = key.script().sample()?; - self.fallback_for_text(sample, key.locale(), false) + let font = create_fallback_font_for_text(sample, key.locale(), false)?; + let family_name = unsafe { CTFontCopyFamilyName(&font) }; + self.name_map.get(&family_name.to_string()).map(|n| n.id()) } } -impl SystemFonts { - fn fallback_for_text( - &mut self, - text: &str, - locale: Option<&str>, - prefer_ui: bool, - ) -> Option { - let font = fallback_for_text(text, locale, prefer_ui)?; - self.name_map.get(&font.family_name()).map(|n| n.id()) +fn create_base_font(prefer_ui_font: bool) -> CFRetained { + if prefer_ui_font { + if let Some(font) = + unsafe { CTFontCreateUIFontForLanguage(CTFontUIFontType::System, 0.0, None) } + { + return font; + } + } + unsafe { + let attrs = CFDictionaryCreate(None, null_mut(), null_mut(), 0, null(), null()); + let desc = CTFontDescriptorCreateWithAttributes(&attrs.unwrap()); + CTFontCreateWithFontDescriptor(&desc, 0.0, null()) } } -fn fallback_for_text(text: &str, locale: Option<&str>, prefer_ui: bool) -> Option { - let cf_text = CFString::new(text); - let cf_text_range = CFRange::init(0, cf_text.char_len()); - let cf_locale = locale.map(CFString::new); - let base_font = { - let desc_attrs = CFDictionary::from_CFType_pairs(&[]); - let mut desc = font_descriptor::new_from_attributes(&desc_attrs); - if prefer_ui { - if let Some(ui_desc) = ui_font_for_language(kCTFontSystemFontType, 0.0, None) - .map(|font| font.copy_descriptor()) - { - desc = ui_desc; - } - } - font::new_from_descriptor(&desc, 0.0) +fn create_fallback_font_for_text( + text: &str, + locale: Option<&str>, + prefer_ui_font: bool, +) -> Option> { + let text = CFString::from_str(text); + let text_range = CFRange { + location: 0, + length: unsafe { CFStringGetLength(&text) }, }; + let locale = locale.map(CFString::from_str); + let base_font = create_base_font(prefer_ui_font); let font = unsafe { - CTFont::wrap_under_create_rule(if let Some(locale) = cf_locale { - CTFontCreateForStringWithLanguage( - base_font.as_concrete_TypeRef(), - cf_text.as_concrete_TypeRef(), - cf_text_range, - locale.as_concrete_TypeRef(), - ) + if let Some(locale) = locale { + CTFontCreateForStringWithLanguage(&base_font, &text, text_range, Some(&locale)) } else { - CTFontCreateForString( - base_font.as_concrete_TypeRef(), - cf_text.as_concrete_TypeRef(), - cf_text_range, - ) - }) + CTFontCreateForString(&base_font, &text, text_range) + } }; Some(font) } - -fn ui_font_for_language( - ui_type: CTFontUIFontType, - size: f64, - language: Option, -) -> Option { - unsafe { - let font_ref = CTFontCreateUIFontForLanguage( - ui_type, - size, - language - .as_ref() - .map(|x| x.as_concrete_TypeRef()) - .unwrap_or(std::ptr::null()), - ); - if font_ref.is_null() { - None - } else { - Some(CTFont::wrap_under_create_rule(font_ref)) - } - } -} - -#[link(name = "CoreText", kind = "framework")] -extern "C" { - fn CTFontCreateUIFontForLanguage( - uiType: CTFontUIFontType, - size: f64, - language: CFStringRef, - ) -> CTFontRef; - - fn CTFontCreateForString( - currentFont: CTFontRef, - string: CFStringRef, - range: CFRange, - ) -> CTFontRef; - - fn CTFontCreateForStringWithLanguage( - currentFont: CTFontRef, - string: CFStringRef, - range: CFRange, - language: CFStringRef, - ) -> CTFontRef; -}