1use std::fmt::{Display, Formatter};
4
5use fontdrasil::types::GlyphName;
6use write_fonts::tables::gpos::builders::AnchorBuilder;
7pub use write_fonts::types::GlyphId16;
8
9mod glyph_class;
10mod glyph_map;
11
12pub(crate) use glyph_class::GlyphClass;
13
14pub use glyph_class::GlyphSet;
15pub use glyph_map::GlyphMap;
16
17#[derive(Debug, Clone)]
21pub(crate) enum GlyphOrClass {
22 Glyph(GlyphId16),
24 Class(GlyphClass),
26 Null,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub enum GlyphIdent {
33 Name(GlyphName),
35 Cid(u16),
37}
38
39#[derive(Clone, Debug, Default)]
40pub(crate) struct MarkClass {
41 pub(crate) members: Vec<(GlyphClass, Option<AnchorBuilder>)>,
42}
43
44impl<T: Into<GlyphName>> From<T> for GlyphIdent {
45 fn from(src: T) -> Self {
46 GlyphIdent::Name(src.into())
47 }
48}
49
50impl Display for GlyphIdent {
51 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
52 match self {
53 GlyphIdent::Name(name) => write!(f, "{}", name),
54 GlyphIdent::Cid(cid) => write!(f, "Cid({})", cid),
55 }
56 }
57}
58
59impl GlyphOrClass {
60 pub(crate) fn len(&self) -> usize {
61 match self {
62 GlyphOrClass::Class(cls) => cls.len(),
63 _ => 1,
64 }
65 }
66
67 pub(crate) fn is_class(&self) -> bool {
68 matches!(self, GlyphOrClass::Class(_))
69 }
70
71 pub(crate) fn is_null(&self) -> bool {
72 matches!(self, GlyphOrClass::Null)
73 }
74
75 pub(crate) fn to_class(&self) -> Option<GlyphClass> {
76 match self {
77 GlyphOrClass::Glyph(gid) => Some((*gid).into()),
78 GlyphOrClass::Class(class) => Some(class.clone()),
79 GlyphOrClass::Null => None,
80 }
81 }
82
83 pub(crate) fn to_glyph(&self) -> Option<GlyphId16> {
84 match self {
85 GlyphOrClass::Glyph(gid) => Some(*gid),
86 _ => None,
87 }
88 }
89
90 pub(crate) fn single_glyph(&self) -> Option<GlyphId16> {
92 match self {
93 GlyphOrClass::Glyph(gid) => Some(*gid),
94 GlyphOrClass::Class(class) if class.len() == 1 => class.iter().next(),
95 _ => None,
96 }
97 }
98
99 pub(crate) fn iter(&self) -> impl Iterator<Item = GlyphId16> + '_ {
100 let mut idx = 0;
101 std::iter::from_fn(move || {
102 let next = match &self {
103 GlyphOrClass::Glyph(id) if idx == 0 => Some(*id),
104 GlyphOrClass::Class(cls) => cls.items().get(idx).copied(),
105 _ => None,
106 };
107 idx += 1;
108 next
109 })
110 }
111
112 pub(crate) fn into_iter_for_target(self) -> impl Iterator<Item = GlyphId16> {
117 let mut idx = 0;
118 std::iter::from_fn(move || {
119 let next = match &self {
120 GlyphOrClass::Glyph(id) if idx == 0 => Some(*id),
121 GlyphOrClass::Null if idx == 0 => Some(GlyphId16::NOTDEF),
122 GlyphOrClass::Class(cls) => cls.items().get(idx).copied(),
123 _ => None,
124 };
125 idx += 1;
126 idx %= self.len();
127 next
128 })
129 }
130}