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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 { | 179 { |
180 } | 180 } |
181 | 181 |
182 Vector<GridTrack> columnTracks; | 182 Vector<GridTrack> columnTracks; |
183 Vector<GridTrack> rowTracks; | 183 Vector<GridTrack> rowTracks; |
184 Vector<size_t> contentSizedTracksIndex; | 184 Vector<size_t> contentSizedTracksIndex; |
185 | 185 |
186 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. | 186 // Performance optimization: hold onto these Vectors until the end of Layout
to avoid repeated malloc / free. |
187 Vector<LayoutUnit> distributeTrackVector; | 187 Vector<LayoutUnit> distributeTrackVector; |
188 Vector<GridTrack*> filteredTracks; | 188 Vector<GridTrack*> filteredTracks; |
| 189 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
189 }; | 190 }; |
190 | 191 |
191 RenderGrid::RenderGrid(Element* element) | 192 RenderGrid::RenderGrid(Element* element) |
192 : RenderBlock(element) | 193 : RenderBlock(element) |
193 , m_gridIsDirty(true) | 194 , m_gridIsDirty(true) |
194 , m_orderIterator(this) | 195 , m_orderIterator(this) |
195 { | 196 { |
196 ASSERT(!childrenInline()); | 197 ASSERT(!childrenInline()); |
197 } | 198 } |
198 | 199 |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 | 655 |
655 if (direction == ForColumns) { | 656 if (direction == ForColumns) { |
656 // FIXME: It's unclear if we should return the intrinsic width or the pr
eferred width. | 657 // FIXME: It's unclear if we should return the intrinsic width or the pr
eferred width. |
657 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html | 658 // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html |
658 return child.maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor
Child(&child); | 659 return child.maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthFor
Child(&child); |
659 } | 660 } |
660 | 661 |
661 return logicalHeightForChild(child, columnTracks); | 662 return logicalHeightForChild(child, columnTracks); |
662 } | 663 } |
663 | 664 |
664 size_t RenderGrid::gridItemSpan(const RenderBox& child, GridTrackSizingDirection
direction) | 665 // We're basically using a class instead of a std::pair for two reasons. First o
f all, accessing gridItem() or |
665 { | 666 // coordinate() is much more self-explanatory that using .first or .second membe
rs in the pair. Secondly the class |
666 GridCoordinate childCoordinate = cachedGridCoordinate(child); | 667 // allows us to precompute the value of the span, something which is quite conve
nient for the sorting. Having a |
667 GridSpan childSpan = (direction == ForRows) ? childCoordinate.rows : childCo
ordinate.columns; | 668 // std::pair<RenderBox*, size_t> does not work either because we still need the
GridCoordinate so we'd have to add an |
| 669 // extra hash lookup for each item at the beginning of RenderGrid::resolveConten
tBasedTrackSizingFunctionsForItems(). |
| 670 class GridItemWithSpan { |
| 671 public: |
| 672 GridItemWithSpan(RenderBox& gridItem, const GridCoordinate& coordinate, Grid
TrackSizingDirection direction) |
| 673 : m_gridItem(gridItem) |
| 674 , m_coordinate(coordinate) |
| 675 { |
| 676 const GridSpan& span = (direction == ForRows) ? coordinate.rows : coordi
nate.columns; |
| 677 m_span = span.resolvedFinalPosition.toInt() - span.resolvedInitialPositi
on.toInt() + 1; |
| 678 } |
668 | 679 |
669 return childSpan.resolvedFinalPosition.toInt() - childSpan.resolvedInitialPo
sition.toInt() + 1; | 680 RenderBox& gridItem() const { return *m_gridItem; } |
670 } | 681 GridCoordinate coordinate() const { return m_coordinate; } |
671 | 682 |
672 typedef std::pair<RenderBox*, size_t> GridItemWithSpan; | 683 bool operator<(const GridItemWithSpan other) const { return m_span < other.m
_span; } |
673 | 684 |
674 // This function sorts by span (.second in the pair) but also places pointers (.
first in the pair) to the same object in | 685 private: |
675 // consecutive positions so duplicates could be easily removed with std::unique(
) for example. | 686 RawPtrWillBeMember<RenderBox> m_gridItem; |
676 static bool gridItemWithSpanSorter(const GridItemWithSpan& item1, const GridItem
WithSpan& item2) | 687 GridCoordinate m_coordinate; |
677 { | 688 size_t m_span; |
678 if (item1.second != item2.second) | 689 }; |
679 return item1.second < item2.second; | |
680 | |
681 return item1.first < item2.first; | |
682 } | |
683 | |
684 static bool uniquePointerInPair(const GridItemWithSpan& item1, const GridItemWit
hSpan& item2) | |
685 { | |
686 return item1.first == item2.first; | |
687 } | |
688 | 690 |
689 void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
n direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace) | 691 void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirectio
n direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace) |
690 { | 692 { |
691 // FIXME: Split the grid tracks into groups that doesn't overlap a <flex> gr
id track (crbug.com/235258). | 693 sizingData.itemsSortedByIncreasingSpan.shrink(0); |
| 694 HashSet<RenderBox*> itemsSet; |
| 695 size_t contentSizedTracksCount = sizingData.contentSizedTracksIndex.size(); |
| 696 for (size_t i = 0; i < contentSizedTracksCount; ++i) { |
| 697 GridIterator iterator(m_grid, direction, sizingData.contentSizedTracksIn
dex[i]); |
| 698 while (RenderBox* gridItem = iterator.nextGridItem()) { |
| 699 if (itemsSet.add(gridItem).isNewEntry) |
| 700 sizingData.itemsSortedByIncreasingSpan.append(GridItemWithSpan(*
gridItem, cachedGridCoordinate(*gridItem), direction)); |
| 701 } |
| 702 } |
| 703 std::sort(sizingData.itemsSortedByIncreasingSpan.begin(), sizingData.itemsSo
rtedByIncreasingSpan.end()); |
692 | 704 |
693 for (size_t i = 0; i < sizingData.contentSizedTracksIndex.size(); ++i) { | 705 Vector<GridItemWithSpan>::iterator end = sizingData.itemsSortedByIncreasingS
pan.end(); |
| 706 for (Vector<GridItemWithSpan>::iterator it = sizingData.itemsSortedByIncreas
ingSpan.begin(); it != end; ++it) { |
| 707 // FIXME: do not consider items with a span > 1 that span a track with a
flexible sizing function. |
| 708 GridItemWithSpan itemWithSpan = *it; |
| 709 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, i
temWithSpan, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::min
ContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); |
| 710 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, i
temWithSpan, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxConte
ntForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); |
| 711 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, i
temWithSpan, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::min
ContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth
); |
| 712 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, i
temWithSpan, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxConte
ntForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth); |
| 713 } |
| 714 |
| 715 for (size_t i = 0; i < contentSizedTracksCount; ++i) { |
694 size_t trackIndex = sizingData.contentSizedTracksIndex[i]; | 716 size_t trackIndex = sizingData.contentSizedTracksIndex[i]; |
695 GridIterator iterator(m_grid, direction, trackIndex); | |
696 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; | |
697 | |
698 while (RenderBox* gridItem = iterator.nextGridItem()) | |
699 itemsSortedByIncreasingSpan.append(std::make_pair(gridItem, gridItem
Span(*gridItem, direction))); | |
700 std::stable_sort(itemsSortedByIncreasingSpan.begin(), itemsSortedByIncre
asingSpan.end(), gridItemWithSpanSorter); | |
701 Vector<GridItemWithSpan>::iterator end = std::unique(itemsSortedByIncrea
singSpan.begin(), itemsSortedByIncreasingSpan.end(), uniquePointerInPair); | |
702 | |
703 for (Vector<GridItemWithSpan>::iterator it = itemsSortedByIncreasingSpan
.begin(); it != end; ++it) { | |
704 RenderBox* gridItem = it->first; | |
705 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat
a, *gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::mi
nContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); | |
706 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat
a, *gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxCont
entForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); | |
707 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat
a, *gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::mi
nContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadt
h); | |
708 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat
a, *gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxCont
entForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth); | |
709 } | |
710 | |
711 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackIndex] : sizingData.rowTracks[trackIndex]; | 717 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackIndex] : sizingData.rowTracks[trackIndex]; |
712 if (track.m_maxBreadth == infinity) | 718 if (track.m_maxBreadth == infinity) |
713 track.m_maxBreadth = track.m_usedBreadth; | 719 track.m_maxBreadth = track.m_usedBreadth; |
714 } | 720 } |
715 } | 721 } |
716 | 722 |
717 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
Direction direction, GridSizingData& sizingData, RenderBox& gridItem, FilterFunc
tion filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGette
r, AccumulatorGrowFunction trackGrowthFunction) | 723 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing
Direction direction, GridSizingData& sizingData, GridItemWithSpan& gridItemWithS
pan, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGe
tter trackGetter, AccumulatorGrowFunction trackGrowthFunction) |
718 { | 724 { |
719 const GridCoordinate coordinate = cachedGridCoordinate(gridItem); | 725 const GridCoordinate coordinate = gridItemWithSpan.coordinate(); |
720 const GridResolvedPosition initialTrackPosition = (direction == ForColumns)
? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo
sition; | 726 const GridResolvedPosition initialTrackPosition = (direction == ForColumns)
? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo
sition; |
721 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ?
coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition
; | 727 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ?
coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition
; |
722 | 728 |
723 sizingData.filteredTracks.shrink(0); | 729 sizingData.filteredTracks.shrink(0); |
724 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio
n <= finalTrackPosition; ++trackPosition) { | 730 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio
n <= finalTrackPosition; ++trackPosition) { |
725 GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt()
); | 731 GridTrackSize trackSize = gridTrackSize(direction, trackPosition.toInt()
); |
726 if (!(trackSize.*filterFunction)()) | 732 if (!(trackSize.*filterFunction)()) |
727 continue; | 733 continue; |
728 | 734 |
729 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; | 735 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; |
730 sizingData.filteredTracks.append(&track); | 736 sizingData.filteredTracks.append(&track); |
731 } | 737 } |
732 | 738 |
733 if (sizingData.filteredTracks.isEmpty()) | 739 if (sizingData.filteredTracks.isEmpty()) |
734 return; | 740 return; |
735 | 741 |
736 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direct
ion, sizingData.columnTracks); | 742 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItemWithSpan
.gridItem(), direction, sizingData.columnTracks); |
737 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn
dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { | 743 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn
dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { |
738 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; | 744 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t
rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; |
739 additionalBreadthSpace -= (track.*trackGetter)(); | 745 additionalBreadthSpace -= (track.*trackGetter)(); |
740 } | 746 } |
741 | 747 |
742 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadt
h|. | 748 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadt
h|. |
743 | 749 |
744 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0
. Instead we directly avoid the function | 750 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0
. Instead we directly avoid the function |
745 // call in those cases as it will be a noop in terms of track sizing. | 751 // call in those cases as it will be a noop in terms of track sizing. |
746 if (additionalBreadthSpace > 0) | 752 if (additionalBreadthSpace > 0) |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1388 if (isOutOfFlowPositioned()) | 1394 if (isOutOfFlowPositioned()) |
1389 return "RenderGrid (positioned)"; | 1395 return "RenderGrid (positioned)"; |
1390 if (isAnonymous()) | 1396 if (isAnonymous()) |
1391 return "RenderGrid (generated)"; | 1397 return "RenderGrid (generated)"; |
1392 if (isRelPositioned()) | 1398 if (isRelPositioned()) |
1393 return "RenderGrid (relative positioned)"; | 1399 return "RenderGrid (relative positioned)"; |
1394 return "RenderGrid"; | 1400 return "RenderGrid"; |
1395 } | 1401 } |
1396 | 1402 |
1397 } // namespace blink | 1403 } // namespace blink |
OLD | NEW |