From: Ben Pfaff Date: Tue, 2 Dec 2025 02:21:25 +0000 (-0800) Subject: distinguish cells from plane locations X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e9ce0f36df92cfd830bc08d31f5fe43a00b76848;p=pspp distinguish cells from plane locations --- diff --git a/rust/pspp/src/output/drivers/csv.rs b/rust/pspp/src/output/drivers/csv.rs index d0963e37ff..f756b36b2b 100644 --- a/rust/pspp/src/output/drivers/csv.rs +++ b/rust/pspp/src/output/drivers/csv.rs @@ -31,7 +31,11 @@ use crate::{ data::{ByteString, Case, Datum, WithEncoding}, dictionary::Dictionary, format::{DisplayPlain, Type}, - output::{Item, drivers::Driver, pivot::Coord2}, + output::{ + Item, + drivers::Driver, + pivot::{ Index2}, + }, util::ToSmallString as _, variable::Variable, }; @@ -332,7 +336,7 @@ impl CsvDriver { write!(&mut self.file, "{}", self.options.delimiter)?; } - let coord = Coord2::new(x, y); + let coord = Index2::new(x, y); let content = table.get(coord); if content.is_top_left() { let display = content.inner().value.display(pivot_table); diff --git a/rust/pspp/src/output/drivers/html.rs b/rust/pspp/src/output/drivers/html.rs index a4c797a8cc..4ea1a8e638 100644 --- a/rust/pspp/src/output/drivers/html.rs +++ b/rust/pspp/src/output/drivers/html.rs @@ -27,10 +27,9 @@ use serde::{Deserialize, Serialize}; use smallstr::SmallString; use crate::output::{ - Details, Item, - drivers::Driver, - pivot::{Axis2, BorderStyle, Color, Coord2, HorzAlign, PivotTable, Rect2, Stroke, VertAlign}, - table::{DrawCell, Table}, + drivers::Driver, pivot::{ + Axis2, BorderStyle, Color, HorzAlign, Index2, IndexRect2, PivotTable, Stroke, VertAlign + }, table::{DrawCell, Table}, Details, Item }; #[derive(Clone, Debug, Deserialize, Serialize)] @@ -86,10 +85,10 @@ where writeln!(&mut self.writer, ">")?; if let Some(title) = output.title { - let cell = title.get(Coord2::new(0, 0)); + let cell = title.get(Index2::new(0, 0)); self.put_cell( DrawCell::new(cell.inner(), &title), - Rect2::new(0..1, 0..1), + IndexRect2::new(0..1, 0..1), "caption", None, )?; @@ -101,7 +100,7 @@ where writeln!(&mut self.writer, "")?; self.put_cell( DrawCell::new(cell.inner(), &layers), - Rect2::new(0..output.body.n[Axis2::X], 0..1), + IndexRect2::new(0..output.body.n[Axis2::X], 0..1), "td", None, )?; @@ -114,7 +113,7 @@ where for y in 0..output.body.n.y() { writeln!(&mut self.writer, "")?; for x in output.body.iter_x(y) { - let cell = output.body.get(Coord2::new(x, y)); + let cell = output.body.get(Index2::new(x, y)); if cell.is_top_left() { let is_header = x < output.body.h[Axis2::X] || y < output.body.h[Axis2::Y]; let tag = if is_header { "th" } else { "td" }; @@ -135,8 +134,8 @@ where writeln!(&mut self.writer, "")?; if let Some(caption) = output.caption { self.put_cell( - DrawCell::new(caption.get(Coord2::new(0, 0)).inner(), &caption), - Rect2::new(0..output.body.n[Axis2::X], 0..1), + DrawCell::new(caption.get(Index2::new(0, 0)).inner(), &caption), + IndexRect2::new(0..output.body.n[Axis2::X], 0..1), "td", None, )?; @@ -148,7 +147,7 @@ where writeln!(&mut self.writer, "")?; self.put_cell( DrawCell::new(cell.inner(), &footnotes), - Rect2::new(0..output.body.n[Axis2::X], 0..1), + IndexRect2::new(0..output.body.n[Axis2::X], 0..1), "td", None, )?; @@ -164,7 +163,7 @@ where fn put_cell( &mut self, cell: DrawCell<'_, '_>, - rect: Rect2, + rect: IndexRect2, tag: &str, table: Option<&Table>, ) -> std::io::Result<()> { @@ -237,7 +236,7 @@ where &mut style, table.get_rule( Axis2::X, - Coord2::new(rect[Axis2::X].end, rect[Axis2::Y].start), + Index2::new(rect[Axis2::X].end, rect[Axis2::Y].start), ), "right", ); @@ -247,7 +246,7 @@ where &mut style, table.get_rule( Axis2::Y, - Coord2::new(rect[Axis2::X].start, rect[Axis2::Y].end), + Index2::new(rect[Axis2::X].start, rect[Axis2::Y].end), ), "bottom", ); diff --git a/rust/pspp/src/output/pivot.rs b/rust/pspp/src/output/pivot.rs index 6da0d028d1..6e8c90960a 100644 --- a/rust/pspp/src/output/pivot.rs +++ b/rust/pspp/src/output/pivot.rs @@ -1606,6 +1606,65 @@ impl TryFrom for Axis2 { } } +#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] +pub struct Index2(pub EnumMap); + +impl Index2 { + pub fn new(x: usize, y: usize) -> Self { + use Axis2::*; + Self(enum_map! { + X => x, + Y => y + }) + } + + pub fn for_axis((a, az): (Axis2, usize), bz: usize) -> Self { + let mut coord = Self::default(); + coord[a] = az; + coord[!a] = bz; + coord + } + + pub fn from_fn(f: F) -> Self + where + F: FnMut(Axis2) -> usize, + { + Self(EnumMap::from_fn(f)) + } + + pub fn x(&self) -> usize { + self.0[Axis2::X] + } + + pub fn y(&self) -> usize { + self.0[Axis2::Y] + } + + pub fn get(&self, axis: Axis2) -> usize { + self.0[axis] + } +} + +impl From> for Index2 { + fn from(value: EnumMap) -> Self { + Self(value) + } +} + +impl Index for Index2 { + type Output = usize; + + fn index(&self, index: Axis2) -> &Self::Output { + &self.0[index] + } +} + +impl IndexMut for Index2 { + fn index_mut(&mut self, index: Axis2) -> &mut Self::Output { + &mut self.0[index] + } +} + /// A 2-dimensional `(x,y)` pair. #[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)] pub struct Coord2(pub EnumMap); @@ -1724,6 +1783,64 @@ impl IndexMut for Rect2 { } } +#[derive(Clone, Debug, Default)] +pub struct IndexRect2(pub EnumMap>); + +impl IndexRect2 { + pub fn new(x_range: Range, y_range: Range) -> Self { + Self(enum_map! { + Axis2::X => x_range.clone(), + Axis2::Y => y_range.clone(), + }) + } + pub fn for_cell(cell: Index2) -> Self { + Self::new(cell.x()..cell.x() + 1, cell.y()..cell.y() + 1) + } + pub fn for_ranges((a, a_range): (Axis2, Range), b_range: Range) -> Self { + let b = !a; + let mut ranges = EnumMap::default(); + ranges[a] = a_range; + ranges[b] = b_range; + Self(ranges) + } + pub fn top_left(&self) -> Index2 { + use Axis2::*; + Index2::new(self[X].start, self[Y].start) + } + pub fn from_fn(f: F) -> Self + where + F: FnMut(Axis2) -> Range, + { + Self(EnumMap::from_fn(f)) + } + pub fn translate(self, offset: Index2) -> IndexRect2 { + Self::from_fn(|axis| self[axis].start + offset[axis]..self[axis].end + offset[axis]) + } + pub fn is_empty(&self) -> bool { + self[Axis2::X].is_empty() || self[Axis2::Y].is_empty() + } +} + +impl From>> for IndexRect2 { + fn from(value: EnumMap>) -> Self { + Self(value) + } +} + +impl Index for IndexRect2 { + type Output = Range; + + fn index(&self, index: Axis2) -> &Self::Output { + &self.0[index] + } +} + +impl IndexMut for IndexRect2 { + fn index_mut(&mut self, index: Axis2) -> &mut Self::Output { + &mut self.0[index] + } +} + #[derive(Copy, Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub enum FootnoteMarkerType { diff --git a/rust/pspp/src/output/pivot/output.rs b/rust/pspp/src/output/pivot/output.rs index a2427b0d35..b19fa9ae92 100644 --- a/rust/pspp/src/output/pivot/output.rs +++ b/rust/pspp/src/output/pivot/output.rs @@ -20,13 +20,13 @@ use enum_map::{EnumMap, enum_map}; use itertools::Itertools; use crate::output::{ - pivot::{HeadingRegion, LabelPosition, Path, RowParity}, + pivot::{HeadingRegion, Index2, IndexRect2, LabelPosition, Path, RowParity}, table::{CellInner, Table}, }; use super::{ - Area, Axis2, Axis3, Border, BorderStyle, BoxBorder, Color, Coord2, Dimension, Footnote, - IntoValueOptions, PivotTable, Rect2, RowColBorder, Stroke, Value, + Area, Axis2, Axis3, Border, BorderStyle, BoxBorder, Color, Dimension, Footnote, + IntoValueOptions, PivotTable, RowColBorder, Stroke, Value, }; /// All of the combinations of dimensions along an axis. @@ -139,15 +139,15 @@ impl PivotTable { I: Iterator> + ExactSizeIterator, { let mut table = Table::new( - Coord2::new(1, rows.len()), - Coord2::new(0, 0), + Index2::new(1, rows.len()), + Index2::new(0, 0), self.style.look.areas.clone(), self.borders(false), self.into_value_options(), ); for (y, row) in rows.enumerate() { table.put( - Rect2::for_cell(Coord2::new(0, y)), + IndexRect2::for_cell(Index2::new(0, y)), CellInner::new(area, row), ); } @@ -178,13 +178,13 @@ impl PivotTable { pub fn output_body(&self, layer_indexes: &[usize], printing: bool) -> Table { let headings = EnumMap::from_fn(|axis| Headings::new(self, axis, layer_indexes)); - let data = Coord2::from_fn(|axis| headings[axis].width()); - let mut stub = Coord2::from_fn(|axis| headings[!axis].height()); + let data = Index2::from_fn(|axis| headings[axis].width()); + let mut stub = Index2::from_fn(|axis| headings[!axis].height()); if headings[Axis2::Y].row_label_position == LabelPosition::Corner && stub.y() == 0 { stub[Axis2::Y] = 1; } let mut body = Table::new( - Coord2::from_fn(|axis| data[axis] + stub[axis]), + Index2::from_fn(|axis| data[axis] + stub[axis]), stub, self.style.look.areas.clone(), self.borders(printing), @@ -205,7 +205,7 @@ impl PivotTable { let data_indexes = self.convert_indexes_ptod(presentation_indexes); let value = self.get(&*data_indexes); body.put( - Rect2::new(x..x + 1, y..y + 1), + IndexRect2::new(x..x + 1, y..y + 1), CellInner::new( Area::Data(RowParity::from(y - stub[Axis2::Y])), Box::new(value.cloned().unwrap_or_default()), @@ -222,7 +222,7 @@ impl PivotTable { && stub.y() > 0 { body.put( - Rect2::new(0..stub.x(), 0..stub.y()), + IndexRect2::new(0..stub.x(), 0..stub.y()), CellInner::new( Area::Corner, self.metadata.corner_text.clone().unwrap_or_default(), @@ -466,7 +466,7 @@ impl<'a> Heading<'a> { let rotate = (rotate_inner_labels && is_inner_row) || (rotate_outer_labels && is_outer_row); table.put( - Rect2::for_ranges((h, x1 + h_ofs..x2 + h_ofs), y1..y2), + IndexRect2::for_ranges((h, x1 + h_ofs..x2 + h_ofs), y1..y2), CellInner::new(Area::Labels(h), Box::new(name.clone())).with_rotate(rotate), ); @@ -546,7 +546,7 @@ impl<'a> Heading<'a> { if dimension_label_position == LabelPosition::Corner { table.put( - Rect2::new(v_ofs..v_ofs + 1, 0..h_ofs), + IndexRect2::new(v_ofs..v_ofs + 1, 0..h_ofs), CellInner::new(Area::Corner, self.dimension.root.name.clone()), ); } diff --git a/rust/pspp/src/output/render.rs b/rust/pspp/src/output/render.rs index 9b4d71cc57..14a5959621 100644 --- a/rust/pspp/src/output/render.rs +++ b/rust/pspp/src/output/render.rs @@ -25,7 +25,7 @@ use itertools::interleave; use num::Integer; use smallvec::SmallVec; -use crate::output::pivot::VertAlign; +use crate::output::pivot::{Index2, IndexRect2, VertAlign}; use crate::output::table::DrawCell; use super::pivot::{Axis2, BorderStyle, Coord2, Look, PivotTable, Rect2, Stroke}; @@ -187,13 +187,13 @@ struct Page { /// Size of the table in cells. /// - n: Coord2, + n: Index2, /// Header size. Cells `0..h[X]` are rendered horizontally, and `0..h[Y]` vertically. - h: Coord2, + h: Index2, /// Main region of cells to render. - r: Rect2, + r: IndexRect2, /// Mappings from [Page] positions to those in the underlying [Table]. maps: EnumMap, @@ -293,7 +293,7 @@ struct Page { /// ``` /// Each entry maps from a cell that overflows to the space that has been /// trimmed off the cell. - overflows: HashMap>, + overflows: HashMap>, /// If a single column (or row) is too wide (or tall) to fit on a page /// reasonably, then [Break::next] will split a single row or column across @@ -354,7 +354,7 @@ fn is_rule(z: usize) -> bool { #[derive(Clone)] pub struct RenderCell<'a> { - rect: Rect2, + rect: IndexRect2, content: &'a Content, } @@ -395,7 +395,7 @@ impl Page { for cell in table.cells().filter(|cell| cell.col_span() == 1) { let mut w = device.measure_cell_width(&DrawCell::new(cell.inner(), &table)); if device.params().px_size.is_some() { - if let Some(region) = table.heading_region(cell.coord) { + if let Some(region) = table.heading_region(cell.pos) { let wr = &heading_widths[region]; if w[Min] < wr[Min] { w[Min] = wr[Min]; @@ -411,7 +411,7 @@ impl Page { } } - let x = cell.coord[X]; + let x = cell.pos[X]; for ext in [Min, Max] { if unspanned_columns[ext][x] < w[ext] { unspanned_columns[ext][x] = w[ext]; @@ -483,7 +483,7 @@ impl Page { let w = joined_width(&cp_x, rect[X].clone()); let h = device.measure_cell_height(&DrawCell::new(cell.inner(), &table), w); - let row = &mut unspanned_rows[cell.coord.y()]; + let row = &mut unspanned_rows[cell.pos.y()]; if h > *row { *row = h; } @@ -519,7 +519,7 @@ impl Page { h[axis] = 0; } } - let r = Rect2::new(h[X]..n[X], h[Y]..n[Y]); + let r = IndexRect2::new(h[X]..n[X], h[Y]..n[Y]); let maps = Self::new_mappings(h, &r); Self { table, @@ -620,7 +620,7 @@ impl Page { *self.cp[axis].last().unwrap() } - fn new_mappings(h: Coord2, r: &Rect2) -> EnumMap { + fn new_mappings(h: Index2, r: &IndexRect2) -> EnumMap { EnumMap::from_fn(|axis| { [ Map { @@ -651,15 +651,15 @@ impl Page { z + self.get_map(axis, z).ofs } - fn map_coord(&self, coord: Coord2) -> Coord2 { - Coord2::from_fn(|a| self.map_z(a, coord[a])) + fn map_coord(&self, coord: Index2) -> Index2 { + Index2::from_fn(|a| self.map_z(a, coord[a])) } - fn get_cell(&self, coord: Coord2) -> RenderCell<'_> { + fn get_cell(&self, coord: Index2) -> RenderCell<'_> { let maps = EnumMap::from_fn(|axis| self.get_map(axis, coord[axis])); let cell = self.table.get(self.map_coord(coord)); RenderCell { - rect: Rect2(cell.rect().0.map(|axis, Range { start, end }| { + rect: IndexRect2(cell.rect().0.map(|axis, Range { start, end }| { let m = maps[axis]; max(m.p0, start - m.ofs)..min(m.p0 + m.n, end - m.ofs) })), @@ -760,7 +760,7 @@ impl Page { if self.h[a] == 0 || z0 > self.h[a] || pixel0 > 0 { let mut z = 0; while z < self.n[b] { - let d = Coord2::for_axis((a, z0), z); + let d = Index2::for_axis((a, z0), z); let cell = self.get_cell(d); let overflow0 = pixel0 > 0 || cell.rect[a].start < z0; let overflow1 = cell.rect[a].end > z1 || (cell.rect[a].end == z1 && pixel1 > 0); @@ -787,7 +787,7 @@ impl Page { // Add overflows along the right side. let mut z = 0; while z < self.n[b] { - let d = Coord2::for_axis((a, z1 - 1), z); + let d = Index2::for_axis((a, z1 - 1), z); let cell = self.get_cell(d); if cell.rect[a].end > z1 || (cell.rect[a].end == z1 && pixel1 > 0) @@ -839,17 +839,17 @@ impl Page { self.draw_cells( device, ofs, - Rect2::new(0..self.n[X] * 2 + 1, 0..self.n[Y] * 2 + 1), + IndexRect2::new(0..self.n[X] * 2 + 1, 0..self.n[Y] * 2 + 1), ); } - fn draw_cells(&self, device: &mut dyn Device, ofs: Coord2, cells: Rect2) { + fn draw_cells(&self, device: &mut dyn Device, ofs: Coord2, cells: IndexRect2) { use Axis2::*; for y in cells[Y].clone() { let mut x = cells[X].start; while x < cells[X].end { if !is_rule(x) && !is_rule(y) { - let cell = self.get_cell(Coord2::new(x / 2, y / 2)); + let cell = self.get_cell(Index2::new(x / 2, y / 2)); self.draw_cell(device, ofs, &cell); x = rule_ofs(cell.rect[X].end); } else { @@ -861,13 +861,13 @@ impl Page { for y in cells[Y].clone() { for x in cells[X].clone() { if is_rule(x) || is_rule(y) { - self.draw_rule(device, ofs, Coord2::new(x, y)); + self.draw_rule(device, ofs, Index2::new(x, y)); } } } } - fn draw_rule(&self, device: &mut dyn Device, ofs: Coord2, coord: Coord2) { + fn draw_rule(&self, device: &mut dyn Device, ofs: Coord2, coord: Index2) { const NO_BORDER: BorderStyle = BorderStyle::none(); let styles = EnumMap::from_fn(|a: Axis2| { let b = !a; @@ -908,15 +908,15 @@ impl Page { } } - fn get_rule(&self, a: Axis2, coord: Coord2) -> BorderStyle { - let coord = Coord2::from_fn(|a| coord[a] / 2); + fn get_rule(&self, a: Axis2, coord: Index2) -> BorderStyle { + let coord = Index2::from_fn(|a| coord[a] / 2); let coord = self.map_coord(coord); let border = self.table.get_rule(a, coord); if self.h[a] > 0 && coord[a] == self.h[a] { let border2 = self .table - .get_rule(a, Coord2::for_axis((a, self.h[a]), coord[!a])); + .get_rule(a, Index2::for_axis((a, self.h[a]), coord[!a])); border.combine(border2) } else { border @@ -982,7 +982,7 @@ struct Selection { z1: usize, p0: usize, p1: usize, - h: Coord2, + h: Index2, } impl Selection { @@ -990,11 +990,11 @@ impl Selection { /// /// `coord` must be in the selected region or the results will not make /// sense. - fn coord_to_subpage(&self, coord: Coord2) -> Coord2 { + fn coord_to_subpage(&self, coord: Index2) -> Index2 { let a = self.a; let b = self.b; let ha0 = self.h[a]; - Coord2::for_axis((a, max(coord[a] + ha0 - self.z0, ha0)), coord[b]) + Index2::for_axis((a, max(coord[a] + ha0 - self.z0, ha0)), coord[b]) } } @@ -1105,7 +1105,7 @@ fn measure_rule(device: &dyn Device, table: &Table, a: Axis2, z: usize) -> usize // Determine the types of rules that are present. let mut rules = EnumMap::default(); for w in 0..table.n[b] { - let stroke = table.get_rule(a, Coord2::for_axis((a, z), w)).stroke; + let stroke = table.get_rule(a, Index2::for_axis((a, z), w)).stroke; rules[stroke] = true; } @@ -1282,7 +1282,7 @@ impl Break { if self.axis == Axis2::Y && device.params().can_adjust_break { let mut x = 0; while x < self.page.n[Axis2::X] { - let cell = self.page.get_cell(Coord2::new(x, z)); + let cell = self.page.get_cell(Index2::new(x, z)); let better_pixel = device.adjust_break( cell.content, Coord2::new( diff --git a/rust/pspp/src/output/table.rs b/rust/pspp/src/output/table.rs index 77c3fa0fa2..174d89d791 100644 --- a/rust/pspp/src/output/table.rs +++ b/rust/pspp/src/output/table.rs @@ -32,17 +32,20 @@ use enum_map::{EnumMap, enum_map}; use ndarray::{Array, Array2}; use crate::output::{ - pivot::{CellStyle, Coord2, DisplayValue, FontStyle, Footnote, HorzAlign, ValueInner}, + pivot::{ + CellStyle, DisplayValue, FontStyle, Footnote, HorzAlign, Index2, IndexRect2, + ValueInner, + }, spv::html, }; use super::pivot::{ - Area, AreaStyle, Axis2, Border, BorderStyle, HeadingRegion, Rect2, Value, ValueOptions, + Area, AreaStyle, Axis2, Border, BorderStyle, HeadingRegion, Value, ValueOptions, }; #[derive(Clone, Debug)] pub struct CellRef<'a> { - pub coord: Coord2, + pub pos: Index2, pub content: &'a Content, } @@ -55,16 +58,16 @@ impl CellRef<'_> { self.content.is_empty() } - pub fn rect(&self) -> Rect2 { - self.content.rect(self.coord) + pub fn rect(&self) -> IndexRect2 { + self.content.rect(self.pos) } pub fn next_x(&self) -> usize { - self.content.next_x(self.coord.x()) + self.content.next_x(self.pos.x()) } pub fn is_top_left(&self) -> bool { - self.content.is_top_left(self.coord) + self.content.is_top_left(self.pos) } pub fn span(&self, axis: Axis2) -> usize { @@ -99,7 +102,7 @@ impl Content { /// Returns the rectangle that this cell covers, only if the cell contains /// that information. (Joined cells always do, and other cells usually /// don't.) - pub fn joined_rect(&self) -> Option<&Rect2> { + pub fn joined_rect(&self) -> Option<&IndexRect2> { match self { Content::Join(cell) => Some(&cell.region), _ => None, @@ -107,11 +110,11 @@ impl Content { } /// Returns the rectangle that this cell covers. If the cell doesn't contain - /// that information, returns a rectangle containing `coord`. - pub fn rect(&self, coord: Coord2) -> Rect2 { + /// that information, returns a rectangle containing `pos`. + pub fn rect(&self, pos: Index2) -> IndexRect2 { match self { Content::Join(cell) => cell.region.clone(), - _ => Rect2::for_cell(coord), + _ => IndexRect2::for_cell(pos), } } @@ -120,8 +123,8 @@ impl Content { .map_or(x + 1, |region| region[Axis2::X].end) } - pub fn is_top_left(&self, coord: Coord2) -> bool { - self.joined_rect().is_none_or(|r| coord == r.top_left()) + pub fn is_top_left(&self, pos: Index2) -> bool { + self.joined_rect().is_none_or(|r| pos == r.top_left()) } pub fn span(&self, axis: Axis2) -> usize { @@ -150,11 +153,11 @@ pub struct Cell { inner: CellInner, /// Occupied table region. - region: Rect2, + region: IndexRect2, } impl Cell { - fn new(inner: CellInner, region: Rect2) -> Self { + fn new(inner: CellInner, region: IndexRect2) -> Self { Self { inner, region } } } @@ -192,10 +195,10 @@ impl CellInner { #[derive(derive_more::Debug)] pub struct Table { /// Number of rows and columns. - pub n: Coord2, + pub n: Index2, /// Table header rows and columns. - pub h: Coord2, + pub h: Index2, pub contents: Array2, @@ -217,8 +220,8 @@ pub struct Table { impl Table { pub fn new( - n: Coord2, - headers: Coord2, + n: Index2, + headers: Index2, areas: EnumMap, borders: EnumMap, value_options: ValueOptions, @@ -237,18 +240,18 @@ impl Table { } } - pub fn get(&self, coord: Coord2) -> CellRef<'_> { + pub fn get(&self, coord: Index2) -> CellRef<'_> { CellRef { - coord, + pos: coord, content: &self.contents[[coord.x(), coord.y()]], } } - pub fn get_rule(&self, axis: Axis2, pos: Coord2) -> BorderStyle { + pub fn get_rule(&self, axis: Axis2, pos: Index2) -> BorderStyle { self.rules[axis][[pos.x(), pos.y()]].map_or(BorderStyle::none(), |b| self.borders[b]) } - pub fn put(&mut self, region: Rect2, inner: CellInner) { + pub fn put(&mut self, region: IndexRect2, inner: CellInner) { use Axis2::*; if region[X].len() == 1 && region[Y].len() == 1 { self.contents[[region[X].start, region[Y].start]] = Content::Value(inner); @@ -295,7 +298,7 @@ impl Table { } /// The heading region that `pos` is part of, if any. - pub fn heading_region(&self, pos: Coord2) -> Option { + pub fn heading_region(&self, pos: Index2) -> Option { if pos.x() < self.h.x() { Some(HeadingRegion::Rows) } else if pos.y() < self.h.y() { @@ -330,7 +333,7 @@ impl Iterator for XIter<'_> { fn next(&mut self) -> Option { let next_x = self .x - .map_or(0, |x| self.table.get(Coord2::new(x, self.y)).next_x()); + .map_or(0, |x| self.table.get(Index2::new(x, self.y)).next_x()); if next_x >= self.table.n.x() { None } else { @@ -353,7 +356,7 @@ impl<'a> Cells<'a> { next: if table.is_empty() { None } else { - Some(table.get(Coord2::new(0, 0))) + Some(table.get(Index2::new(0, 0))) }, } } @@ -370,9 +373,9 @@ impl<'a> Iterator for Cells<'a> { self.next = loop { let next_x = next.next_x(); let coord = if next_x < self.table.n[X] { - Coord2::new(next_x, next.coord.y()) - } else if next.coord.y() + 1 < self.table.n[Y] { - Coord2::new(0, next.coord.y() + 1) + Index2::new(next_x, next.pos.y()) + } else if next.pos.y() + 1 < self.table.n[Y] { + Index2::new(0, next.pos.y() + 1) } else { break None; };