| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2024-10-04 13:19:50 +02:00
										 |  |  |  * Copyright (c) 2020, Andreas Kling <andreas@ladybird.org> | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #pragma once
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <AK/Forward.h>
 | 
					
						
							| 
									
										
										
										
											2022-12-04 21:57:21 +03:00
										 |  |  | #include <LibWeb/Layout/FormattingContext.h>
 | 
					
						
							| 
									
										
										
										
											2023-08-20 03:08:38 +00:00
										 |  |  | #include <LibWeb/Layout/TableGrid.h>
 | 
					
						
							| 
									
										
										
										
											2023-01-14 15:05:08 +01:00
										 |  |  | #include <LibWeb/Layout/TableWrapper.h>
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | namespace Web::Layout { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 03:37:26 +00:00
										 |  |  | enum class TableDimension { | 
					
						
							|  |  |  |     Row, | 
					
						
							|  |  |  |     Column | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 21:57:21 +03:00
										 |  |  | class TableFormattingContext final : public FormattingContext { | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2024-09-11 01:03:02 +02:00
										 |  |  |     explicit TableFormattingContext(LayoutState&, LayoutMode, Box const&, FormattingContext* parent); | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  |     ~TableFormattingContext(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 00:28:22 +02:00
										 |  |  |     void run_until_width_calculation(AvailableSpace const& available_space); | 
					
						
							| 
									
										
										
										
											2024-03-19 10:18:49 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-11 01:03:02 +02:00
										 |  |  |     virtual void run(AvailableSpace const&) override; | 
					
						
							| 
									
										
										
										
											2023-03-19 09:57:31 +01:00
										 |  |  |     virtual CSSPixels automatic_content_width() const override; | 
					
						
							| 
									
										
										
										
											2022-11-23 17:46:10 +00:00
										 |  |  |     virtual CSSPixels automatic_content_height() const override; | 
					
						
							| 
									
										
										
										
											2024-10-05 22:18:53 +02:00
										 |  |  |     StaticPositionRect calculate_static_position_rect(Box const&) const; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-29 14:11:19 +03:00
										 |  |  |     Box const& table_box() const { return context_box(); } | 
					
						
							| 
									
										
										
										
											2023-01-14 15:05:08 +01:00
										 |  |  |     TableWrapper const& table_wrapper() const | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2025-01-21 09:12:05 -05:00
										 |  |  |         return as<TableWrapper>(*table_box().containing_block()); | 
					
						
							| 
									
										
										
										
											2023-01-14 15:05:08 +01:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-08 01:54:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-01 03:06:21 +00:00
										 |  |  |     static bool border_is_less_specific(const CSS::BorderData& a, const CSS::BorderData& b); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-13 22:42:43 +02:00
										 |  |  |     virtual void parent_context_did_dimension_child_root_box() override; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2024-09-11 01:03:02 +02:00
										 |  |  |     CSSPixels run_caption_layout(CSS::CaptionSide); | 
					
						
							| 
									
										
										
										
											2023-06-07 02:10:55 +00:00
										 |  |  |     CSSPixels compute_capmin(); | 
					
						
							| 
									
										
										
										
											2023-07-15 01:12:10 +00:00
										 |  |  |     void compute_constrainedness(); | 
					
						
							| 
									
										
										
										
											2023-08-12 23:48:36 +00:00
										 |  |  |     void compute_cell_measures(); | 
					
						
							| 
									
										
										
										
											2023-07-15 01:41:42 +00:00
										 |  |  |     void compute_outer_content_sizes(); | 
					
						
							| 
									
										
										
										
											2023-06-08 03:37:26 +00:00
										 |  |  |     template<class RowOrColumn> | 
					
						
							| 
									
										
										
										
											2023-06-26 02:48:09 +00:00
										 |  |  |     void initialize_table_measures(); | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  |     void compute_table_measures(); | 
					
						
							| 
									
										
										
										
											2023-07-17 01:22:11 +00:00
										 |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     void compute_intrinsic_percentage(size_t max_cell_span); | 
					
						
							| 
									
										
										
										
											2023-01-05 18:56:34 +03:00
										 |  |  |     void compute_table_width(); | 
					
						
							|  |  |  |     void distribute_width_to_columns(); | 
					
						
							| 
									
										
										
										
											2023-07-15 02:46:47 +00:00
										 |  |  |     void distribute_excess_width_to_columns(CSSPixels available_width); | 
					
						
							| 
									
										
										
										
											2023-08-07 01:33:37 +00:00
										 |  |  |     void distribute_excess_width_to_columns_fixed_mode(CSSPixels excess_width); | 
					
						
							| 
									
										
										
										
											2024-09-11 01:03:02 +02:00
										 |  |  |     void compute_table_height(); | 
					
						
							| 
									
										
										
										
											2023-04-29 00:43:05 +03:00
										 |  |  |     void distribute_height_to_rows(); | 
					
						
							| 
									
										
										
										
											2023-06-22 17:22:12 +00:00
										 |  |  |     void position_row_boxes(); | 
					
						
							| 
									
										
										
										
											2023-01-08 00:57:57 +03:00
										 |  |  |     void position_cell_boxes(); | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  |     void border_conflict_resolution(); | 
					
						
							| 
									
										
										
										
											2023-06-16 02:48:56 +00:00
										 |  |  |     CSSPixels border_spacing_horizontal() const; | 
					
						
							|  |  |  |     CSSPixels border_spacing_vertical() const; | 
					
						
							| 
									
										
										
										
											2023-08-20 03:08:38 +00:00
										 |  |  |     void finish_grid_initialization(TableGrid const&); | 
					
						
							| 
									
										
										
										
											2022-09-24 13:39:43 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-15 02:46:47 +00:00
										 |  |  |     CSSPixels compute_columns_total_used_width() const; | 
					
						
							|  |  |  |     void commit_candidate_column_widths(Vector<CSSPixels> const& candidate_widths); | 
					
						
							|  |  |  |     void assign_columns_width_linear_combination(Vector<CSSPixels> const& candidate_widths, CSSPixels available_width); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 01:33:37 +00:00
										 |  |  |     template<class ColumnFilter, class BaseWidthGetter> | 
					
						
							|  |  |  |     bool distribute_excess_width_proportionally_to_base_width(CSSPixels excess_width, ColumnFilter column_filter, BaseWidthGetter base_width_getter); | 
					
						
							| 
									
										
										
										
											2023-07-15 02:46:47 +00:00
										 |  |  |     template<class ColumnFilter> | 
					
						
							|  |  |  |     bool distribute_excess_width_equally(CSSPixels excess_width, ColumnFilter column_filter); | 
					
						
							|  |  |  |     template<class ColumnFilter> | 
					
						
							|  |  |  |     bool distribute_excess_width_by_intrinsic_percentage(CSSPixels excess_width, ColumnFilter column_filter); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 01:33:37 +00:00
										 |  |  |     bool use_fixed_mode_layout() const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-04-29 00:43:05 +03:00
										 |  |  |     CSSPixels m_table_height { 0 }; | 
					
						
							| 
									
										
										
										
											2022-12-15 12:57:36 +00:00
										 |  |  |     CSSPixels m_automatic_content_height { 0 }; | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-05 18:44:04 +03:00
										 |  |  |     Optional<AvailableSpace> m_available_space; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  |     struct Column { | 
					
						
							| 
									
										
										
										
											2022-12-15 12:57:36 +00:00
										 |  |  |         CSSPixels left_offset { 0 }; | 
					
						
							| 
									
										
										
										
											2023-06-08 03:37:26 +00:00
										 |  |  |         CSSPixels min_size { 0 }; | 
					
						
							|  |  |  |         CSSPixels max_size { 0 }; | 
					
						
							| 
									
										
										
										
											2022-12-15 12:57:36 +00:00
										 |  |  |         CSSPixels used_width { 0 }; | 
					
						
							| 
									
										
										
										
											2023-07-17 00:23:07 +00:00
										 |  |  |         bool has_intrinsic_percentage { false }; | 
					
						
							|  |  |  |         double intrinsic_percentage { 0 }; | 
					
						
							| 
									
										
										
										
											2023-06-28 03:06:03 +00:00
										 |  |  |         // Store whether the column is constrained: https://www.w3.org/TR/css-tables-3/#constrainedness
 | 
					
						
							|  |  |  |         bool is_constrained { false }; | 
					
						
							| 
									
										
										
										
											2023-07-15 02:46:47 +00:00
										 |  |  |         // Store whether the column has originating cells, defined in https://www.w3.org/TR/css-tables-3/#terminology.
 | 
					
						
							|  |  |  |         bool has_originating_cells { false }; | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-20 03:08:38 +00:00
										 |  |  |     using Cell = TableGrid::Cell; | 
					
						
							|  |  |  |     using Row = TableGrid::Row; | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 03:37:26 +00:00
										 |  |  |     // Accessors to enable direction-agnostic table measurement.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static size_t cell_span(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static size_t cell_index(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static CSSPixels cell_min_size(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static CSSPixels cell_max_size(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-17 01:22:11 +00:00
										 |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static double cell_percentage_contribution(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     static bool cell_has_intrinsic_percentage(Cell const& cell); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     void initialize_intrinsic_percentages_from_rows_or_columns(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     void initialize_intrinsic_percentages_from_cells(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-16 02:48:56 +00:00
										 |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     CSSPixels border_spacing(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 03:37:26 +00:00
										 |  |  |     template<class RowOrColumn> | 
					
						
							|  |  |  |     Vector<RowOrColumn>& table_rows_or_columns(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-18 03:55:39 +00:00
										 |  |  |     CSSPixels compute_row_content_height(Cell const& cell) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |     enum class ConflictingSide { | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  |         Top, | 
					
						
							|  |  |  |         Bottom, | 
					
						
							|  |  |  |         Left, | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |         Right, | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |     struct ConflictingEdge { | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |         GC::Ptr<Node const> element; | 
					
						
							| 
									
										
										
										
											2023-07-12 04:20:37 +00:00
										 |  |  |         Painting::PaintableBox::ConflictingElementKind element_kind; | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |         ConflictingSide side; | 
					
						
							| 
									
										
										
										
											2023-07-12 04:20:37 +00:00
										 |  |  |         Optional<size_t> row; | 
					
						
							|  |  |  |         Optional<size_t> column; | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-12 04:20:37 +00:00
										 |  |  |     static TableFormattingContext::ConflictingEdge const& winning_conflicting_edge(TableFormattingContext::ConflictingEdge const& a, TableFormattingContext::ConflictingEdge const& b); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 03:02:54 +00:00
										 |  |  |     static const CSS::BorderData& border_data_conflicting_edge(ConflictingEdge const& conflicting_edge); | 
					
						
							| 
									
										
										
										
											2024-03-19 10:18:49 +01:00
										 |  |  |     static Painting::PaintableBox::BorderDataWithElementKind const border_data_with_element_kind_from_conflicting_edge(ConflictingEdge const& conflicting_edge); | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  |     class BorderConflictFinder { | 
					
						
							|  |  |  |     public: | 
					
						
							|  |  |  |         BorderConflictFinder(TableFormattingContext const* context); | 
					
						
							| 
									
										
										
										
											2023-07-02 03:39:06 +00:00
										 |  |  |         Vector<ConflictingEdge> conflicting_edges(Cell const&, ConflictingSide) const; | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     private: | 
					
						
							|  |  |  |         void collect_conflicting_col_elements(); | 
					
						
							| 
									
										
										
										
											2023-07-09 23:04:24 +00:00
										 |  |  |         void collect_conflicting_row_group_elements(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-19 03:07:39 +00:00
										 |  |  |         void collect_cell_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const; | 
					
						
							|  |  |  |         void collect_row_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const; | 
					
						
							|  |  |  |         void collect_row_group_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const; | 
					
						
							|  |  |  |         void collect_column_group_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const; | 
					
						
							|  |  |  |         void collect_table_box_conflicting_edges(Vector<ConflictingEdge>&, Cell const&, ConflictingSide) const; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |         GC::Ptr<Node const> get_col_element(size_t index) const | 
					
						
							| 
									
										
										
										
											2024-11-05 01:13:57 +01:00
										 |  |  |         { | 
					
						
							|  |  |  |             if (index >= m_col_elements_by_index.size()) | 
					
						
							|  |  |  |                 return {}; | 
					
						
							|  |  |  |             return m_col_elements_by_index[index]; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-09 23:04:24 +00:00
										 |  |  |         struct RowGroupInfo { | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |             GC::Ptr<Node const> row_group; | 
					
						
							| 
									
										
										
										
											2023-07-09 23:04:24 +00:00
										 |  |  |             size_t start_index; | 
					
						
							|  |  |  |             size_t row_count; | 
					
						
							|  |  |  |         }; | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-11-15 04:01:23 +13:00
										 |  |  |         Vector<GC::Ptr<Node const>> m_col_elements_by_index; | 
					
						
							| 
									
										
										
										
											2023-07-09 23:04:24 +00:00
										 |  |  |         Vector<Optional<RowGroupInfo>> m_row_group_elements_by_index; | 
					
						
							| 
									
										
										
										
											2023-06-04 14:21:20 +00:00
										 |  |  |         TableFormattingContext const* m_context; | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  |     Vector<Cell> m_cells; | 
					
						
							| 
									
										
										
										
											2023-07-09 03:02:54 +00:00
										 |  |  |     Vector<Vector<Optional<Cell const&>>> m_cells_by_coordinate; | 
					
						
							| 
									
										
										
										
											2022-12-04 22:39:38 +03:00
										 |  |  |     Vector<Column> m_columns; | 
					
						
							|  |  |  |     Vector<Row> m_rows; | 
					
						
							| 
									
										
										
										
											2020-11-22 13:38:18 +01:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |