From f2c506e0dc8cf930b8daa057e1b3a0a748f78e51 Mon Sep 17 00:00:00 2001 From: Andrey Zgarbul Date: Sat, 12 Dec 2020 16:52:22 +0300 Subject: [PATCH] nodelist --- engine/src/node.rs | 10 ++++ engine/src/node/nodelist.rs | 96 +++++++++++++++++++++++++++++++++++ engine/src/xetex_linebreak.rs | 41 +++++++-------- engine/src/xetex_math.rs | 49 ++++-------------- engine/src/xetex_xetex0.rs | 13 ++--- 5 files changed, 138 insertions(+), 71 deletions(-) create mode 100644 engine/src/node/nodelist.rs diff --git a/engine/src/node.rs b/engine/src/node.rs index 60d81d2b33..a3e2a73e8d 100644 --- a/engine/src/node.rs +++ b/engine/src/node.rs @@ -264,6 +264,9 @@ impl List { MEM[self.ptr() + 5].b32.s1 = v; self } + pub(crate) unsafe fn list(&self) -> NodeList { + NodeList::from(&mut MEM[self.ptr() + 5].b32.s1) + } pub(crate) unsafe fn glue_sign(&self) -> GlueSign { GlueSign::from(MEM[self.ptr() + 5].b16.s1) } @@ -562,6 +565,9 @@ impl Discretionary { pub(crate) unsafe fn pre_break(&self) -> i32 { MEM[self.ptr() + 1].b32.s0 } + pub(crate) unsafe fn pre_break_nl<'a>(&'a self) -> NodeList<'a> { + NodeList::from(&mut MEM[self.ptr() + 1].b32.s0) + } pub(crate) unsafe fn set_pre_break(&mut self, v: i32) -> &mut Self { MEM[self.ptr() + 1].b32.s0 = v; self @@ -2442,3 +2448,7 @@ pub(crate) const SYNCTEX_FIELD_SIZE: i32 = 1; pub(crate) trait NodeSize { const SIZE: i32; } + +pub(crate) use self::nodelist::NodeList; + +mod nodelist; diff --git a/engine/src/node/nodelist.rs b/engine/src/node/nodelist.rs new file mode 100644 index 0000000000..8cab5ea19e --- /dev/null +++ b/engine/src/node/nodelist.rs @@ -0,0 +1,96 @@ +use crate::xetex_ini::MEM; +fn next<'a>(p: &'a i32) -> &'a i32 { + unsafe { &MEM[(*p as usize)].b32.s1 } +} + +use crate::xetex_xetexd::{TeXInt, TeXOpt}; +pub struct NodeList<'a>(&'a mut i32); +impl<'a> NodeList<'a> { + pub fn from(p: &'a mut i32) -> Self { + Self(p) + } + pub fn ptr(&self) -> Option { + self.0.opt() + } + pub fn iter(&self) -> Iter<'_> { + Iter::new(self.0) + } + pub fn iter_mut(&mut self) -> IterMut { + IterMut::new(&mut self.0) + } + pub fn tail(&self) -> Option { + self.iter().last() + } + pub fn is_empty(&self) -> bool { + self.ptr().is_none() + } + pub fn len(&self) -> usize { + self.iter().count() + } + pub fn push(&mut self, p: usize) -> usize { + if let Some(tail) = self.iter_mut().last() { + unsafe { MEM[tail].b32.s1 = Some(p).tex_int() } + } else { + *self.0 = Some(p).tex_int() + } + p + } +} + +impl<'a> IntoIterator for &'a NodeList<'a> { + type Item = usize; + type IntoIter = Iter<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + +pub struct Iter<'a>(&'a i32); + +impl<'a> Iter<'a> { + fn new(p: &'a i32) -> Self { + Self(p) + } +} + +impl<'a> std::iter::Iterator for Iter<'a> { + type Item = usize; + fn next(&mut self) -> Option { + if let Some(p) = self.0.opt() { + self.0 = next(self.0); + Some(p) + } else { + None + } + } +} + +impl<'a> IntoIterator for &'a mut NodeList<'a> { + type Item = usize; + type IntoIter = IterMut<'a>; + + fn into_iter(self) -> Self::IntoIter { + self.iter_mut() + } +} + +pub struct IterMut<'a>(&'a i32); + +impl<'a> IterMut<'a> { + fn new(p: &'a mut i32) -> Self { + Self(p) + } +} + +impl<'a> std::iter::Iterator for IterMut<'a> { + type Item = usize; + fn next(&mut self) -> Option { + if let Some(p) = self.0.opt() { + self.0 = next(self.0); + Some(p) + } else { + None + } + } +} diff --git a/engine/src/xetex_linebreak.rs b/engine/src/xetex_linebreak.rs index f7aab64f6d..24d00aff08 100644 --- a/engine/src/xetex_linebreak.rs +++ b/engine/src/xetex_linebreak.rs @@ -2327,10 +2327,9 @@ unsafe fn hyphenate() { /*952: */ j = (reconstitute(j, hn, bchar, TOO_BIG_CHAR) as i32 + 1) as i16; /*:944*/ *LLIST_link(major_tail) = *LLIST_link(HOLD_HEAD); - while let Some(next) = llist_link(major_tail) { - major_tail = next; - r_count += 1; - } + let nl = NodeList::from(LLIST_link(major_tail)); + r_count += nl.len() as i32; + major_tail = nl.tail().unwrap_or(major_tail); } } if r_count > 127 { @@ -2386,30 +2385,31 @@ unsafe fn reconstitute(mut j: i16, n: i16, mut bchar: i32, mut hchar: i32) -> i1 let mut k: font_index = 0; hyphen_passed = 0; - let mut t = HOLD_HEAD as i32; + let mut t = HOLD_HEAD; let mut w = Scaled::ZERO; *LLIST_link(HOLD_HEAD) = None.tex_int(); cur_l = hu[j as usize]; - cur_q = t; + cur_q = t as i32; if j == 0 { ligature_present = init_lig; - let mut popt = init_list.opt(); if ligature_present { lft_hit = init_lft } - while let Some(p) = popt { - *LLIST_link(t as usize) = Some(get_avail()).tex_int(); - t = *LLIST_link(t as usize); - MEM[t as usize].b16.s1 = hf as u16; - MEM[t as usize].b16.s0 = MEM[p].b16.s0; - popt = llist_link(p) + for p in &NodeList::from(&mut init_list) { + let a = get_avail(); + MEM[a].b16.s1 = hf as u16; + MEM[a].b16.s0 = MEM[p].b16.s0; + *LLIST_link(t) = Some(a).tex_int(); + t = a; } } else if cur_l < TOO_BIG_CHAR { - *LLIST_link(t as usize) = Some(get_avail()).tex_int(); - t = *LLIST_link(t as usize); - MEM[t as usize].b16.s1 = hf as u16; - MEM[t as usize].b16.s0 = cur_l as u16 + let a = get_avail(); + MEM[a].b16.s1 = hf as u16; + MEM[a].b16.s0 = cur_l as u16; + *LLIST_link(t) = Some(a).tex_int(); + t = a; } + let mut t = t as i32; lig_stack = None; cur_r = if (j as i32) < n as i32 { hu[(j + 1) as usize] @@ -2659,11 +2659,8 @@ unsafe fn total_pw(q: &Active, p: Option) -> Scaled { match p.map(Node::from) { Some(Node::Text(TxtNode::Disc(d))) if d.pre_break().opt().is_some() => { - if let Some(mut m) = d.pre_break().opt() { - while let Some(next) = llist_link(m) { - m = next; - } - r = Some(m); + if let Some(tail) = d.pre_break_nl().tail() { + r = Some(tail); } } _ => r = find_protchar_right(lopt, r), diff --git a/engine/src/xetex_math.rs b/engine/src/xetex_math.rs index ba491e2e65..a56f6fd83a 100644 --- a/engine/src/xetex_math.rs +++ b/engine/src/xetex_math.rs @@ -157,7 +157,7 @@ pub(crate) unsafe fn init_math(input: &mut input_state_t) { let p = new_math(Scaled::ZERO, MathType::Eq(BE::Begin, MathMode::Left)); *LLIST_link(TEMP_HEAD) = Some(p.ptr()).tex_int(); just_copy( - jb.list_ptr().opt(), + jb.list(), p.ptr(), Some(new_math(Scaled::ZERO, MathType::Eq(BE::End, MathMode::Left)).ptr()) .tex_int(), @@ -328,8 +328,7 @@ pub(crate) unsafe fn init_math(input: &mut input_state_t) { popt = llist_link(p); } if get_int_par(IntPar::texxet) > 0 { - while let Some(l) = LR_ptr.opt() { - let tmp_ptr = l; + while let Some(tmp_ptr) = LR_ptr.opt() { LR_ptr = *LLIST_link(tmp_ptr); *LLIST_link(tmp_ptr) = avail.tex_int(); avail = Some(tmp_ptr); @@ -1026,13 +1025,9 @@ pub(crate) unsafe fn after_math(input: &mut input_state_t) { cur_style = (MathStyle::Text, 0); mlist_penalties = !cur_list.mode.0; mlist_to_hlist(); - *LLIST_link(cur_list.tail) = *LLIST_link(TEMP_HEAD); - while let Some(next) = LLIST_link(cur_list.tail).opt() { - cur_list.tail = next; - } let m = new_math(get_dimen_par(DimenPar::math_surround), MathType::After); - *LLIST_link(cur_list.tail) = Some(m.ptr()).tex_int(); - cur_list.tail = m.ptr(); + *LLIST_link(cur_list.tail) = *LLIST_link(TEMP_HEAD); + cur_list.tail = NodeList::from(LLIST_link(cur_list.tail)).push(m.ptr()); cur_list.aux.b32.s0 = 1000; unsave(input); } else { @@ -2234,14 +2229,7 @@ unsafe fn make_ord(q: &mut Ord) { } unsafe fn attach_hkern_to_new_hlist(q: &mut BaseMath, delta: Scaled) -> usize { let z = new_kern(delta); - if let Some(mut y) = MEM[q.ptr() + 1].b32.s1.opt() { - while let Some(next) = llist_link(y) { - y = next; - } - *LLIST_link(y) = Some(z.ptr()).tex_int(); - } else { - MEM[q.ptr() + 1].b32.s1 = Some(z.ptr()).tex_int(); - } + NodeList::from(&mut MEM[q.ptr() + 1].b32.s1).push(z.ptr()); MEM[q.ptr() + 1].b32.s1 as usize } unsafe fn make_scripts(q: &mut BaseMath, delta: Scaled) { @@ -2511,14 +2499,7 @@ unsafe fn make_scripts(q: &mut BaseMath, delta: Scaled) { x.set_shift_amount(shift_down); } } - if let Some(mut p) = MEM[q.ptr() + 1].b32.s1.opt() { - while let Some(next) = llist_link(p) { - p = next; - } - *LLIST_link(p) = Some(x.ptr()).tex_int(); - } else { - MEM[q.ptr() + 1].b32.s1 = Some(x.ptr()).tex_int(); - } + NodeList::from(&mut MEM[q.ptr() + 1].b32.s1).push(x.ptr()); } unsafe fn make_left_right( q: &mut LeftRight, @@ -3201,18 +3182,13 @@ unsafe fn stack_glyph_into_box(b: &mut List, f: internal_font_number, g: i32) { p.set_font(f as u16).set_glyph(g as u16); p.set_metrics(true); if b.is_horizontal() { - if let Some(mut q) = b.list_ptr().opt() { - while let Some(next) = llist_link(q) { - q = next; - } - *LLIST_link(q) = Some(p.ptr()).tex_int(); + if !b.list().is_empty() { let h = b.height(); b.set_height(h.max(p.height())); let d = b.depth(); b.set_depth(d.max(p.depth())); - } else { - b.set_list_ptr(Some(p.ptr()).tex_int()); } + b.list().push(p.ptr()); } else { *LLIST_link(p.ptr()) = b.list_ptr(); b.set_list_ptr(Some(p.ptr()).tex_int()); @@ -3226,14 +3202,7 @@ unsafe fn stack_glue_into_box(b: &mut List, min: Scaled, max: Scaled) { q.set_size(min).set_stretch(max - min); let p = new_glue(&q); if b.is_horizontal() { - if let Some(mut q) = b.list_ptr().opt() { - while let Some(next) = llist_link(q) { - q = next; - } - *LLIST_link(q) = Some(p.ptr()).tex_int(); - } else { - b.set_list_ptr(Some(p.ptr()).tex_int()); - } + b.list().push(p.ptr()); } else { *LLIST_link(p.ptr()) = b.list_ptr(); b.set_list_ptr(Some(p.ptr()).tex_int()); diff --git a/engine/src/xetex_xetex0.rs b/engine/src/xetex_xetex0.rs index 721873732e..0c9e0944b0 100644 --- a/engine/src/xetex_xetex0.rs +++ b/engine/src/xetex_xetex0.rs @@ -12380,9 +12380,8 @@ pub(crate) unsafe fn append_discretionary(input: &mut input_state_t, chr: i32) { pub(crate) unsafe fn build_discretionary(input: &mut input_state_t) { unsave(input); let mut q = cur_list.head; - let mut popt = llist_link(q); let mut n = 0; - while let Some(p) = popt { + for p in &NodeList::from(LLIST_link(q)) { match CharOrText::from(p) { CharOrText::Char(_) => {} CharOrText::Text(n) => match n { @@ -12407,7 +12406,6 @@ pub(crate) unsafe fn build_discretionary(input: &mut input_state_t) { }, } q = p; - popt = llist_link(q); n += 1; } let p = MEM[cur_list.head].b32.s1; @@ -12627,8 +12625,8 @@ pub(crate) unsafe fn push_math(c: GroupCode) { cur_list.aux.b32.s1 = None.tex_int(); new_save_level(c); } -pub(crate) unsafe fn just_copy(mut popt: Option, mut h: usize, t: i32) { - while let Some(p) = popt { +pub(crate) unsafe fn just_copy(nl: NodeList, mut h: usize, t: i32) { + for p in &nl { let mut r = 0; let mut words = 1; @@ -12728,9 +12726,6 @@ pub(crate) unsafe fn just_copy(mut popt: Option, mut h: usize, t: i32) { *LLIST_link(h) = Some(r).tex_int(); h = r; } - - // not_found: - popt = llist_link(p); } *LLIST_link(h) = t; } @@ -12743,7 +12738,7 @@ pub(crate) unsafe fn just_reverse(p: usize) { *LLIST_link(p) = None.tex_int(); flush_node_list(Some(th)); } else { - just_copy(llist_link(p), TEMP_HEAD, None.tex_int()); + just_copy(NodeList::from(LLIST_link(p)), TEMP_HEAD, None.tex_int()); q = llist_link(TEMP_HEAD); } let mut t = Edge(new_edge(cur_dir, Scaled::ZERO));