@@ -1139,56 +1139,61 @@ def grid_layout(context, box, bottom_space, skip_stack, containing_block,
11391139 this_page_children = []
11401140 resume_row = None
11411141 if skip_stack :
1142- skip_row = next (iter (skip_stack ))
1142+ first_skip_row = min (skip_stack )
1143+ last_skip_row = max (skip_stack )
11431144 skip_height = (
1144- sum (size for size , _ in rows_sizes [:skip_row ]) +
1145- (len (rows_sizes [:skip_row ]) - 1 ) * row_gap )
1145+ sum (size for size , _ in rows_sizes [:last_skip_row ]) +
1146+ (len (rows_sizes [:last_skip_row ]) - 1 ) * row_gap )
11461147 else :
1147- skip_row = 0
1148- skip_height = 0
1148+ first_skip_row = last_skip_row = skip_height = 0
11491149 resume_at = None
11501150 total_height = (
1151- sum (size for size , _ in rows_sizes [skip_row :]) +
1152- (len (rows_sizes [skip_row :]) - 1 ) * row_gap )
1151+ sum (size for size , _ in rows_sizes [last_skip_row :]) +
1152+ (len (rows_sizes [last_skip_row :]) - 1 ) * row_gap )
1153+
1154+ def _add_page_children (max_row = inf ):
1155+ for j , child in enumerate (children ):
1156+ _ , y , _ , _ = children_positions [child ]
1157+ if not first_skip_row <= y < max_row :
1158+ # Item in previous or next rows.
1159+ continue
1160+ child_skip_stack = (skip_stack or {}).get (y )
1161+ if child_skip_stack is None or j in child_skip_stack :
1162+ # No skip stack for this row or child in skip stack.
1163+ this_page_children .append ((j , child ))
1164+
11531165 row_lines_positions = (
1154- [* rows_positions [skip_row + 1 :], box .content_box_y () + total_height ])
1155- for i , row_y in enumerate (row_lines_positions , start = skip_row ):
1166+ [* rows_positions [last_skip_row + 1 :], box .content_box_y () + total_height ])
1167+ for i , row_y in enumerate (row_lines_positions , start = first_skip_row ):
11561168 # TODO: handle break-before and break-after for rows.
11571169 overflows = context .overflows_page (bottom_space , row_y - skip_height )
1170+ if overflows :
1171+ resume_row = i
11581172 if overflows and not page_is_empty :
11591173 if box .style ['break_inside' ] == 'avoid' :
11601174 # Avoid breaks inside grid container, break before.
11611175 return None , None , {'break' : 'any' , 'page' : None }, [], False
1162- resume_row = i
11631176 if page_breaks_by_row [i ]['inside' ] == 'avoid' :
11641177 # Break before current row.
11651178 if resume_row == 0 :
11661179 # First row, break before grid container.
11671180 return None , None , {'break' : 'any' , 'page' : None }, [], False
11681181 # Mark all children before and in current row as drawn on the page.
1169- for j , child in enumerate (children ):
1170- _ , y , _ , _ = children_positions [child ]
1171- if skip_row <= y < resume_row :
1172- this_page_children .append ((j , child ))
1182+ _add_page_children (resume_row )
11731183 resume_at = {resume_row : None }
11741184 else :
11751185 # Break inside current row.
11761186 # Mark all children before current row as drawn on the page.
1177- for j , child in enumerate (children ):
1178- _ , y , _ , _ = children_positions [child ]
1179- if skip_row <= y <= resume_row :
1180- this_page_children .append ((j , child ))
1187+ _add_page_children (resume_row + 1 )
11811188 break
11821189 page_is_empty = False
11831190 else :
1184- for j , child in enumerate (children ):
1185- _ , y , _ , _ = children_positions [child ]
1186- if skip_row <= y :
1187- this_page_children .append ((j , child ))
1191+ # Mark all children as drawn on the page.
1192+ _add_page_children ()
11881193 if box .height == 'auto' :
11891194 box .height = (
1190- sum (size for size , _ in rows_sizes [skip_row :resume_row ]) +
1191- (len (rows_sizes [skip_row :resume_row ]) - 1 ) * row_gap )
1195+ sum (size for size , _ in rows_sizes [last_skip_row :resume_row ]) +
1196+ (len (rows_sizes [last_skip_row :resume_row ]) - 1 ) * row_gap )
11921197
11931198 # Lay out grid items.
11941199 justify_items = set (box .style ['justify_items' ])
@@ -1219,6 +1224,13 @@ def grid_layout(context, box, bottom_space, skip_stack, containing_block,
12191224 height = (
12201225 sum (size for size , _ in rows_sizes [y :y + height ]) +
12211226 (height - 1 ) * row_gap )
1227+ if y < last_skip_row :
1228+ # Shift split spanning item from its row to last skip row.
1229+ child_skip_height = (
1230+ sum (size for size , _ in rows_sizes [y :last_skip_row ]) +
1231+ max (0 , len (rows_sizes [y :last_skip_row ]) - 1 ) * row_gap )
1232+ child .position_y += child_skip_height
1233+ height -= child_skip_height
12221234
12231235 # TODO: Apply auto margin.
12241236 if child .margin_top == 'auto' :
@@ -1266,18 +1278,21 @@ def grid_layout(context, box, bottom_space, skip_stack, containing_block,
12661278 page_is_empty , absolute_boxes , fixed_boxes )[:3 ]
12671279 if new_child :
12681280 page_is_empty = False
1269- if child_resume_at :
1281+ if child_resume_at or resume_row == y :
1282+ # Child is broken.
12701283 if resume_at is None :
12711284 resume_at = {}
12721285 if y not in resume_at :
12731286 resume_at [y ] = {}
1287+ if child_resume_at :
1288+ # There is some content left for next page.
12741289 resume_at [y ][i ] = child_resume_at
1290+ elif resume_row == y :
1291+ # Only display the bottom of an empty cell.
1292+ assert isinstance (new_child , boxes .ParentBox )
1293+ previous_skip_child = max (child_skip_stack ) if child_skip_stack else 0
1294+ resume_at [y ][i ] = {previous_skip_child + len (new_child .children ): None }
12751295 else :
1276- if resume_at is None :
1277- resume_at = {}
1278- if y not in resume_at :
1279- resume_at [y ] = {}
1280- resume_at [y ][i ] = {0 : None }
12811296 continue
12821297
12831298 if justify_self & {'normal' , 'stretch' }:
0 commit comments