From 443cf60ae21d7d638a3279b64e22f6beb3a5f1b0 Mon Sep 17 00:00:00 2001 From: PgBiel <9021226+PgBiel@users.noreply.github.com> Date: Mon, 11 Mar 2024 07:32:44 -0300 Subject: [PATCH] Ensure hline/vline positioning respects colspan/rowspan (#3610) --- crates/typst/src/layout/grid/layout.rs | 22 +++++++++++++++++++--- tests/ref/layout/grid-stroke.png | Bin 55633 -> 57339 bytes tests/typ/layout/grid-stroke.typ | 13 +++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/crates/typst/src/layout/grid/layout.rs b/crates/typst/src/layout/grid/layout.rs index 772c107e8..20b2ddc8f 100644 --- a/crates/typst/src/layout/grid/layout.rs +++ b/crates/typst/src/layout/grid/layout.rs @@ -646,6 +646,8 @@ impl CellGrid { ResolvableGridItem::Cell(cell) => cell, }; let cell_span = cell.span(); + let colspan = cell.colspan(styles).get(); + let rowspan = cell.rowspan(styles).get(); // Let's calculate the cell's final position based on its // requested position. let resolved_index = { @@ -654,6 +656,8 @@ impl CellGrid { resolve_cell_position( cell_x, cell_y, + colspan, + rowspan, &resolved_cells, &mut auto_index, min_auto_index, @@ -663,8 +667,6 @@ impl CellGrid { }; let x = resolved_index % c; let y = resolved_index / c; - let colspan = cell.colspan(styles).get(); - let rowspan = cell.rowspan(styles).get(); if colspan > c - x { bail!( @@ -1284,9 +1286,12 @@ impl CellGrid { /// positioning. Useful with headers: if a cell in a header has automatic /// positioning, it should start at the header's first row, and not at the end /// of the previous row. +#[allow(clippy::too_many_arguments)] fn resolve_cell_position( cell_x: Smart, cell_y: Smart, + colspan: usize, + rowspan: usize, resolved_cells: &[Option], auto_index: &mut usize, min_auto_index: usize, @@ -1316,7 +1321,18 @@ fn resolve_cell_position( // Ensure the next cell with automatic position will be // placed after this one (maybe not immediately after). - *auto_index = resolved_index + 1; + // + // The calculation below also affects the position of the upcoming + // automatically-positioned lines. + *auto_index = if colspan == columns { + // The cell occupies all columns, so no cells can be placed + // after it until all of its rows have been spanned. + resolved_index + colspan * rowspan + } else { + // The next cell will have to be placed at least after its + // spanned columns. + resolved_index + colspan + }; Ok(resolved_index) } diff --git a/tests/ref/layout/grid-stroke.png b/tests/ref/layout/grid-stroke.png index 409d10f10ec964692e8c0a4b254895b684ef27ff..e9f9b0615065d4ae08bf872f24e8be162dc4ea32 100644 GIT binary patch delta 2051 zcmV+e2>kcavIG0S1CSRErw9T7000?6)M)?!-@>saMb>{m_U@QP$v6(+_;Q1T_yXEQ zTyn5Y$3Tc2dKFEPP_6BPp-!%Z%E;ShL%;b6E3($u6#KRI}C_u+`^ z^W~3tAPUFxIsg8Aj;GyD5yNmeOis|qWHM<@lj`+)JbACzOFsEDo6X}fluD)fe4hN+ zXf)zgVy=I1xI>FyQGA|;;l5$mZnu?6C7aF0JTay*tyU|S%jNU=7$fd>yCX4lyWQA; z6$*veTEvK^TrP))w7zFpE|>8>b8>PLQ~z467AF*~*Xv_2#G7QiEyRHy-?)uNqr_OT zSUi*vuN9A}R;w{)fZ_gNNY2I?jYfmPASU;>JEc0fpBz}nV2I;221julTm12OyxDBh z{RTR?PN&m;zn}aqKL$f=ieiu&PZ+nW)#`A%klc?QR7{y}ACsZiH(7c=$-e79I6Hg( z<8_Mb>GiX~@apPG9Hw`%P9N?uOgb>QSc!|3xLC=*hT)>KUz6+9*T?g(v95mpNqt@1 z{CYdSJpKM9_DdL=^S< zz`cM%v_#|ggUEBsE#4QOpWXog000000001h+cAL6LX(l89Ft(64S%q--?H-cv-16$ z@-IJr^*%ZNh<84C5Cbt_J7O4*$H`>U?RJ|?CSt%=$1s^pLZQ&X!NK|YIWd53l5%%< zcXf3|3?K&O{{H^@`kEL(48(voI*#ky9jtvrV5 zbh@{|LM5j2r>7@=O~SgzFq_S8Z*L_@vREueqtWN{9UdN@o}RwGzAhGvx5Xe%cye;0 z)9E6S$n*2F*?(*vjYh5tZh<0 zpAQ5A;`xW+aL6_ZTOC6>ojyA|6E|iL1_NTiwhz#DyMJB8FdmPI0gCdsy}Jp8Eer!V z-g{zLOt#8KC<&V>-IAoc!%m&d)`Bt%ixcvZkyx1Q?!r!tk7gwiw(bT^G#b z4h|0X_kZ`VtgL)AH|go=N%rd)h9T2mWY^9o7!rxZ;^N}S$cRjciO1t$Alq#2(RIDE zvojWpt*x!)=jU5nqSHG#IH<0!o}HbQ-9N!#(Cv1AgdrM@dOV(`rKOXT6PZn4Sy_2= za{~sl0S0;gE-x=nCX?2t&8DWN)X&L6S*FZSO@B?L-tzf;zr`SDmAbmRv9U4h8}st= z{C+gwte55i1tI?1Vq zfdFI!403!cr6wjO{^Ulg4BpF#L6#Frsnylhy}i9~IJ~>NyS=@Ad3gy2%61HqNJJ@R zo_`rWNuKF7O}n_b$cSNRXhN=r)xgRCWF#cW|P zmmI~##j+0B+S;;)_Ju+rFpv!}+~42px__=|njGt`t*vq|NRIW?yXNNR(` z$KBrE%Ij65(WpF@e;rsimn;nF!-kKJj^qbkUte>XMC^29%|KuP1Azey1O_k=7?TOQ z5`Tf=Zvz8?0Sp8NFc28PKwtm^8!srO4i68(Ku*LEiA1b{Na1i;Fv!Ic7|4kjq*yFA zIy&0c*5>tkHBFnIo(2Os5koK-EGa1ogYwwLovuuBbUo%j@zPr2Q%s{*xgO_6vlaaa-1CSRE5eNbR007m|Bmn>b*%+}UMb>}6_U@QP$v6(+_~PIozJN9n zmmF-%|7F zSS-fYB1SZoN+mp`^*zIKxs3OjOePak|9ZV1ClsyM>tis)n`FE##DN~)xQ#}m#8|0R zI+PHv6_2UaYB6Sj;dC%0XXA`Uqd1)|CiizcrMQ!6*BdIqV37PRKL$f=ieiu&PZ+nW z)#`A%klc?QR7{!f9y6QGU~oEy|7UOtH<8_Mb>CLmi z@ap