@@ -338,4 +338,68 @@ describe('Integration test: tables', function () {
338338 } ) ;
339339 } ) ;
340340
341+ it ( 'keeps row heights stable when rowSpan crosses pages with dontBreakRows (#2895)' , function ( ) {
342+ var dd = {
343+ content : {
344+ table : {
345+ dontBreakRows : true ,
346+ heights : 45 ,
347+ widths : [ 50 , 100 , 200 , 50 ] ,
348+ body : [
349+ [ '1' , '2' , '3' , '4' ] ,
350+ [ { rowSpan : 4 , text : '4span' } , null , null , null ] ,
351+ [ null , null , null , null ] ,
352+ [ { rowSpan : 2 , text : '2span' } , null , null , null ] ,
353+ [ null , null , null , null ] ,
354+ [ { rowSpan : 2 , text : null } , null , null , null ] ,
355+ [ null , null , null , null ] ,
356+ [ { rowSpan : 2 , text : null } , null , null , null ] ,
357+ [ null , null , null , null ] ,
358+ [ null , null , null , null ] ,
359+ [ { rowSpan : 15 , text : 'span 15' , maxHeight : 50 } , null , null , null ] ,
360+ [ null , null , null , null ] ,
361+ [ null , null , null , null ] ,
362+ [ null , null , null , null ] ,
363+ [ null , null , null , null ] ,
364+ [ null , null , null , null ] ,
365+ [ null , null , null , null ] ,
366+ [ null , null , null , null ] ,
367+ [ null , null , null , null ] ,
368+ [ null , null , null , null ] ,
369+ [ null , null , null , null ] ,
370+ [ null , null , null , null ] ,
371+ [ null , null , null , null ] ,
372+ [ null , null , null , null ] ,
373+ [ null , null , null , null ] ,
374+ [ null , null , null , null ] ,
375+ [ null , null , null , null ] ,
376+ [ { rowSpan : 5 , text : 'span 5' } , null , null , null ] ,
377+ [ null , null , null , null ] ,
378+ [ { rowSpan : 2 , text : null } , null , null , null ] ,
379+ [ null , null , null , null ] ,
380+ [ null , null , null , null ]
381+ ]
382+ }
383+ }
384+ } ;
385+
386+ var pages = testHelper . renderPages ( 'A4' , dd ) ;
387+ var lastPage = pages [ pages . length - 1 ] ;
388+ var horizontalLineYs = [ ...new Set (
389+ lastPage . items
390+ . filter ( node => node . type === 'vector' && node . item . type === 'line' && Math . abs ( node . item . y1 - node . item . y2 ) < 0.001 )
391+ . map ( node => Number ( node . item . y1 . toFixed ( 3 ) ) )
392+ ) ] . sort ( ( a , b ) => a - b ) ;
393+
394+ var maxGap = 0 ;
395+ for ( var i = 1 ; i < horizontalLineYs . length ; i ++ ) {
396+ maxGap = Math . max ( maxGap , horizontalLineYs [ i ] - horizontalLineYs [ i - 1 ] ) ;
397+ }
398+
399+ // Each row is 45pt tall. A gap above ~90pt would indicate a blown-out row caused
400+ // by a negative discountY when a rowspan started on a previous page. Allow up to
401+ // 2x row height (90pt) as a safe upper bound; anything beyond that is the bug.
402+ assert . ok ( maxGap < 90 , 'max gap between horizontal lines was ' + maxGap + 'pt, expected < 90pt' ) ;
403+ } ) ;
404+
341405} ) ;
0 commit comments