Skip to repository content192 lines · 7.2 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T05:39:46.733Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
open_type.rs
1#![allow(unused, non_upper_case_globals)]
2
3use cocoa::appkit::CGFloat;
4use core_foundation::{
5 array::{
6 CFArray, CFArrayAppendArray, CFArrayAppendValue, CFArrayCreateMutable, CFArrayGetCount,
7 CFArrayGetValueAtIndex, CFArrayRef, CFMutableArrayRef, kCFTypeArrayCallBacks,
8 },
9 base::{CFRelease, TCFType, kCFAllocatorDefault},
10 dictionary::{
11 CFDictionaryCreate, kCFTypeDictionaryKeyCallBacks, kCFTypeDictionaryValueCallBacks,
12 },
13 number::CFNumber,
14 string::{CFString, CFStringRef},
15};
16use core_foundation_sys::locale::CFLocaleCopyPreferredLanguages;
17use core_graphics::{display::CFDictionary, geometry::CGAffineTransform};
18use core_text::font_descriptor::{
19 TraitAccessors, kCTFontFamilyNameAttribute, kCTFontItalicTrait, kCTFontSlantTrait,
20 kCTFontTraitsAttribute, kCTFontWeightTrait, kCTFontWidthTrait,
21};
22use core_text::{
23 font::{CTFont, CTFontRef, cascade_list_for_languages},
24 font_descriptor::{
25 CTFontDescriptor, CTFontDescriptorCopyAttributes, CTFontDescriptorCreateCopyWithFeature,
26 CTFontDescriptorCreateWithAttributes, CTFontDescriptorCreateWithNameAndSize,
27 CTFontDescriptorRef, kCTFontCascadeListAttribute, kCTFontFeatureSettingsAttribute,
28 },
29};
30use font_kit::font::Font as FontKitFont;
31use gpui::{FontFallbacks, FontFeatures};
32use std::ptr;
33
34pub fn apply_features_and_fallbacks(
35 font: &mut FontKitFont,
36 features: &FontFeatures,
37 fallbacks: Option<&FontFallbacks>,
38) -> anyhow::Result<()> {
39 unsafe {
40 let mut keys = vec![kCTFontFeatureSettingsAttribute];
41 let mut values = vec![generate_feature_array(features)];
42 if let Some(fallbacks) = fallbacks
43 && !fallbacks.fallback_list().is_empty()
44 {
45 keys.push(kCTFontCascadeListAttribute);
46 values.push(generate_fallback_array(fallbacks, font));
47 }
48 let attrs = CFDictionaryCreate(
49 kCFAllocatorDefault,
50 keys.as_ptr() as _,
51 values.as_ptr() as _,
52 keys.len() as isize,
53 &kCFTypeDictionaryKeyCallBacks,
54 &kCFTypeDictionaryValueCallBacks,
55 );
56
57 for value in &values {
58 CFRelease(*value as _);
59 }
60
61 let new_descriptor = CTFontDescriptorCreateWithAttributes(attrs);
62 CFRelease(attrs as _);
63 let new_descriptor = CTFontDescriptor::wrap_under_create_rule(new_descriptor);
64 let new_font = CTFontCreateCopyWithAttributes(
65 font.native_font().as_concrete_TypeRef(),
66 0.0,
67 std::ptr::null(),
68 new_descriptor.as_concrete_TypeRef(),
69 );
70 let new_font = CTFont::wrap_under_create_rule(new_font);
71 *font = font_kit::font::Font::from_native_font(&new_font);
72
73 Ok(())
74 }
75}
76
77fn generate_feature_array(features: &FontFeatures) -> CFMutableArrayRef {
78 unsafe {
79 let feature_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
80 for (tag, value) in features.tag_value_list() {
81 let keys = [kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue];
82 let values = [
83 CFString::new(tag).as_CFTypeRef(),
84 CFNumber::from(*value as i32).as_CFTypeRef(),
85 ];
86 let dict = CFDictionaryCreate(
87 kCFAllocatorDefault,
88 &keys as *const _ as _,
89 &values as *const _ as _,
90 2,
91 &kCFTypeDictionaryKeyCallBacks,
92 &kCFTypeDictionaryValueCallBacks,
93 );
94 values.into_iter().for_each(|value| CFRelease(value));
95 CFArrayAppendValue(feature_array, dict as _);
96 CFRelease(dict as _);
97 }
98 feature_array
99 }
100}
101
102fn generate_fallback_array(fallbacks: &FontFallbacks, font: &mut FontKitFont) -> CFMutableArrayRef {
103 unsafe {
104 let symbolic_traits = font.native_font().symbolic_traits();
105 let all_traits = font.native_font().all_traits();
106
107 let fallback_array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
108 for user_fallback in fallbacks.fallback_list() {
109 let name = CFString::from(user_fallback.as_str());
110
111 let traits_keys = [kCTFontWeightTrait, kCTFontSlantTrait];
112 let weight_value = CFNumber::from(all_traits.normalized_weight());
113 let slant_value = CFNumber::from(if (symbolic_traits & kCTFontItalicTrait) != 0 {
114 1.0
115 } else {
116 0.0
117 });
118 let traits_values = [weight_value.as_CFTypeRef(), slant_value.as_CFTypeRef()];
119 let traits = CFDictionaryCreate(
120 kCFAllocatorDefault,
121 &traits_keys as *const _ as _,
122 &traits_values as *const _ as _,
123 traits_keys.len() as isize,
124 &kCFTypeDictionaryKeyCallBacks,
125 &kCFTypeDictionaryValueCallBacks,
126 );
127 drop(weight_value);
128 drop(slant_value);
129
130 let attr_keys = [kCTFontFamilyNameAttribute, kCTFontTraitsAttribute];
131 let attr_values = [name.as_CFTypeRef(), traits as _];
132 let attrs = CFDictionaryCreate(
133 kCFAllocatorDefault,
134 &attr_keys as *const _ as _,
135 &attr_values as *const _ as _,
136 attr_keys.len() as isize,
137 &kCFTypeDictionaryKeyCallBacks,
138 &kCFTypeDictionaryValueCallBacks,
139 );
140 CFRelease(traits as _);
141
142 let fallback_desc = CTFontDescriptorCreateWithAttributes(attrs);
143 CFRelease(attrs as _);
144
145 CFArrayAppendValue(fallback_array, fallback_desc as _);
146 CFRelease(fallback_desc as _);
147 }
148
149 let font_ref = font.native_font().as_concrete_TypeRef();
150 append_system_fallbacks(fallback_array, font_ref);
151 fallback_array
152 }
153}
154
155fn append_system_fallbacks(fallback_array: CFMutableArrayRef, font_ref: CTFontRef) {
156 unsafe {
157 let preferred_languages: CFArray<CFString> =
158 CFArray::wrap_under_create_rule(CFLocaleCopyPreferredLanguages());
159
160 let default_fallbacks = CTFontCopyDefaultCascadeListForLanguages(
161 font_ref,
162 preferred_languages.as_concrete_TypeRef(),
163 );
164 let default_fallbacks: CFArray<CTFontDescriptor> =
165 CFArray::wrap_under_create_rule(default_fallbacks);
166
167 for desc in default_fallbacks
168 .iter()
169 .filter(|desc| desc.font_path().is_some())
170 {
171 CFArrayAppendValue(fallback_array, desc.as_concrete_TypeRef() as _);
172 }
173 }
174}
175
176#[link(name = "CoreText", kind = "framework")]
177unsafe extern "C" {
178 static kCTFontOpenTypeFeatureTag: CFStringRef;
179 static kCTFontOpenTypeFeatureValue: CFStringRef;
180
181 fn CTFontCreateCopyWithAttributes(
182 font: CTFontRef,
183 size: CGFloat,
184 matrix: *const CGAffineTransform,
185 attributes: CTFontDescriptorRef,
186 ) -> CTFontRef;
187 fn CTFontCopyDefaultCascadeListForLanguages(
188 font: CTFontRef,
189 languagePrefList: CFArrayRef,
190 ) -> CFArrayRef;
191}
192