diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-03-19 17:57:31 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-03-19 17:57:31 +0100 |
| commit | 264a7dedd42e27cd9e604037640cf0594b2ec46b (patch) | |
| tree | d26feea399d54bb86bd44878f40293983bf5251d /src/env.rs | |
| parent | ca3df70e2a5069832d7d2135967674c34a155442 (diff) | |
Scheduled maintenance 🔨
- 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
Diffstat (limited to 'src/env.rs')
| -rw-r--r-- | src/env.rs | 79 |
1 files changed, 76 insertions, 3 deletions
@@ -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<Self::Face> { + 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<Box<dyn FontSource<Face = FaceBuf>>>; + +/// 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<u8>, i: u32) -> Option<Self> { + 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<PathBuf, ResourceId>, |
