| 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 |