diff options
author | martinfalisse <martinmotteditfalisse@gmail.com> | 2023-01-17 13:50:41 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-01-21 14:35:00 +0100 |
commit | 47c77858b60a29c4b165795f2cd6afd93d3f468c (patch) | |
tree | e484ce882d731f59b1184ec52a6bae42236a9d89 /Userland/Libraries/LibWeb/Layout | |
parent | fa5d0161767d3d2d7cd5c3754ac4f36f36ee73ce (diff) | |
download | serenity-47c77858b60a29c4b165795f2cd6afd93d3f468c.zip |
LibWeb: Calculate valid grid areas
When starting the GridFormattingContext, calculate the valid grid areas
as declared in the `grid-template-areas` property. Since this doesn't
change, are able to do this once and store the results.
Diffstat (limited to 'Userland/Libraries/LibWeb/Layout')
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp | 49 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/GridFormattingContext.h | 11 |
2 files changed, 60 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp index deff848ef6..d33b98340c 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.cpp @@ -1591,6 +1591,53 @@ void GridFormattingContext::calculate_sizes_of_rows(Box const& box) } } +void GridFormattingContext::build_valid_grid_areas(Box const& box) +{ + Vector<GridArea> found_grid_areas; + + auto get_index_of_found_grid_area = [&](String needle) -> int { + for (size_t x = 0; x < found_grid_areas.size(); x++) { + if (found_grid_areas[x].name == needle) + return static_cast<int>(x); + } + return -1; + }; + + // https://www.w3.org/TR/css-grid-2/#grid-template-areas-property + // If a named grid area spans multiple grid cells, but those cells do not form a single + // filled-in rectangle, the declaration is invalid. + for (int y = 0; y < static_cast<int>(box.computed_values().grid_template_areas().size()); y++) { + for (int x = 0; x < static_cast<int>(box.computed_values().grid_template_areas()[y].size()); x++) { + auto grid_area_idx = get_index_of_found_grid_area(box.computed_values().grid_template_areas()[y][x]); + if (grid_area_idx == -1) { + found_grid_areas.append({ box.computed_values().grid_template_areas()[y][x], y, y + 1, x, x + 1 }); + } else { + auto& grid_area = found_grid_areas[grid_area_idx]; + if (grid_area.row_start == y) { + if (grid_area.column_end == x) + grid_area.column_end = grid_area.column_end + 1; + else + return; + } else { + if (grid_area.row_end == y) { + if (grid_area.column_start != x) + return; + grid_area.row_end = grid_area.row_end + 1; + } else if (grid_area.row_end == y + 1) { + if (grid_area.column_end < x || grid_area.column_end > x + 1) + return; + } else { + return; + } + } + } + } + } + + for (auto const& checked_grid_area : found_grid_areas) + m_valid_grid_areas.append(checked_grid_area); +} + void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const& available_space) { auto grid_template_columns = box.computed_values().grid_template_columns(); @@ -1614,6 +1661,8 @@ void GridFormattingContext::run(Box const& box, LayoutMode, AvailableSpace const m_occupation_grid = OccupationGrid(column_count, row_count); + build_valid_grid_areas(box); + // https://drafts.csswg.org/css-grid/#auto-placement-algo // 8.5. Grid Item Placement Algorithm diff --git a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h index a79264f9cb..6c43f71b6f 100644 --- a/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h +++ b/Userland/Libraries/LibWeb/Layout/GridFormattingContext.h @@ -89,6 +89,15 @@ private: } }; + struct GridArea { + String name; + int row_start { 0 }; + int row_end { 1 }; + int column_start { 0 }; + int column_end { 1 }; + }; + Vector<GridArea> m_valid_grid_areas; + Vector<TemporaryTrack> m_grid_rows; Vector<TemporaryTrack> m_grid_columns; @@ -107,6 +116,8 @@ private: int count_of_repeated_auto_fill_or_fit_tracks(Vector<CSS::ExplicitGridTrack> const& track_list, AvailableSpace const&, Box const&); int get_count_of_tracks(Vector<CSS::ExplicitGridTrack> const&, AvailableSpace const&, Box const&); + void build_valid_grid_areas(Box const&); + void place_item_with_row_and_column_position(Box const& box, Box const& child_box); void place_item_with_row_position(Box const& box, Box const& child_box); void place_item_with_column_position(Box const& box, Box const& child_box, int& auto_placement_cursor_x, int& auto_placement_cursor_y); |