1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use i_slint_core::textlayout::sharedparley::parley;
use std::cell::RefCell;
use std::collections::HashMap;
pub struct FontCache {
font_mgr: skia_safe::FontMgr,
fonts: HashMap<(u64, u32), Option<skia_safe::Typeface>>,
}
impl Default for FontCache {
fn default() -> Self {
Self { font_mgr: skia_safe::FontMgr::new(), fonts: Default::default() }
}
}
impl FontCache {
pub fn font(&mut self, font: &parley::FontData) -> Option<skia_safe::Typeface> {
self.fonts
.entry((font.data.id(), font.index))
.or_insert_with(|| {
let typeface = self.font_mgr.new_from_data(
font.data.as_ref(),
if font.index > 0 { Some(font.index as _) } else { None },
);
// Due to https://issues.skia.org/issues/310510989, fonts from true type collections
// with an index > 0 fail to load on macOS. As a workaround, we manually extract the font from the
// collection and load it as a single font.
#[cfg(target_vendor = "apple")]
if font.index > 0 && typeface.is_none() {
{
if let Some(typeface) = read_fonts::CollectionRef::new(font.data.as_ref())
.ok()
.and_then(|ttc| ttc.get(font.index).ok())
.map(|ttf| {
write_fonts::FontBuilder::new().copy_missing_tables(ttf).build()
})
.and_then(|new_ttf| self.font_mgr.new_from_data(&new_ttf, None))
{
return Some(typeface);
}
}
}
typeface
})
.clone()
}
}
thread_local! {
pub static FONT_CACHE: RefCell<FontCache> = RefCell::new(Default::default())
}