use std::sync::LazyLock;
use topcoat_core::fnv1a;
use crate::FontFaces;
#[derive(Debug, Clone, PartialEq)]
pub struct FontData {
family: String,
faces: FontFaces,
hash: u64,
}
impl FontData {
#[must_use]
pub fn new(family: impl Into<String>, faces: impl TryInto<FontFaces>) -> Self {
let family = family.into();
let faces = faces
.try_into()
.unwrap_or_else(|_| panic!("font faces must not be empty"));
let h = fnv1a::hash_continue(fnv1a::hash(family.as_bytes()), b"\0");
let hash = faces.hash(h);
Self {
family,
faces,
hash,
}
}
#[must_use]
pub fn family(&self) -> &str {
&self.family
}
#[must_use]
pub fn faces(&self) -> &FontFaces {
&self.faces
}
#[must_use]
pub fn hash(&self) -> u64 {
self.hash
}
}
#[derive(Debug, Clone, Copy)]
pub struct Font(&'static LazyLock<FontData>);
impl Font {
#[must_use]
pub const fn new(data: &'static LazyLock<FontData>) -> Self {
Self(data)
}
#[must_use]
pub fn family(&self) -> &str {
self.0.family()
}
#[must_use]
pub fn faces(&self) -> &FontFaces {
self.0.faces()
}
#[must_use]
pub fn hash(&self) -> u64 {
self.0.hash()
}
}
impl PartialEq for Font {
fn eq(&self, other: &Self) -> bool {
std::ptr::eq(self.0, other.0)
}
}
impl Eq for Font {}
#[cfg(feature = "discover")]
inventory::collect!(Font);
#[doc(hidden)]
#[cfg(feature = "discover")]
#[macro_export]
macro_rules! register_font {
($font:expr) => {
$crate::internal::inventory::submit! { $font }
};
}
#[doc(hidden)]
#[cfg(not(feature = "discover"))]
#[macro_export]
macro_rules! register_font {
($font:expr) => {};
}