1use alloc::vec::Vec;
2
3use mathtex_ir::{
4 Fragment, FragmentMetadata, Glue, GlyphRun, Kern, LayoutBox, LayoutList, LayoutNode,
5 LayoutNodeKind, ListKind, NodeId, Point, Rect, Rule, Style, Surface,
6};
7
8#[derive(Clone, Debug)]
10pub struct IrEmitter {
11 fragment: Fragment,
12 next_node: u32,
13}
14
15impl IrEmitter {
16 #[must_use]
18 pub fn new(metadata: FragmentMetadata) -> Self {
19 Self {
20 fragment: Fragment {
21 metadata,
22 ..Fragment::default()
23 },
24 next_node: 0,
25 }
26 }
27
28 pub fn set_surface(&mut self, surface: Surface) {
30 self.fragment.surface = surface;
31 }
32
33 pub fn emit_box(&mut self, node: EmitNode, layout_box: LayoutBox) -> NodeId {
35 self.emit(node, LayoutNodeKind::Box(layout_box))
36 }
37
38 pub fn emit_list(&mut self, node: EmitNode, kind: ListKind, children: Vec<NodeId>) -> NodeId {
40 self.emit(node, LayoutNodeKind::List(LayoutList { kind, children }))
41 }
42
43 pub fn emit_glyph_run(&mut self, node: EmitNode, glyph_run: GlyphRun) -> NodeId {
45 self.emit(node, LayoutNodeKind::GlyphRun(glyph_run))
46 }
47
48 pub fn emit_rule(&mut self, node: EmitNode, rule: Rule) -> NodeId {
50 self.emit(node, LayoutNodeKind::Rule(rule))
51 }
52
53 pub fn emit_glue(&mut self, node: EmitNode, glue: Glue) -> NodeId {
55 self.emit(node, LayoutNodeKind::Glue(glue))
56 }
57
58 pub fn emit_kern(&mut self, node: EmitNode, kern: Kern) -> NodeId {
60 self.emit(node, LayoutNodeKind::Kern(kern))
61 }
62
63 #[must_use]
65 pub fn finish(self) -> Fragment {
66 self.fragment
67 }
68
69 fn emit(&mut self, node: EmitNode, kind: LayoutNodeKind) -> NodeId {
70 let id = NodeId(self.next_node);
71 self.next_node += 1;
72
73 self.fragment.nodes.push(LayoutNode {
74 id,
75 origin: node.origin,
76 bounds: node.bounds,
77 primary_source: None,
78 style: node.style,
79 kind,
80 });
81
82 id
83 }
84}
85
86#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
88pub struct EmitNode {
89 pub origin: Point,
91 pub bounds: Rect,
93 pub style: Style,
95}
96
97impl EmitNode {
98 #[must_use]
100 pub fn with_style(mut self, style: Style) -> Self {
101 self.style = style;
102 self
103 }
104}