Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2011 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 114 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { | 114 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { |
| 115 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; | 115 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; |
| 116 if (m_childIndex < children.size()) | 116 if (m_childIndex < children.size()) |
| 117 return children[m_childIndex++]; | 117 return children[m_childIndex++]; |
| 118 | 118 |
| 119 m_childIndex = 0; | 119 m_childIndex = 0; |
| 120 } | 120 } |
| 121 return 0; | 121 return 0; |
| 122 } | 122 } |
| 123 | 123 |
| 124 PassOwnPtr<GridCoordinate> nextEmptyGridArea() | 124 bool checkEmptyCells(size_t rowSpan, size_t columnSpan) const |
| 125 { | |
| 126 // Ignore cells outside current grid as we will grow it later if needed. | |
| 127 size_t maxRows = std::min(m_rowIndex + rowSpan, m_grid.size()); | |
| 128 size_t maxColumns = std::min(m_columnIndex + columnSpan, m_grid[0].size( )); | |
| 129 | |
| 130 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spanning areas to be small. | |
| 131 for (size_t row = m_rowIndex; row < maxRows; ++row) { | |
| 132 for (size_t column = m_columnIndex; column < maxColumns; ++column) { | |
| 133 const GridCell& children = m_grid[row][column]; | |
| 134 if (!children.isEmpty()) | |
| 135 return false; | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 return true; | |
| 140 } | |
| 141 | |
| 142 PassOwnPtr<GridCoordinate> nextEmptyGridArea(size_t fixedTrackSpan, size_t v aryingTrackSpan) | |
| 125 { | 143 { |
| 126 ASSERT(!m_grid.isEmpty()); | 144 ASSERT(!m_grid.isEmpty()); |
| 145 ASSERT(fixedTrackSpan >= 1 && varyingTrackSpan >= 1); | |
| 146 | |
| 147 size_t rowSpan = (m_direction == ForColumns) ? varyingTrackSpan : fixedT rackSpan; | |
| 148 size_t columnSpan = (m_direction == ForColumns) ? fixedTrackSpan : varyi ngTrackSpan; | |
| 127 | 149 |
| 128 size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m _columnIndex; | 150 size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m _columnIndex; |
| 129 const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_gr id.size() : m_grid[0].size(); | 151 const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_gr id.size() : m_grid[0].size(); |
| 130 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { | 152 for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) { |
| 131 const GridCell& children = m_grid[m_rowIndex][m_columnIndex]; | 153 if (checkEmptyCells(rowSpan, columnSpan)) { |
| 132 if (children.isEmpty()) { | 154 OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(Grid Span(m_rowIndex, m_rowIndex + rowSpan - 1), GridSpan(m_columnIndex, m_columnInde x + columnSpan - 1))); |
| 133 OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(Grid Span(m_rowIndex, m_rowIndex), GridSpan(m_columnIndex, m_columnIndex))); | |
| 134 // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over. | 155 // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over. |
| 135 ++varyingTrackIndex; | 156 ++varyingTrackIndex; |
| 136 return result.release(); | 157 return result.release(); |
| 137 } | 158 } |
| 138 } | 159 } |
| 139 return nullptr; | 160 return nullptr; |
| 140 } | 161 } |
| 141 | 162 |
| 142 private: | 163 private: |
| 143 const GridRepresentation& m_grid; | 164 const GridRepresentation& m_grid; |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 840 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA utoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0)); | 861 GridSpan positions = GridResolvedPosition::resolveGridPositionsFromA utoPlacementPosition(*style(), *child, ForColumns, GridResolvedPosition(0)); |
| 841 maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions. resolvedFinalPosition.next().toInt()); | 862 maximumColumnIndex = std::max<size_t>(maximumColumnIndex, positions. resolvedFinalPosition.next().toInt()); |
| 842 } | 863 } |
| 843 } | 864 } |
| 844 | 865 |
| 845 m_grid.grow(maximumRowIndex); | 866 m_grid.grow(maximumRowIndex); |
| 846 for (size_t i = 0; i < m_grid.size(); ++i) | 867 for (size_t i = 0; i < m_grid.size(); ++i) |
| 847 m_grid[i].grow(maximumColumnIndex); | 868 m_grid[i].grow(maximumColumnIndex); |
| 848 } | 869 } |
| 849 | 870 |
| 850 bool RenderGrid::checkEmptyCells(const GridCoordinate& coordinate) const | |
| 851 { | |
| 852 // Ignore cells outside current grid as we will grow it later if needed. | |
| 853 size_t maxRows = std::min(coordinate.rows.resolvedFinalPosition.next().toInt (), gridRowCount()); | |
| 854 size_t maxColumns = std::min(coordinate.columns.resolvedFinalPosition.next() .toInt(), gridColumnCount()); | |
| 855 | |
| 856 // This adds a O(N^2) behavior that shouldn't be a big deal as we expect spa nning areas to be small. | |
| 857 for (size_t row = coordinate.rows.resolvedInitialPosition.toInt(); row < max Rows; ++row) { | |
| 858 for (size_t column = coordinate.columns.resolvedInitialPosition.toInt(); column < maxColumns; ++column) { | |
| 859 const GridCell& children = m_grid[row][column]; | |
| 860 if (!children.isEmpty()) | |
| 861 return false; | |
| 862 } | |
| 863 } | |
| 864 | |
| 865 return true; | |
| 866 } | |
| 867 | |
| 868 PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOu tsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection , const GridSpan& specifiedPositions) const | 871 PassOwnPtr<GridCoordinate> RenderGrid::createEmptyGridAreaAtSpecifiedPositionsOu tsideGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection , const GridSpan& specifiedPositions) const |
| 869 { | 872 { |
| 870 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns; | 873 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns; |
| 871 const size_t endOfCrossDirection = crossDirection == ForColumns ? gridColumn Count() : gridRowCount(); | 874 const size_t endOfCrossDirection = crossDirection == ForColumns ? gridColumn Count() : gridRowCount(); |
| 872 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosition sFromAutoPlacementPosition(*style(), *gridItem, crossDirection, GridResolvedPosi tion(endOfCrossDirection)); | 875 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosition sFromAutoPlacementPosition(*style(), *gridItem, crossDirection, GridResolvedPosi tion(endOfCrossDirection)); |
| 873 return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossD irectionPositions : specifiedPositions, specifiedDirection == ForColumns ? speci fiedPositions : crossDirectionPositions)); | 876 return adoptPtr(new GridCoordinate(specifiedDirection == ForColumns ? crossD irectionPositions : specifiedPositions, specifiedDirection == ForColumns ? speci fiedPositions : crossDirectionPositions)); |
| 874 } | 877 } |
| 875 | 878 |
| 876 PassOwnPtr<GridCoordinate> RenderGrid::findEmptyGridAreaAtSpecifiedPositionsInsi deGrid(const RenderBox* gridItem, GridTrackSizingDirection specifiedDirection, c onst GridSpan& specifiedPositions) const | |
| 877 { | |
| 878 GridTrackSizingDirection crossDirection = specifiedDirection == ForColumns ? ForRows : ForColumns; | |
| 879 | |
| 880 GridIterator iterator(m_grid, specifiedDirection, specifiedPositions.resolve dInitialPosition.toInt()); | |
| 881 OwnPtr<GridCoordinate> emptyGridArea; | |
| 882 for (emptyGridArea = iterator.nextEmptyGridArea(); emptyGridArea; emptyGridA rea = iterator.nextEmptyGridArea()) { | |
| 883 GridResolvedPosition crossDirectionInitialPositionIndex = crossDirection == ForColumns ? emptyGridArea->columns.resolvedInitialPosition : emptyGridArea- >rows.resolvedInitialPosition; | |
| 884 GridSpan crossDirectionPositions = GridResolvedPosition::resolveGridPosi tionsFromAutoPlacementPosition(*style(), *gridItem, crossDirection, crossDirecti onInitialPositionIndex); | |
| 885 | |
| 886 emptyGridArea->rows = specifiedDirection == ForColumns ? crossDirectionP ositions : specifiedPositions; | |
| 887 emptyGridArea->columns = specifiedDirection == ForColumns ? specifiedPos itions : crossDirectionPositions; | |
| 888 if (checkEmptyCells(*emptyGridArea)) | |
| 889 break; | |
| 890 } | |
| 891 | |
| 892 return emptyGridArea.release(); | |
| 893 } | |
| 894 | |
| 895 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au toGridItems) | 879 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& au toGridItems) |
| 896 { | 880 { |
| 897 for (size_t i = 0; i < autoGridItems.size(); ++i) { | 881 for (size_t i = 0; i < autoGridItems.size(); ++i) { |
| 898 OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridP ositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection() ); | 882 OwnPtr<GridSpan> majorAxisPositions = GridResolvedPosition::resolveGridP ositionsFromStyle(*style(), *autoGridItems[i], autoPlacementMajorAxisDirection() ); |
| 899 OwnPtr<GridCoordinate> emptyGridArea = findEmptyGridAreaAtSpecifiedPosit ionsInsideGrid(autoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPo sitions); | 883 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions FromAutoPlacementPosition(*style(), *autoGridItems[i], autoPlacementMinorAxisDir ection(), GridResolvedPosition(0)); |
| 884 | |
| 885 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx isPositions->resolvedInitialPosition.toInt()); | |
| 886 OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea(majorA xisPositions->integerSpan(), minorAxisPositions.integerSpan()); | |
| 900 if (!emptyGridArea) | 887 if (!emptyGridArea) |
| 901 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(a utoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions); | 888 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(a utoGridItems[i], autoPlacementMajorAxisDirection(), *majorAxisPositions); |
| 902 insertItemIntoGrid(autoGridItems[i], *emptyGridArea); | 889 insertItemIntoGrid(autoGridItems[i], *emptyGridArea); |
| 903 } | 890 } |
| 904 } | 891 } |
| 905 | 892 |
| 906 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri dItems) | 893 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGri dItems) |
| 907 { | 894 { |
| 908 for (size_t i = 0; i < autoGridItems.size(); ++i) | 895 for (size_t i = 0; i < autoGridItems.size(); ++i) |
| 909 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); | 896 placeAutoMajorAxisItemOnGrid(autoGridItems[i]); |
| 910 } | 897 } |
| 911 | 898 |
| 912 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) | 899 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem) |
| 913 { | 900 { |
| 914 OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPosit ionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection()); | 901 OwnPtr<GridSpan> minorAxisPositions = GridResolvedPosition::resolveGridPosit ionsFromStyle(*style(), *gridItem, autoPlacementMinorAxisDirection()); |
| 915 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridI tem, autoPlacementMajorAxisDirection())); | 902 ASSERT(!GridResolvedPosition::resolveGridPositionsFromStyle(*style(), *gridI tem, autoPlacementMajorAxisDirection())); |
| 916 OwnPtr<GridCoordinate> emptyGridArea; | 903 OwnPtr<GridCoordinate> emptyGridArea; |
| 917 if (minorAxisPositions) { | 904 if (minorAxisPositions) { |
| 918 emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(gridItem , autoPlacementMinorAxisDirection(), *minorAxisPositions); | 905 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositions FromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection() , GridResolvedPosition(0)); |
| 906 | |
| 907 GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAx isPositions->resolvedInitialPosition.toInt()); | |
| 908 emptyGridArea = iterator.nextEmptyGridArea(minorAxisPositions->integerSp an(), majorAxisPositions.integerSpan()); | |
| 919 if (!emptyGridArea) | 909 if (!emptyGridArea) |
| 920 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g ridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions); | 910 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g ridItem, autoPlacementMinorAxisDirection(), *minorAxisPositions); |
| 921 } else { | 911 } else { |
| 912 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPositions FromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirection() , GridResolvedPosition(0)); | |
|
Julien - ping for review
2014/06/16 20:31:35
This line is now common to the 2 branches and it c
Manuel Rego
2014/06/16 21:15:34
Yeah, you're right. I'm moving it outside the if.
| |
| 913 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPositions FromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirection() , GridResolvedPosition(0)); | |
| 914 | |
| 922 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC olumns) ? gridColumnCount() : gridRowCount(); | 915 const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForC olumns) ? gridColumnCount() : gridRowCount(); |
| 923 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major AxisIndex) { | 916 for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++major AxisIndex) { |
| 924 // We need to resolve the position for every different index as the number of cells might vary depending on it. | 917 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), maj orAxisIndex); |
| 925 // This will happen when we have "span <custom-indent>", which has a different resolution based on the position. | 918 emptyGridArea = iterator.nextEmptyGridArea(majorAxisPositions.intege rSpan(), minorAxisPositions.integerSpan()); |
| 926 GridSpan majorAxisPositions = GridResolvedPosition::resolveGridPosit ionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMajorAxisDirecti on(), majorAxisIndex); | |
| 927 emptyGridArea = findEmptyGridAreaAtSpecifiedPositionsInsideGrid(grid Item, autoPlacementMajorAxisDirection(), majorAxisPositions); | |
| 928 | 919 |
| 929 if (emptyGridArea) { | 920 if (emptyGridArea) { |
| 930 // Check that it fits in the minor axis direction, as we shouldn 't grow in that direction here (it was already managed in populateExplicitGridAn dOrderIterator()). | 921 // Check that it fits in the minor axis direction, as we shouldn 't grow in that direction here (it was already managed in populateExplicitGridAn dOrderIterator()). |
| 931 GridResolvedPosition minorAxisFinalPositionIndex = autoPlacement MinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPositio n : emptyGridArea->rows.resolvedFinalPosition; | 922 GridResolvedPosition minorAxisFinalPositionIndex = autoPlacement MinorAxisDirection() == ForColumns ? emptyGridArea->columns.resolvedFinalPositio n : emptyGridArea->rows.resolvedFinalPosition; |
| 932 const size_t endOfMinorAxis = autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() : gridRowCount(); | 923 const size_t endOfMinorAxis = autoPlacementMinorAxisDirection() == ForColumns ? gridColumnCount() : gridRowCount(); |
| 933 if (minorAxisFinalPositionIndex.toInt() < endOfMinorAxis) | 924 if (minorAxisFinalPositionIndex.toInt() < endOfMinorAxis) |
| 934 break; | 925 break; |
| 935 } | 926 } |
| 936 } | 927 } |
| 937 | 928 |
| 938 if (!emptyGridArea) { | 929 if (!emptyGridArea) |
| 939 GridSpan minorAxisPositions = GridResolvedPosition::resolveGridPosit ionsFromAutoPlacementPosition(*style(), *gridItem, autoPlacementMinorAxisDirecti on(), GridResolvedPosition(0)); | |
| 940 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); | 930 emptyGridArea = createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(g ridItem, autoPlacementMinorAxisDirection(), minorAxisPositions); |
| 941 } | |
| 942 } | 931 } |
| 943 | 932 |
| 944 insertItemIntoGrid(gridItem, *emptyGridArea); | 933 insertItemIntoGrid(gridItem, *emptyGridArea); |
| 945 } | 934 } |
| 946 | 935 |
| 947 GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const | 936 GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const |
| 948 { | 937 { |
| 949 GridAutoFlow flow = style()->gridAutoFlow(); | 938 GridAutoFlow flow = style()->gridAutoFlow(); |
| 950 ASSERT(flow != AutoFlowNone); | 939 ASSERT(flow != AutoFlowNone); |
| 951 return (flow == AutoFlowColumn) ? ForColumns : ForRows; | 940 return (flow == AutoFlowColumn) ? ForColumns : ForRows; |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1259 if (isOutOfFlowPositioned()) | 1248 if (isOutOfFlowPositioned()) |
| 1260 return "RenderGrid (positioned)"; | 1249 return "RenderGrid (positioned)"; |
| 1261 if (isAnonymous()) | 1250 if (isAnonymous()) |
| 1262 return "RenderGrid (generated)"; | 1251 return "RenderGrid (generated)"; |
| 1263 if (isRelPositioned()) | 1252 if (isRelPositioned()) |
| 1264 return "RenderGrid (relative positioned)"; | 1253 return "RenderGrid (relative positioned)"; |
| 1265 return "RenderGrid"; | 1254 return "RenderGrid"; |
| 1266 } | 1255 } |
| 1267 | 1256 |
| 1268 } // namespace WebCore | 1257 } // namespace WebCore |
| OLD | NEW |