1use crate::Bitmap;
2use bit_vec::BitVec;
3use std::{
4 borrow::Borrow,
5 cmp::Ordering,
6 collections::{BTreeSet, HashMap},
7 fmt::{self, Debug, Display, Formatter}
8};
9
10#[derive(Clone, Copy, Debug, Eq, PartialEq)]
11pub struct BoundingBox {
12 pub width: u32,
13 pub height: u32,
14 pub offset_x: i32,
15 pub offset_y: i32
16}
17
18#[derive(Clone, Copy, Debug, Eq, PartialEq)]
19pub struct Size {
20 pub pt: u32,
21 pub xres: u32,
22 pub yres: u32
23}
24
25#[derive(Clone)]
26pub enum Value {
27 Integer(i32),
28 String(String)
29}
30
31impl Debug for Value {
32 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
33 match self {
34 Self::Integer(i) => write!(f, "{i}"),
35 Self::String(str) => write!(f, "{str:?}")
36 }
37 }
38}
39
40impl Display for Value {
41 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
42 match self {
43 Self::Integer(i) => write!(f, "{i}"),
44 Self::String(str) => write!(f, "{str}")
45 }
46 }
47}
48
49#[derive(Clone, Debug)]
50pub struct Glyph {
51 pub(crate) name: String,
52 pub(crate) encoding: u32,
53 pub(crate) swidth: Option<(f64, f64)>,
54 pub(crate) dwidth: Option<(f64, f64)>,
55 pub(crate) bbox: BoundingBox,
56 pub(crate) bitmap: Vec<BitVec>
57}
58
59impl Glyph {
60 pub fn name(&self) -> &str {
62 &self.name
63 }
64
65 pub fn encoding(&self) -> u32 {
67 self.encoding
68 }
69
70 pub fn swidth(&self) -> Option<(f64, f64)> {
72 self.swidth
73 }
74
75 pub fn dwidth(&self) -> Option<(f64, f64)> {
77 self.dwidth
78 }
79
80 pub fn bounding_box(&self) -> BoundingBox {
82 self.bbox
83 }
84
85 pub fn bitmap(&self) -> Bitmap<'_> {
87 Bitmap {
88 data: &self.bitmap,
89 bbox: self.bbox
90 }
91 }
92}
93
94pub(crate) struct GlyphWrapper(Glyph);
96
97impl From<Glyph> for GlyphWrapper {
98 fn from(glyph: Glyph) -> Self {
99 Self(glyph)
100 }
101}
102
103impl Borrow<u32> for GlyphWrapper {
104 fn borrow(&self) -> &u32 {
105 &self.0.encoding
106 }
107}
108
109impl PartialEq for GlyphWrapper {
110 fn eq(&self, other: &Self) -> bool {
111 self.0.encoding == other.0.encoding
112 }
113}
114
115impl Eq for GlyphWrapper {}
116
117impl PartialEq<u32> for GlyphWrapper {
118 fn eq(&self, other: &u32) -> bool {
119 self.0.encoding == *other
120 }
121}
122
123impl PartialOrd for GlyphWrapper {
124 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
125 Some(self.cmp(other))
126 }
127}
128
129impl Ord for GlyphWrapper {
130 fn cmp(&self, other: &Self) -> Ordering {
131 self.0.encoding.cmp(&other.0.encoding)
132 }
133}
134
135pub trait GlyphIdx {
137 fn encoding(self) -> u32;
138}
139
140impl GlyphIdx for u32 {
141 fn encoding(self) -> u32 {
142 self
143 }
144}
145
146impl GlyphIdx for char {
147 fn encoding(self) -> u32 {
148 self as _
149 }
150}
151
152pub struct Font {
153 pub(crate) version: Option<i32>,
154 pub(crate) name: String,
155 pub(crate) bbox: BoundingBox,
156 pub(crate) size: Size,
157 pub(crate) properties: HashMap<String, Value>,
158
159 pub(crate) glyphs: BTreeSet<GlyphWrapper>
160}
161
162impl Font {
163 pub fn version(&self) -> Option<i32> {
165 self.version
166 }
167
168 pub fn name(&self) -> &str {
170 &self.name
171 }
172
173 pub fn bounding_box(&self) -> BoundingBox {
175 self.bbox
176 }
177
178 pub fn size(&self) -> Size {
180 self.size
181 }
182
183 pub fn property(&self, key: &str) -> Option<&Value> {
185 self.properties.get(key)
186 }
187
188 pub fn glyphs(&self) -> impl IntoIterator<Item = &Glyph> {
190 self.glyphs.iter().map(|gw| &gw.0)
191 }
192
193 pub fn glyph<I: GlyphIdx>(&self, ch: I) -> Option<&Glyph> {
195 self.glyphs.get(&ch.encoding()).map(|gw| &gw.0)
196 }
197}