Make rendering of svg that has text work out of the box (#2560)

* fix: load system fonts to usvg font_db, this will make rendering of text in svg that has it

* feat: add an example that renders svg that has text on it

* Initialize `fontdb` only once for `vector` images

* Remove `svg_text` example

* Set `fontdb` for `usvg::Options` in `tiny_skia::vector`

---------

Co-authored-by: Héctor Ramón Jiménez <hector@hecrj.dev>
This commit is contained in:
Jovansonlee Cesar 2024-09-14 05:43:00 +08:00 committed by GitHub
parent e0da42efed
commit 0c502801e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 19 deletions

View file

@ -8,6 +8,7 @@ use tiny_skia::Transform;
use std::cell::RefCell;
use std::collections::hash_map;
use std::fs;
use std::sync::Arc;
#[derive(Debug)]
pub struct Pipeline {
@ -68,6 +69,7 @@ struct Cache {
tree_hits: FxHashSet<u64>,
rasters: FxHashMap<RasterKey, tiny_skia::Pixmap>,
raster_hits: FxHashSet<RasterKey>,
fontdb: Option<Arc<usvg::fontdb::Database>>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@ -81,23 +83,32 @@ impl Cache {
fn load(&mut self, handle: &Handle) -> Option<&usvg::Tree> {
let id = handle.id();
// TODO: Reuse `cosmic-text` font database
if self.fontdb.is_none() {
let mut fontdb = usvg::fontdb::Database::new();
fontdb.load_system_fonts();
self.fontdb = Some(Arc::new(fontdb));
}
let options = usvg::Options {
fontdb: self
.fontdb
.as_ref()
.expect("fontdb must be initialized")
.clone(),
..usvg::Options::default()
};
if let hash_map::Entry::Vacant(entry) = self.trees.entry(id) {
let svg = match handle.data() {
Data::Path(path) => {
fs::read_to_string(path).ok().and_then(|contents| {
usvg::Tree::from_str(
&contents,
&usvg::Options::default(), // TODO: Set usvg::Options::fontdb
)
.ok()
usvg::Tree::from_str(&contents, &options).ok()
})
}
Data::Bytes(bytes) => {
usvg::Tree::from_data(
bytes,
&usvg::Options::default(), // TODO: Set usvg::Options::fontdb
)
.ok()
usvg::Tree::from_data(bytes, &options).ok()
}
};