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 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 std::reference_wrapper<RenderBox> m_gridItem; |
|
Julien - ping for review
2014/10/13 19:38:18
I would just use a pointer, which is unfortunate,
svillar
2014/10/14 06:32:01
Acknowledged.
| |
| 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 |