Commit bfded3cd authored by Ian Kilpatrick's avatar Ian Kilpatrick Committed by Commit Bot

[TableNG] Fix basic cache-misses.

This patch unifies creates the constraint-space for table-cells. Before
we had two different code-paths leading to subtle differences in
construction causing various types of cache misses.

This unifies the code-paths ensuring that they can remain as similar as
possible.

Bug: 958381
Change-Id: I59d7252ba3db52c36b2118d9695cea106326a1e7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2498836
Commit-Queue: Ian Kilpatrick <ikilpatrick@chromium.org>
Reviewed-by: default avatarAleks Totic <atotic@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821770}
parent 0d944e3e
......@@ -111,7 +111,7 @@ NGConstraintSpace NGConstraintSpace::CreateFromLayoutObject(
builder.SetHideTableCellIfEmpty(
cell_style.EmptyCells() == EEmptyCells::kHide &&
table_style.BorderCollapse() == EBorderCollapse::kSeparate);
builder.SetHasTableCellCollapsedBorder(
builder.SetIsTableCellWithCollapsedBorders(
cell_block.Parent()->Parent()->Parent()->StyleRef().BorderCollapse() ==
EBorderCollapse::kCollapse);
}
......
......@@ -977,11 +977,11 @@ class CORE_EXPORT NGConstraintSpace final {
bool IsTableCellWithCollapsedBorders() const {
return data_union_type == kTableCellData &&
table_cell_data_.has_collapsed_border;
table_cell_data_.has_collapsed_borders;
}
void SetIsTableCellWithCollapsedBorders(bool has_collapsed_border) {
EnsureTableCellData()->has_collapsed_border = has_collapsed_border;
void SetIsTableCellWithCollapsedBorders(bool has_collapsed_borders) {
EnsureTableCellData()->has_collapsed_borders = has_collapsed_borders;
}
void SetTableRowData(
......@@ -1095,25 +1095,24 @@ class CORE_EXPORT NGConstraintSpace final {
struct TableCellData {
bool MaySkipLayout(const TableCellData& other) const {
// NOTE: We don't compare |table_cell_alignment_baseline| as it is
// still possible to hit the cache if this differs.
return table_cell_borders == other.table_cell_borders &&
table_cell_intrinsic_padding_block_start ==
other.table_cell_intrinsic_padding_block_start &&
table_cell_intrinsic_padding_block_end ==
other.table_cell_intrinsic_padding_block_end &&
table_cell_alignment_baseline ==
other.table_cell_alignment_baseline &&
table_cell_column_index == other.table_cell_column_index &&
is_hidden_for_paint == other.is_hidden_for_paint &&
has_collapsed_border == other.has_collapsed_border;
has_collapsed_borders == other.has_collapsed_borders;
}
bool IsInitialForMaySkipLayout() const {
return table_cell_borders == NGBoxStrut() &&
table_cell_intrinsic_padding_block_start == LayoutUnit() &&
table_cell_intrinsic_padding_block_end == LayoutUnit() &&
table_cell_column_index == kNotFound &&
table_cell_alignment_baseline == base::nullopt &&
!is_hidden_for_paint && !has_collapsed_border;
table_cell_column_index == kNotFound && !is_hidden_for_paint &&
!has_collapsed_borders;
}
NGBoxStrut table_cell_borders;
......@@ -1122,13 +1121,13 @@ class CORE_EXPORT NGConstraintSpace final {
wtf_size_t table_cell_column_index = kNotFound;
base::Optional<LayoutUnit> table_cell_alignment_baseline;
bool is_hidden_for_paint = false;
bool has_collapsed_border = false;
bool has_collapsed_borders = false;
};
struct TableRowData {
bool MaySkipLayout(const TableRowData& other) const {
return table_data->EqualTableSpecificData(other.table_data.get()) &&
table_data->MaySkipRowLayout(other.table_data.get(), row_index);
return table_data->IsTableSpecificDataEqual(*other.table_data) &&
table_data->MaySkipRowLayout(*other.table_data, row_index);
}
bool IsInitialForMaySkipLayout() const {
return !table_data && row_index == kNotFound;
......@@ -1140,8 +1139,8 @@ class CORE_EXPORT NGConstraintSpace final {
struct TableSectionData {
bool MaySkipLayout(const TableSectionData& other) const {
return table_data->EqualTableSpecificData(other.table_data.get()) &&
table_data->MaySkipSectionLayout(other.table_data.get(),
return table_data->IsTableSpecificDataEqual(*other.table_data) &&
table_data->MaySkipSectionLayout(*other.table_data,
section_index);
}
bool IsInitialForMaySkipLayout() const {
......
......@@ -328,16 +328,21 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
DCHECK(!is_table_cell_hidden_for_paint_set_);
is_table_cell_hidden_for_paint_set_ = true;
#endif
space_.EnsureRareData()->SetIsTableCellHiddenForPaint(is_hidden_for_paint);
if (is_hidden_for_paint) {
space_.EnsureRareData()->SetIsTableCellHiddenForPaint(
is_hidden_for_paint);
}
}
void SetHasTableCellCollapsedBorder(bool is_collapsed_border) {
void SetIsTableCellWithCollapsedBorders(bool has_collapsed_borders) {
#if DCHECK_IS_ON()
DCHECK(!is_table_cell_collapsed_border_set_);
is_table_cell_collapsed_border_set_ = true;
DCHECK(!is_table_cell_with_collapsed_borders_set_);
is_table_cell_with_collapsed_borders_set_ = true;
#endif
space_.EnsureRareData()->SetIsTableCellWithCollapsedBorders(
is_collapsed_border);
if (has_collapsed_borders) {
space_.EnsureRareData()->SetIsTableCellWithCollapsedBorders(
has_collapsed_borders);
}
}
void SetTableCellChildLayoutMode(
......@@ -463,7 +468,7 @@ class CORE_EXPORT NGConstraintSpaceBuilder final {
bool is_table_cell_alignment_baseline_set_ = false;
bool is_table_cell_column_index_set_ = false;
bool is_table_cell_hidden_for_paint_set_ = false;
bool is_table_cell_collapsed_border_set_ = false;
bool is_table_cell_with_collapsed_borders_set_ = false;
bool is_custom_layout_data_set_ = false;
bool is_lines_until_clamp_set_ = false;
bool is_table_row_data_set_ = false;
......
......@@ -1699,5 +1699,39 @@ TEST_F(NGLayoutResultCachingTest, HitOrthogonalRoot) {
EXPECT_NE(result.get(), nullptr);
}
TEST_F(NGLayoutResultCachingTest, SimpleTable) {
ScopedLayoutNGTableForTest table_ng(true);
SetBodyInnerHTML(R"HTML(
<table>
<td id="target1">abc</td>
<td id="target2">abc</td>
</table>
)HTML");
auto* target1 = To<LayoutBlock>(GetLayoutObjectByElementId("target1"));
auto* target2 = To<LayoutBlock>(GetLayoutObjectByElementId("target2"));
// Both "target1", and "target1" should have only had one "measure" pass
// performed.
scoped_refptr<const NGLayoutResult> result1 =
target1->GetCachedLayoutResult();
scoped_refptr<const NGLayoutResult> measure1 =
target1->GetCachedMeasureResult();
EXPECT_EQ(result1->GetConstraintSpaceForCaching().CacheSlot(),
NGCacheSlot::kMeasure);
EXPECT_NE(result1.get(), nullptr);
EXPECT_EQ(result1.get(), measure1.get());
scoped_refptr<const NGLayoutResult> result2 =
target2->GetCachedLayoutResult();
scoped_refptr<const NGLayoutResult> measure2 =
target2->GetCachedMeasureResult();
EXPECT_EQ(result2->GetConstraintSpaceForCaching().CacheSlot(),
NGCacheSlot::kMeasure);
EXPECT_NE(result2.get(), nullptr);
EXPECT_EQ(result2.get(), measure2.get());
}
} // namespace
} // namespace blink
......@@ -104,36 +104,36 @@ class NGTableConstraintSpaceData
bool is_constrained;
};
bool EqualTableSpecificData(const NGTableConstraintSpaceData* other) const {
return table_inline_size == other->table_inline_size &&
table_writing_direction == other->table_writing_direction &&
table_border_spacing == other->table_border_spacing &&
treat_table_block_size_as_constrained ==
other->treat_table_block_size_as_constrained &&
hide_table_cell_if_empty == other->hide_table_cell_if_empty &&
column_locations == other->column_locations;
bool IsTableSpecificDataEqual(const NGTableConstraintSpaceData& other) const {
return table_inline_size == other.table_inline_size &&
table_writing_direction == other.table_writing_direction &&
table_border_spacing == other.table_border_spacing &&
is_table_block_size_specified ==
other.is_table_block_size_specified &&
hide_table_cell_if_empty == other.hide_table_cell_if_empty &&
column_locations == other.column_locations;
}
bool MaySkipRowLayout(const NGTableConstraintSpaceData* other,
bool MaySkipRowLayout(const NGTableConstraintSpaceData& other,
wtf_size_t row_index) const {
if (other->rows.size() <= row_index)
if (other.rows.size() <= row_index)
return false;
if (rows[row_index] != other->rows[row_index])
if (rows[row_index] != other.rows[row_index])
return false;
DCHECK_LT(row_index, rows.size());
wtf_size_t end_index =
rows[row_index].start_cell_index + rows[row_index].cell_count;
for (wtf_size_t cell_index = rows[row_index].start_cell_index;
cell_index < end_index; ++cell_index) {
if (cells[cell_index] != other->cells[cell_index])
if (cells[cell_index] != other.cells[cell_index])
return false;
}
return true;
}
bool MaySkipSectionLayout(const NGTableConstraintSpaceData* other,
bool MaySkipSectionLayout(const NGTableConstraintSpaceData& other,
wtf_size_t section_index) const {
if (other->sections.size() <= section_index)
if (other.sections.size() <= section_index)
return false;
DCHECK_LT(section_index, sections.size());
wtf_size_t end_index = sections[section_index].start_row_index +
......@@ -154,7 +154,9 @@ class NGTableConstraintSpaceData
WritingDirectionMode table_writing_direction =
WritingDirectionMode(WritingMode::kHorizontalTb, TextDirection::kLtr);
LogicalSize table_border_spacing;
bool treat_table_block_size_as_constrained;
// If the block-size of the table is specified (not 'auto').
bool is_table_block_size_specified;
bool hide_table_cell_if_empty; // currently on regular constraint space.
bool has_collapsed_borders;
};
......
......@@ -124,7 +124,7 @@ LayoutUnit ComputeEmptyTableInlineSize(
const LayoutUnit undistributable_space,
const NGTableTypes::Caption& caption_constraint,
const NGBoxStrut& table_border_padding,
const bool is_collapsed) {
const bool has_collapsed_borders) {
// If table has a css inline size, use that.
if (space.IsFixedInlineSize() || !table_style.LogicalWidth().IsAuto() ||
!table_style.LogicalMinWidth().IsAuto()) {
......@@ -136,7 +136,7 @@ LayoutUnit ComputeEmptyTableInlineSize(
table_border_padding.InlineSum());
}
// Table is defined by its border/padding.
if (is_collapsed) {
if (has_collapsed_borders) {
return LayoutUnit();
}
return assignable_table_inline_size + table_border_padding.InlineSum();
......@@ -150,8 +150,7 @@ LayoutUnit ComputeAssignableTableInlineSize(
const NGTableTypes::Caption& caption_constraint,
const LayoutUnit undistributable_space,
const NGBoxStrut& table_border_padding,
const bool is_fixed_layout,
const bool is_collapsed) {
const bool is_fixed_layout) {
if (space.IsFixedInlineSize()) {
return (space.AvailableSize().inline_size - undistributable_space)
.ClampNegativeToZero();
......@@ -243,7 +242,7 @@ scoped_refptr<NGTableConstraintSpaceData> CreateConstraintSpaceData(
data->table_inline_size = table_inline_size;
data->table_writing_direction = style.GetWritingDirection();
data->table_border_spacing = border_spacing;
data->treat_table_block_size_as_constrained = !style.LogicalHeight().IsAuto();
data->is_table_block_size_specified = !style.LogicalHeight().IsAuto();
data->hide_table_cell_if_empty =
style.EmptyCells() == EEmptyCells::kHide &&
style.BorderCollapse() == EBorderCollapse::kSeparate;
......@@ -434,8 +433,7 @@ LayoutUnit NGTableLayoutAlgorithm::ComputeTableInlineSize(
const LayoutUnit assignable_table_inline_size =
ComputeAssignableTableInlineSize(
table, space, *column_constraints, caption_constraint,
undistributable_space, table_border_padding, is_fixed_layout,
table_borders->IsCollapsed());
undistributable_space, table_border_padding, is_fixed_layout);
if (column_constraints->data.IsEmpty()) {
return ComputeEmptyTableInlineSize(
space, table.Style(), assignable_table_inline_size,
......@@ -499,8 +497,7 @@ scoped_refptr<const NGLayoutResult> NGTableLayoutAlgorithm::Layout() {
const LayoutUnit assignable_table_inline_size =
ComputeAssignableTableInlineSize(
Node(), ConstraintSpace(), *column_constraints, caption_constraint,
undistributable_space, border_padding, is_fixed_layout,
table_borders->IsCollapsed());
undistributable_space, border_padding, is_fixed_layout);
// Distribute assignable table width.
const Vector<LayoutUnit> column_sizes =
......@@ -673,13 +670,12 @@ void NGTableLayoutAlgorithm::ComputeRows(
ConstraintSpace(), Style(), table_border_padding, kIndefiniteSize,
table_grid_inline_size);
const bool is_table_block_size_specified = !Style().LogicalHeight().IsAuto();
LayoutUnit total_table_block_size;
wtf_size_t section_index = 0;
for (const NGBlockNode& section : grouped_children) {
NGTableAlgorithmUtils::ComputeSectionMinimumRowBlockSizes(
section, table_grid_inline_size,
/* is_restricted_block_size_table */ css_table_block_size !=
kIndefiniteSize,
section, table_grid_inline_size, is_table_block_size_specified,
column_locations, table_borders, border_spacing.block_size,
section_index++, sections, rows, cell_block_constraints);
total_table_block_size += sections->back().block_size;
......
......@@ -103,7 +103,7 @@ NGTableTypes::CellInlineConstraint NGTableTypes::CreateCellInlineConstraint(
bool is_fixed_layout,
const NGBoxStrut& cell_border,
const NGBoxStrut& cell_padding,
bool is_collapsed) {
bool has_collapsed_borders) {
base::Optional<LayoutUnit> css_inline_size;
base::Optional<LayoutUnit> css_min_inline_size;
base::Optional<LayoutUnit> css_max_inline_size;
......@@ -120,7 +120,7 @@ NGTableTypes::CellInlineConstraint NGTableTypes::CreateCellInlineConstraint(
MinMaxSizesInput input(kIndefiniteSize, MinMaxSizesType::kIntrinsic);
MinMaxSizesResult min_max_size;
bool need_constraint_space = is_collapsed || !is_parallel;
bool need_constraint_space = has_collapsed_borders || !is_parallel;
if (need_constraint_space) {
NGConstraintSpaceBuilder builder(table_writing_mode,
node.Style().GetWritingMode(),
......
......@@ -188,7 +188,7 @@ class CORE_EXPORT NGTableTypes {
bool is_fixed_layout,
const NGBoxStrut& cell_border,
const NGBoxStrut& cell_padding,
bool is_collapsed);
bool has_collapsed_borders);
static Section CreateSection(const NGLayoutInputNode&,
wtf_size_t start_row,
......
......@@ -72,7 +72,7 @@ void ApplyCellConstraintsToColumnConstraints(
NGTableTypes::Row ComputeMinimumRowBlockSize(
const NGBlockNode& row,
const LayoutUnit cell_percentage_inline_size,
const bool is_restricted_block_size_table,
const bool is_table_block_size_specified,
const NGTableTypes::ColumnLocations& column_locations,
const NGTableBorders& table_borders,
wtf_size_t row_index,
......@@ -83,51 +83,35 @@ NGTableTypes::Row ComputeMinimumRowBlockSize(
NGColspanCellTabulator* colspan_cell_tabulator) {
const WritingDirectionMode table_writing_direction =
row.Style().GetWritingDirection();
const bool has_collapsed_borders = table_borders.IsCollapsed();
auto CreateCellConstraintSpace = [&column_locations, &table_writing_direction,
&is_restricted_block_size_table,
&is_table_block_size_specified,
&has_collapsed_borders,
&cell_percentage_inline_size](
const NGBlockNode& cell,
wtf_size_t start_column_index,
const NGBoxStrut& cell_borders) {
wtf_size_t start_column = start_column_index;
wtf_size_t end_column = std::min(start_column + cell.TableCellColspan() - 1,
column_locations.size() - 1);
LayoutUnit cell_inline_size = column_locations[end_column].offset +
column_locations[end_column].size -
column_locations[start_column].offset;
// TODO(crbug.com/736072): Support orthogonal table cells.
// See http://wpt.live/css/css-writing-modes/table-cell-001.html
NGConstraintSpaceBuilder builder(table_writing_direction.GetWritingMode(),
cell.Style().GetWritingMode(),
/* is_new_fc */ true);
builder.SetTextDirection(cell.Style().Direction());
builder.SetTableCellBorders(cell_borders);
if (!IsParallelWritingMode(table_writing_direction.GetWritingMode(),
cell.Style().GetWritingMode())) {
PhysicalSize icb_size = cell.InitialContainingBlockSize();
builder.SetOrthogonalFallbackInlineSize(
IsHorizontalWritingMode(table_writing_direction.GetWritingMode())
? icb_size.height
: icb_size.width);
builder.SetIsShrinkToFit(cell.Style().LogicalWidth().IsAuto());
}
builder.SetAvailableSize(LogicalSize(cell_inline_size, kIndefiniteSize));
// Standard:
// https://www.w3.org/TR/css-tables-3/#computing-the-table-height "the
// computed height (if definite, percentages being considered 0px)"
LogicalSize percentage_resolution_size(cell_percentage_inline_size,
kIndefiniteSize);
builder.SetPercentageResolutionSize(percentage_resolution_size);
builder.SetReplacedPercentageResolutionSize(percentage_resolution_size);
builder.SetIsFixedInlineSize(true);
builder.SetIsTableCell(true, /* is_legacy_table_cell */ false);
builder.SetIsRestrictedBlockSizeTableCell(is_restricted_block_size_table);
builder.SetNeedsBaseline(true);
builder.SetCacheSlot(NGCacheSlot::kMeasure);
return builder.ToConstraintSpace();
const wtf_size_t start_column = start_column_index;
const wtf_size_t end_column =
std::min(start_column + cell.TableCellColspan() - 1,
column_locations.size() - 1);
const LayoutUnit cell_inline_size = column_locations[end_column].offset +
column_locations[end_column].size -
column_locations[start_column].offset;
// Typically we want these values to match the "layout" pass as close as
// possible. The one exception is "is_hidden_for_paint". This is set to
// true if a cell should be hidden within a collapsed column. If this is
// the case, the size is almost certainly different causing a second layout.
return NGTableAlgorithmUtils::CreateTableCellConstraintSpace(
table_writing_direction, cell, cell_borders,
{cell_inline_size, kIndefiniteSize}, cell_percentage_inline_size,
/* alignment_baseline */ base::nullopt, start_column,
/* is_fixed_block_size_indefinite */ false,
is_table_block_size_specified,
/* is_hidden_for_paint */ false, has_collapsed_borders,
NGCacheSlot::kMeasure);
};
// TODO(layout-ng) Scrollbars should be frozen when computing row sizes.
......@@ -389,6 +373,63 @@ void ComputeSectionInlineConstraints(
} // namespace
// static
NGConstraintSpace NGTableAlgorithmUtils::CreateTableCellConstraintSpace(
const WritingDirectionMode table_writing_direction,
const NGBlockNode cell,
const NGBoxStrut& cell_borders,
LogicalSize cell_size,
LayoutUnit percentage_inline_size,
base::Optional<LayoutUnit> alignment_baseline,
wtf_size_t column_index,
bool is_fixed_block_size_indefinite,
bool is_table_block_size_specified,
bool is_hidden_for_paint,
bool has_collapsed_borders,
NGCacheSlot cache_slot) {
const auto& cell_style = cell.Style();
const auto table_writing_mode = table_writing_direction.GetWritingMode();
const auto cell_writing_mode = cell_style.GetWritingMode();
NGConstraintSpaceBuilder builder(table_writing_mode, cell_writing_mode,
/* is_new_fc */ true);
builder.SetIsTableCell(true, /* is_legacy_table_cell */ false);
builder.SetTextDirection(cell_style.Direction());
if (!IsParallelWritingMode(table_writing_mode, cell_writing_mode)) {
const PhysicalSize icb_size = cell.InitialContainingBlockSize();
builder.SetOrthogonalFallbackInlineSize(
table_writing_direction.IsHorizontal() ? icb_size.height
: icb_size.width);
builder.SetIsShrinkToFit(cell.Style().LogicalWidth().IsAuto());
}
builder.SetAvailableSize(cell_size);
builder.SetIsFixedInlineSize(true);
if (cell_size.block_size != kIndefiniteSize) {
builder.SetIsFixedBlockSize(true);
builder.SetIsFixedBlockSizeIndefinite(is_fixed_block_size_indefinite);
}
// Standard:
// https://www.w3.org/TR/css-tables-3/#computing-the-table-height "the
// computed height (if definite, percentages being considered 0px)"
builder.SetPercentageResolutionSize(
{percentage_inline_size, kIndefiniteSize});
builder.SetTableCellBorders(cell_borders);
builder.SetTableCellAlignmentBaseline(alignment_baseline);
builder.SetTableCellColumnIndex(column_index);
builder.SetIsRestrictedBlockSizeTableCell(is_table_block_size_specified);
builder.SetIsTableCellHiddenForPaint(is_hidden_for_paint);
builder.SetIsTableCellWithCollapsedBorders(has_collapsed_borders);
builder.SetHideTableCellIfEmpty(
!has_collapsed_borders && cell_style.EmptyCells() == EEmptyCells::kHide);
builder.SetNeedsBaseline(true);
builder.SetCacheSlot(cache_slot);
return builder.ToConstraintSpace();
}
scoped_refptr<NGTableTypes::Columns>
NGTableAlgorithmUtils::ComputeColumnConstraints(
const NGBlockNode& table,
......@@ -431,7 +472,7 @@ NGTableAlgorithmUtils::ComputeColumnConstraints(
void NGTableAlgorithmUtils::ComputeSectionMinimumRowBlockSizes(
const NGBlockNode& section,
const LayoutUnit cell_percentage_inline_size,
const bool is_restricted_block_size_table,
const bool is_table_block_size_restricted,
const NGTableTypes::ColumnLocations& column_locations,
const NGTableBorders& table_borders,
const LayoutUnit block_border_spacing,
......@@ -452,7 +493,7 @@ void NGTableAlgorithmUtils::ComputeSectionMinimumRowBlockSizes(
row = To<NGBlockNode>(row.NextSibling())) {
colspan_cell_tabulator.StartRow();
NGTableTypes::Row row_constraint = ComputeMinimumRowBlockSize(
row, cell_percentage_inline_size, is_restricted_block_size_table,
row, cell_percentage_inline_size, is_table_block_size_restricted,
column_locations, table_borders, current_row++, section_index,
/* is_section_collapsed */ section.Style().Visibility() ==
EVisibility::kCollapse,
......
......@@ -10,6 +10,9 @@
namespace blink {
struct LogicalSize;
enum class NGCacheSlot;
class NGConstraintSpace;
class NGTableBorders;
class NGBlockNode;
......@@ -25,6 +28,24 @@ class NGTableAlgorithmUtils {
align == EVerticalAlign::kLength;
}
// Creates a constraint-space for a table-cell.
//
// In order to make the cache as effective as possible, we try and keep
// creating the constraint-space for table-cells as consistent as possible.
static NGConstraintSpace CreateTableCellConstraintSpace(
const WritingDirectionMode table_writing_direction,
const NGBlockNode cell,
const NGBoxStrut& cell_borders,
LogicalSize cell_size,
LayoutUnit percentage_inline_size,
base::Optional<LayoutUnit> alignment_baseline,
wtf_size_t column_index,
bool is_fixed_block_size_indefinite,
bool is_restricted_block_size_table,
bool is_hidden_for_paint,
bool has_collapsed_borders,
NGCacheSlot);
static scoped_refptr<NGTableTypes::Columns> ComputeColumnConstraints(
const NGBlockNode& table,
const NGTableGroupedChildren&,
......
......@@ -33,9 +33,10 @@ scoped_refptr<const NGLayoutResult> NGTableRowLayoutAlgorithm::Layout() {
base::Optional<LayoutUnit> row_baseline,
bool row_is_collapsed,
wtf_size_t* cell_location_start_column) {
wtf_size_t start_column = table_data.cells[cell_index].start_column;
wtf_size_t end_column = std::min(start_column + cell.TableCellColspan() - 1,
table_data.column_locations.size() - 1);
const wtf_size_t start_column = table_data.cells[cell_index].start_column;
const wtf_size_t end_column =
std::min(start_column + cell.TableCellColspan() - 1,
table_data.column_locations.size() - 1);
*cell_location_start_column = start_column;
// When columns spanned by the cell are collapsed, cell geometry is defined
// by:
......@@ -56,53 +57,28 @@ scoped_refptr<const NGLayoutResult> NGTableRowLayoutAlgorithm::Layout() {
const NGTableConstraintSpaceData::Cell& cell_data =
table_data.cells[cell_index];
LayoutUnit cell_inline_size =
const LayoutUnit cell_inline_size =
table_data.column_locations[cell_location_end_column].offset +
table_data.column_locations[cell_location_end_column].inline_size -
table_data.column_locations[*cell_location_start_column].offset;
LayoutUnit cell_block_size =
const LayoutUnit cell_block_size =
row_is_collapsed ? LayoutUnit() : cell_data.block_size;
NGConstraintSpaceBuilder builder(
table_data.table_writing_direction.GetWritingMode(),
cell.Style().GetWritingMode(), /* is_new_fc */ true);
builder.SetAvailableSize({cell_inline_size, cell_block_size});
builder.SetIsFixedInlineSize(true);
builder.SetIsFixedBlockSize(true);
builder.SetTextDirection(Style().Direction());
PhysicalSize icb_size = Node().InitialContainingBlockSize();
builder.SetOrthogonalFallbackInlineSize(
IsHorizontalWritingMode(
table_data.table_writing_direction.GetWritingMode())
? icb_size.height
: icb_size.width);
builder.SetPercentageResolutionSize(
LogicalSize(container_builder_.InlineSize(), kIndefiniteSize));
// Percentage block resolution size is only valid if
// cell height is specified, or table height is specified.
bool is_block_size_indefinite =
!cell_data.is_constrained &&
!table_data.treat_table_block_size_as_constrained;
if (is_block_size_indefinite)
builder.SetIsFixedBlockSizeIndefinite(true);
builder.SetIsTableCell(/* is_table_cell */ true,
/* is_legacy_table_cell */ false);
builder.SetTableCellBorders(cell_data.border_box_borders);
builder.SetTableCellAlignmentBaseline(row_baseline);
builder.SetTableCellColumnIndex(start_column);
builder.SetHasTableCellCollapsedBorder(table_data.has_collapsed_borders);
builder.SetNeedsBaseline(true);
builder.SetIsTableCellHiddenForPaint(
table_data.column_locations[*cell_location_start_column].is_collapsed &&
*cell_location_start_column == cell_location_end_column);
builder.SetHideTableCellIfEmpty(!table_data.has_collapsed_borders &&
cell.Style().EmptyCells() ==
EEmptyCells::kHide);
// Percentage block resolution size is only valid if cell block-size is
// specified, or the table block-size is specified.
const bool is_fixed_block_size_indefinite =
!cell_data.is_constrained && !table_data.is_table_block_size_specified;
return builder.ToConstraintSpace();
const bool is_hidden_for_paint =
table_data.column_locations[*cell_location_start_column].is_collapsed &&
*cell_location_start_column == cell_location_end_column;
return NGTableAlgorithmUtils::CreateTableCellConstraintSpace(
table_data.table_writing_direction, cell, cell_data.border_box_borders,
{cell_inline_size, cell_block_size}, container_builder_.InlineSize(),
row_baseline, start_column, is_fixed_block_size_indefinite,
table_data.is_table_block_size_specified, is_hidden_for_paint,
table_data.has_collapsed_borders, NGCacheSlot::kLayout);
};
const NGTableConstraintSpaceData::Row& row = table_data.rows[row_index];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment