A simple CPU rendered GUI IDE experience.
Diffstat (limited to 'src/text/mapper.rs')
-rw-r--r--src/text/mapper.rs224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/text/mapper.rs b/src/text/mapper.rs
new file mode 100644
index 0000000..2d29286
--- /dev/null
+++ b/src/text/mapper.rs
@@ -0,0 +1,224 @@
+use std::ops::Deref;
+
+use dsb::Cell;
+
+#[derive(Copy, Clone)]
+/// this struct is made to mimic a simple 2d vec
+/// over the entire text area
+/// without requiring that entire allocation, and the subsequent copy into the output area.
+/// ```text
+/// text above view offset (global text area)²
+/// ╶╶╶╶╶├╶╶╶╶╶╶╶╶╶╶╶╶╶╶╶ view offset
+/// ┏━━━━┿━━━━━━━━━━━━┓← into_ and into_s³
+/// ┃ ╏← offset y ┃
+/// ┃ ┏╺╺┿╺╺╺╺╺╺╺╺╺╺╺╺┃
+/// ┃ ╏ v╎iewable area┃
+/// ┃ ╏ g╎oes here¹ ┃
+/// ┃ ╏ ╎ ┃
+/// ┃ ╏ ╎ ┃
+/// ┃ ╏ ╎ ┃
+/// ┗━━━━━━━━━━━━━━━━━┛
+/// ═ ══╎
+/// ↑ ↑ ╎
+/// │ ╰ horiz scroll
+/// ╰ horizontal offset
+/// ```
+#[allow(dead_code)] // ?
+pub struct Mapper {
+ /// c, r
+ pub into_s: (usize, usize),
+ pub ox: usize,
+ pub oy: usize,
+
+ pub from_c: usize,
+ pub from_r: usize,
+ pub vo: usize,
+ pub ho: usize,
+}
+pub struct Output<'a> {
+ pub into: &'a mut [Cell],
+ pub output: Mapper,
+}
+impl Deref for Output<'_> {
+ type Target = Mapper;
+
+ fn deref(&self) -> &Self::Target {
+ &self.output
+ }
+}
+
+impl Mapper {
+ /// translate an index into the global text buffer² into an (x, y), of the global text buffer
+ // fn to_point(&self, rope: &Rope, index: usize) -> (usize, usize) {
+ // ((index % self.from_c), (index / self.from_c))
+ // }
+
+ // fn from_point(&self, (x, y): (usize, usize)) -> usize {
+ // y * self.from_c + x
+ // }
+
+ /// translate an (x, y) into the global text buffer²
+ /// to a point over the viewable area¹ (offset by the given offsets) of the global text buffer,
+ /// returning none if the given point is outside of the viewable area
+ fn translate(&self, (x, y): (usize, usize)) -> Option<(usize, usize)> {
+ let (x, y) = (
+ x.checked_sub(self.ho)? + self.ox,
+ y.checked_sub(self.vo)? + self.oy,
+ );
+ ((x < self.into_s.0) & (y < self.into_s.1)
+ & (x >= self.ox) // this is kind of forced already but its ok
+ & (y >= self.oy)) // "
+ .then_some((x, y))
+ }
+ /// converts an (x, y) of the viewable area¹ to an index into [`Output::into`]
+ fn from_point_global(&self, (x, y): (usize, usize)) -> usize {
+ y * self.into_s.0 + x
+ }
+ // /// translate an index into a (x, y), of the output³
+ // fn to_point_global(&self, index: usize) -> (usize, usize) {
+ // (index % self.into_s.0, index / self.into_s.0)
+ // }
+ // fn etalsnart_(
+ // &self,
+ // (x, y): (usize, usize),
+ // ) -> Option<(usize, usize)> {
+ // Some((
+ // x.checked_sub(self.ox)? + self.ho, //
+ // y.checked_sub(self.oy)? + self.vo,
+ // ))
+ // }
+}
+impl<'a> Output<'a> {
+ // /// get an index thats relative over the viewable area¹ of the global text area
+ // fn get_at_compensated(
+ // &mut self,
+ // (x, y): (usize, usize),
+ // ) -> Option<&mut Cell> {
+ // Some(&mut self.into[(y + self.oy) * self.into_s.0 + (x + self.ox)])
+ // }
+ pub fn get_range(
+ &mut self,
+ a: (usize, usize),
+ b: (usize, usize),
+ ) -> impl Iterator<Item = &mut Cell> {
+ self.get_range_enumerated(a, b).map(|x| x.0)
+ }
+ // needs rope to work properly (see [xy])
+ // pub fn get_char_range(
+ // &mut self,
+ // a: usize,
+ // b: usize,
+ // ) -> impl Iterator<Item = &mut Cell> {
+ // self.get_range_enumerated(self.to_point(a), self.to_point(b))
+ // .map(|x| x.0)
+ // }
+ //// coords reference global text buffer²
+ pub gen fn get_range_enumerated(
+ &mut self,
+ (x1, y1): (usize, usize),
+ (x2, y2): (usize, usize),
+ // impl Iterator<Item = (&mut Cell, (usize, usize))> {
+ ) -> (&mut Cell, (usize, usize)) {
+ let m = self.output;
+ let c = self.into.as_mut_ptr();
+ // x1 = x1.checked_sub(m.ho).unwrap_or(m.ho);
+ // x2 = x2.checked_sub(m.ho).unwrap_or(m.ho);
+ // y1 = y1.checked_sub(m.vo).unwrap_or(m.vo);
+ // y2 = y2.checked_sub(m.vo).unwrap_or(m.vo);
+ // let a = m.from_point((x1, y1));
+ // let b = m.from_point((x2, y2));
+ // let a = m.from_point_global(m.translate(m.to_point(a)).unwrap());
+ // let b = m.from_point_global(m.translate(m.to_point(b)).unwrap());
+ // dbg!(a, b);
+ let mut p = (x1, y1);
+ while p != (x2, y2) {
+ if let Some(x) = m.translate(p) {
+ // SAFETY: trust me very disjoint
+ yield (unsafe { &mut *c.add(m.from_point_global(x)) }, p)
+ }
+ p.0 += 1;
+ if p.0.checked_sub(m.ho) == Some(m.from_c) {
+ p.0 = 0;
+ p.1 += 1;
+ if p.1 > y2 {
+ break;
+ }
+ }
+ if let Some(x) = p.0.checked_sub(m.ho)
+ && x > m.from_c
+ {
+ break;
+ }
+ }
+
+ // (a..=b)
+ // .filter_map(move |x| {
+ // // println!("{:?} {x}", m.translate(m.to_point(x)));
+ // let (x, y) = m.to_point(x);
+ // m.translate((x, y))
+ // // m.to_point_global(x)
+ // })
+ // .inspect(move |x| {
+ // assert!(x.0 < self.into_s.0 && x.1 < self.into_s.1);
+ // assert!(m.from_point_global(*x) < self.into.len());
+ // })
+ // .map(move |x| {
+ // // SAFETY: :)
+ // (unsafe { &mut *p.add(m.from_point_global(x)) }, x)
+ // })
+ // self.get_char_range_enumerated(
+ // self.output.from_point(a),
+ // self.output.from_point(b),
+ // )
+ }
+
+ // oughtnt really be multiline
+ pub fn get_simple(
+ &mut self,
+ s: (usize, usize),
+ e: (usize, usize),
+ ) -> Option<&mut [Cell]> {
+ let s = self.from_point_global(self.translate(s)?);
+ let e = self.from_point_global(self.translate(e)?);
+ self.into.get_mut(s..e)
+ }
+ // impl<'a> IndexMut<(usize, usize)> for Output<'a> {
+ // fn index_mut(&mut self, p: (usize, usize)) -> &mut Self::Output {
+ // let x = self.from_point_global(self.translate(p).unwrap());
+ // &mut self.into[x]
+ // }
+ // }
+ pub fn get(&mut self, p: (usize, usize)) -> Option<&mut Cell> {
+ let n = self.from_point_global(self.translate(p)?);
+ self.into.get_mut(n)
+ }
+}
+
+// impl<'a> Index<usize> for Output<'a> {
+// type Output = Cell;
+
+// fn index(&self, index: usize) -> &Self::Output {
+// &self[self.translate(index).unwrap()]
+// }
+// }
+
+// impl<'a> IndexMut<usize> for Output<'a> {
+// fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+// let x = self.translate(index).unwrap();
+// &mut self[x]
+// }
+// }
+
+// impl<'a> Index<(usize, usize)> for Output<'a> {
+// type Output = Cell;
+
+// fn index(&self, p: (usize, usize)) -> &Self::Output {
+// &self.into[self.from_point_global(self.translate(p).unwrap())]
+// }
+// }
+// impl<'a> IndexMut<(usize, usize)> for Output<'a> {
+// fn index_mut(&mut self, p: (usize, usize)) -> &mut Self::Output {
+// let x = self.from_point_global(self.translate(p).unwrap());
+// &mut self.into[x]
+// }
+// }