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