Serenity Operating System
at master 149 lines 5.4 kB view raw
1/* 2 * Copyright (c) 2022-2023, Martin Falisse <mfalisse@outlook.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <LibWeb/CSS/Length.h> 10#include <LibWeb/Layout/FormattingContext.h> 11 12namespace Web::Layout { 13 14class OccupationGrid { 15public: 16 OccupationGrid(int column_count, int row_count); 17 OccupationGrid(); 18 19 void maybe_add_column(int needed_number_of_columns); 20 void maybe_add_row(int needed_number_of_rows); 21 void set_occupied(int column_start, int column_end, int row_start, int row_end); 22 void set_occupied(int column_index, int row_index); 23 24 int column_count() { return static_cast<int>(m_occupation_grid[0].size()); } 25 int row_count() { return static_cast<int>(m_occupation_grid.size()); } 26 bool is_occupied(int column_index, int row_index); 27 28private: 29 Vector<Vector<bool>> m_occupation_grid; 30}; 31 32class PositionedBox { 33public: 34 PositionedBox(Box const& box, int row, int row_span, int column, int column_span) 35 : m_box(box) 36 , m_row(row) 37 , m_row_span(row_span) 38 , m_column(column) 39 , m_column_span(column_span) 40 { 41 } 42 43 Box const& box() { return m_box; } 44 45 int raw_row_span() { return m_row_span; } 46 int raw_column_span() { return m_column_span; } 47 48 int gap_adjusted_row(Box const& parent_box); 49 int gap_adjusted_column(Box const& parent_box); 50 51private: 52 Box const& m_box; 53 int m_row { 0 }; 54 int m_row_span { 1 }; 55 int m_column { 0 }; 56 int m_column_span { 1 }; 57}; 58 59class GridFormattingContext final : public FormattingContext { 60public: 61 explicit GridFormattingContext(LayoutState&, Box const& grid_container, FormattingContext* parent); 62 ~GridFormattingContext(); 63 64 virtual void run(Box const&, LayoutMode, AvailableSpace const& available_space) override; 65 virtual CSSPixels automatic_content_height() const override; 66 67private: 68 CSSPixels m_automatic_content_height { 0 }; 69 bool is_auto_positioned_row(CSS::GridTrackPlacement const&, CSS::GridTrackPlacement const&) const; 70 bool is_auto_positioned_column(CSS::GridTrackPlacement const&, CSS::GridTrackPlacement const&) const; 71 bool is_auto_positioned_track(CSS::GridTrackPlacement const&, CSS::GridTrackPlacement const&) const; 72 73 struct TemporaryTrack { 74 CSS::GridSize min_track_sizing_function; 75 CSS::GridSize max_track_sizing_function; 76 CSSPixels base_size { 0 }; 77 CSSPixels growth_limit { 0 }; 78 CSSPixels space_to_distribute { 0 }; 79 CSSPixels planned_increase { 0 }; 80 bool is_gap { false }; 81 82 TemporaryTrack(CSS::GridSize min_track_sizing_function, CSS::GridSize max_track_sizing_function) 83 : min_track_sizing_function(min_track_sizing_function) 84 , max_track_sizing_function(max_track_sizing_function) 85 { 86 } 87 88 TemporaryTrack(CSS::GridSize track_sizing_function) 89 : min_track_sizing_function(track_sizing_function) 90 , max_track_sizing_function(track_sizing_function) 91 { 92 } 93 94 TemporaryTrack(CSSPixels size, bool is_gap) 95 : min_track_sizing_function(CSS::GridSize(CSS::Length::make_px(size))) 96 , max_track_sizing_function(CSS::GridSize(CSS::Length::make_px(size))) 97 , base_size(size) 98 , is_gap(is_gap) 99 { 100 } 101 102 TemporaryTrack() 103 : min_track_sizing_function(CSS::GridSize::make_auto()) 104 , max_track_sizing_function(CSS::GridSize::make_auto()) 105 { 106 } 107 }; 108 109 struct GridArea { 110 String name; 111 int row_start { 0 }; 112 int row_end { 1 }; 113 int column_start { 0 }; 114 int column_end { 1 }; 115 }; 116 Vector<GridArea> m_valid_grid_areas; 117 118 Vector<TemporaryTrack> m_grid_rows; 119 Vector<TemporaryTrack> m_grid_columns; 120 121 OccupationGrid m_occupation_grid; 122 Vector<PositionedBox> m_positioned_boxes; 123 Vector<Box const&> m_boxes_to_place; 124 125 CSSPixels get_free_space_x(AvailableSpace const& available_space); 126 CSSPixels get_free_space_y(Box const&); 127 128 int get_line_index_by_line_name(String const& line_name, CSS::GridTrackSizeList); 129 CSSPixels resolve_definite_track_size(CSS::GridSize const&, AvailableSpace const&, Box const&); 130 size_t count_of_gap_columns(); 131 size_t count_of_gap_rows(); 132 CSSPixels resolve_size(CSS::Size const&, AvailableSize const&, Box const&); 133 int count_of_repeated_auto_fill_or_fit_tracks(Vector<CSS::ExplicitGridTrack> const& track_list, AvailableSpace const&, Box const&); 134 int get_count_of_tracks(Vector<CSS::ExplicitGridTrack> const&, AvailableSpace const&, Box const&); 135 136 void build_valid_grid_areas(Box const&); 137 int find_valid_grid_area(String const& needle); 138 139 void place_item_with_row_and_column_position(Box const& box, Box const& child_box); 140 void place_item_with_row_position(Box const& box, Box const& child_box); 141 void place_item_with_column_position(Box const& box, Box const& child_box, int& auto_placement_cursor_x, int& auto_placement_cursor_y); 142 void place_item_with_no_declared_position(Box const& child_box, int& auto_placement_cursor_x, int& auto_placement_cursor_y); 143 144 void initialize_grid_tracks(Box const&, AvailableSpace const&, int column_count, int row_count); 145 void calculate_sizes_of_columns(Box const&, AvailableSpace const&); 146 void calculate_sizes_of_rows(Box const&); 147}; 148 149}