From 0c502801e359706a182f01da1465c17b15fa6c67 Mon Sep 17 00:00:00 2001 From: Jovansonlee Cesar Date: Sat, 14 Sep 2024 05:43:00 +0800 Subject: Make rendering of svg that has text work out of the box (#2560) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 --- tiny_skia/src/vector.rs | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'tiny_skia') diff --git a/tiny_skia/src/vector.rs b/tiny_skia/src/vector.rs index 8a15f47f..ea7de215 100644 --- a/tiny_skia/src/vector.rs +++ b/tiny_skia/src/vector.rs @@ -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, rasters: FxHashMap, raster_hits: FxHashSet, + fontdb: Option>, } #[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() } }; -- cgit