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::{CFURLCopyFileSystemPath, kCFURLPOSIXPathStyle, CFURL};
19 use core_graphics::base::CGFloat;
20
21 use libc::c_void;
22 use std::mem;
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;
55 }
56
57 impl SymbolicTraitAccessors for CTFontSymbolicTraits {
is_italic(&self) -> bool58 fn is_italic(&self) -> bool { (*self & kCTFontItalicTrait) != 0 }
is_bold(&self) -> bool59 fn is_bold(&self) -> bool { (*self & kCTFontBoldTrait) != 0 }
is_expanded(&self) -> bool60 fn is_expanded(&self) -> bool { (*self & kCTFontExpandedTrait) != 0 }
is_condensed(&self) -> bool61 fn is_condensed(&self) -> bool { (*self & kCTFontCondensedTrait) != 0 }
is_monospace(&self) -> bool62 fn is_monospace(&self) -> bool { (*self & kCTFontMonoSpaceTrait) != 0 }
63 }
64
65 pub type CTFontStylisticClass = u32;
66 pub const kCTFontUnknownClass: CTFontStylisticClass = (0 << kCTFontClassMaskShift );
67 pub const kCTFontOldStyleSerifsClass: CTFontStylisticClass = (1 << kCTFontClassMaskShift );
68 pub const kCTFontTransitionalSerifsClass: CTFontStylisticClass = (2 << kCTFontClassMaskShift );
69 pub const kCTFontModernSerifsClass: CTFontStylisticClass = (3 << kCTFontClassMaskShift );
70 pub const kCTFontClarendonSerifsClass: CTFontStylisticClass = (4 << kCTFontClassMaskShift );
71 pub const kCTFontSlabSerifsClass: CTFontStylisticClass = (5 << kCTFontClassMaskShift );
72 pub const kCTFontFreeformSerifsClass: CTFontStylisticClass = (7 << kCTFontClassMaskShift );
73 pub const kCTFontSansSerifClass: CTFontStylisticClass = (8 << kCTFontClassMaskShift );
74 pub const kCTFontOrnamentalsClass: CTFontStylisticClass = (9 << kCTFontClassMaskShift );
75 pub const kCTFontScriptsClass: CTFontStylisticClass = (10 << kCTFontClassMaskShift );
76 pub const kCTFontSymbolicClass: CTFontStylisticClass = (12 << kCTFontClassMaskShift );
77
78 pub trait StylisticClassAccessors {
is_serif(&self) -> bool79 fn is_serif(&self) -> bool;
is_sans_serif(&self) -> bool80 fn is_sans_serif(&self) -> bool;
is_script(&self) -> bool81 fn is_script(&self) -> bool;
is_fantasy(&self) -> bool82 fn is_fantasy(&self) -> bool;
is_symbols(&self) -> bool83 fn is_symbols(&self) -> bool;
84 }
85
86 impl StylisticClassAccessors for CTFontStylisticClass {
is_serif(&self) -> bool87 fn is_serif(&self) -> bool {
88 let any_serif_class = kCTFontOldStyleSerifsClass
89 | kCTFontTransitionalSerifsClass
90 | kCTFontModernSerifsClass
91 | kCTFontClarendonSerifsClass
92 | kCTFontSlabSerifsClass
93 | kCTFontFreeformSerifsClass;
94
95 return (*self & any_serif_class) != 0;
96 }
97
is_sans_serif(&self) -> bool98 fn is_sans_serif(&self) -> bool {
99 return (*self & kCTFontSansSerifClass) != 0;
100 }
101
is_script(&self) -> bool102 fn is_script(&self) -> bool {
103 return (*self & kCTFontScriptsClass) != 0;
104 }
105
is_fantasy(&self) -> bool106 fn is_fantasy(&self) -> bool {
107 return (*self & kCTFontOrnamentalsClass) != 0;
108 }
109
is_symbols(&self) -> bool110 fn is_symbols(&self) -> bool {
111 return (*self & kCTFontSymbolicClass) != 0;
112 }
113 }
114
115 pub type CTFontAttributes = CFDictionary;
116
117 pub type CTFontTraits = CFDictionary;
118
119 pub trait TraitAccessors {
symbolic_traits(&self) -> CTFontSymbolicTraits120 fn symbolic_traits(&self) -> CTFontSymbolicTraits;
normalized_weight(&self) -> f64121 fn normalized_weight(&self) -> f64;
normalized_width(&self) -> f64122 fn normalized_width(&self) -> f64;
normalized_slant(&self) -> f64123 fn normalized_slant(&self) -> f64;
124 }
125
126 trait TraitAccessorPrivate {
extract_number_for_key(&self, key: CFStringRef) -> CFNumber127 unsafe fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber;
128 }
129
130 impl TraitAccessorPrivate for CTFontTraits {
extract_number_for_key(&self, key: CFStringRef) -> CFNumber131 unsafe fn extract_number_for_key(&self, key: CFStringRef) -> CFNumber {
132 let cftype = self.get_CFType(mem::transmute(key));
133 assert!(cftype.instance_of::<CFNumber>());
134 CFNumber::wrap_under_get_rule(mem::transmute(cftype.as_CFTypeRef()))
135 }
136
137 }
138
139 impl TraitAccessors for CTFontTraits {
symbolic_traits(&self) -> CTFontSymbolicTraits140 fn symbolic_traits(&self) -> CTFontSymbolicTraits {
141 unsafe {
142 let number = self.extract_number_for_key(kCTFontSymbolicTrait);
143 number.to_i64().unwrap() as u32
144 }
145 }
146
normalized_weight(&self) -> f64147 fn normalized_weight(&self) -> f64 {
148 unsafe {
149 let number = self.extract_number_for_key(kCTFontWeightTrait);
150 number.to_f64().unwrap()
151 }
152 }
153
normalized_width(&self) -> f64154 fn normalized_width(&self) -> f64 {
155 unsafe {
156 let number = self.extract_number_for_key(kCTFontWidthTrait);
157 number.to_f64().unwrap()
158 }
159 }
160
normalized_slant(&self) -> f64161 fn normalized_slant(&self) -> f64 {
162 unsafe {
163 let number = self.extract_number_for_key(kCTFontSlantTrait);
164 number.to_f64().unwrap()
165 }
166 }
167 }
168
169 /*
170 * CTFontDescriptor.h
171 */
172 pub type CTFontOrientation = u32;
173 pub const kCTFontDefaultOrientation: CTFontOrientation = 0;
174 pub const kCTFontHorizontalOrientation: CTFontOrientation = 1;
175 pub const kCTFontVerticalOrientation: CTFontOrientation = 2;
176
177 pub type CTFontPriority = u32;
178 pub const kCTFontPrioritySystem: CTFontPriority = 10000;
179 pub const kCTFontPriorityNetwork: CTFontPriority = 20000;
180 pub const kCTFontPriorityComputer: CTFontPriority = 30000;
181 pub const kCTFontPriorityUser: CTFontPriority = 40000;
182 pub const kCTFontPriorityDynamic: CTFontPriority = 50000;
183 pub const kCTFontPriorityProcess: CTFontPriority = 60000;
184
185 #[repr(C)]
186 pub struct __CTFontDescriptor(c_void);
187
188 pub type CTFontDescriptorRef = *const __CTFontDescriptor;
189
190 declare_TCFType! {
191 CTFontDescriptor, CTFontDescriptorRef
192 }
193 impl_TCFType!(CTFontDescriptor, CTFontDescriptorRef, CTFontDescriptorGetTypeID);
194 impl_CFTypeDescription!(CTFontDescriptor);
195
196
197 impl CTFontDescriptor {
get_string_attribute(&self, attribute: CFStringRef) -> Option<String>198 fn get_string_attribute(&self, attribute: CFStringRef) -> Option<String> {
199 unsafe {
200 let value = CTFontDescriptorCopyAttribute(self.0, attribute);
201 if value.is_null() {
202 return None
203 }
204
205 let value = CFType::wrap_under_create_rule(value);
206 assert!(value.instance_of::<CFString>());
207 let s = CFString::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef()));
208 Some(s.to_string())
209 }
210 }
211
212 }
213
214 impl CTFontDescriptor {
family_name(&self) -> String215 pub fn family_name(&self) -> String {
216 unsafe {
217 let value = self.get_string_attribute(kCTFontFamilyNameAttribute);
218 value.expect("A font must have a non-null family name.")
219 }
220 }
221
font_name(&self) -> String222 pub fn font_name(&self) -> String {
223 unsafe {
224 let value = self.get_string_attribute(kCTFontNameAttribute);
225 value.expect("A font must have a non-null name.")
226 }
227 }
228
style_name(&self) -> String229 pub fn style_name(&self) -> String {
230 unsafe {
231 let value = self.get_string_attribute(kCTFontStyleNameAttribute);
232 value.expect("A font must have a non-null style name.")
233 }
234 }
235
display_name(&self) -> String236 pub fn display_name(&self) -> String {
237 unsafe {
238 let value = self.get_string_attribute(kCTFontDisplayNameAttribute);
239 value.expect("A font must have a non-null display name.")
240 }
241 }
242
font_path(&self) -> Option<String>243 pub fn font_path(&self) -> Option<String> {
244 unsafe {
245 let value = CTFontDescriptorCopyAttribute(self.0, kCTFontURLAttribute);
246 if value.is_null() {
247 return None;
248 }
249
250 let value = CFType::wrap_under_create_rule(value);
251 assert!(value.instance_of::<CFURL>());
252 let url = CFURL::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef()));
253 let path = CFString::wrap_under_create_rule(CFURLCopyFileSystemPath(
254 url.as_concrete_TypeRef(),
255 kCFURLPOSIXPathStyle,
256 )).to_string();
257 Some(path)
258 }
259 }
260
traits(&self) -> CTFontTraits261 pub fn traits(&self) -> CTFontTraits {
262 unsafe {
263 let value = CTFontDescriptorCopyAttribute(self.0, kCTFontTraitsAttribute);
264 assert!(!value.is_null());
265 let value = CFType::wrap_under_create_rule(value);
266 assert!(value.instance_of::<CFDictionary>());
267 CFDictionary::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef()))
268 }
269 }
270 }
271
new_from_attributes(attributes: &CFDictionary) -> CTFontDescriptor272 pub fn new_from_attributes(attributes: &CFDictionary) -> CTFontDescriptor {
273 unsafe {
274 let result: CTFontDescriptorRef =
275 CTFontDescriptorCreateWithAttributes(attributes.as_concrete_TypeRef());
276 CTFontDescriptor::wrap_under_create_rule(result)
277 }
278 }
279
new_from_variations(variations: &CFDictionary) -> CTFontDescriptor280 pub fn new_from_variations(variations: &CFDictionary) -> CTFontDescriptor {
281 unsafe {
282 let var_key = CFType::wrap_under_get_rule(mem::transmute(kCTFontVariationAttribute));
283 let var_val = CFType::wrap_under_get_rule(variations.as_CFTypeRef());
284 let attributes = CFDictionary::from_CFType_pairs(&[(var_key, var_val)]);
285 new_from_attributes(&attributes)
286 }
287 }
288
debug_descriptor(desc: &CTFontDescriptor)289 pub fn debug_descriptor(desc: &CTFontDescriptor) {
290 println!("family: {}", desc.family_name());
291 println!("name: {}", desc.font_name());
292 println!("style: {}", desc.style_name());
293 println!("display: {}", desc.display_name());
294 println!("path: {:?}", desc.font_path());
295 desc.show();
296 }
297
298 extern {
299 /*
300 * CTFontTraits.h
301 */
302
303 // font trait constants
304 pub static kCTFontSymbolicTrait: CFStringRef;
305 pub static kCTFontWeightTrait: CFStringRef;
306 pub static kCTFontWidthTrait: CFStringRef;
307 pub static kCTFontSlantTrait: CFStringRef;
308
309 /*
310 * CTFontDescriptor.h
311 */
312
313 // font attribute constants. Note that the name-related attributes
314 // here are somewhat flaky. Servo creates CTFont instances and
315 // then uses CTFontCopyName to get more fine-grained names.
316 pub static kCTFontURLAttribute: CFStringRef; // value: CFURLRef
317 pub static kCTFontNameAttribute: CFStringRef; // value: CFStringRef
318 pub static kCTFontDisplayNameAttribute: CFStringRef; // value: CFStringRef
319 pub static kCTFontFamilyNameAttribute: CFStringRef; // value: CFStringRef
320 pub static kCTFontStyleNameAttribute: CFStringRef; // value: CFStringRef
321 pub static kCTFontTraitsAttribute: CFStringRef;
322 pub static kCTFontVariationAttribute: CFStringRef;
323 pub static kCTFontSizeAttribute: CFStringRef;
324 pub static kCTFontMatrixAttribute: CFStringRef;
325 pub static kCTFontCascadeListAttribute: CFStringRef;
326 pub static kCTFontCharacterSetAttribute: CFStringRef;
327 pub static kCTFontLanguagesAttribute: CFStringRef;
328 pub static kCTFontBaselineAdjustAttribute: CFStringRef;
329 pub static kCTFontMacintoshEncodingsAttribute: CFStringRef;
330 pub static kCTFontFeaturesAttribute: CFStringRef;
331 pub static kCTFontFeatureSettingsAttribute: CFStringRef;
332 pub static kCTFontFixedAdvanceAttribute: CFStringRef;
333 pub static kCTFontOrientationAttribute: CFStringRef;
334 pub static kCTFontFormatAttribute: CFStringRef;
335 pub static kCTFontRegistrationScopeAttribute: CFStringRef;
336 pub static kCTFontPriorityAttribute: CFStringRef;
337 pub static kCTFontEnabledAttribute: CFStringRef;
338
CTFontDescriptorCopyAttribute(descriptor: CTFontDescriptorRef, attribute: CFStringRef) -> CFTypeRef339 pub fn CTFontDescriptorCopyAttribute(descriptor: CTFontDescriptorRef,
340 attribute: CFStringRef) -> CFTypeRef;
CTFontDescriptorCopyAttributes(descriptor: CTFontDescriptorRef) -> CFDictionaryRef341 pub fn CTFontDescriptorCopyAttributes(descriptor: CTFontDescriptorRef) -> CFDictionaryRef;
CTFontDescriptorCopyLocalizedAttribute(descriptor: CTFontDescriptorRef, attribute: CFStringRef, language: *mut CFStringRef) -> CFTypeRef342 pub fn CTFontDescriptorCopyLocalizedAttribute(descriptor: CTFontDescriptorRef,
343 attribute: CFStringRef,
344 language: *mut CFStringRef) -> CFTypeRef;
CTFontDescriptorCreateCopyWithAttributes(original: CTFontDescriptorRef, attributes: CFDictionaryRef) -> CTFontDescriptorRef345 pub fn CTFontDescriptorCreateCopyWithAttributes(original: CTFontDescriptorRef,
346 attributes: CFDictionaryRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateCopyWithFeature(original: CTFontDescriptorRef, featureTypeIdentifier: CFNumberRef, featureSelectorIdentifier: CFNumberRef) -> CTFontDescriptorRef347 pub fn CTFontDescriptorCreateCopyWithFeature(original: CTFontDescriptorRef,
348 featureTypeIdentifier: CFNumberRef,
349 featureSelectorIdentifier: CFNumberRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateCopyWithVariation(original: CTFontDescriptorRef, variationIdentifier: CFNumberRef, variationValue: CGFloat) -> CTFontDescriptorRef350 pub fn CTFontDescriptorCreateCopyWithVariation(original: CTFontDescriptorRef,
351 variationIdentifier: CFNumberRef,
352 variationValue: CGFloat) -> CTFontDescriptorRef;
CTFontDescriptorCreateMatchingFontDescriptor(descriptor: CTFontDescriptorRef, mandatoryAttributes: CFSetRef) -> CTFontDescriptorRef353 pub fn CTFontDescriptorCreateMatchingFontDescriptor(descriptor: CTFontDescriptorRef,
354 mandatoryAttributes: CFSetRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateWithAttributes(attributes: CFDictionaryRef) -> CTFontDescriptorRef355 pub fn CTFontDescriptorCreateWithAttributes(attributes: CFDictionaryRef) -> CTFontDescriptorRef;
CTFontDescriptorCreateWithNameAndSize(name: CFStringRef, size: CGFloat) -> CTFontDescriptorRef356 pub fn CTFontDescriptorCreateWithNameAndSize(name: CFStringRef, size: CGFloat) -> CTFontDescriptorRef;
CTFontDescriptorGetTypeID() -> CFTypeID357 pub fn CTFontDescriptorGetTypeID() -> CFTypeID;
358 }
359
360 extern {
CTFontDescriptorCreateMatchingFontDescriptors(descriptor: CTFontDescriptorRef, mandatoryAttributes: CFSetRef) -> CFArrayRef361 pub fn CTFontDescriptorCreateMatchingFontDescriptors(descriptor: CTFontDescriptorRef,
362 mandatoryAttributes: CFSetRef) -> CFArrayRef;
363 }
364