From 264a7dedd42e27cd9e604037640cf0594b2ec46b Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 19 Mar 2021 17:57:31 +0100 Subject: =?UTF-8?q?Scheduled=20maintenance=20=F0=9F=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New naming scheme - TextNode instead of NodeText - CallExpr instead of ExprCall - ... - Less glob imports - Removes Value::Args variant - Removes prelude - Renames Layouted to Fragment - Moves font into env - Moves shaping into layout - Moves frame into separate module --- src/env.rs | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 76 insertions(+), 3 deletions(-) (limited to 'src/env.rs') diff --git a/src/env.rs b/src/env.rs index 66cc5e19..3db71e08 100644 --- a/src/env.rs +++ b/src/env.rs @@ -7,11 +7,13 @@ use std::fs; use std::io::Cursor; use std::path::{Path, PathBuf}; -use fontdock::fs::FsSource; +use fontdock::{ContainsChar, FaceFromVec, FaceId, FontSource}; use image::io::Reader as ImageReader; use image::{DynamicImage, GenericImageView, ImageFormat}; +use ttf_parser::Face; -use crate::font::FontLoader; +#[cfg(feature = "fs")] +use fontdock::fs::{FsIndex, FsSource}; /// Encapsulates all environment dependencies (fonts, resources). #[derive(Debug)] @@ -25,13 +27,84 @@ pub struct Env { impl Env { /// Create an empty environment for testing purposes. pub fn blank() -> Self { + struct BlankSource; + + impl FontSource for BlankSource { + type Face = FaceBuf; + + fn load(&self, _: FaceId) -> Option { + None + } + } + Self { - fonts: FontLoader::new(Box::new(FsSource::new(vec![])), vec![]), + fonts: FontLoader::new(Box::new(BlankSource), vec![]), resources: ResourceLoader::new(), } } } +/// A font loader that is backed by a dynamic source. +pub type FontLoader = fontdock::FontLoader>>; + +/// An owned font face. +pub struct FaceBuf { + data: Box<[u8]>, + face: Face<'static>, +} + +impl FaceBuf { + /// Get a reference to the underlying face. + pub fn get(&self) -> &Face<'_> { + // We can't implement Deref because that would leak the internal 'static + // lifetime. + &self.face + } + + /// The raw face data. + pub fn data(&self) -> &[u8] { + &self.data + } +} + +impl FaceFromVec for FaceBuf { + fn from_vec(vec: Vec, i: u32) -> Option { + let data = vec.into_boxed_slice(); + + // SAFETY: The slices's location is stable in memory since we don't + // touch it and it can't be touched from outside this type. + let slice: &'static [u8] = + unsafe { std::slice::from_raw_parts(data.as_ptr(), data.len()) }; + + Some(Self { + data, + face: Face::from_slice(slice, i).ok()?, + }) + } +} + +impl ContainsChar for FaceBuf { + fn contains_char(&self, c: char) -> bool { + self.get().glyph_index(c).is_some() + } +} + +/// Simplify font loader construction from an [`FsIndex`]. +#[cfg(feature = "fs")] +pub trait FsIndexExt { + /// Create a font loader backed by a boxed [`FsSource`] which serves all + /// indexed font faces. + fn into_dynamic_loader(self) -> FontLoader; +} + +#[cfg(feature = "fs")] +impl FsIndexExt for FsIndex { + fn into_dynamic_loader(self) -> FontLoader { + let (files, descriptors) = self.into_vecs(); + FontLoader::new(Box::new(FsSource::new(files)), descriptors) + } +} + /// Loads resource from the file system. pub struct ResourceLoader { paths: HashMap, -- cgit v1.2.3