use crate::Bitmap;
use bit_vec::BitVec;
use std::{
borrow::Borrow,
cmp::Ordering,
collections::{BTreeSet, HashMap},
fmt::{self, Debug, Display, Formatter}
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct BoundingBox {
pub width: u32,
pub height: u32,
pub offset_x: i32,
pub offset_y: i32
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Size {
pub pt: u32,
pub xres: u32,
pub yres: u32
}
#[derive(Clone)]
pub enum Value {
Integer(i32),
String(String)
}
impl Debug for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Integer(i) => write!(f, "{i}"),
Self::String(str) => write!(f, "{str:?}")
}
}
}
impl Display for Value {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Integer(i) => write!(f, "{i}"),
Self::String(str) => write!(f, "{str}")
}
}
}
#[derive(Clone, Debug)]
pub struct Glyph {
pub(crate) name: String,
pub(crate) encoding: u32,
pub(crate) swidth: Option<(f64, f64)>,
pub(crate) dwidth: Option<(f64, f64)>,
pub(crate) bbox: BoundingBox,
pub(crate) bitmap: Vec<BitVec>
}
impl Glyph {
pub fn name(&self) -> &str {
&self.name
}
pub fn encoding(&self) -> u32 {
self.encoding
}
pub fn swidth(&self) -> Option<(f64, f64)> {
self.swidth
}
pub fn dwidth(&self) -> Option<(f64, f64)> {
self.dwidth
}
pub fn bounding_box(&self) -> BoundingBox {
self.bbox
}
pub fn bitmap(&self) -> Bitmap<'_> {
Bitmap {
data: &self.bitmap,
bbox: self.bbox
}
}
}
pub(crate) struct GlyphWrapper(Glyph);
impl From<Glyph> for GlyphWrapper {
fn from(glyph: Glyph) -> Self {
Self(glyph)
}
}
impl Borrow<u32> for GlyphWrapper {
fn borrow(&self) -> &u32 {
&self.0.encoding
}
}
impl PartialEq for GlyphWrapper {
fn eq(&self, other: &Self) -> bool {
self.0.encoding == other.0.encoding
}
}
impl Eq for GlyphWrapper {}
impl PartialEq<u32> for GlyphWrapper {
fn eq(&self, other: &u32) -> bool {
self.0.encoding == *other
}
}
impl PartialOrd for GlyphWrapper {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for GlyphWrapper {
fn cmp(&self, other: &Self) -> Ordering {
self.0.encoding.cmp(&other.0.encoding)
}
}
pub trait GlyphIdx {
fn encoding(self) -> u32;
}
impl GlyphIdx for u32 {
fn encoding(self) -> u32 {
self
}
}
impl GlyphIdx for char {
fn encoding(self) -> u32 {
self as _
}
}
pub struct Font {
pub(crate) version: Option<i32>,
pub(crate) name: String,
pub(crate) bbox: BoundingBox,
pub(crate) size: Size,
pub(crate) properties: HashMap<String, Value>,
pub(crate) glyphs: BTreeSet<GlyphWrapper>
}
impl Font {
pub fn version(&self) -> Option<i32> {
self.version
}
pub fn name(&self) -> &str {
&self.name
}
pub fn bounding_box(&self) -> BoundingBox {
self.bbox
}
pub fn size(&self) -> Size {
self.size
}
pub fn property(&self, key: &str) -> Option<&Value> {
self.properties.get(key)
}
pub fn glyphs(&self) -> impl IntoIterator<Item = &Glyph> {
self.glyphs.iter().map(|gw| &gw.0)
}
pub fn glyph<I: GlyphIdx>(&self, ch: I) -> Option<&Glyph> {
self.glyphs.get(&ch.encoding()).map(|gw| &gw.0)
}
}