font_kit/sources/
directwrite.rs1use dwrote::Font as DWriteFont;
14use dwrote::FontCollection as DWriteFontCollection;
15use std::any::Any;
16
17use crate::error::SelectionError;
18use crate::family_handle::FamilyHandle;
19use crate::family_name::FamilyName;
20use crate::handle::Handle;
21use crate::properties::Properties;
22use crate::source::Source;
23
24#[allow(missing_debug_implementations)]
26pub struct DirectWriteSource {
27 system_font_collection: DWriteFontCollection,
28}
29
30impl DirectWriteSource {
31 pub fn new() -> DirectWriteSource {
33 DirectWriteSource {
34 system_font_collection: DWriteFontCollection::system(),
35 }
36 }
37
38 pub fn all_fonts(&self) -> Result<Vec<Handle>, SelectionError> {
40 let mut handles = Vec::new();
41
42 for dwrite_family in self.system_font_collection.families_iter() {
43 for font_index in 0..dwrite_family.get_font_count() {
44 let Ok(dwrite_font) = dwrite_family.font(font_index) else {
45 continue;
46 };
47 handles.push(self.create_handle_from_dwrite_font(dwrite_font))
48 }
49 }
50
51 Ok(handles)
52 }
53
54 pub fn all_families(&self) -> Result<Vec<String>, SelectionError> {
56 Ok(self
57 .system_font_collection
58 .families_iter()
59 .filter_map(|dwrite_family| dwrite_family.family_name().ok())
60 .collect())
61 }
62
63 pub fn select_family_by_name(&self, family_name: &str) -> Result<FamilyHandle, SelectionError> {
67 let mut family = FamilyHandle::new();
68 let dwrite_family = match self.system_font_collection.font_family_by_name(family_name) {
69 Ok(Some(dwrite_family)) => dwrite_family,
70 Err(_) | Ok(None) => return Err(SelectionError::NotFound),
71 };
72 for font_index in 0..dwrite_family.get_font_count() {
73 let Ok(dwrite_font) = dwrite_family.font(font_index) else {
74 continue;
75 };
76 family.push(self.create_handle_from_dwrite_font(dwrite_font));
77 }
78 Ok(family)
79 }
80
81 pub fn select_by_postscript_name(
86 &self,
87 postscript_name: &str,
88 ) -> Result<Handle, SelectionError> {
89 <Self as Source>::select_by_postscript_name(self, postscript_name)
90 }
91
92 #[inline]
95 pub fn select_best_match(
96 &self,
97 family_names: &[FamilyName],
98 properties: &Properties,
99 ) -> Result<Handle, SelectionError> {
100 <Self as Source>::select_best_match(self, family_names, properties)
101 }
102
103 fn create_handle_from_dwrite_font(&self, dwrite_font: DWriteFont) -> Handle {
104 let dwrite_font_face = dwrite_font.create_font_face();
105 let dwrite_font_files = dwrite_font_face.get_files();
106 Handle::Path {
107 path: dwrite_font_files[0].get_font_file_path().unwrap(),
108 font_index: dwrite_font_face.get_index(),
109 }
110 }
111}
112
113impl Source for DirectWriteSource {
114 #[inline]
115 fn all_fonts(&self) -> Result<Vec<Handle>, SelectionError> {
116 self.all_fonts()
117 }
118
119 #[inline]
120 fn all_families(&self) -> Result<Vec<String>, SelectionError> {
121 self.all_families()
122 }
123
124 #[inline]
125 fn select_family_by_name(&self, family_name: &str) -> Result<FamilyHandle, SelectionError> {
126 self.select_family_by_name(family_name)
127 }
128
129 #[inline]
130 fn as_any(&self) -> &dyn Any {
131 self
132 }
133
134 #[inline]
135 fn as_mut_any(&mut self) -> &mut dyn Any {
136 self
137 }
138}