Skip to content

Commit 69258db

Browse files
committed
feature/fontique - softwarerenderer - Replace usage of fontdb with fontique (#9405)
* feature/fontique - softwarerenderer - Replace usage of fontdb with fontique * Get rid of oncecell
1 parent 8e2df00 commit 69258db

File tree

5 files changed

+157
-139
lines changed

5 files changed

+157
-139
lines changed

internal/common/sharedfontique.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@
33

44
pub use fontique;
55

6-
thread_local! {
7-
pub static COLLECTION: std::cell::RefCell<fontique::Collection> = Default::default()
6+
static COLLECTION: std::sync::LazyLock<Collection> = std::sync::LazyLock::new(|| Collection {
7+
inner: fontique::Collection::new(fontique::CollectionOptions {
8+
shared: true,
9+
..Default::default()
10+
}),
11+
source_cache: fontique::SourceCache::new_shared(),
12+
});
13+
14+
pub fn get_collection() -> Collection {
15+
COLLECTION.clone()
16+
}
17+
18+
#[derive(Clone)]
19+
pub struct Collection {
20+
inner: fontique::Collection,
21+
source_cache: fontique::SourceCache,
22+
}
23+
24+
impl Collection {
25+
pub fn query<'a>(&'a mut self) -> fontique::Query<'a> {
26+
self.inner.query(&mut self.source_cache)
27+
}
28+
29+
pub fn register_fonts(&mut self, data: impl Into<fontique::Blob<u8>>) -> usize {
30+
self.inner.register_fonts(data.into(), None).len()
31+
}
832
}

internal/core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ unsafe-single-threaded = []
4848

4949
unicode = ["unicode-script", "unicode-linebreak"]
5050

51-
software-renderer-systemfonts = ["shared-fontdb", "shared-fontique", "rustybuzz", "fontdue", "software-renderer"]
51+
software-renderer-systemfonts = ["shared-fontique", "rustybuzz", "fontdue", "software-renderer"]
5252
software-renderer = ["bytemuck"]
5353

5454
image-decoders = ["dep:image", "dep:clru"]

internal/core/graphics.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,44 @@ impl FontRequest {
168168
}
169169
}
170170

171+
#[cfg(feature = "shared-fontique")]
172+
impl FontRequest {
173+
/// Attempts to query the fontique font collection for a matching font.
174+
pub fn query_fontique(&self) -> Option<i_slint_common::sharedfontique::fontique::QueryFont> {
175+
use i_slint_common::sharedfontique::{self, fontique};
176+
177+
let mut collection = sharedfontique::get_collection();
178+
179+
let mut query = collection.query();
180+
query.set_families(
181+
self.family.as_ref().map(|family| fontique::QueryFamily::from(family.as_str())),
182+
);
183+
184+
query.set_attributes(fontique::Attributes {
185+
weight: self
186+
.weight
187+
.as_ref()
188+
.map(|&weight| fontique::FontWeight::new(weight as f32))
189+
.unwrap_or_default(),
190+
style: if self.italic {
191+
fontique::FontStyle::Italic
192+
} else {
193+
fontique::FontStyle::Normal
194+
},
195+
..Default::default()
196+
});
197+
198+
let mut font = None;
199+
200+
query.matches_with(|queried_font| {
201+
font = Some(queried_font.clone());
202+
fontique::QueryStatus::Stop
203+
});
204+
205+
font
206+
}
207+
}
208+
171209
/// Internal enum to specify which version of OpenGL to request
172210
/// from the windowing system.
173211
#[derive(Debug, Clone, PartialEq)]

internal/core/software_renderer/fonts/systemfonts.rs

Lines changed: 32 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,31 @@ use alloc::rc::Rc;
88
use std::collections::HashMap;
99

1010
use crate::lengths::ScaleFactor;
11-
use i_slint_common::sharedfontdb::{self, fontdb};
11+
use i_slint_common::sharedfontique::{self, fontique};
1212

1313
use super::super::PhysicalLength;
1414
use super::vectorfont::VectorFont;
1515

1616
crate::thread_local! {
17-
static FONTDUE_FONTS: RefCell<HashMap<fontdb::ID, Rc<fontdue::Font>>> = Default::default();
17+
static FONTDUE_FONTS: RefCell<HashMap<fontique::FamilyId, Rc<fontdue::Font>>> = Default::default();
1818
}
1919

20-
fn get_or_create_fontdue_font(fontdb: &fontdb::Database, id: fontdb::ID) -> Rc<fontdue::Font> {
20+
fn get_or_create_fontdue_font(font: &fontique::QueryFont) -> Rc<fontdue::Font> {
2121
FONTDUE_FONTS.with(|font_cache| {
2222
font_cache
2323
.borrow_mut()
24-
.entry(id)
25-
.or_insert_with(|| {
26-
fontdb
27-
.with_face_data(id, |face_data, font_index| {
28-
fontdue::Font::from_bytes(
29-
face_data,
30-
fontdue::FontSettings {
31-
collection_index: font_index,
32-
scale: 40.,
33-
..Default::default()
34-
},
35-
)
36-
.expect("fatal: fontdue is unable to parse truetype font")
37-
.into()
38-
})
39-
.unwrap()
24+
.entry(font.family.0)
25+
.or_insert_with(move || {
26+
fontdue::Font::from_bytes(
27+
font.blob.data(),
28+
fontdue::FontSettings {
29+
collection_index: font.index,
30+
scale: 40.,
31+
..Default::default()
32+
},
33+
)
34+
.expect("fatal: fontdue is unable to parse truetype font")
35+
.into()
4036
})
4137
.clone()
4238
})
@@ -46,60 +42,39 @@ pub fn match_font(
4642
request: &super::FontRequest,
4743
scale_factor: super::ScaleFactor,
4844
) -> Option<VectorFont> {
49-
request.family.as_ref().and_then(|family_str| {
50-
let query = request.to_fontdb_query();
51-
45+
if request.family.is_some() {
5246
let requested_pixel_size: PhysicalLength =
5347
(request.pixel_size.unwrap_or(super::DEFAULT_FONT_SIZE).cast() * scale_factor).cast();
5448

55-
sharedfontdb::FONT_DB.with(|fonts| {
56-
let borrowed_fontdb = fonts.borrow();
57-
borrowed_fontdb.query_with_family(query, Some(family_str)).map(|font_id| {
58-
let fontdue_font = get_or_create_fontdue_font(&borrowed_fontdb, font_id);
59-
VectorFont::new(font_id, fontdue_font.clone(), requested_pixel_size)
60-
})
61-
})
62-
})
49+
if let Some(font) = request.query_fontique() {
50+
let fontdue_font = get_or_create_fontdue_font(&font);
51+
Some(VectorFont::new(font, fontdue_font, requested_pixel_size))
52+
} else {
53+
None
54+
}
55+
} else {
56+
None
57+
}
6358
}
6459

6560
pub fn fallbackfont(font_request: &super::FontRequest, scale_factor: ScaleFactor) -> VectorFont {
6661
let requested_pixel_size: PhysicalLength =
6762
(font_request.pixel_size.unwrap_or(super::DEFAULT_FONT_SIZE).cast() * scale_factor).cast();
6863

69-
sharedfontdb::FONT_DB.with_borrow(|fonts| {
70-
let query = font_request.to_fontdb_query();
71-
72-
let fallback_font_id = fonts
73-
.query_with_family(query, None)
74-
.expect("fatal: query for fallback font returned empty font list");
75-
76-
let fontdue_font = get_or_create_fontdue_font(fonts, fallback_font_id);
77-
VectorFont::new(fallback_font_id, fontdue_font, requested_pixel_size)
78-
})
64+
let font = font_request.query_fontique().unwrap();
65+
let fontdue_font = get_or_create_fontdue_font(&font);
66+
VectorFont::new(font, fontdue_font, requested_pixel_size)
7967
}
8068

8169
pub fn register_font_from_memory(data: &'static [u8]) -> Result<(), Box<dyn std::error::Error>> {
82-
sharedfontdb::FONT_DB.with_borrow_mut(|fonts| {
83-
fonts.make_mut().load_font_source(fontdb::Source::Binary(std::sync::Arc::new(data)))
84-
});
70+
sharedfontique::get_collection().register_fonts(data.to_vec());
8571
Ok(())
8672
}
8773

8874
#[cfg(not(target_family = "wasm"))]
8975
pub fn register_font_from_path(path: &std::path::Path) -> Result<(), Box<dyn std::error::Error>> {
9076
let requested_path = path.canonicalize().unwrap_or_else(|_| path.into());
91-
sharedfontdb::FONT_DB.with_borrow_mut(|fonts| {
92-
for face_info in fonts.faces() {
93-
match &face_info.source {
94-
fontdb::Source::Binary(_) => {}
95-
fontdb::Source::File(loaded_path) | fontdb::Source::SharedFile(loaded_path, ..) => {
96-
if *loaded_path == requested_path {
97-
return Ok(());
98-
}
99-
}
100-
}
101-
}
102-
103-
fonts.make_mut().load_font_file(requested_path).map_err(|e| e.into())
104-
})
77+
let contents = std::fs::read(requested_path)?;
78+
sharedfontique::get_collection().register_fonts(contents);
79+
Ok(())
10580
}

0 commit comments

Comments
 (0)