#![doc = include_str!("../../docs/glyph-lookup.md")]
use super::{FontCodepoints, GlyphMetrics, GlyphRaster, LineMetrics, MetricsTable, RawGlyphs};
#[derive(Clone, Copy, Debug)]
pub struct GlyphTable<'meta, 'map, 'data> {
codepoints: FontCodepoints<'meta>,
metrics: MetricsTable<'meta>,
glyphs: RawGlyphs<'map, 'data>,
}
impl<'meta, 'map, 'data> GlyphTable<'meta, 'map, 'data> {
pub fn new(
codepoints: FontCodepoints<'meta>,
metrics: MetricsTable<'meta>,
glyphs: RawGlyphs<'map, 'data>,
) -> Result<Self, GlyphTableError> {
if codepoints.len() != metrics.len() || codepoints.len() != glyphs.len() {
return Err(GlyphTableError::Cardinality {
codepoints: codepoints.len(),
metrics: metrics.len(),
glyphs: glyphs.len(),
});
}
Ok(Self {
codepoints,
metrics,
glyphs,
})
}
pub const fn len(self) -> usize {
self.codepoints.len()
}
pub const fn is_empty(self) -> bool {
self.codepoints.is_empty()
}
pub const fn codepoints(self) -> FontCodepoints<'meta> {
self.codepoints
}
pub fn line_metrics(self) -> LineMetrics {
self.metrics.line_metrics()
}
pub fn get(self, ordinal: usize) -> Option<Glyph<'data>> {
Some(Glyph {
raster: self.glyphs.get(ordinal)?,
metrics: self
.metrics
.get(ordinal)
.expect("validated glyph cardinality"),
})
}
pub fn glyph(self, codepoint: char) -> Option<Glyph<'data>> {
self.get(self.codepoints.binary_search(codepoint).ok()?)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Glyph<'data> {
metrics: GlyphMetrics,
raster: GlyphRaster<'data>,
}
impl<'data> Glyph<'data> {
pub const fn metrics(self) -> GlyphMetrics {
self.metrics
}
pub const fn raster(self) -> GlyphRaster<'data> {
self.raster
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[non_exhaustive]
pub enum GlyphTableError {
Cardinality {
codepoints: usize,
metrics: usize,
glyphs: usize,
},
}
#[cfg(test)]
mod tests;