1 // Copyright 2013 The Servo Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 #![allow(non_upper_case_globals)]
11
12 use core_foundation::array::CFArrayRef;
13 use core_foundation::base::{CFType, CFTypeID, CFTypeRef, TCFType};
14 use core_foundation::dictionary::{CFDictionary, CFDictionaryRef};
15 use core_foundation::number::{CFNumber, CFNumberRef};
16 use core_foundation::set::CFSetRef;
17 use core_foundation::string::{CFString, CFStringRef};
18 use core_foundation::url::{CFURL, CFURLRef};
19 use core_graphics::base::CGFloat;
20
21 use std::os::raw::c_void;
22 use std::path::PathBuf;
23
24 /*
25 * CTFontTraits.h
26 */
27 // actually, these are extern enums
28 pub type CTFontFormat = u32;
29 pub const kCTFontFormatUnrecognized: CTFontFormat = 0;
30 pub const kCTFontFormatOpenTypePostScript: CTFontFormat = 1;
31 pub const kCTFontFormatOpenTypeTrueType: CTFontFormat = 2;
32 pub const kCTFontFormatTrueType: CTFontFormat = 3;
33 pub const kCTFontFormatPostScript: CTFontFormat = 4;
34 pub const kCTFontFormatBitmap: CTFontFormat = 5;
35
36 pub const kCTFontClassMaskShift: u32 = 28;
37
38 pub type CTFontSymbolicTraits = u32;
39 pub const kCTFontItalicTrait: CTFontSymbolicTraits = (1 << 0);
40 pub const kCTFontBoldTrait: CTFontSymbolicTraits = (1 << 1);
41 pub const kCTFontExpandedTrait: CTFontSymbolicTraits = (1 << 5);
42 pub const kCTFontCondensedTrait: CTFontSymbolicTraits = (1 << 6);
43 pub const kCTFontMonoSpaceTrait: CTFontSymbolicTraits = (1 << 10);
44 pub const kCTFontVerticalTrait: CTFontSymbolicTraits = (1 << 11);
45 pub const kCTFontUIOptimizedTrait: CTFontSymbolicTraits = (1 << 12);
46 pub const kCTFontColorGlyphsTrait: CTFontSymbolicTraits = (1 << 13);
47 pub const kCTFontClassMaskTrait: CTFontSymbolicTraits = (15 << kCTFontClassMaskShift );
48
49 pub trait SymbolicTraitAccessors {
is_italic(&self) -> bool50 fn is_italic(&self) -> bool;
is_bold(&self) -> bool51 fn is_bold(&self) -> bool;
is_expanded(&self) -> bool52 fn is_expanded(&self) -> bool;
is_condensed(&self) -> bool53 fn is_condensed(&self) -> bool;
is_monospace(&self) -> bool54 fn is_monospace(&self) -> bool;
is_vertical(&self) -> bool55 fn is_vertical(&self) -> bool;
56 }
57
58 impl SymbolicTraitAccessors for CTFontSymbolicTraits {
is_italic(&self) -> bool59 fn is_italic(&self) -> bool { (*self & kCTFontItalicTrait) != 0 }
is_bold(&self) -> bool60 fn is_bold(&self) -> bool { (*self & kCTFontBoldTrait) != 0 }
is_expanded(&self) -> bool61 fn is_expanded(&self) -> bool { (*self & kCTFontExpandedTrait) != 0 }
is_condensed(&self) -> bool62 fn is_condensed(&self) -> bool { (*self & kCTFontCondensedTrait) != 0 }
is_monospace(&self) -> bool63 fn is_monospace(&self) -> bool { (*self & kCTFontMonoSpaceTrait) != 0 }
is_vertical(&self) -> bool64 fn is_vertical(&self) -> bool { (*self & kCTFontVerticalTrait) != 0 }
65 }
66
67 pub type CTFontStylisticClass = u32;
68 pub const kCTFontUnknownClass: CTFontStylisticClass = (0 << kCTFontClassMaskShift );
69 pub const kCTFontOldStyleSerifsClass: CTFontStylisticClass = (1 << kCTFontClassMaskShift );
70 pub const kCTFontTransitionalSerifsClass: CTFontStylisticClass = (2 << kCTFontClassMaskShift );
71 pub const kCTFontModernSerifsClass: CTFontStylisticClass = (3 << kCTFontClassMaskShift );
72 pub const kCTFontClarendonSerifsClass: CTFontStylisticClass = (4 << kCTFontClassMaskShift );
73 pub const kCTFontSlabSerifsClass: CTFontStylisticClass = (5 << kCTFontClassMaskShift );
74 pub const kCTFontFreeformSerifsClass: CTFontStylisticClass = (7 << kCTFontClassMaskShift );
75 pub const kCTFontSansSerifClass: CTFontStylisticClass = (8 << kCTFontClassMaskShift );
76 pub const kCTFontOrnamentalsClass: CTFontStylisticClass = (9 << kCTFontClassMaskShift );
77 pub const kCTFontScriptsClass: CTFontStylisticClass = (10 << kCTFontClassMaskShift );
78 pub const kCTFontSymbolicClass: CTFontStylisticClass = (12 << kCTFontClassMaskShift );
79
80 pub trait StylisticClassAccessors {
is_serif(&self) -> bool81 fn is_serif(&self) -> bool;
is_sans_serif(&self) -> bool82 fn is_sans_serif(&self) -> bool;
is_script(&self) -> bool83 fn is_script(&self) -> bool;
is_fantasy(&self) -> bool84 fn is_fantasy(&self) -> bool;
is_symbols(&self) -> bool85 fn is_symbols(&self) -> bool;
86 }
87
88 impl StylisticClassAccessors for CTFontStylisticClass {
is_serif(&self) -> bool89 fn is_serif(&self) -> bool {
90 let any_serif_class = kCTFontOldStyleSerifsClass
91 | kCTFontTransitionalSerifsClass
92 | kCTFontModernSerifsClass
93 | kCTFontClarendonSerifsClass
94 | kCTFontSlabSerifsClass
95 | kCTFontFreeformSerifsClass;
96
97 (*self & any_serif_class) != 0
98 }
99
is_sans_serif(&self) -> bool100 fn is_sans_serif(&self) -> bool {
101 (*self & kCTFontSansSerifClass) != 0
102 }
103
is_script(&self) -> bool104 fn is_script(&self) -> bool {
105 (*self & kCTFontScriptsClass) != 0
106 }
107
is_fantasy(&self) -> bool108 fn is_fantasy(&self) -> bool {
109 (*self & kCTFontOrnamentalsClass) != 0
110 }
111
is_symbols(&self) -> bool112 fn is_symbols(&self) -> bool {
113 (*self & kCTFontSymbolicClass) != 0
114 }
115 }
116
117 pub type CTFontAttributes = CFDictionary;
118
119 pub type CTFontTraits = CFDictionary<CFString, CFType>;
120
121 pub trait TraitAccessors {
symbolic_traits(&self) -> CTFontSymbolicTraits122 fn symbolic_traits(&self) -> CTFontSymbolicTraits;
normalized_weight(&self) -> f64123 fn normalized_weight(&self) -> f64;
normalized_width(&self) -> f64124 fn normalized_width(&self) -> f64;
normalized_slant(&self) -> f64125 fn normalized_slant(&self) -> f64;
126 }
127
128 trait TraitAccessorPrivate {
extract_number_for_key(&self, key: CFStringRef) -> CFNumber129 fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber;
130 }
131
132 impl TraitAccessorPrivate for CTFontTraits {
extract_number_for_key(&self, key: CFStringRef) -> CFNumber133 fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber {
134 let cftype = self.get(key);
135 cftype.downcast::<CFNumber>().unwrap()
136 }
137
138 }
139
140 impl TraitAccessors for CTFontTraits {
symbolic_traits(&self) -> CTFontSymbolicTraits141 fn symbolic_traits(&self) -> CTFontSymbolicTraits {
142 unsafe {
143 let number = self.extract_number_for_key(kCTFontSymbolicTrait);
144 number.to_i64().unwrap() as u32
145 }
146 }
147
normalized_weight(&self) -> f64148 fn normalized_weight(&self) -> f64 {
149 unsafe {
150 let number = self.extract_number_for_key(kCTFontWeightTrait);
151 number.to_f64().unwrap()
152 }
153 }
154
normalized_width(&self) -> f64155 fn normalized_width(&self) -> f64 {
156 unsafe {
157 let number = self.extract_number_for_key(kCTFontWidthTrait);
158 number.to_f64().unwrap()
159 }
160 }
161
normalized_slant(&self) -> f64162 fn normalized_slant(&self) -> f64 {
163 unsafe {
164 let number = self.extract_number_for_key(kCTFontSlantTrait);
165 number.to_f64().unwrap()
166 }
167 }
168 }
169
170 /*
171 * CTFontDescriptor.h
172 */
173 pub type CTFontOrientation = u32;
174 pub const kCTFontDefaultOrientation: CTFontOrientation = 0;
175 pub const kCTFontHorizontalOrientation: CTFontOrientation = 1;
176 pub const kCTFontVerticalOrientation: CTFontOrientation = 2;
177
178 pub type CTFontPriority = u32;
179 pub const kCTFontPrioritySystem: CTFontPriority = 10000;
180 pub const kCTFontPriorityNetwork: CTFontPriority = 20000;
181 pub const kCTFontPriorityComputer: CTFontPriority = 30000;
182 pub const kCTFontPriorityUser: CTFontPriority = 40000;
183 pub const kCTFontPriorityDynamic: CTFontPriority = 50000;
184 pub const kCTFontPriorityProcess: CTFontPriority = 60000;
185
186 #[repr(C)]
187 pub struct __CTFontDescriptor(c_void);
188
189 pub type CTFontDescriptorRef = *const __CTFontDescriptor;
190
191 declare_TCFType! {
192 CTFontDescriptor, CTFontDescriptorRef
193 }
194 impl_TCFType!(CTFontDescriptor, CTFontDescriptorRef, CTFontDescriptorGetTypeID);
195 impl_CFTypeDescription!(CTFontDescriptor);
196
197
198 impl CTFontDescriptor {
get_string_attribute(&self, attribute: CFStringRef) -> Option<String>199 fn get_string_attribute(&self, attribute: CFStringRef) -> Option<String> {
200 unsafe {
201 let value = CTFontDescriptorCopyAttribute(self.0, attribute);
202 if value.is_null() {
203 return None
204 }
205
206 let value = CFType::wrap_under_create_rule(value);
207 assert!(value.instance_of::<CFString>());
208 let s = CFString::wrap_under_get_rule(value.as_CFTypeRef() as CFStringRef);
209 Some(s.to_string())
210 }
211 }
212
213 }
214
215 impl CTFontDescriptor {
family_name(&self) -> String216 pub fn family_name(&self) -> String {
217 unsafe {
218 let value = self.get_string_attribute(kCTFontFamilyNameAttribute);
219 value.expect("A font must have a non-null family name.")
220 }
221 }
222
font_name(&self) -> String223 pub fn font_name(&self) -> String {
224 unsafe {
225 let value = self.get_string_attribute(kCTFontNameAttribute);
226 value.expect("A font must have a non-null name.")
227 }
228 }
229
style_name(&self) -> String230 pub fn style_name(&self) -> String {
231 unsafe {
232 let value = self.get_string_attribute(kCTFontStyleNameAttribute);
233 value.expect("A font must have a non-null style name.")
234 }
235 }
236
display_name(&self) -> String237 pub fn display_name(&self) -> String {
238 unsafe {
239 let value = self.get_string_attribute(kCTFontDisplayNameAttribute);
240 value.expect("A font must have a non-null display name.")
241 }
242 }
243
font_format(&self) -> Option<CTFontFormat>244 pub fn font_format(&self) -> Option<CTFontFormat> {
245 unsafe {
246 let value = CTFontDescriptorCopyAttribute(self.0, kCTFontFormatAttribute);
247 if value.is_null() {
248 return None;
249 }
250
251 let value = CFType::wrap_under_create_rule(value);
252 assert!(value.instance_of::<CFNumber>());
253 let format = CFNumber::wrap_under_get_rule(value.as_CFTypeRef() as CFNumberRef);
254 format.to_i32().map(|x| x as CTFontFormat)
255 }
256 }
257
font_path(&self) -> Option<PathBuf>258 pub fn font_path(&self) -> Option<PathBuf> {
259 unsafe {
260 let value = CTFontDescriptorCopyAttribute(self.0, kCTFontURLAttribute);
261 if value.is_null() {
262 return None;
263 }
264
265 let value = CFType::wrap_under_create_rule(value);
266 assert!(value.instance_of::<CFURL>());
267 let url = CFURL::wrap_under_get_rule(value.as_CFTypeRef() as CFURLRef);
268 url.to_path()
269 }
270 }
271
traits(&self) -> CTFontTraits272 pub fn traits(&self) -> CTFontTraits {
273 unsafe {
274 let value = CTFontDescriptorCopyAttribute(self.0, kCTFontTraitsAttribute);
275 assert!(!value.is_null());
276 let value = CFType::wrap_under_create_rule(value);
277 assert!(value.instance_of::<CFDictionary>());
278 CFDictionary::wrap_under_get_rule(value.as_CFTypeRef() as CFDictionaryRef)
279 }
280 }
281 }
282
new_from_attributes(attributes: &CFDictionary<CFString, CFType>) -> CTFontDescriptor283 pub fn new_from_attributes(attributes: &CFDictionary<CFString, CFType>) -> CTFontDescriptor {
284 unsafe {
285 let result: CTFontDescriptorRef =
286 CTFontDescriptorCreateWithAttributes(attributes.as_concrete_TypeRef());
287 CTFontDescriptor::wrap_under_create_rule(result)
288 }
289 }
290
new_from_variations(variations: &CFDictionary<CFString, CFNumber>) -> CTFontDescriptor291 pub fn new_from_variations(variations: &CFDictionary<CFString, CFNumber>) -> CTFontDescriptor {
292 unsafe {
293 let var_key = CFString::wrap_under_get_rule(kCTFontVariationAttribute);
294 let var_val = CFType::wrap_under_get_rule(variations.as_CFTypeRef());
295 let attributes = CFDictionary::from_CFType_pairs(&[(var_key, var_val)]);
296 new_from_attributes(&attributes)
297 }
298 }
299
new_from_postscript_name(name: &CFString) -> CTFontDescriptor300 pub fn new_from_postscript_name(name: &CFString) -> CTFontDescriptor {
301 unsafe {
302 let result: CTFontDescriptorRef =
303 CTFontDescriptorCreateWithNameAndSize(name.as_concrete_TypeRef(), 0.0);
304 CTFontDescriptor::wrap_under_create_rule(result)
305 }
306 }
307
debug_descriptor(desc: &CTFontDescriptor)308 pub fn debug_descriptor(desc: &CTFontDescriptor) {
309 println!("family: {}", desc.family_name());
310 println!("name: {}", desc.font_name());
311 println!("style: {}", desc.style_name());
312 println!("display: {}", desc.display_name());
313 println!("path: {:?}", desc.font_path());
314 desc.show();
315 }
316
317 extern {
318 /*
319 * CTFontTraits.h
320 */
321
322 // font trait constants
323 pub static kCTFontSymbolicTrait: CFStringRef;
324 pub static kCTFontWeightTrait: CFStringRef;
325 pub static kCTFontWidthTrait: CFStringRef;
326 pub static kCTFontSlantTrait: CFStringRef;
327
328 /*
329 * CTFontDescriptor.h
330 */
331
332 // font attribute constants. Note that the name-related attributes
333 // here are somewhat flaky. Servo creates CTFont instances and
334 // then uses CTFontCopyName to get more fine-grained names.
335 pub static kCTFontURLAttribute: CFStringRef; // value: CFURLRef
336 pub static kCTFontNameAttribute: CFStringRef; // value: CFStringRef
337 pub static kCTFontDisplayNameAttribute: CFStringRef; // value: CFStringRef
338 pub static kCTFontFamilyNameAttribute: CFStringRef; // value: CFStringRef
339 pub static kCTFontStyleNameAttribute: CFStringRef; // value: CFStringRef
340 pub static kCTFontTraitsAttribute: CFStringRef;
341 pub static kCTFontVariationAttribute: CFStringRef;
342 pub static kCTFontSizeAttribute: CFStringRef;
343 pub static kCTFontMatrixAttribute: CFStringRef;
344 pub static kCTFontCascadeListAttribute: CFStringRef;
345 pub static kCTFontCharacterSetAttribute: CFStringRef;
346 pub static kCTFontLanguagesAttribute: CFStringRef;
347 pub static kCTFontBaselineAdjustAttribute: CFStringRef;
348 pub static kCTFontMacintoshEncodingsAttribute: CFStringRef;
349 pub static kCTFontFeaturesAttribute: CFStringRef;
350 pub static kCTFontFeatureSettingsAttribute: CFStringRef;
351 pub static kCTFontFixedAdvanceAttribute: CFStringRef;
352 pub static kCTFontOrientationAttribute: CFStringRef;
353 pub static kCTFontFormatAttribute: CFStringRef;
354 pub static kCTFontRegistrationScopeAttribute: CFStringRef;
355 pub static kCTFontPriorityAttribute: CFStringRef;
356 pub static kCTFontEnabledAttribute: CFStringRef;
357
CTFontDescriptorCopyAttribute(descriptor: CTFontDescriptorRef, attribute: CFStringRef) -> CFTypeRef358 pub fn CTFontDescriptorCopyAttribute(descriptor: CTFontDescriptorRef,
359 attribute: CFStringRef) -> CFTypeRef;
CTFontDescriptorCopyAttributes(descriptor: CTFontDescriptorRef) -> CFDictionaryRef360 pub fn CTFontDescriptorCopyAttributes(descriptor: CTFontDescriptorRef) -> CFDictionaryRef;
CTFontDescriptorCopyLocalizedAttribute(descriptor: CTFontDescriptorRef, attribute: CFStringRef, language: *mut CFStringRef) -> CFTypeRef361 pub fn CTFontDescriptorCopyLocalizedAttribute(descriptor: CTFontDescriptorRef,
362 attribute: CFStringRef,
363 language: *mut CFStringRef) -> CFTypeRef;
CTFontDescriptorCreateCopyWithAttributes(original: CTFontDescriptorRef, attributes: CFDictionaryRef) -> CTFontDescriptorRef364 pub fn CTFontDescriptorCreateCopyWithAttributes(original: CTFontDescriptorRef,
365 attributes: CFDictionaryRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateCopyWithFeature(original: CTFontDescriptorRef, featureTypeIdentifier: CFNumberRef, featureSelectorIdentifier: CFNumberRef) -> CTFontDescriptorRef366 pub fn CTFontDescriptorCreateCopyWithFeature(original: CTFontDescriptorRef,
367 featureTypeIdentifier: CFNumberRef,
368 featureSelectorIdentifier: CFNumberRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateCopyWithVariation(original: CTFontDescriptorRef, variationIdentifier: CFNumberRef, variationValue: CGFloat) -> CTFontDescriptorRef369 pub fn CTFontDescriptorCreateCopyWithVariation(original: CTFontDescriptorRef,
370 variationIdentifier: CFNumberRef,
371 variationValue: CGFloat) -> CTFontDescriptorRef;
CTFontDescriptorCreateMatchingFontDescriptor(descriptor: CTFontDescriptorRef, mandatoryAttributes: CFSetRef) -> CTFontDescriptorRef372 pub fn CTFontDescriptorCreateMatchingFontDescriptor(descriptor: CTFontDescriptorRef,
373 mandatoryAttributes: CFSetRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateWithAttributes(attributes: CFDictionaryRef) -> CTFontDescriptorRef374 pub fn CTFontDescriptorCreateWithAttributes(attributes: CFDictionaryRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateWithNameAndSize(name: CFStringRef, size: CGFloat) -> CTFontDescriptorRef375 pub fn CTFontDescriptorCreateWithNameAndSize(name: CFStringRef, size: CGFloat) -> CTFontDescriptorRef;
CTFontDescriptorGetTypeID() -> CFTypeID376 pub fn CTFontDescriptorGetTypeID() -> CFTypeID;
377 }
378
379 extern {
CTFontDescriptorCreateMatchingFontDescriptors(descriptor: CTFontDescriptorRef, mandatoryAttributes: CFSetRef) -> CFArrayRef380 pub fn CTFontDescriptorCreateMatchingFontDescriptors(descriptor: CTFontDescriptorRef,
381 mandatoryAttributes: CFSetRef) -> CFArrayRef;
382 }
383