1use crate::engine::filesystem::{File, SourceRef, SourceReference};
3use crate::engine::fontsystem::{Font, FontSystem};
4use crate::engine::EngineTypes;
5use crate::tex::characters::Character;
6use crate::tex::nodes::boxes::{HBoxInfo, TeXBox};
7use crate::tex::nodes::math::MathGroup;
8use crate::tex::nodes::vertical::VNode;
9use crate::tex::nodes::{display_do_indent, BoxTarget, Leaders, NodeTrait, NodeType, WhatsitNode};
10use crate::tex::numerics::Skip;
11use crate::tex::numerics::TeXDimen;
12use crate::tex::tokens::token_lists::TokenList;
13
14#[derive(Clone, Debug)]
16pub enum HNode<ET: EngineTypes> {
17 Penalty(i32),
19 Mark(usize, TokenList<ET::Token>),
21 Whatsit(WhatsitNode<ET>),
23 HSkip(Skip<ET::Dim>),
25 HFil,
27 HFill,
29 HFilneg,
31 Hss,
33 Space,
35 HKern(ET::Dim),
37 Leaders(Leaders<ET>),
39 Box(TeXBox<ET>),
41 VRule {
43 width: Option<ET::Dim>,
45 height: Option<ET::Dim>,
47 depth: Option<ET::Dim>,
49 start: SourceRef<ET>,
51 end: SourceRef<ET>,
53 },
54 Insert(usize, Box<[VNode<ET>]>),
56 VAdjust(Box<[VNode<ET>]>),
58 MathGroup(MathGroup<ET>),
60 Char {
62 char: ET::Char,
64 font: <ET::FontSystem as FontSystem>::Font,
66 },
67 Accent {
69 accent: ET::Char,
71 char: ET::Char,
73 font: <ET::FontSystem as FontSystem>::Font,
75 },
76 Custom(ET::CustomNode),
78}
79
80impl<ET: EngineTypes> NodeTrait<ET> for HNode<ET> {
81 fn display_fmt(&self, indent: usize, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82 match self {
83 HNode::Penalty(p) => {
84 display_do_indent(indent, f)?;
85 write!(f, "<penalty:{}>", p)
86 }
87 HNode::Leaders(l) => l.display_fmt(indent, f),
88 HNode::Box(b) => b.display_fmt(indent, f),
89 HNode::Mark(i, _) => {
90 display_do_indent(indent, f)?;
91 write!(f, "<mark:{}>", i)
92 }
93 HNode::VRule {
94 width,
95 height,
96 depth,
97 ..
98 } => {
99 write!(f, "<vrule")?;
100 if let Some(w) = width {
101 write!(f, " width={}", w)?;
102 }
103 if let Some(h) = height {
104 write!(f, " height={}", h)?;
105 }
106 if let Some(d) = depth {
107 write!(f, " depth={}", d)?;
108 }
109 write!(f, ">")
110 }
111 HNode::Insert(n, ch) => {
112 display_do_indent(indent, f)?;
113 write!(f, "<insert {}>", n)?;
114 for c in ch.iter() {
115 c.display_fmt(indent + 2, f)?;
116 }
117 display_do_indent(indent, f)?;
118 write!(f, "</insert>")
119 }
120 HNode::VAdjust(ls) => {
121 display_do_indent(indent, f)?;
122 f.write_str("<vadjust>")?;
123 for c in ls.iter() {
124 c.display_fmt(indent + 2, f)?;
125 }
126 display_do_indent(indent, f)?;
127 f.write_str("</vadjust>")
128 }
129 HNode::MathGroup(mg) => mg.display_fmt(indent, f),
130 HNode::Char { char, .. } => {
131 char.display_fmt(f);
132 Ok(())
133 }
134 HNode::Accent { accent, char, .. } => {
135 write!(
136 f,
137 "<accent accent=\"{}\" char=\"{}\" />",
138 accent.display(),
139 char.display()
140 )
141 }
142 HNode::Whatsit(w) => {
143 display_do_indent(indent, f)?;
144 write!(f, "{:?}", w)
145 }
146 HNode::HSkip(s) => write!(f, "<hskip:{}>", s),
147 HNode::HFil => write!(f, "<hfil>"),
148 HNode::HFill => write!(f, "<hfill>"),
149 HNode::HFilneg => write!(f, "<hfilneg>"),
150 HNode::Hss => write!(f, "<hss>"),
151 HNode::Space => write!(f, "<space>"),
152 HNode::HKern(d) => write!(f, "<hkern:{}>", d),
153 HNode::Custom(n) => n.display_fmt(indent, f),
154 }
155 }
156 fn height(&self) -> ET::Dim {
157 match self {
158 HNode::Box(b) => b.height(),
159 HNode::VRule { height, .. } => height.unwrap_or_default(),
160 HNode::Char { char, font } => font.get_ht(*char),
161 HNode::Leaders(l) => l.height(),
162 HNode::MathGroup(mg) => mg.height(),
163 HNode::Custom(n) => n.height(),
164 HNode::Accent { char, font, .. } => {
165 font.get_ht(*char) }
167 _ => ET::Dim::default(),
168 }
169 }
170 fn width(&self) -> ET::Dim {
171 match self {
172 HNode::Box(b) => b.width(),
173 HNode::Char { char, font } => font.get_wd(*char),
174 HNode::VRule { width, .. } => width.unwrap_or(ET::Dim::from_sp(26214)),
175 HNode::Leaders(l) => l.width(),
176 HNode::MathGroup(mg) => mg.width(),
177 HNode::Custom(n) => n.width(),
178 HNode::HKern(d) => *d,
179 HNode::HSkip(s) => s.base,
180 HNode::Accent { char, font, .. } => font.get_wd(*char),
181 HNode::Space => ET::Dim::from_sp(65536 * 5), _ => ET::Dim::default(),
183 }
184 }
185 fn depth(&self) -> ET::Dim {
186 match self {
187 HNode::Box(b) => b.depth(),
188 HNode::Char { char, font } => font.get_dp(*char),
189 HNode::Accent { char, font, .. } => font.get_dp(*char),
190 HNode::VRule { depth, .. } => depth.unwrap_or_default(),
191 HNode::Leaders(l) => l.depth(),
192 HNode::MathGroup(mg) => mg.depth(),
193 HNode::Custom(n) => n.depth(),
194 _ => ET::Dim::default(),
195 }
196 }
197 fn nodetype(&self) -> NodeType {
198 match self {
199 HNode::Penalty(_) => NodeType::Penalty,
200 HNode::VRule { .. } => NodeType::Rule,
201 HNode::Box(b) => b.nodetype(),
202 HNode::Char { .. } => NodeType::Char,
203 HNode::HKern(_) => NodeType::Kern,
204 HNode::Insert(..) => NodeType::Insertion,
205 HNode::VAdjust(_) => NodeType::Adjust,
206 HNode::MathGroup { .. } => NodeType::Math,
207 HNode::Mark(_, _) => NodeType::Mark,
208 HNode::Whatsit(_) => NodeType::WhatsIt,
209 HNode::Accent { .. } => NodeType::Char,
210 HNode::Leaders(_) => NodeType::Glue,
211 HNode::HSkip(_)
212 | HNode::Space
213 | HNode::HFil
214 | HNode::HFill
215 | HNode::HFilneg
216 | HNode::Hss => NodeType::Glue,
217 HNode::Custom(n) => n.nodetype(),
218 }
219 }
220 fn opaque(&self) -> bool {
221 match self {
222 HNode::Mark(_, _) => true,
223 HNode::Custom(n) => n.opaque(),
224 _ => false,
225 }
226 }
227
228 fn sourceref(&self) -> Option<(&SourceRef<ET>, &SourceRef<ET>)> {
229 match self {
230 HNode::VRule { start, end, .. } => Some((start, end)),
231 HNode::Box(b) => b.sourceref(),
232 HNode::MathGroup(mg) => mg.sourceref(),
233 _ => None,
234 }
235 }
236}
237
238#[derive(Clone, Debug)]
241pub enum HorizontalNodeListType<ET: EngineTypes> {
242 Paragraph(SourceReference<<ET::File as File>::SourceRefID>),
244 Box(HBoxInfo<ET>, SourceRef<ET>, BoxTarget<ET>),
246 VAlign,
248 HAlignRow(SourceRef<ET>),
250 HAlignCell(SourceRef<ET>, u8),
254}