From cb36b729d1de8d897c78ea84c3524448541cf15e Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 8 Dec 2025 08:44:40 -0800 Subject: [PATCH] breaking tables mostly works --- rust/pspp/src/output/drivers/cairo/fsm.rs | 4 +- rust/pspp/src/output/pivot.rs | 1 + rust/pspp/src/output/render.rs | 55 ++++++++++++++++++----- 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/rust/pspp/src/output/drivers/cairo/fsm.rs b/rust/pspp/src/output/drivers/cairo/fsm.rs index 60b006dcf7..5c411ec1d9 100644 --- a/rust/pspp/src/output/drivers/cairo/fsm.rs +++ b/rust/pspp/src/output/drivers/cairo/fsm.rs @@ -738,9 +738,7 @@ impl Device for CairoDevice<'_> { bb[Axis2::Y].start += valign_offset; for axis in [Axis2::X, Axis2::Y] { bb[axis].start += px_to_xr(draw_cell.cell_style.margins[axis][0] as isize); - bb[axis].end = bb[axis] - .end - .saturating_sub(draw_cell.cell_style.margins[axis][0] as isize); + bb[axis].end -= px_to_xr(draw_cell.cell_style.margins[axis][1] as isize); } if bb[Axis2::X].start < bb[Axis2::X].end && bb[Axis2::Y].start < bb[Axis2::Y].end { self.cell_draw(draw_cell, bb, clip); diff --git a/rust/pspp/src/output/pivot.rs b/rust/pspp/src/output/pivot.rs index 1b7f3672af..0ee01c6ba4 100644 --- a/rust/pspp/src/output/pivot.rs +++ b/rust/pspp/src/output/pivot.rs @@ -1382,6 +1382,7 @@ impl Color { self.with_alpha(255) } + /// Displays opaque colors as `#rrggbb` and others as `rgb(r, g, b, alpha)`. pub fn display_css(&self) -> DisplayCss { DisplayCss(*self) } diff --git a/rust/pspp/src/output/render.rs b/rust/pspp/src/output/render.rs index 1714bc5cdb..4e8176da24 100644 --- a/rust/pspp/src/output/render.rs +++ b/rust/pspp/src/output/render.rs @@ -540,13 +540,15 @@ impl Page { let cell = self.table.table.get(CellPos { x, y }); // XXX skip if not top-left cell let rect = cell.rect(); - let bb = Rect2::from_fn(|a| { + let mut bb = Rect2::from_fn(|a| { cp[a][rect[a].start * 2 + 1]..cp[a][(rect[a].end - 1) * 2 + 2] }); - let clip = if y < self.table.h().y { + let mut clip = if y < self.table.h().y { if x < self.table.h().x { + // Corner bb.clone() } else { + // Top stub Rect2::new( max(bb[X].start, self.ranges[X].start) ..min(bb[X].end, self.ranges[X].end), @@ -554,15 +556,29 @@ impl Page { ) } } else if x < self.table.h().x { + // Left stub Rect2::new( bb[X].clone(), max(bb[Y].start, self.ranges[Y].start)..min(bb[Y].end, self.ranges[Y].end), ) } else { + // Body Rect2::from_fn(|a| { max(bb[a].start, self.ranges[a].start)..min(bb[a].end, self.ranges[a].end) }) }; + if clip[X].start >= clip[X].end || clip[Y].start >= clip[Y].end { + continue; + } + for a in [X, Y] { + if bb[a].start >= self.ranges[a].start { + let h = self.ranges[a].start - self.table.headers_width(a); + bb[a].start -= h; + bb[a].end -= h; + clip[a].start -= h; + clip[a].end -= h; + } + } let draw_cell = DrawCell::new(cell.content.inner(), &self.table.table); let valign_offset = match draw_cell.cell_style.vert_align { VertAlign::Top => 0, @@ -594,12 +610,32 @@ impl Page { .enumerate() .filter(|(x, _)| *x % 2 == 0 || y % 2 == 0) { - self.draw_rule(device, ofs, CellPos { x, y }); + let mut bb = Rect2::new(xr.clone(), yr.clone()); + + let h = self.table.headers_width(X); + if xr.start < h { + } else if self.ranges[X].contains(&xr.start) { + bb[X].start -= self.ranges[X].start - h; + bb[X].end -= self.ranges[X].start - h; + } else { + continue; + } + + let h = self.table.headers_width(Y); + if yr.start < h { + } else if self.ranges[Y].contains(&yr.start) { + bb[Y].start -= self.ranges[Y].start - h; + bb[Y].end -= self.ranges[Y].start - h; + } else { + continue; + } + + self.draw_rule(device, ofs, CellPos { x, y }, bb); } } } - fn draw_rule(&self, device: &mut dyn Device, ofs: Coord2, coord: CellPos) { + fn draw_rule(&self, device: &mut dyn Device, ofs: Coord2, coord: CellPos, bb: Rect2) { const NO_BORDER: BorderStyle = BorderStyle::none(); let styles = EnumMap::from_fn(|a: Axis2| { let b = !a; @@ -631,9 +667,7 @@ impl Page { .values() .all(|border| border.iter().all(BorderStyle::is_none)) { - let bb = Rect2::from_fn(|a| self.table.cp[a][coord[a]]..self.table.cp[a][coord[a] + 1]) - .translate(ofs); - device.draw_line(bb, styles); + device.draw_line(bb.translate(ofs), styles); } } @@ -883,9 +917,10 @@ impl Break { if !self.has_next() { return Ok(None); } - let target = size - .checked_sub(self.page.table.headers_width(self.axis)) - .ok_or(())?; + let target = size - self.page.table.headers_width(self.axis); + if target <= 0 { + return Err(()); + } let start = self.page.ranges[self.axis].start; let (end, next_start) = self.find_breakpoint(start..start + target, device); let result = Page { -- 2.30.2