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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 private: | 143 private: |
144 const Vector<Vector<Vector<RenderBox*, 1> > >& m_grid; | 144 const Vector<Vector<Vector<RenderBox*, 1> > >& m_grid; |
145 TrackSizingDirection m_direction; | 145 TrackSizingDirection m_direction; |
146 size_t m_rowIndex; | 146 size_t m_rowIndex; |
147 size_t m_columnIndex; | 147 size_t m_columnIndex; |
148 size_t m_childIndex; | 148 size_t m_childIndex; |
149 }; | 149 }; |
150 | 150 |
151 RenderGrid::RenderGrid(Element* element) | 151 RenderGrid::RenderGrid(Element* element) |
152 : RenderBlock(element) | 152 : RenderBlock(element) |
| 153 , m_orderIterator(this) |
153 { | 154 { |
154 // All of our children must be block level. | 155 // All of our children must be block level. |
155 setChildrenInline(false); | 156 setChildrenInline(false); |
156 } | 157 } |
157 | 158 |
158 RenderGrid::~RenderGrid() | 159 RenderGrid::~RenderGrid() |
159 { | 160 { |
160 } | 161 } |
161 | 162 |
162 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) | 163 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit) |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 size_t RenderGrid::explicitGridRowCount() const | 438 size_t RenderGrid::explicitGridRowCount() const |
438 { | 439 { |
439 return style()->gridDefinitionRows().size(); | 440 return style()->gridDefinitionRows().size(); |
440 } | 441 } |
441 | 442 |
442 size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const | 443 size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const |
443 { | 444 { |
444 return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColu
mnCount() : explicitGridRowCount(); | 445 return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColu
mnCount() : explicitGridRowCount(); |
445 } | 446 } |
446 | 447 |
447 size_t RenderGrid::maximumIndexInDirection(TrackSizingDirection direction) const | |
448 { | |
449 size_t maximumIndex = std::max<size_t>(1, (direction == ForColumns) ? explic
itGridColumnCount() : explicitGridRowCount()); | |
450 | |
451 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { | |
452 // This function bypasses the cache (cachedGridCoordinate()) as it is us
ed to build it. | |
453 OwnPtr<GridSpan> positions = resolveGridPositionsFromStyle(child, direct
ion); | |
454 | |
455 // |positions| is NULL if we need to run the auto-placement algorithm. O
ur estimation ignores | |
456 // this case as the auto-placement algorithm will grow the grid as neede
d. | |
457 if (!positions) | |
458 continue; | |
459 | |
460 maximumIndex = std::max(maximumIndex, positions->finalPositionIndex + 1)
; | |
461 } | |
462 | |
463 return maximumIndex; | |
464 } | |
465 | |
466 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<Gri
dTrack>& columnTracks) | 448 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<Gri
dTrack>& columnTracks) |
467 { | 449 { |
468 // FIXME: We shouldn't force a layout every time this function is called but | 450 // FIXME: We shouldn't force a layout every time this function is called but |
469 // 1) Return computeLogicalHeight's value if it's available. Unfortunately c
omputeLogicalHeight | 451 // 1) Return computeLogicalHeight's value if it's available. Unfortunately c
omputeLogicalHeight |
470 // doesn't return if the logical height is available so would need to be cha
nged. | 452 // doesn't return if the logical height is available so would need to be cha
nged. |
471 // 2) Relayout if the column track's used breadth changed OR the logical hei
ght is unavailable. | 453 // 2) Relayout if the column track's used breadth changed OR the logical hei
ght is unavailable. |
472 if (!child->needsLayout()) | 454 if (!child->needsLayout()) |
473 child->setNeedsLayout(true, MarkOnlyThis); | 455 child->setNeedsLayout(true, MarkOnlyThis); |
474 | 456 |
475 child->setOverrideContainingBlockContentLogicalWidth(gridAreaBreadthForChild
(child, ForColumns, columnTracks)); | 457 child->setOverrideContainingBlockContentLogicalWidth(gridAreaBreadthForChild
(child, ForColumns, columnTracks)); |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil
d, ForRows, rowTrack); | 618 const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(chil
d, ForRows, rowTrack); |
637 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c
hild, ForColumns, columnTrack); | 619 const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(c
hild, ForColumns, columnTrack); |
638 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); | 620 insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan)); |
639 } | 621 } |
640 | 622 |
641 void RenderGrid::placeItemsOnGrid() | 623 void RenderGrid::placeItemsOnGrid() |
642 { | 624 { |
643 ASSERT(!gridWasPopulated()); | 625 ASSERT(!gridWasPopulated()); |
644 ASSERT(m_gridItemCoordinate.isEmpty()); | 626 ASSERT(m_gridItemCoordinate.isEmpty()); |
645 | 627 |
646 m_grid.grow(maximumIndexInDirection(ForRows)); | 628 populateExplicitGridAndOrderIterator(); |
647 size_t maximumColumnIndex = maximumIndexInDirection(ForColumns); | |
648 for (size_t i = 0; i < m_grid.size(); ++i) | |
649 m_grid[i].grow(maximumColumnIndex); | |
650 | 629 |
651 Vector<RenderBox*> autoMajorAxisAutoGridItems; | 630 Vector<RenderBox*> autoMajorAxisAutoGridItems; |
652 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; | 631 Vector<RenderBox*> specifiedMajorAxisAutoGridItems; |
653 GridAutoFlow autoFlow = style()->gridAutoFlow(); | 632 GridAutoFlow autoFlow = style()->gridAutoFlow(); |
654 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { | 633 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) { |
655 // FIXME: We never re-resolve positions if the grid is grown during auto
-placement which may lead auto / <integer> | 634 // FIXME: We never re-resolve positions if the grid is grown during auto
-placement which may lead auto / <integer> |
656 // positions to not match the author's intent. The specification is uncl
ear on what should be done in this case. | 635 // positions to not match the author's intent. The specification is uncl
ear on what should be done in this case. |
657 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For
Rows); | 636 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For
Rows); |
658 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child,
ForColumns); | 637 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child,
ForColumns); |
659 if (!rowPositions || !columnPositions) { | 638 if (!rowPositions || !columnPositions) { |
660 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? columnPositions.get() : rowPositions.get(); | 639 GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() ==
ForColumns) ? columnPositions.get() : rowPositions.get(); |
661 if (!majorAxisPositions) | 640 if (!majorAxisPositions) |
662 autoMajorAxisAutoGridItems.append(child); | 641 autoMajorAxisAutoGridItems.append(child); |
663 else | 642 else |
664 specifiedMajorAxisAutoGridItems.append(child); | 643 specifiedMajorAxisAutoGridItems.append(child); |
665 continue; | 644 continue; |
666 } | 645 } |
667 insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions
)); | 646 insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions
)); |
668 } | 647 } |
669 | 648 |
670 ASSERT(gridRowCount() >= style()->gridDefinitionRows().size()); | 649 ASSERT(gridRowCount() >= style()->gridDefinitionRows().size()); |
671 ASSERT(gridColumnCount() >= style()->gridDefinitionColumns().size()); | 650 ASSERT(gridColumnCount() >= style()->gridDefinitionColumns().size()); |
672 | 651 |
673 if (autoFlow == AutoFlowNone) { | 652 if (autoFlow == AutoFlowNone) { |
674 // If we did collect some grid items, they won't be placed thus never la
id out. | 653 // If we did collect some grid items, they won't be placed thus never la
id out. |
675 ASSERT(!autoMajorAxisAutoGridItems.size()); | 654 ASSERT(!autoMajorAxisAutoGridItems.size()); |
676 ASSERT(!specifiedMajorAxisAutoGridItems.size()); | 655 ASSERT(!specifiedMajorAxisAutoGridItems.size()); |
677 return; | 656 return; |
678 } | 657 } |
679 | 658 |
680 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); | 659 placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems); |
681 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); | 660 placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems); |
682 } | 661 } |
683 | 662 |
| 663 void RenderGrid::populateExplicitGridAndOrderIterator() |
| 664 { |
| 665 // FIXME: We should find a way to share OrderIterator's Vector's |
| 666 // initialization code with RenderFlexibleBox. |
| 667 Vector<int> orderValues; |
| 668 bool anyChildHasDefaultOrderValue = false; |
| 669 |
| 670 size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount()); |
| 671 size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount()); |
| 672 |
| 673 for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBo
x()) { |
| 674 // Avoid growing the vector for the common-case default value of 0. |
| 675 if (int order = child->style()->order()) |
| 676 orderValues.append(child->style()->order()); |
| 677 else |
| 678 anyChildHasDefaultOrderValue = true; |
| 679 |
| 680 // This function bypasses the cache (cachedGridCoordinate()) as it is us
ed to build it. |
| 681 OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, For
Rows); |
| 682 OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child,
ForColumns); |
| 683 |
| 684 // |positions| is 0 if we need to run the auto-placement algorithm. Our
estimation ignores |
| 685 // this case as the auto-placement algorithm will grow the grid as neede
d. |
| 686 if (rowPositions) |
| 687 maximumRowIndex = std::max(maximumRowIndex, rowPositions->finalPosit
ionIndex + 1); |
| 688 if (columnPositions) |
| 689 maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->f
inalPositionIndex + 1); |
| 690 } |
| 691 |
| 692 m_grid.grow(maximumRowIndex); |
| 693 for (size_t i = 0; i < m_grid.size(); ++i) |
| 694 m_grid[i].grow(maximumColumnIndex); |
| 695 |
| 696 if (anyChildHasDefaultOrderValue) { |
| 697 // Avoid growing the vector to the default capacity of 16 if we're only
going to put one item in it. |
| 698 if (orderValues.isEmpty()) |
| 699 orderValues.reserveInitialCapacity(1); |
| 700 orderValues.append(0); |
| 701 } |
| 702 |
| 703 m_orderIterator.setOrderValues(orderValues); |
| 704 } |
| 705 |
684 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(Vector<RenderBox*> autoGridI
tems) | 706 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(Vector<RenderBox*> autoGridI
tems) |
685 { | 707 { |
686 for (size_t i = 0; i < autoGridItems.size(); ++i) { | 708 for (size_t i = 0; i < autoGridItems.size(); ++i) { |
687 OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(auto
GridItems[i], autoPlacementMajorAxisDirection()); | 709 OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(auto
GridItems[i], autoPlacementMajorAxisDirection()); |
688 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx
isPositions->initialPositionIndex); | 710 GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAx
isPositions->initialPositionIndex); |
689 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea())
{ | 711 if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea())
{ |
690 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPosi
tionIndex, emptyGridArea->columns.initialPositionIndex); | 712 insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPosi
tionIndex, emptyGridArea->columns.initialPositionIndex); |
691 continue; | 713 continue; |
692 } | 714 } |
693 | 715 |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
966 // FIXME: |columnTrack| and |rowTrack| should be smaller than our column / r
ow count. | 988 // FIXME: |columnTrack| and |rowTrack| should be smaller than our column / r
ow count. |
967 for (size_t i = 0; i < coordinate.columns.initialPositionIndex && i < column
Tracks.size(); ++i) | 989 for (size_t i = 0; i < coordinate.columns.initialPositionIndex && i < column
Tracks.size(); ++i) |
968 offset.setX(offset.x() + columnTracks[i].m_usedBreadth); | 990 offset.setX(offset.x() + columnTracks[i].m_usedBreadth); |
969 for (size_t i = 0; i < coordinate.rows.initialPositionIndex && i < rowTracks
.size(); ++i) | 991 for (size_t i = 0; i < coordinate.rows.initialPositionIndex && i < rowTracks
.size(); ++i) |
970 offset.setY(offset.y() + rowTracks[i].m_usedBreadth); | 992 offset.setY(offset.y() + rowTracks[i].m_usedBreadth); |
971 | 993 |
972 // FIXME: Handle margins on the grid item. | 994 // FIXME: Handle margins on the grid item. |
973 return offset; | 995 return offset; |
974 } | 996 } |
975 | 997 |
| 998 void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOff
set) |
| 999 { |
| 1000 for (RenderBox* child = m_orderIterator.first(); child; child = m_orderItera
tor.next()) |
| 1001 paintChild(child, paintInfo, paintOffset); |
| 1002 } |
| 1003 |
976 const char* RenderGrid::renderName() const | 1004 const char* RenderGrid::renderName() const |
977 { | 1005 { |
978 if (isFloating()) | 1006 if (isFloating()) |
979 return "RenderGrid (floating)"; | 1007 return "RenderGrid (floating)"; |
980 if (isOutOfFlowPositioned()) | 1008 if (isOutOfFlowPositioned()) |
981 return "RenderGrid (positioned)"; | 1009 return "RenderGrid (positioned)"; |
982 if (isAnonymous()) | 1010 if (isAnonymous()) |
983 return "RenderGrid (generated)"; | 1011 return "RenderGrid (generated)"; |
984 if (isRelPositioned()) | 1012 if (isRelPositioned()) |
985 return "RenderGrid (relative positioned)"; | 1013 return "RenderGrid (relative positioned)"; |
986 return "RenderGrid"; | 1014 return "RenderGrid"; |
987 } | 1015 } |
988 | 1016 |
989 } // namespace WebCore | 1017 } // namespace WebCore |
OLD | NEW |