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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 { | 177 { |
| 178 } | 178 } |
| 179 | 179 |
| 180 Vector<GridTrack> columnTracks; | 180 Vector<GridTrack> columnTracks; |
| 181 Vector<GridTrack> rowTracks; | 181 Vector<GridTrack> rowTracks; |
| 182 Vector<size_t> contentSizedTracksIndex; | 182 Vector<size_t> contentSizedTracksIndex; |
| 183 | 183 |
| 184 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. | 184 // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free. |
| 185 Vector<LayoutUnit> distributeTrackVector; | 185 Vector<LayoutUnit> distributeTrackVector; |
| 186 Vector<GridTrack*> filteredTracks; | 186 Vector<GridTrack*> filteredTracks; |
| 187 Vector<size_t> growAboveMaxBreadthTrackIndexes; | |
| 187 }; | 188 }; |
| 188 | 189 |
| 189 RenderGrid::RenderGrid(Element* element) | 190 RenderGrid::RenderGrid(Element* element) |
| 190 : RenderBlock(element) | 191 : RenderBlock(element) |
| 191 , m_gridIsDirty(true) | 192 , m_gridIsDirty(true) |
| 192 , m_orderIterator(this) | 193 , m_orderIterator(this) |
| 193 { | 194 { |
| 194 ASSERT(!childrenInline()); | 195 ASSERT(!childrenInline()); |
| 195 } | 196 } |
| 196 | 197 |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 GridIterator iterator(m_grid, direction, trackIndex); | 695 GridIterator iterator(m_grid, direction, trackIndex); |
| 695 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; | 696 Vector<GridItemWithSpan> itemsSortedByIncreasingSpan; |
| 696 | 697 |
| 697 while (RenderBox* gridItem = iterator.nextGridItem()) | 698 while (RenderBox* gridItem = iterator.nextGridItem()) |
| 698 itemsSortedByIncreasingSpan.append(std::make_pair(gridItem, gridItem Span(*gridItem, direction))); | 699 itemsSortedByIncreasingSpan.append(std::make_pair(gridItem, gridItem Span(*gridItem, direction))); |
| 699 std::stable_sort(itemsSortedByIncreasingSpan.begin(), itemsSortedByIncre asingSpan.end(), gridItemWithSpanSorter); | 700 std::stable_sort(itemsSortedByIncreasingSpan.begin(), itemsSortedByIncre asingSpan.end(), gridItemWithSpanSorter); |
| 700 Vector<GridItemWithSpan>::iterator end = std::unique(itemsSortedByIncrea singSpan.begin(), itemsSortedByIncreasingSpan.end(), uniquePointerInPair); | 701 Vector<GridItemWithSpan>::iterator end = std::unique(itemsSortedByIncrea singSpan.begin(), itemsSortedByIncreasingSpan.end(), uniquePointerInPair); |
| 701 | 702 |
| 702 for (Vector<GridItemWithSpan>::iterator it = itemsSortedByIncreasingSpan .begin(); it != end; ++it) { | 703 for (Vector<GridItemWithSpan>::iterator it = itemsSortedByIncreasingSpan .begin(); it != end; ++it) { |
| 703 RenderBox* gridItem = it->first; | 704 RenderBox* gridItem = it->first; |
| 704 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::mi nContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); | 705 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::mi nContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, &GridTra ckSize::hasMinContentMinTrackBreadthAndMinOrMaxContentMaxTrackBreadth); |
| 705 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxCont entForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth); | 706 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxCont entForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, &GridTrackSiz e::hasMaxContentMinTrackBreadthAndMaxContentMaxTrackBreadth); |
| 706 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::mi nContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadt h); | 707 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::mi nContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadt h); |
| 707 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxCont entForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth); | 708 resolveContentBasedTrackSizingFunctionsForItems(direction, sizingDat a, *gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxCont entForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth); |
| 708 } | 709 } |
| 709 | 710 |
| 710 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndex] : sizingData.rowTracks[trackIndex]; | 711 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndex] : sizingData.rowTracks[trackIndex]; |
| 711 if (track.m_maxBreadth == infinity) | 712 if (track.m_maxBreadth == infinity) |
| 712 track.m_maxBreadth = track.m_usedBreadth; | 713 track.m_maxBreadth = track.m_usedBreadth; |
| 713 } | 714 } |
| 714 } | 715 } |
| 715 | 716 |
| 716 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, RenderBox& gridItem, FilterFunc tion filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGette r, AccumulatorGrowFunction trackGrowthFunction) | 717 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizing Direction direction, GridSizingData& sizingData, RenderBox& gridItem, FilterFunc tion filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGette r, AccumulatorGrowFunction trackGrowthFunction, FilterFunction growAboveMaxBread thFilterFunction) |
| 717 { | 718 { |
| 718 const GridCoordinate coordinate = cachedGridCoordinate(gridItem); | 719 const GridCoordinate coordinate = cachedGridCoordinate(gridItem); |
| 719 const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo sition; | 720 const GridResolvedPosition initialTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedInitialPosition : coordinate.rows.resolvedInitialPo sition; |
| 720 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition ; | 721 const GridResolvedPosition finalTrackPosition = (direction == ForColumns) ? coordinate.columns.resolvedFinalPosition : coordinate.rows.resolvedFinalPosition ; |
| 721 | 722 |
| 723 sizingData.growAboveMaxBreadthTrackIndexes.shrink(0); | |
| 722 sizingData.filteredTracks.shrink(0); | 724 sizingData.filteredTracks.shrink(0); |
| 723 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio n <= finalTrackPosition; ++trackPosition) { | 725 for (GridResolvedPosition trackPosition = initialTrackPosition; trackPositio n <= finalTrackPosition; ++trackPosition) { |
| 724 const GridTrackSize& trackSize = gridTrackSize(direction, trackPosition. toInt()); | 726 const GridTrackSize& trackSize = gridTrackSize(direction, trackPosition. toInt()); |
| 725 if (!(trackSize.*filterFunction)()) | 727 if (!(trackSize.*filterFunction)()) |
| 726 continue; | 728 continue; |
| 727 | 729 |
| 728 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; | 730 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackPosition.toInt()] : sizingData.rowTracks[trackPosition.toInt()]; |
| 729 sizingData.filteredTracks.append(&track); | 731 sizingData.filteredTracks.append(&track); |
| 732 | |
| 733 if (growAboveMaxBreadthFilterFunction && (trackSize.*growAboveMaxBreadth FilterFunction)()) | |
| 734 sizingData.growAboveMaxBreadthTrackIndexes.append(sizingData.filtere dTracks.size() - 1); | |
|
Julien - ping for review
2014/09/30 17:36:57
This line seems really weird: we are checking the
svillar
2014/10/01 07:48:56
The reason is because this function and distribute
Julien - ping for review
2014/10/21 16:58:08
Now I understand the rationale for the logic but s
svillar
2014/10/22 07:16:17
Exactly that's the reason why I used the indexes,
| |
| 730 } | 735 } |
| 731 | 736 |
| 732 if (sizingData.filteredTracks.isEmpty()) | 737 if (sizingData.filteredTracks.isEmpty()) |
| 733 return; | 738 return; |
| 734 | 739 |
| 735 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direct ion, sizingData.columnTracks); | 740 LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direct ion, sizingData.columnTracks); |
| 736 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { | 741 for (GridResolvedPosition trackIndexForSpace = initialTrackPosition; trackIn dexForSpace <= finalTrackPosition; ++trackIndexForSpace) { |
| 737 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; | 742 GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[t rackIndexForSpace.toInt()] : sizingData.rowTracks[trackIndexForSpace.toInt()]; |
| 738 additionalBreadthSpace -= (track.*trackGetter)(); | 743 additionalBreadthSpace -= (track.*trackGetter)(); |
| 739 } | 744 } |
| 740 | 745 |
| 741 // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadt h|. | |
| 742 | |
| 743 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0 . Instead we directly avoid the function | 746 // Specs mandate to floor additionalBreadthSpace (extra-space in specs) to 0 . Instead we directly avoid the function |
| 744 // call in those cases as it will be a noop in terms of track sizing. | 747 // call in those cases as it will be a noop in terms of track sizing. |
| 745 if (additionalBreadthSpace > 0) | 748 if (additionalBreadthSpace > 0) |
| 746 distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.filteredT racks, trackGetter, trackGrowthFunction, sizingData, additionalBreadthSpace); | 749 distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.growAbove MaxBreadthTrackIndexes, trackGetter, trackGrowthFunction, sizingData, additional BreadthSpace); |
| 747 } | 750 } |
| 748 | 751 |
| 749 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) | 752 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTr ack* track2) |
| 750 { | 753 { |
| 751 // This check ensures that we respect the irreflexivity property of the stri ct weak ordering required by std::sort | 754 // This check ensures that we respect the irreflexivity property of the stri ct weak ordering required by std::sort |
| 752 // (forall x: NOT x < x). | 755 // (forall x: NOT x < x). |
| 753 if (track1->m_maxBreadth == infinity && track2->m_maxBreadth == infinity) | 756 if (track1->m_maxBreadth == infinity && track2->m_maxBreadth == infinity) |
| 754 return false; | 757 return false; |
| 755 | 758 |
| 756 if (track1->m_maxBreadth == infinity || track2->m_maxBreadth == infinity) | 759 if (track1->m_maxBreadth == infinity || track2->m_maxBreadth == infinity) |
| 757 return track2->m_maxBreadth == infinity; | 760 return track2->m_maxBreadth == infinity; |
| 758 | 761 |
| 759 return (track1->m_maxBreadth - track1->m_usedBreadth) < (track2->m_maxBreadt h - track2->m_usedBreadth); | 762 return (track1->m_maxBreadth - track1->m_usedBreadth) < (track2->m_maxBreadt h - track2->m_usedBreadth); |
| 760 } | 763 } |
| 761 | 764 |
| 762 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<Grid Track*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter trackGetter, Accumula torGrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& ava ilableLogicalSpace) | 765 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<size _t>* growAboveMaxBreadthTrackIndexes, AccumulatorGetter trackGetter, Accumulator GrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& availa bleLogicalSpace) |
| 763 { | 766 { |
| 764 ASSERT(availableLogicalSpace > 0); | 767 ASSERT(availableLogicalSpace > 0); |
| 765 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential); | 768 std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential); |
| 766 | 769 |
| 767 size_t tracksSize = tracks.size(); | 770 size_t tracksSize = tracks.size(); |
| 768 sizingData.distributeTrackVector.resize(tracksSize); | 771 sizingData.distributeTrackVector.resize(tracksSize); |
| 769 | 772 |
| 770 for (size_t i = 0; i < tracksSize; ++i) { | 773 for (size_t i = 0; i < tracksSize; ++i) { |
| 771 GridTrack& track = *tracks[i]; | 774 GridTrack& track = *tracks[i]; |
| 772 LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksS ize - i); | 775 LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksS ize - i); |
| 773 LayoutUnit trackBreadth = (tracks[i]->*trackGetter)(); | 776 LayoutUnit trackBreadth = (tracks[i]->*trackGetter)(); |
| 774 LayoutUnit growthShare = track.m_maxBreadth == infinity ? availableLogic alSpaceShare : std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBr eadth); | 777 LayoutUnit growthShare = track.m_maxBreadth == infinity ? availableLogic alSpaceShare : std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBr eadth); |
| 775 ASSERT(growthShare != infinity); | 778 ASSERT(growthShare != infinity); |
| 776 sizingData.distributeTrackVector[i] = trackBreadth; | 779 sizingData.distributeTrackVector[i] = trackBreadth; |
| 777 // We should never shrink any grid track or else we can't guarantee we a bide by our min-sizing function. | 780 // We should never shrink any grid track or else we can't guarantee we a bide by our min-sizing function. |
| 778 if (growthShare > 0) { | 781 if (growthShare > 0) { |
| 779 sizingData.distributeTrackVector[i] += growthShare; | 782 sizingData.distributeTrackVector[i] += growthShare; |
| 780 availableLogicalSpace -= growthShare; | 783 availableLogicalSpace -= growthShare; |
| 781 } | 784 } |
| 782 } | 785 } |
| 783 | 786 |
| 784 if (availableLogicalSpace > 0 && tracksForGrowthAboveMaxBreadth) { | 787 if (availableLogicalSpace > 0 && growAboveMaxBreadthTrackIndexes) { |
| 785 tracksSize = tracksForGrowthAboveMaxBreadth->size(); | 788 size_t indexesSize = growAboveMaxBreadthTrackIndexes->size(); |
| 786 for (size_t i = 0; i < tracksSize; ++i) { | 789 size_t tracksGrowingAboveMaxBreadthSize = indexesSize ? indexesSize : tr acksSize; |
| 787 LayoutUnit growthShare = availableLogicalSpace / (tracksSize - i); | 790 // If we have a non-null empty vector of track indexes to grow above max breadth means that we should grow all |
| 788 sizingData.distributeTrackVector[i] += growthShare; | 791 // affected tracks. |
|
Julien - ping for review
2014/09/30 17:36:57
The specification uses 2 passes for growth. Is thi
svillar
2014/10/01 07:48:57
Hmm I don't get this. Which 2 passes are you talki
Julien - ping for review
2014/10/21 16:58:08
I think I was referring to this text from step 2:
svillar
2014/10/22 07:16:17
Yeah it isn't obvious after a first read but the f
| |
| 792 for (size_t i = 0; i < tracksGrowingAboveMaxBreadthSize; ++i) { | |
| 793 LayoutUnit growthShare = availableLogicalSpace / (tracksGrowingAbove MaxBreadthSize - i); | |
| 794 size_t distributeTrackIndex = indexesSize ? growAboveMaxBreadthTrack Indexes->at(i) : i; | |
| 795 sizingData.distributeTrackVector[distributeTrackIndex] += growthShar e; | |
| 789 availableLogicalSpace -= growthShare; | 796 availableLogicalSpace -= growthShare; |
| 790 } | 797 } |
| 791 } | 798 } |
| 792 | 799 |
| 793 for (size_t i = 0; i < tracksSize; ++i) { | 800 for (size_t i = 0; i < tracksSize; ++i) { |
| 794 LayoutUnit growth = sizingData.distributeTrackVector[i] - (tracks[i]->*t rackGetter)(); | 801 LayoutUnit growth = sizingData.distributeTrackVector[i] - (tracks[i]->*t rackGetter)(); |
| 795 if (growth >= 0) | 802 if (growth >= 0) |
| 796 (tracks[i]->*trackGrowthFunction)(growth); | 803 (tracks[i]->*trackGrowthFunction)(growth); |
| 797 } | 804 } |
| 798 } | 805 } |
| (...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1454 if (isOutOfFlowPositioned()) | 1461 if (isOutOfFlowPositioned()) |
| 1455 return "RenderGrid (positioned)"; | 1462 return "RenderGrid (positioned)"; |
| 1456 if (isAnonymous()) | 1463 if (isAnonymous()) |
| 1457 return "RenderGrid (generated)"; | 1464 return "RenderGrid (generated)"; |
| 1458 if (isRelPositioned()) | 1465 if (isRelPositioned()) |
| 1459 return "RenderGrid (relative positioned)"; | 1466 return "RenderGrid (relative positioned)"; |
| 1460 return "RenderGrid"; | 1467 return "RenderGrid"; |
| 1461 } | 1468 } |
| 1462 | 1469 |
| 1463 } // namespace blink | 1470 } // namespace blink |
| OLD | NEW |