mirror of
https://github.com/storytold/deckcraft.git
synced 2026-10-13 23:08:23 +00:00
Render: table borders draw their dashes, compound bands and diagonals
Explicit cell borders were stroked as plain solid lines (no dash, compound or cap), and diagonal borders (lnTlToBr, lnBlToTr) were read but never drawn. Both now go through the shape line stroker; diagonals are drawn under the cell edges. Wild synthetic set: border styles slide 5.67 -> 2.26, thick merged-cell borders 1.20 -> 0.69. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
9d4541b8b4
commit
cef6e1a8c8
3 files changed
+40
-6
No files matched your search
@@ -1376,7 +1376,7 @@ fn blur(sigma: f64) -> Filter {
|
||||
/// Stroke `path` with `line`. A gradient line is laid out over `extent` (the untrimmed outline the
|
||||
/// line belongs to; `path` itself when `None`).
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn stroke(
|
||||
pub(crate) fn stroke(
|
||||
ctx: &mut RenderContext,
|
||||
rctx: &Ctx,
|
||||
line: &Line,
|
||||
|
||||
@@ -348,6 +348,17 @@ pub fn draw(
|
||||
},
|
||||
}
|
||||
}
|
||||
// Diagonal borders, under the edges: drawn like any line (dashes, compound, caps).
|
||||
for (r, c, rect) in &rects {
|
||||
let Some(cell) = t.cell(*r, *c) else { continue };
|
||||
for (line, a, b) in [(&cell.diag_down, (rect.x0, rect.y0), (rect.x1, rect.y1)), (&cell.diag_up, (rect.x0, rect.y1), (rect.x1, rect.y0))] {
|
||||
let Some(l) = line.as_ref().filter(|l| l.fill.as_ref().is_some_and(|f| !f.is_none())) else { continue };
|
||||
let mut p = BezPath::new();
|
||||
p.move_to(a);
|
||||
p.line_to(b);
|
||||
crate::stroke(ctx, rctx, l, None, &p, None, m, l.width.unwrap_or(1.0).max(0.0), 1.0);
|
||||
}
|
||||
}
|
||||
// Borders: explicit cell borders, else the style's grid.
|
||||
for (r, c, rect) in &rects {
|
||||
let Some(cell) = t.cell(*r, *c) else { continue };
|
||||
@@ -361,11 +372,16 @@ pub fn draw(
|
||||
for (i, e) in edges.iter().enumerate() {
|
||||
let line = cell.borders.get(i).and_then(|b| b.as_ref());
|
||||
let (col, wd) = match line {
|
||||
Some(l) => match &l.fill {
|
||||
Some(Fill::Solid { color: cc }) => (rctx.color(cc, None), l.width.unwrap_or(1.0)),
|
||||
Some(Fill::None) => continue,
|
||||
_ => continue,
|
||||
},
|
||||
// An explicit border is drawn like any line: dashed, compound, gradient.
|
||||
Some(l) => {
|
||||
if l.fill.as_ref().is_some_and(|f| !f.is_none()) {
|
||||
let mut p = BezPath::new();
|
||||
p.move_to((e.0, e.1));
|
||||
p.line_to((e.2, e.3));
|
||||
crate::stroke(ctx, rctx, l, None, &p, None, m, l.width.unwrap_or(1.0).max(0.25), 1.0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
None => match lk.sides.get(i).copied().flatten().or(lk.border) {
|
||||
Some(b) if b.0.a > 0 && b.1 > 0.0 => b,
|
||||
_ => continue,
|
||||
|
||||
@@ -580,3 +580,21 @@ fn a_bevelled_shape_is_lit_from_the_upper_left() {
|
||||
let img = render(vec![bevelled(r#"<a:sp3d><a:bevelT w="152400" h="76200"/></a:sp3d>"#)]);
|
||||
assert!(close(img.pixel(165, 104), base, 2) && close(img.pixel(165, 165), base, 2));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn table_borders_take_their_dashes_and_diagonals_are_drawn() {
|
||||
let mut t = deckcraft_model::Table::new(1, 1, 200.0, 100.0);
|
||||
t.style = "none".into();
|
||||
let mut dashed = Line::solid(ColorRef::rgb(RED), 4.0);
|
||||
dashed.dash = Some(deckcraft_model::style::Dash::Preset { name: "dash".into() });
|
||||
if let Some(c) = t.rows.first_mut().and_then(|r| r.cells.first_mut()) {
|
||||
c.borders[2] = Some(dashed);
|
||||
c.diag_down = Some(Line::solid(ColorRef::rgb(Rgba::rgb(0, 0, 255)), 4.0));
|
||||
}
|
||||
let sh = Shape { id: ShapeId(27), xfrm: Some(Xfrm::new(100.0, 100.0, 200.0, 100.0)), kind: ShapeKind::Table(t), ..Default::default() };
|
||||
let img = render(vec![sh]);
|
||||
// Dashes of 4 widths (16 pt) on, 3 (12 pt) off along the top edge, from its start.
|
||||
assert!(close(img.pixel(108, 100), RED, 40) && close(img.pixel(122, 100), WHITE, 30) && close(img.pixel(135, 100), RED, 40));
|
||||
// The diagonal from top-left to bottom-right passes through the middle.
|
||||
assert!(close(img.pixel(200, 150), Rgba::rgb(0, 0, 255), 40), "{:?}", img.pixel(200, 150));
|
||||
}
|
||||
Reference in new issue
Block a user