summaryrefslogtreecommitdiff
path: root/src/env.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-03-19 17:57:31 +0100
committerLaurenz <laurmaedje@gmail.com>2021-03-19 17:57:31 +0100
commit264a7dedd42e27cd9e604037640cf0594b2ec46b (patch)
treed26feea399d54bb86bd44878f40293983bf5251d /src/env.rs
parentca3df70e2a5069832d7d2135967674c34a155442 (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.rs79
1 files changed, 76 insertions, 3 deletions
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<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>,