1pub mod system_fonts {
21 use core_text::font_descriptor::*;
22 use core_text::font_descriptor;
23 use core_text;
24 use std::fs::File;
25 use std::mem;
26 use std::ptr;
27 use core_foundation::string::CFString;
28 use core_foundation::number::CFNumber;
29 use core_foundation::array::CFArray;
30 use core_foundation::dictionary::CFDictionary;
31 use core_foundation::base::{CFType, TCFType};
32 use core_foundation::url::CFURL;
33 use libc::c_int;
34 use std::io::Read;
35 pub type FontProperty = CTFontDescriptor;
37
38 pub struct FontPropertyBuilder {
40 symbolic_traits: CTFontSymbolicTraits,
41 family: String
42 }
43
44 impl FontPropertyBuilder {
45 pub fn new() -> FontPropertyBuilder {
46 FontPropertyBuilder{ symbolic_traits: 0, family: String::new()}
47 }
48
49 pub fn italic(mut self) -> FontPropertyBuilder {
50 self.symbolic_traits |= kCTFontItalicTrait;
51 self
52 }
53
54 pub fn oblique(self) -> FontPropertyBuilder {
55 self.italic()
56 }
57
58 pub fn monospace(mut self) -> FontPropertyBuilder {
59 self.symbolic_traits |= kCTFontMonoSpaceTrait;
60 self
61 }
62
63 pub fn bold(mut self) -> FontPropertyBuilder {
64 self.symbolic_traits |= kCTFontBoldTrait;
65 self
66 }
67
68 pub fn family(mut self, name: &str) -> FontPropertyBuilder {
69 self.family = name.to_string();
70 self
71 }
72
73 pub fn build(self) -> FontProperty {
74 let family_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontFamilyNameAttribute) };
75 let family_name: CFString = self.family.parse().unwrap();
76 let traits_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontTraitsAttribute) };
77 let symbolic_traits_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontSymbolicTrait) };
78 let traits = CFDictionary::from_CFType_pairs(&[(symbolic_traits_attr.as_CFType(), CFNumber::from(self.symbolic_traits as i32).as_CFType())]);
79 let mut attributes = Vec::new();
80 attributes.push((traits_attr, traits.as_CFType()));
81 if self.family.len() != 0 {
82 attributes.push((family_attr, family_name.as_CFType()));
83 }
84 let attributes = CFDictionary::from_CFType_pairs(&attributes);
85 font_descriptor::new_from_attributes(&attributes)
86 }
87 }
88
89 pub fn get(config: &FontProperty) -> Option<(Vec<u8>, c_int)> {
91 let mut buffer = Vec::new();
92 let url: CFURL;
93 unsafe {
94 let value =
95 CTFontDescriptorCopyAttribute(config.as_concrete_TypeRef(), kCTFontURLAttribute);
96
97 if value.is_null() {
98 return None
99 }
100
101 let value: CFType = TCFType::wrap_under_get_rule(value);
102 if !value.instance_of::<CFURL>() {
103 return None
104 }
105 url = TCFType::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef()));
106 }
107 if let Some(path) = url.to_path() {
108 match File::open(path).and_then(|mut f| f.read_to_end(&mut buffer)) {
109 Ok(_) => return Some((buffer, 0)),
110 Err(_) => return None,
111 }
112 };
113 return None
114 }
115
116 pub fn query_all() -> Vec<String> {
118 core_text::font_collection::get_family_names()
119 .iter()
120 .map(|family_name| family_name.to_string())
121 .collect()
122 }
123
124 pub fn query_specific(property: &mut FontProperty) -> Vec<String> {
126 let descs: CFArray<CTFontDescriptor> = unsafe {
127 let descs = CTFontDescriptorCreateMatchingFontDescriptors(
128 property.as_concrete_TypeRef(),
129 ptr::null(),
130 );
131 TCFType::wrap_under_create_rule(descs)
132 };
133 descs
134 .iter()
135 .map(|desc| desc.family_name())
136 .collect::<Vec<_>>()
137 }
138}