blob: 521845a4ab618a6ea8296fb59626ea36b7092f19 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_UTILS_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_UTILS_H_
#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h"
#include "third_party/blink/renderer/core/style/computed_style_constants.h"
namespace blink {
class NGBlockNode;
class NGBoxFragment;
class NGConstraintSpace;
class NGTableBorders;
enum class NGCacheSlot;
struct LogicalSize;
// Table size distribution algorithms.
class NGTableAlgorithmUtils {
public:
static bool IsBaseline(EVerticalAlign align) {
return align == EVerticalAlign::kBaseline ||
align == EVerticalAlign::kBaselineMiddle ||
align == EVerticalAlign::kSub || align == EVerticalAlign::kSuper ||
align == EVerticalAlign::kTextTop ||
align == EVerticalAlign::kTextBottom ||
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&,
const NGTableBorders& table_borders,
const NGBoxStrut& border_padding);
static void ComputeSectionMinimumRowBlockSizes(
const NGBlockNode& section,
const LayoutUnit cell_percentage_resolution_inline_size,
const bool is_restricted_block_size_table,
const NGTableTypes::ColumnLocations& column_locations,
const NGTableBorders& table_borders,
const LayoutUnit block_border_spacing,
wtf_size_t section_index,
bool treat_section_as_tbody,
NGTableTypes::Sections* sections,
NGTableTypes::Rows* rows,
NGTableTypes::CellBlockConstraints* cell_block_constraints);
};
// NGColspanCellTabulator keeps track of columns occupied by colspanned cells
// when traversing rows in a section. It is used to compute cell's actual
// column.
// Usage:
// NGColspanCellTabulator colspan_cell_tabulator;
// for (Row r : section.rows) {
// colspan_cell_tabulator.StartRow();
// for (Cell c : row.cells) {
// colspan_cell_tabulator.FindNextFreeColumn();
// // colspan_cell_tabulator.CurrentColumn() has a valid value here.
// colspan_cell_tabulator.ProcessCell();
// }
// colspan_cell_tabulator.EndRow();
// }
class NGColspanCellTabulator {
public:
unsigned CurrentColumn() { return current_column_; }
void StartRow();
void FindNextFreeColumn();
void ProcessCell(const NGBlockNode& cell);
void EndRow();
struct Cell {
Cell(unsigned column_start, unsigned span, unsigned remaining_rows)
: column_start(column_start),
span(span),
remaining_rows(remaining_rows) {}
unsigned column_start;
unsigned span;
unsigned remaining_rows;
};
private:
unsigned current_column_ = 0;
Vector<Cell> colspanned_cells_;
};
// NGRowBaselineTabulator computes baseline information for row.
// Standard: https://www.w3.org/TR/css-tables-3/#row-layout
// Baseline is either max-baseline of baseline-aligned cells,
// or bottom content edge of non-baseline-aligned cells.
class NGRowBaselineTabulator {
public:
void ProcessCell(const NGBoxFragment& fragment,
const LayoutUnit cell_min_block_size,
bool is_baseline_aligned,
bool is_parallel,
bool descendant_depends_on_percentage_block_size);
LayoutUnit ComputeRowBlockSize(const LayoutUnit max_cell_block_size);
LayoutUnit ComputeBaseline(const LayoutUnit row_block_size);
bool ComputeBaselineDependsOnPercentageBlockDescendant();
private:
// Cell baseline is computed from baseline-aligned cells.
base::Optional<LayoutUnit> max_cell_ascent_;
base::Optional<LayoutUnit> max_cell_descent_;
bool max_cell_baseline_depends_on_percentage_block_descendant_ = false;
// Non-baseline aligned cells are used to compute baseline if baseline
// cells are not available.
base::Optional<LayoutUnit> fallback_cell_descent_;
bool fallback_cell_depends_on_percentage_block_descendant_ = false;
};
} // namespace blink
WTF_ALLOW_MOVE_INIT_AND_COMPARE_WITH_MEM_FUNCTIONS(
blink::NGColspanCellTabulator::Cell)
#endif // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_TABLE_NG_TABLE_LAYOUT_ALGORITHM_UTILS_H_