mirror of
https://github.com/Kozea/WeasyPrint.git
synced 2024-10-04 07:57:52 +03:00
Avoid nested loops for intermediate intrinsic percentage widths
Fix #1155.
This commit is contained in:
parent
1b8ac91004
commit
f17bd4bfca
@ -9,6 +9,7 @@ Baron's unofficial draft (https://dbaron.org/css/intrinsic/).
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from functools import cache
|
||||||
from math import inf
|
from math import inf
|
||||||
|
|
||||||
from ..formatting_structure import boxes
|
from ..formatting_structure import boxes
|
||||||
@ -453,6 +454,7 @@ def table_and_columns_preferred_widths(context, box, outer=True):
|
|||||||
break
|
break
|
||||||
|
|
||||||
colspan_cells = []
|
colspan_cells = []
|
||||||
|
colspans = set()
|
||||||
|
|
||||||
# Define the intermediate content widths
|
# Define the intermediate content widths
|
||||||
min_content_widths = [0] * grid_width
|
min_content_widths = [0] * grid_width
|
||||||
@ -480,6 +482,7 @@ def table_and_columns_preferred_widths(context, box, outer=True):
|
|||||||
intrinsic_percentages[i], _percentage_contribution(cell))
|
intrinsic_percentages[i], _percentage_contribution(cell))
|
||||||
else:
|
else:
|
||||||
colspan_cells.append(cell)
|
colspan_cells.append(cell)
|
||||||
|
colspans.add(cell.colspan - 1)
|
||||||
|
|
||||||
# Intermediate content widths for span > 1 is wrong in the 4.1 section, as
|
# Intermediate content widths for span > 1 is wrong in the 4.1 section, as
|
||||||
# explained in its third issue. Min- and max-content widths are handled by
|
# explained in its third issue. Min- and max-content widths are handled by
|
||||||
@ -487,45 +490,49 @@ def table_and_columns_preferred_widths(context, box, outer=True):
|
|||||||
# widths to columns that have originating cells.
|
# widths to columns that have originating cells.
|
||||||
|
|
||||||
# Intermediate intrinsic percentage widths for span > 1
|
# Intermediate intrinsic percentage widths for span > 1
|
||||||
for span in range(1, grid_width):
|
rows_origins = []
|
||||||
|
for y, row in enumerate(grid):
|
||||||
|
origin = None
|
||||||
|
rows_origins.append(row_origins := [])
|
||||||
|
for x, cell in enumerate(row):
|
||||||
|
if cell:
|
||||||
|
origin = x
|
||||||
|
row_origins.append(origin)
|
||||||
|
|
||||||
|
@cache
|
||||||
|
def get_percentage_contribution(origin_cell, origin, max_content_width):
|
||||||
|
# Cached for big colspan values, see #1155.
|
||||||
|
cell_slice = slice(origin, origin + origin_cell.colspan)
|
||||||
|
baseline_percentage = sum(intrinsic_percentages[cell_slice])
|
||||||
|
cell_percentage_contribution = _percentage_contribution(origin_cell)
|
||||||
|
diff = max(0, cell_percentage_contribution - baseline_percentage)
|
||||||
|
other_columns_contributions = [
|
||||||
|
max_content_widths[j]
|
||||||
|
for j in range(origin, origin + origin_cell.colspan)
|
||||||
|
if intrinsic_percentages[j] == 0]
|
||||||
|
other_columns_contributions_sum = sum(other_columns_contributions)
|
||||||
|
if other_columns_contributions_sum == 0:
|
||||||
|
ratio = 1 / (len(other_columns_contributions) or 1)
|
||||||
|
else:
|
||||||
|
ratio = max_content_width / other_columns_contributions_sum
|
||||||
|
return diff * ratio
|
||||||
|
|
||||||
|
for span in sorted(colspans):
|
||||||
percentage_contributions = []
|
percentage_contributions = []
|
||||||
for i in range(grid_width):
|
for i in range(grid_width):
|
||||||
percentage_contribution = intrinsic_percentages[i]
|
if percentage_contribution := intrinsic_percentages[i]:
|
||||||
for j in range(len(zipped_grid[i])):
|
percentage_contributions.append(percentage_contribution)
|
||||||
indexes = [k for k in range(i + 1) if grid[j][k]]
|
continue
|
||||||
if not indexes:
|
for row, row_origins in zip(grid, rows_origins):
|
||||||
|
if (origin := row_origins[i]) is None:
|
||||||
continue
|
continue
|
||||||
origin = max(indexes)
|
origin_cell = row[origin]
|
||||||
origin_cell = grid[j][origin]
|
|
||||||
if origin_cell.colspan - 1 != span:
|
if origin_cell.colspan - 1 != span:
|
||||||
continue
|
continue
|
||||||
cell_slice = slice(origin, origin + origin_cell.colspan)
|
cell_percentage_contribution = get_percentage_contribution(
|
||||||
baseline_percentage = sum(intrinsic_percentages[cell_slice])
|
origin_cell, origin, max_content_widths[i])
|
||||||
|
percentage_contribution = max(
|
||||||
# Cell contribution to intrinsic percentage width
|
percentage_contribution, cell_percentage_contribution)
|
||||||
if intrinsic_percentages[i] == 0:
|
|
||||||
diff = max(
|
|
||||||
0,
|
|
||||||
_percentage_contribution(origin_cell) -
|
|
||||||
baseline_percentage)
|
|
||||||
other_columns_contributions = [
|
|
||||||
max_content_widths[j]
|
|
||||||
for j in range(origin, origin + origin_cell.colspan)
|
|
||||||
if intrinsic_percentages[j] == 0]
|
|
||||||
other_columns_contributions_sum = sum(
|
|
||||||
other_columns_contributions)
|
|
||||||
if other_columns_contributions_sum == 0:
|
|
||||||
if other_columns_contributions:
|
|
||||||
ratio = 1 / len(other_columns_contributions)
|
|
||||||
else:
|
|
||||||
ratio = 1
|
|
||||||
else:
|
|
||||||
ratio = (
|
|
||||||
max_content_widths[i] /
|
|
||||||
other_columns_contributions_sum)
|
|
||||||
percentage_contribution = max(
|
|
||||||
percentage_contribution,
|
|
||||||
diff * ratio)
|
|
||||||
|
|
||||||
percentage_contributions.append(percentage_contribution)
|
percentage_contributions.append(percentage_contribution)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user