1use std::{fmt, sync::Arc};
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
10pub struct FontId(pub u64);
11
12#[derive(Clone)]
16pub struct FontBytes(Arc<dyn AsRef<[u8]> + Send + Sync>);
17
18impl FontBytes {
19 #[must_use]
21 pub fn from_shared(source: Arc<dyn AsRef<[u8]> + Send + Sync>) -> Self {
22 Self(source)
23 }
24}
25impl std::ops::Deref for FontBytes {
26 type Target = [u8];
27 fn deref(&self) -> &[u8] {
28 (*self.0).as_ref()
29 }
30}
31impl AsRef<[u8]> for FontBytes {
32 fn as_ref(&self) -> &[u8] {
33 self
34 }
35}
36impl PartialEq for FontBytes {
37 fn eq(&self, other: &Self) -> bool {
38 Arc::ptr_eq(&self.0, &other.0) || **self == **other
39 }
40}
41impl Eq for FontBytes {}
42impl From<Arc<[u8]>> for FontBytes {
43 fn from(bytes: Arc<[u8]>) -> Self {
44 Self(Arc::new(bytes))
45 }
46}
47impl From<Vec<u8>> for FontBytes {
48 fn from(bytes: Vec<u8>) -> Self {
49 Self(Arc::new(bytes))
50 }
51}
52impl From<&'static [u8]> for FontBytes {
53 fn from(bytes: &'static [u8]) -> Self {
54 Self(Arc::new(bytes))
55 }
56}
57impl<const N: usize> From<[u8; N]> for FontBytes {
58 fn from(bytes: [u8; N]) -> Self {
59 Self(Arc::new(bytes))
60 }
61}
62
63#[derive(Clone, PartialEq, Eq)]
67pub struct FontHandle {
68 id: FontId,
69 bytes: FontBytes,
70 face_index: u32,
71}
72impl FontHandle {
73 #[must_use]
74 pub fn new(id: FontId, bytes: impl Into<FontBytes>) -> Self {
75 Self::with_face_index(id, bytes, 0)
76 }
77 #[must_use]
80 pub fn with_face_index(id: FontId, bytes: impl Into<FontBytes>, face_index: u32) -> Self {
81 Self {
82 id,
83 bytes: bytes.into(),
84 face_index,
85 }
86 }
87 #[must_use]
88 pub const fn id(&self) -> FontId {
89 self.id
90 }
91 #[must_use]
92 pub fn bytes(&self) -> &FontBytes {
93 &self.bytes
94 }
95 #[must_use]
96 pub const fn face_index(&self) -> u32 {
97 self.face_index
98 }
99}
100impl fmt::Debug for FontHandle {
101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 f.debug_struct("FontHandle")
103 .field("id", &self.id)
104 .field("face_index", &self.face_index)
105 .finish_non_exhaustive()
106 }
107}