// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0 use core::cell::RefCell; use alloc::boxed::Box; use alloc::rc::Rc; use std::collections::HashMap; use crate::lengths::ScaleFactor; use i_slint_common::sharedfontique::{self, fontique}; use super::super::PhysicalLength; use super::vectorfont::VectorFont; crate::thread_local! { static FONTDUE_FONTS: RefCell>> = Default::default(); } fn get_or_create_fontdue_font(font: &fontique::QueryFont) -> Rc { FONTDUE_FONTS.with(|font_cache| { font_cache .borrow_mut() .entry(font.family.0) .or_insert_with(move || { fontdue::Font::from_bytes( font.blob.data(), fontdue::FontSettings { collection_index: font.index, scale: 40., ..Default::default() }, ) .expect("fatal: fontdue is unable to parse truetype font") .into() }) .clone() }) } pub fn match_font( request: &super::FontRequest, scale_factor: super::ScaleFactor, ) -> Option { if request.family.is_some() { let requested_pixel_size: PhysicalLength = (request.pixel_size.unwrap_or(super::DEFAULT_FONT_SIZE).cast() * scale_factor).cast(); if let Some(font) = request.query_fontique() { let fontdue_font = get_or_create_fontdue_font(&font); Some(VectorFont::new(font, fontdue_font, requested_pixel_size)) } else { None } } else { None } } pub fn fallbackfont(font_request: &super::FontRequest, scale_factor: ScaleFactor) -> VectorFont { let requested_pixel_size: PhysicalLength = (font_request.pixel_size.unwrap_or(super::DEFAULT_FONT_SIZE).cast() * scale_factor).cast(); let font = font_request.query_fontique().unwrap(); let fontdue_font = get_or_create_fontdue_font(&font); VectorFont::new(font, fontdue_font, requested_pixel_size) } pub fn register_font_from_memory(data: &'static [u8]) -> Result<(), Box> { sharedfontique::get_collection().register_fonts(data.to_vec().into(), None); Ok(()) } #[cfg(not(target_family = "wasm"))] pub fn register_font_from_path(path: &std::path::Path) -> Result<(), Box> { let requested_path = path.canonicalize().unwrap_or_else(|_| path.into()); let contents = std::fs::read(requested_path)?; sharedfontique::get_collection().register_fonts(contents.into(), None); Ok(()) }