plotters_font_loader/
macos.rs1pub 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(mut self) -> FontProperty {
74 let family_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontFamilyNameAttribute) };
75 let name_str = match self.family.as_str() {
76 "serif" => {
77 self.symbolic_traits |= kCTFontModernSerifsClass;
78 ""
79 },
80 "sans-serif" => {
81 self.symbolic_traits |= kCTFontSansSerifClass;
82 ""
83 },
84 "monospace" => {
85 self.symbolic_traits |= kCTFontMonoSpaceTrait;
86 ""
87 },
88 name => name,
89 };
90 let family_name: CFString = name_str.parse().unwrap();
91 let traits_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontTraitsAttribute) };
92 let symbolic_traits_attr: CFString = unsafe { TCFType::wrap_under_get_rule(kCTFontSymbolicTrait) };
93 let traits = CFDictionary::from_CFType_pairs(&[(symbolic_traits_attr.as_CFType(), CFNumber::from(self.symbolic_traits as i32).as_CFType())]);
94 let mut attributes = Vec::new();
95 attributes.push((traits_attr, traits.as_CFType()));
96 if name_str.len() != 0 {
97 attributes.push((family_attr, family_name.as_CFType()));
98 }
99 let attributes = CFDictionary::from_CFType_pairs(&attributes);
100 font_descriptor::new_from_attributes(&attributes)
101 }
102 }
103
104 pub fn get(config: &FontProperty) -> Option<(Vec<u8>, c_int)> {
106 let mut buffer = Vec::new();
107 let url: CFURL;
108 unsafe {
109 let value =
110 CTFontDescriptorCopyAttribute(config.as_concrete_TypeRef(), kCTFontURLAttribute);
111
112 if value.is_null() {
113 return None
114 }
115
116 let value: CFType = TCFType::wrap_under_get_rule(value);
117 if !value.instance_of::<CFURL>() {
118 return None
119 }
120 url = TCFType::wrap_under_get_rule(mem::transmute(value.as_CFTypeRef()));
121 }
122 if let Some(path) = url.to_path() {
123 match File::open(path).and_then(|mut f| f.read_to_end(&mut buffer)) {
124 Ok(_) => return Some((buffer, 0)),
125 Err(_) => return None,
126 }
127 };
128 return None
129 }
130
131 pub fn query_all() -> Vec<String> {
133 core_text::font_collection::get_family_names()
134 .iter()
135 .map(|family_name| family_name.to_string())
136 .collect()
137 }
138
139 pub fn query_specific(property: &mut FontProperty) -> Vec<String> {
141 let descs: CFArray<CTFontDescriptor> = unsafe {
142 let descs = CTFontDescriptorCreateMatchingFontDescriptors(
143 property.as_concrete_TypeRef(),
144 ptr::null(),
145 );
146 TCFType::wrap_under_create_rule(descs)
147 };
148 descs
149 .iter()
150 .map(|desc| desc.family_name())
151 .collect::<Vec<_>>()
152 }
153}