2022-10-24 08:56:48 -06:00
|
|
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
|
|
|
|
|
2022-11-15 12:26:59 -07:00
|
|
|
use core::ops::Deref;
|
2022-10-18 12:07:22 -06:00
|
|
|
|
2022-11-15 12:26:59 -07:00
|
|
|
pub(crate) mod fallback;
|
2022-10-18 17:13:48 -06:00
|
|
|
|
2022-10-18 12:07:22 -06:00
|
|
|
pub use self::system::*;
|
|
|
|
|
mod system;
|
2022-11-15 12:26:59 -07:00
|
|
|
|
2023-03-01 02:50:10 +01:00
|
|
|
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
2023-03-01 12:15:58 +01:00
|
|
|
#[cfg_attr(not(feature = "swash"), repr(transparent))]
|
2023-03-01 02:50:10 +01:00
|
|
|
/// Identifies a [`Font`] in a [`FontSystem`]
|
|
|
|
|
pub struct FontKey {
|
|
|
|
|
pub id: fontdb::ID,
|
|
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
pub swash: (u32, swash::CacheKey),
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-29 22:29:17 -03:30
|
|
|
/// A font
|
2022-11-15 12:26:59 -07:00
|
|
|
pub struct Font<'a> {
|
|
|
|
|
pub info: &'a fontdb::FaceInfo,
|
|
|
|
|
pub data: &'a [u8],
|
|
|
|
|
pub rustybuzz: rustybuzz::Face<'a>,
|
|
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
pub swash: (u32, swash::CacheKey),
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> Font<'a> {
|
|
|
|
|
pub fn new(info: &'a fontdb::FaceInfo) -> Option<Self> {
|
|
|
|
|
let data = match &info.source {
|
|
|
|
|
fontdb::Source::Binary(data) => data.deref().as_ref(),
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
fontdb::Source::File(path) => {
|
|
|
|
|
log::warn!("Unsupported fontdb Source::File('{}')", path.display());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
fontdb::Source::SharedFile(_path, data) => data.deref().as_ref(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Some(Self {
|
|
|
|
|
info,
|
|
|
|
|
data,
|
|
|
|
|
rustybuzz: rustybuzz::Face::from_slice(data, info.index)?,
|
|
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
swash: {
|
|
|
|
|
let swash = swash::FontRef::from_index(data, info.index as usize)?;
|
|
|
|
|
(swash.offset, swash.key)
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 02:50:10 +01:00
|
|
|
pub fn from_key(db: &'a fontdb::Database, key: FontKey) -> Option<Self> {
|
|
|
|
|
let info = db.face(key.id)?;
|
|
|
|
|
let data = match &info.source {
|
|
|
|
|
fontdb::Source::Binary(data) => data.deref().as_ref(),
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
fontdb::Source::File(path) => {
|
|
|
|
|
log::warn!("Unsupported fontdb Source::File('{}')", path.display());
|
|
|
|
|
return None;
|
|
|
|
|
}
|
|
|
|
|
#[cfg(feature = "std")]
|
|
|
|
|
fontdb::Source::SharedFile(_path, data) => data.deref().as_ref(),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Some(Self {
|
|
|
|
|
info,
|
|
|
|
|
data,
|
|
|
|
|
rustybuzz: rustybuzz::Face::from_slice(data, info.index)?,
|
|
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
swash: key.swash,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn key(&self) -> FontKey {
|
|
|
|
|
FontKey {
|
|
|
|
|
id: self.info.id,
|
|
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
swash: self.swash,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 11:50:10 +01:00
|
|
|
pub fn name(&self) -> &str {
|
|
|
|
|
if let Some((name, _)) = self.info.families.first() {
|
|
|
|
|
name
|
|
|
|
|
} else {
|
|
|
|
|
&self.info.post_script_name
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn contains_family(&self, family: &str) -> bool {
|
|
|
|
|
self.info.families.iter().any(|(name, _)| name == family)
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-15 12:26:59 -07:00
|
|
|
#[cfg(feature = "swash")]
|
|
|
|
|
pub fn as_swash(&self) -> swash::FontRef {
|
|
|
|
|
swash::FontRef {
|
|
|
|
|
data: self.data,
|
|
|
|
|
offset: self.swash.0,
|
|
|
|
|
key: self.swash.1,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|