use std::sync::Arc;
use alot::{LotId, Lots};
use kludgine::cosmic_text::fontdb::{self, Language};
use kludgine::cosmic_text::{Stretch, Style, Weight};
use crate::value::Dynamic;
#[derive(Clone, Default, PartialEq)]
pub struct FontCollection(pub(crate) Dynamic<FontCollectionData>);
impl FontCollection {
#[must_use]
pub fn push_unloadable(&self, font_data: Vec<u8>) -> LoadedFont {
LoadedFont(Arc::new(LoadedFontHandle {
collection: self.clone(),
id: self.push_inner(font_data),
}))
}
#[must_use]
pub fn with(self, font_data: Vec<u8>) -> Self {
self.push(font_data);
self
}
pub fn push(&self, font_data: Vec<u8>) {
self.push_inner(font_data);
}
fn push_inner(&self, font_data: Vec<u8>) -> LotId {
self.0.lock().fonts.push(Arc::new(font_data))
}
}
pub(crate) struct FontIter<'a> {
collection: *const (),
iter: alot::unordered::EntryIter<'a, Arc<Vec<u8>>>,
}
impl<'a> Iterator for FontIter<'a> {
type Item = (LoadedFontId, &'a Arc<Vec<u8>>);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next().map(|(id, data)| {
(
LoadedFontId {
collection: self.collection,
id,
},
data,
)
})
}
}
#[derive(Default)]
pub(crate) struct FontCollectionData {
fonts: Lots<Arc<Vec<u8>>>,
}
impl FontCollectionData {
pub(crate) fn fonts(&self, collection: &FontCollection) -> FontIter<'_> {
FontIter {
collection: collection.0.as_ptr(),
iter: self.fonts.entries(),
}
}
}
#[derive(PartialEq)]
struct LoadedFontHandle {
collection: FontCollection,
id: LotId,
}
impl Drop for LoadedFontHandle {
fn drop(&mut self) {
let mut collection = self.collection.0.lock();
collection.fonts.remove(self.id);
}
}
#[derive(PartialEq, Clone)]
pub struct LoadedFont(Arc<LoadedFontHandle>);
impl LoadedFont {
pub(crate) fn id(&self) -> LoadedFontId {
LoadedFontId {
collection: self.0.collection.0.as_ptr(),
id: self.0.id,
}
}
}
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
pub(crate) struct LoadedFontId {
pub(crate) collection: *const (),
pub(crate) id: LotId,
}
#[derive(Debug)]
pub struct LoadedFontFace {
pub id: fontdb::ID,
pub families: Vec<(String, Language)>,
pub weight: Weight,
pub style: Style,
pub stretch: Stretch,
}