Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright (C) 2011 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "core/rendering/RenderGrid.h"
     28 
     29 #include "core/rendering/LayoutRepainter.h"
     30 #include "core/rendering/RenderLayer.h"
     31 #include "core/rendering/RenderView.h"
     32 #include "core/rendering/style/GridCoordinate.h"
     33 
     34 namespace WebCore {
     35 
     36 static const int infinity = -1;
     37 
     38 class GridTrack {
     39 public:
     40     GridTrack()
     41         : m_usedBreadth(0)
     42         , m_maxBreadth(0)
     43     {
     44     }
     45 
     46     void growUsedBreadth(LayoutUnit growth)
     47     {
     48         ASSERT(growth >= 0);
     49         m_usedBreadth += growth;
     50     }
     51     LayoutUnit usedBreadth() const { return m_usedBreadth; }
     52 
     53     void growMaxBreadth(LayoutUnit growth)
     54     {
     55         if (m_maxBreadth == infinity)
     56             m_maxBreadth = m_usedBreadth + growth;
     57         else
     58             m_maxBreadth += growth;
     59     }
     60     LayoutUnit maxBreadthIfNotInfinite() const
     61     {
     62         return (m_maxBreadth == infinity) ? m_usedBreadth : m_maxBreadth;
     63     }
     64 
     65     LayoutUnit m_usedBreadth;
     66     LayoutUnit m_maxBreadth;
     67 };
     68 
     69 struct GridTrackForNormalization {
     70     GridTrackForNormalization(const GridTrack& track, double flex)
     71         : m_track(&track)
     72         , m_flex(flex)
     73         , m_normalizedFlexValue(track.m_usedBreadth / flex)
     74     {
     75     }
     76 
     77     // Required by std::sort.
     78     GridTrackForNormalization operator=(const GridTrackForNormalization& o)
     79     {
     80         m_track = o.m_track;
     81         m_flex = o.m_flex;
     82         m_normalizedFlexValue = o.m_normalizedFlexValue;
     83         return *this;
     84     }
     85 
     86     const GridTrack* m_track;
     87     double m_flex;
     88     LayoutUnit m_normalizedFlexValue;
     89 };
     90 
     91 class RenderGrid::GridIterator {
     92     WTF_MAKE_NONCOPYABLE(GridIterator);
     93 public:
     94     // |direction| is the direction that is fixed to |fixedTrackIndex| so e.g
     95     // GridIterator(m_grid, ForColumns, 1) will walk over the rows of the 2nd column.
     96     GridIterator(const GridRepresentation& grid, GridTrackSizingDirection direction, size_t fixedTrackIndex)
     97         : m_grid(grid)
     98         , m_direction(direction)
     99         , m_rowIndex((direction == ForColumns) ? 0 : fixedTrackIndex)
    100         , m_columnIndex((direction == ForColumns) ? fixedTrackIndex : 0)
    101         , m_childIndex(0)
    102     {
    103         ASSERT(m_rowIndex < m_grid.size());
    104         ASSERT(m_columnIndex < m_grid[0].size());
    105     }
    106 
    107     RenderBox* nextGridItem()
    108     {
    109         ASSERT(!m_grid.isEmpty());
    110 
    111         size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
    112         const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
    113         for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
    114             const GridCell& children = m_grid[m_rowIndex][m_columnIndex];
    115             if (m_childIndex < children.size())
    116                 return children[m_childIndex++];
    117 
    118             m_childIndex = 0;
    119         }
    120         return 0;
    121     }
    122 
    123     PassOwnPtr<GridCoordinate> nextEmptyGridArea()
    124     {
    125         ASSERT(!m_grid.isEmpty());
    126 
    127         size_t& varyingTrackIndex = (m_direction == ForColumns) ? m_rowIndex : m_columnIndex;
    128         const size_t endOfVaryingTrackIndex = (m_direction == ForColumns) ? m_grid.size() : m_grid[0].size();
    129         for (; varyingTrackIndex < endOfVaryingTrackIndex; ++varyingTrackIndex) {
    130             const GridCell& children = m_grid[m_rowIndex][m_columnIndex];
    131             if (children.isEmpty()) {
    132                 OwnPtr<GridCoordinate> result = adoptPtr(new GridCoordinate(GridSpan(m_rowIndex, m_rowIndex), GridSpan(m_columnIndex, m_columnIndex)));
    133                 // Advance the iterator to avoid an infinite loop where we would return the same grid area over and over.
    134                 ++varyingTrackIndex;
    135                 return result.release();
    136             }
    137         }
    138         return nullptr;
    139     }
    140 
    141 private:
    142     const GridRepresentation& m_grid;
    143     GridTrackSizingDirection m_direction;
    144     size_t m_rowIndex;
    145     size_t m_columnIndex;
    146     size_t m_childIndex;
    147 };
    148 
    149 struct RenderGrid::GridSizingData {
    150     WTF_MAKE_NONCOPYABLE(GridSizingData);
    151 public:
    152     GridSizingData(size_t gridColumnCount, size_t gridRowCount)
    153         : columnTracks(gridColumnCount)
    154         , rowTracks(gridRowCount)
    155     {
    156     }
    157 
    158     Vector<GridTrack> columnTracks;
    159     Vector<GridTrack> rowTracks;
    160     Vector<size_t> contentSizedTracksIndex;
    161 
    162     // Performance optimization: hold onto these Vectors until the end of Layout to avoid repeated malloc / free.
    163     Vector<LayoutUnit> distributeTrackVector;
    164     Vector<GridTrack*> filteredTracks;
    165 };
    166 
    167 RenderGrid::RenderGrid(Element* element)
    168     : RenderBlock(element)
    169     , m_gridIsDirty(true)
    170     , m_orderIterator(this)
    171     , m_gridItemOverflowGridArea(false)
    172 {
    173     // All of our children must be block level.
    174     setChildrenInline(false);
    175 }
    176 
    177 RenderGrid::~RenderGrid()
    178 {
    179 }
    180 
    181 void RenderGrid::addChild(RenderObject* newChild, RenderObject* beforeChild)
    182 {
    183     RenderBlock::addChild(newChild, beforeChild);
    184 
    185     if (gridIsDirty())
    186         return;
    187 
    188     if (!newChild->isBox()) {
    189         dirtyGrid();
    190         return;
    191     }
    192 
    193     RenderBox* newChildBox = toRenderBox(newChild);
    194     OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(newChildBox, ForRows);
    195     OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(newChildBox, ForColumns);
    196     if (!rowPositions || !columnPositions) {
    197         // The new child requires the auto-placement algorithm to run so we need to recompute the grid fully.
    198         dirtyGrid();
    199     } else {
    200         if (gridRowCount() <= rowPositions->finalPositionIndex || gridColumnCount() <= columnPositions->finalPositionIndex) {
    201             // FIXME: We could just insert the new child provided we had a primitive to arbitrarily grow the grid.
    202             dirtyGrid();
    203         } else {
    204             insertItemIntoGrid(newChildBox, GridCoordinate(*rowPositions, *columnPositions));
    205         }
    206     }
    207 }
    208 
    209 void RenderGrid::removeChild(RenderObject* child)
    210 {
    211     RenderBlock::removeChild(child);
    212 
    213     if (gridIsDirty())
    214         return;
    215 
    216     ASSERT(child->isBox());
    217     // FIXME: We could avoid dirtying the grid in some cases (e.g. if it's an explicitly positioned element).
    218     dirtyGrid();
    219 }
    220 
    221 void RenderGrid::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    222 {
    223     RenderBlock::styleDidChange(diff, oldStyle);
    224     if (!oldStyle)
    225         return;
    226 
    227     // FIXME: The following checks could be narrowed down if we kept track of which type of grid items we have:
    228     // - explicit grid size changes impact negative explicitely positioned and auto-placed grid items.
    229     // - named grid lines only impact grid items with named grid lines.
    230     // - auto-flow changes only impacts auto-placed children.
    231 
    232     if (explicitGridDidResize(oldStyle)
    233         || namedGridLinesDefinitionDidChange(oldStyle)
    234         || oldStyle->gridAutoFlow() != style()->gridAutoFlow())
    235         dirtyGrid();
    236 }
    237 
    238 bool RenderGrid::explicitGridDidResize(const RenderStyle* oldStyle) const
    239 {
    240     return oldStyle->gridDefinitionColumns().size() != style()->gridDefinitionColumns().size()
    241         || oldStyle->gridDefinitionRows().size() != style()->gridDefinitionRows().size();
    242 }
    243 
    244 bool RenderGrid::namedGridLinesDefinitionDidChange(const RenderStyle* oldStyle) const
    245 {
    246     return oldStyle->namedGridRowLines() != style()->namedGridRowLines()
    247         || oldStyle->namedGridColumnLines() != style()->namedGridColumnLines();
    248 }
    249 
    250 void RenderGrid::layoutBlock(bool relayoutChildren, LayoutUnit)
    251 {
    252     ASSERT(needsLayout());
    253 
    254     if (!relayoutChildren && simplifiedLayout())
    255         return;
    256 
    257     // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
    258     // It would be nice to refactor some of the duplicate code.
    259     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
    260     LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
    261 
    262     // Regions changing widths can force us to relayout our children.
    263     RenderFlowThread* flowThread = flowThreadContainingBlock();
    264     if (logicalWidthChangedInRegions(flowThread))
    265         relayoutChildren = true;
    266     if (updateRegionsAndShapesLogicalSize(flowThread))
    267         relayoutChildren = true;
    268 
    269     LayoutSize previousSize = size();
    270 
    271     setLogicalHeight(0);
    272     updateLogicalWidth();
    273 
    274     layoutGridItems();
    275 
    276     LayoutUnit oldClientAfterEdge = clientLogicalBottom();
    277     updateLogicalHeight();
    278 
    279     if (size() != previousSize)
    280         relayoutChildren = true;
    281 
    282     layoutPositionedObjects(relayoutChildren || isRoot());
    283 
    284     computeRegionRangeForBlock(flowThread);
    285 
    286     computeOverflow(oldClientAfterEdge);
    287     statePusher.pop();
    288 
    289     updateLayerTransform();
    290 
    291     // Update our scroll information if we're overflow:auto/scroll/hidden now that we know if
    292     // we overflow or not.
    293     if (hasOverflowClip())
    294         layer()->scrollableArea()->updateAfterLayout();
    295 
    296     repainter.repaintAfterLayout();
    297 
    298     clearNeedsLayout();
    299 }
    300 
    301 void RenderGrid::computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
    302 {
    303     const_cast<RenderGrid*>(this)->placeItemsOnGrid();
    304 
    305     GridSizingData sizingData(gridColumnCount(), gridRowCount());
    306     LayoutUnit availableLogicalSpace = 0;
    307     const_cast<RenderGrid*>(this)->computedUsedBreadthOfGridTracks(ForColumns, sizingData, availableLogicalSpace);
    308 
    309     for (size_t i = 0; i < sizingData.columnTracks.size(); ++i) {
    310         LayoutUnit minTrackBreadth = sizingData.columnTracks[i].m_usedBreadth;
    311         LayoutUnit maxTrackBreadth = sizingData.columnTracks[i].m_maxBreadth;
    312         maxTrackBreadth = std::max(maxTrackBreadth, minTrackBreadth);
    313 
    314         minLogicalWidth += minTrackBreadth;
    315         maxLogicalWidth += maxTrackBreadth;
    316 
    317         // FIXME: This should add in the scrollbarWidth (e.g. see RenderFlexibleBox).
    318     }
    319 }
    320 
    321 void RenderGrid::computePreferredLogicalWidths()
    322 {
    323     ASSERT(preferredLogicalWidthsDirty());
    324 
    325     m_minPreferredLogicalWidth = 0;
    326     m_maxPreferredLogicalWidth = 0;
    327 
    328     // FIXME: We don't take our own logical width into account. Once we do, we need to make sure
    329     // we apply (and test the interaction with) min-width / max-width.
    330 
    331     computeIntrinsicLogicalWidths(m_minPreferredLogicalWidth, m_maxPreferredLogicalWidth);
    332 
    333     LayoutUnit borderAndPaddingInInlineDirection = borderAndPaddingLogicalWidth();
    334     m_minPreferredLogicalWidth += borderAndPaddingInInlineDirection;
    335     m_maxPreferredLogicalWidth += borderAndPaddingInInlineDirection;
    336 
    337     clearPreferredLogicalWidthsDirty();
    338 }
    339 
    340 void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData)
    341 {
    342     LayoutUnit availableLogicalSpace = (direction == ForColumns) ? availableLogicalWidth() : availableLogicalHeight(IncludeMarginBorderPadding);
    343     computedUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
    344 }
    345 
    346 void RenderGrid::computedUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
    347 {
    348     Vector<GridTrack>& tracks = (direction == ForColumns) ? sizingData.columnTracks : sizingData.rowTracks;
    349     sizingData.contentSizedTracksIndex.shrink(0);
    350     for (size_t i = 0; i < tracks.size(); ++i) {
    351         GridTrack& track = tracks[i];
    352         const GridTrackSize& trackSize = gridTrackSize(direction, i);
    353         const GridLength& minTrackBreadth = trackSize.minTrackBreadth();
    354         const GridLength& maxTrackBreadth = trackSize.maxTrackBreadth();
    355 
    356         track.m_usedBreadth = computeUsedBreadthOfMinLength(direction, minTrackBreadth);
    357         track.m_maxBreadth = computeUsedBreadthOfMaxLength(direction, maxTrackBreadth, track.m_usedBreadth);
    358 
    359         track.m_maxBreadth = std::max(track.m_maxBreadth, track.m_usedBreadth);
    360 
    361         if (trackSize.isContentSized())
    362             sizingData.contentSizedTracksIndex.append(i);
    363     }
    364 
    365     if (!sizingData.contentSizedTracksIndex.isEmpty())
    366         resolveContentBasedTrackSizingFunctions(direction, sizingData, availableLogicalSpace);
    367 
    368     for (size_t i = 0; i < tracks.size(); ++i) {
    369         ASSERT(tracks[i].m_maxBreadth != infinity);
    370         availableLogicalSpace -= tracks[i].m_usedBreadth;
    371     }
    372 
    373     if (availableLogicalSpace <= 0)
    374         return;
    375 
    376     const size_t tracksSize = tracks.size();
    377     Vector<GridTrack*> tracksForDistribution(tracksSize);
    378     for (size_t i = 0; i < tracksSize; ++i)
    379         tracksForDistribution[i] = tracks.data() + i;
    380 
    381     distributeSpaceToTracks(tracksForDistribution, 0, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth, sizingData, availableLogicalSpace);
    382 
    383     // 4. Grow all Grid tracks having a fraction as the MaxTrackSizingFunction.
    384 
    385     // FIXME: Handle the case where RemainingSpace is not defined.
    386     double normalizedFractionBreadth = computeNormalizedFractionBreadth(tracks, direction, availableLogicalSpace);
    387     for (size_t i = 0; i < tracksSize; ++i) {
    388         const GridTrackSize& trackSize = gridTrackSize(direction, i);
    389         if (!trackSize.maxTrackBreadth().isFlex())
    390             continue;
    391 
    392         tracks[i].m_usedBreadth = std::max<LayoutUnit>(tracks[i].m_usedBreadth, normalizedFractionBreadth * trackSize.maxTrackBreadth().flex());
    393     }
    394 }
    395 
    396 LayoutUnit RenderGrid::computeUsedBreadthOfMinLength(GridTrackSizingDirection direction, const GridLength& gridLength) const
    397 {
    398     if (gridLength.isFlex())
    399         return 0;
    400 
    401     const Length& trackLength = gridLength.length();
    402     ASSERT(!trackLength.isAuto());
    403     if (trackLength.isSpecified())
    404         return computeUsedBreadthOfSpecifiedLength(direction, trackLength);
    405 
    406     ASSERT(trackLength.isMinContent() || trackLength.isMaxContent());
    407     return 0;
    408 }
    409 
    410 LayoutUnit RenderGrid::computeUsedBreadthOfMaxLength(GridTrackSizingDirection direction, const GridLength& gridLength, LayoutUnit usedBreadth) const
    411 {
    412     if (gridLength.isFlex())
    413         return usedBreadth;
    414 
    415     const Length& trackLength = gridLength.length();
    416     ASSERT(!trackLength.isAuto());
    417     if (trackLength.isSpecified()) {
    418         LayoutUnit computedBreadth = computeUsedBreadthOfSpecifiedLength(direction, trackLength);
    419         ASSERT(computedBreadth != infinity);
    420         return computedBreadth;
    421     }
    422 
    423     ASSERT(trackLength.isMinContent() || trackLength.isMaxContent());
    424     return infinity;
    425 }
    426 
    427 LayoutUnit RenderGrid::computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection direction, const Length& trackLength) const
    428 {
    429     ASSERT(trackLength.isSpecified());
    430     // FIXME: The -1 here should be replaced by whatever the intrinsic height of the grid is.
    431     return valueForLength(trackLength, direction == ForColumns ? logicalWidth() : computeContentLogicalHeight(style()->logicalHeight(), -1), view());
    432 }
    433 
    434 static bool sortByGridNormalizedFlexValue(const GridTrackForNormalization& track1, const GridTrackForNormalization& track2)
    435 {
    436     return track1.m_normalizedFlexValue < track2.m_normalizedFlexValue;
    437 }
    438 
    439 double RenderGrid::computeNormalizedFractionBreadth(Vector<GridTrack>& tracks, GridTrackSizingDirection direction, LayoutUnit availableLogicalSpace) const
    440 {
    441     // |availableLogicalSpace| already accounts for the used breadths so no need to remove it here.
    442 
    443     Vector<GridTrackForNormalization> tracksForNormalization;
    444     for (size_t i = 0; i < tracks.size(); ++i) {
    445         const GridTrackSize& trackSize = gridTrackSize(direction, i);
    446         if (!trackSize.maxTrackBreadth().isFlex())
    447             continue;
    448 
    449         tracksForNormalization.append(GridTrackForNormalization(tracks[i], trackSize.maxTrackBreadth().flex()));
    450     }
    451 
    452     // FIXME: Ideally we shouldn't come here without any <flex> grid track.
    453     if (tracksForNormalization.isEmpty())
    454         return LayoutUnit();
    455 
    456     std::sort(tracksForNormalization.begin(), tracksForNormalization.end(), sortByGridNormalizedFlexValue);
    457 
    458     // These values work together: as we walk over our grid tracks, we increase fractionValueBasedOnGridItemsRatio
    459     // to match a grid track's usedBreadth to <flex> ratio until the total fractions sized grid tracks wouldn't
    460     // fit into availableLogicalSpaceIgnoringFractionTracks.
    461     double accumulatedFractions = 0;
    462     LayoutUnit fractionValueBasedOnGridItemsRatio = 0;
    463     LayoutUnit availableLogicalSpaceIgnoringFractionTracks = availableLogicalSpace;
    464 
    465     for (size_t i = 0; i < tracksForNormalization.size(); ++i) {
    466         const GridTrackForNormalization& track = tracksForNormalization[i];
    467         if (track.m_normalizedFlexValue > fractionValueBasedOnGridItemsRatio) {
    468             // If the normalized flex value (we ordered |tracksForNormalization| by increasing normalized flex value)
    469             // will make us overflow our container, then stop. We have the previous step's ratio is the best fit.
    470             if (track.m_normalizedFlexValue * accumulatedFractions > availableLogicalSpaceIgnoringFractionTracks)
    471                 break;
    472 
    473             fractionValueBasedOnGridItemsRatio = track.m_normalizedFlexValue;
    474         }
    475 
    476         accumulatedFractions += track.m_flex;
    477         // This item was processed so we re-add its used breadth to the available space to accurately count the remaining space.
    478         availableLogicalSpaceIgnoringFractionTracks += track.m_track->m_usedBreadth;
    479     }
    480 
    481     return availableLogicalSpaceIgnoringFractionTracks / accumulatedFractions;
    482 }
    483 
    484 const GridTrackSize& RenderGrid::gridTrackSize(GridTrackSizingDirection direction, size_t i) const
    485 {
    486     const Vector<GridTrackSize>& trackStyles = (direction == ForColumns) ? style()->gridDefinitionColumns() : style()->gridDefinitionRows();
    487     if (i >= trackStyles.size())
    488         return (direction == ForColumns) ? style()->gridAutoColumns() : style()->gridAutoRows();
    489 
    490     return trackStyles[i];
    491 }
    492 
    493 size_t RenderGrid::explicitGridColumnCount() const
    494 {
    495     return style()->gridDefinitionColumns().size();
    496 }
    497 
    498 size_t RenderGrid::explicitGridRowCount() const
    499 {
    500     return style()->gridDefinitionRows().size();
    501 }
    502 
    503 size_t RenderGrid::explicitGridSizeForSide(GridPositionSide side) const
    504 {
    505     return (side == ColumnStartSide || side == ColumnEndSide) ? explicitGridColumnCount() : explicitGridRowCount();
    506 }
    507 
    508 LayoutUnit RenderGrid::logicalContentHeightForChild(RenderBox* child, Vector<GridTrack>& columnTracks)
    509 {
    510     SubtreeLayoutScope layoutScope(child);
    511     if (child->style()->logicalHeight().isPercent())
    512         layoutScope.setNeedsLayout(child);
    513 
    514     child->setOverrideContainingBlockContentLogicalWidth(gridAreaBreadthForChild(child, ForColumns, columnTracks));
    515     // If |child| has a percentage logical height, we shouldn't let it override its intrinsic height, which is
    516     // what we are interested in here. Thus we need to set the override logical height to -1 (no possible resolution).
    517     child->setOverrideContainingBlockContentLogicalHeight(-1);
    518     child->layoutIfNeeded();
    519     return child->logicalHeight();
    520 }
    521 
    522 LayoutUnit RenderGrid::minContentForChild(RenderBox* child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
    523 {
    524     bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
    525     // FIXME: Properly support orthogonal writing mode.
    526     if (hasOrthogonalWritingMode)
    527         return 0;
    528 
    529     if (direction == ForColumns) {
    530         // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
    531         // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
    532         return child->minPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
    533     }
    534 
    535     return logicalContentHeightForChild(child, columnTracks);
    536 }
    537 
    538 LayoutUnit RenderGrid::maxContentForChild(RenderBox* child, GridTrackSizingDirection direction, Vector<GridTrack>& columnTracks)
    539 {
    540     bool hasOrthogonalWritingMode = child->isHorizontalWritingMode() != isHorizontalWritingMode();
    541     // FIXME: Properly support orthogonal writing mode.
    542     if (hasOrthogonalWritingMode)
    543         return LayoutUnit();
    544 
    545     if (direction == ForColumns) {
    546         // FIXME: It's unclear if we should return the intrinsic width or the preferred width.
    547         // See http://lists.w3.org/Archives/Public/www-style/2013Jan/0245.html
    548         return child->maxPreferredLogicalWidth() + marginIntrinsicLogicalWidthForChild(child);
    549     }
    550 
    551     return logicalContentHeightForChild(child, columnTracks);
    552 }
    553 
    554 void RenderGrid::resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
    555 {
    556     // FIXME: Split the grid tracks into groups that doesn't overlap a <flex> grid track (crbug.com/235258).
    557 
    558     // FIXME: Per step 2 of the specification, we should order the grid items by increasing span.
    559 
    560     for (size_t i = 0; i < sizingData.contentSizedTracksIndex.size(); ++i) {
    561         GridIterator iterator(m_grid, direction, sizingData.contentSizedTracksIndex[i]);
    562         while (RenderBox* gridItem = iterator.nextGridItem()) {
    563             resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMinOrMaxContentMinTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
    564             resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMaxContentMinTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::usedBreadth, &GridTrack::growUsedBreadth);
    565             resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMinOrMaxContentMaxTrackBreadth, &RenderGrid::minContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
    566             resolveContentBasedTrackSizingFunctionsForItems(direction, sizingData, gridItem, &GridTrackSize::hasMaxContentMaxTrackBreadth, &RenderGrid::maxContentForChild, &GridTrack::maxBreadthIfNotInfinite, &GridTrack::growMaxBreadth);
    567         }
    568 
    569         GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[i] : sizingData.rowTracks[i];
    570         if (track.m_maxBreadth == infinity)
    571             track.m_maxBreadth = track.m_usedBreadth;
    572     }
    573 }
    574 
    575 void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection direction, GridSizingData& sizingData, RenderBox* gridItem, FilterFunction filterFunction, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction)
    576 {
    577     const GridCoordinate coordinate = cachedGridCoordinate(gridItem);
    578     const size_t initialTrackIndex = (direction == ForColumns) ? coordinate.columns.initialPositionIndex : coordinate.rows.initialPositionIndex;
    579     const size_t finalTrackIndex = (direction == ForColumns) ? coordinate.columns.finalPositionIndex : coordinate.rows.finalPositionIndex;
    580 
    581     sizingData.filteredTracks.shrink(0);
    582     for (size_t trackIndex = initialTrackIndex; trackIndex <= finalTrackIndex; ++trackIndex) {
    583         const GridTrackSize& trackSize = gridTrackSize(direction, trackIndex);
    584         if (!(trackSize.*filterFunction)())
    585             continue;
    586 
    587         GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndex] : sizingData.rowTracks[trackIndex];
    588         sizingData.filteredTracks.append(&track);
    589     }
    590 
    591     if (sizingData.filteredTracks.isEmpty())
    592         return;
    593 
    594     LayoutUnit additionalBreadthSpace = (this->*sizingFunction)(gridItem, direction, sizingData.columnTracks);
    595     for (size_t trackIndexForSpace = initialTrackIndex; trackIndexForSpace <= finalTrackIndex; ++trackIndexForSpace) {
    596         GridTrack& track = (direction == ForColumns) ? sizingData.columnTracks[trackIndexForSpace] : sizingData.rowTracks[trackIndexForSpace];
    597         additionalBreadthSpace -= (track.*trackGetter)();
    598     }
    599 
    600     // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadth|.
    601     distributeSpaceToTracks(sizingData.filteredTracks, &sizingData.filteredTracks, trackGetter, trackGrowthFunction, sizingData, additionalBreadthSpace);
    602 }
    603 
    604 static bool sortByGridTrackGrowthPotential(const GridTrack* track1, const GridTrack* track2)
    605 {
    606     return (track1->m_maxBreadth - track1->m_usedBreadth) < (track2->m_maxBreadth - track2->m_usedBreadth);
    607 }
    608 
    609 void RenderGrid::distributeSpaceToTracks(Vector<GridTrack*>& tracks, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
    610 {
    611     std::sort(tracks.begin(), tracks.end(), sortByGridTrackGrowthPotential);
    612 
    613     size_t tracksSize = tracks.size();
    614     sizingData.distributeTrackVector.resize(tracksSize);
    615 
    616     for (size_t i = 0; i < tracksSize; ++i) {
    617         GridTrack& track = *tracks[i];
    618         LayoutUnit availableLogicalSpaceShare = availableLogicalSpace / (tracksSize - i);
    619         LayoutUnit trackBreadth = (tracks[i]->*trackGetter)();
    620         LayoutUnit growthShare = std::min(availableLogicalSpaceShare, track.m_maxBreadth - trackBreadth);
    621         sizingData.distributeTrackVector[i] = trackBreadth;
    622         // We should never shrink any grid track or else we can't guarantee we abide by our min-sizing function.
    623         if (growthShare > 0) {
    624             sizingData.distributeTrackVector[i] += growthShare;
    625             availableLogicalSpace -= growthShare;
    626         }
    627     }
    628 
    629     if (availableLogicalSpace > 0 && tracksForGrowthAboveMaxBreadth) {
    630         tracksSize = tracksForGrowthAboveMaxBreadth->size();
    631         for (size_t i = 0; i < tracksSize; ++i) {
    632             LayoutUnit growthShare = availableLogicalSpace / (tracksSize - i);
    633             sizingData.distributeTrackVector[i] += growthShare;
    634             availableLogicalSpace -= growthShare;
    635         }
    636     }
    637 
    638     for (size_t i = 0; i < tracksSize; ++i) {
    639         LayoutUnit growth = sizingData.distributeTrackVector[i] - (tracks[i]->*trackGetter)();
    640         if (growth >= 0)
    641             (tracks[i]->*trackGrowthFunction)(growth);
    642     }
    643 }
    644 
    645 #ifndef NDEBUG
    646 bool RenderGrid::tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection direction, const Vector<GridTrack>& tracks)
    647 {
    648     for (size_t i = 0; i < tracks.size(); ++i) {
    649         const GridTrackSize& trackSize = gridTrackSize(direction, i);
    650         const GridLength& minTrackBreadth = trackSize.minTrackBreadth();
    651         if (computeUsedBreadthOfMinLength(direction, minTrackBreadth) > tracks[i].m_usedBreadth)
    652             return false;
    653     }
    654     return true;
    655 }
    656 #endif
    657 
    658 void RenderGrid::growGrid(GridTrackSizingDirection direction)
    659 {
    660     if (direction == ForColumns) {
    661         const size_t oldColumnSize = m_grid[0].size();
    662         for (size_t row = 0; row < m_grid.size(); ++row)
    663             m_grid[row].grow(oldColumnSize + 1);
    664     } else {
    665         const size_t oldRowSize = m_grid.size();
    666         m_grid.grow(oldRowSize + 1);
    667         m_grid[oldRowSize].grow(m_grid[0].size());
    668     }
    669 }
    670 
    671 void RenderGrid::insertItemIntoGrid(RenderBox* child, const GridCoordinate& coordinate)
    672 {
    673     for (size_t row = coordinate.rows.initialPositionIndex; row <= coordinate.rows.finalPositionIndex; ++row) {
    674         for (size_t column = coordinate.columns.initialPositionIndex; column <= coordinate.columns.finalPositionIndex; ++column)
    675             m_grid[row][column].append(child);
    676     }
    677 
    678     m_gridItemCoordinate.set(child, coordinate);
    679 }
    680 
    681 void RenderGrid::insertItemIntoGrid(RenderBox* child, size_t rowTrack, size_t columnTrack)
    682 {
    683     const GridSpan& rowSpan = resolveGridPositionsFromAutoPlacementPosition(child, ForRows, rowTrack);
    684     const GridSpan& columnSpan = resolveGridPositionsFromAutoPlacementPosition(child, ForColumns, columnTrack);
    685     insertItemIntoGrid(child, GridCoordinate(rowSpan, columnSpan));
    686 }
    687 
    688 void RenderGrid::placeItemsOnGrid()
    689 {
    690     if (!gridIsDirty())
    691         return;
    692 
    693     ASSERT(m_gridItemCoordinate.isEmpty());
    694 
    695     populateExplicitGridAndOrderIterator();
    696 
    697     // We clear the dirty bit here as the grid sizes have been updated, this means
    698     // that we can safely call gridRowCount() / gridColumnCount().
    699     m_gridIsDirty = false;
    700 
    701     Vector<RenderBox*> autoMajorAxisAutoGridItems;
    702     Vector<RenderBox*> specifiedMajorAxisAutoGridItems;
    703     GridAutoFlow autoFlow = style()->gridAutoFlow();
    704     for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next()) {
    705         // FIXME: We never re-resolve positions if the grid is grown during auto-placement which may lead auto / <integer>
    706         // positions to not match the author's intent. The specification is unclear on what should be done in this case.
    707         OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, ForRows);
    708         OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns);
    709         if (!rowPositions || !columnPositions) {
    710             GridSpan* majorAxisPositions = (autoPlacementMajorAxisDirection() == ForColumns) ? columnPositions.get() : rowPositions.get();
    711             if (!majorAxisPositions)
    712                 autoMajorAxisAutoGridItems.append(child);
    713             else
    714                 specifiedMajorAxisAutoGridItems.append(child);
    715             continue;
    716         }
    717         insertItemIntoGrid(child, GridCoordinate(*rowPositions, *columnPositions));
    718     }
    719 
    720     ASSERT(gridRowCount() >= style()->gridDefinitionRows().size());
    721     ASSERT(gridColumnCount() >= style()->gridDefinitionColumns().size());
    722 
    723     if (autoFlow == AutoFlowNone) {
    724         // If we did collect some grid items, they won't be placed thus never laid out.
    725         ASSERT(!autoMajorAxisAutoGridItems.size());
    726         ASSERT(!specifiedMajorAxisAutoGridItems.size());
    727         return;
    728     }
    729 
    730     placeSpecifiedMajorAxisItemsOnGrid(specifiedMajorAxisAutoGridItems);
    731     placeAutoMajorAxisItemsOnGrid(autoMajorAxisAutoGridItems);
    732 
    733     m_grid.shrinkToFit();
    734 }
    735 
    736 void RenderGrid::populateExplicitGridAndOrderIterator()
    737 {
    738     OrderIteratorPopulator populator(m_orderIterator);
    739 
    740     size_t maximumRowIndex = std::max<size_t>(1, explicitGridRowCount());
    741     size_t maximumColumnIndex = std::max<size_t>(1, explicitGridColumnCount());
    742 
    743     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    744         populator.collectChild(child);
    745 
    746         // This function bypasses the cache (cachedGridCoordinate()) as it is used to build it.
    747         OwnPtr<GridSpan> rowPositions = resolveGridPositionsFromStyle(child, ForRows);
    748         OwnPtr<GridSpan> columnPositions = resolveGridPositionsFromStyle(child, ForColumns);
    749 
    750         // |positions| is 0 if we need to run the auto-placement algorithm. Our estimation ignores
    751         // this case as the auto-placement algorithm will grow the grid as needed.
    752         if (rowPositions)
    753             maximumRowIndex = std::max(maximumRowIndex, rowPositions->finalPositionIndex + 1);
    754         if (columnPositions)
    755             maximumColumnIndex = std::max(maximumColumnIndex, columnPositions->finalPositionIndex + 1);
    756     }
    757 
    758     m_grid.grow(maximumRowIndex);
    759     for (size_t i = 0; i < m_grid.size(); ++i)
    760         m_grid[i].grow(maximumColumnIndex);
    761 }
    762 
    763 void RenderGrid::placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGridItems)
    764 {
    765     for (size_t i = 0; i < autoGridItems.size(); ++i) {
    766         OwnPtr<GridSpan> majorAxisPositions = resolveGridPositionsFromStyle(autoGridItems[i], autoPlacementMajorAxisDirection());
    767         GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisPositions->initialPositionIndex);
    768         if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
    769             insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
    770             continue;
    771         }
    772 
    773         growGrid(autoPlacementMinorAxisDirection());
    774         OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea();
    775         ASSERT(emptyGridArea);
    776         insertItemIntoGrid(autoGridItems[i], emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
    777     }
    778 }
    779 
    780 void RenderGrid::placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>& autoGridItems)
    781 {
    782     for (size_t i = 0; i < autoGridItems.size(); ++i)
    783         placeAutoMajorAxisItemOnGrid(autoGridItems[i]);
    784 }
    785 
    786 void RenderGrid::placeAutoMajorAxisItemOnGrid(RenderBox* gridItem)
    787 {
    788     OwnPtr<GridSpan> minorAxisPositions = resolveGridPositionsFromStyle(gridItem, autoPlacementMinorAxisDirection());
    789     ASSERT(!resolveGridPositionsFromStyle(gridItem, autoPlacementMajorAxisDirection()));
    790     size_t minorAxisIndex = 0;
    791     if (minorAxisPositions) {
    792         minorAxisIndex = minorAxisPositions->initialPositionIndex;
    793         GridIterator iterator(m_grid, autoPlacementMinorAxisDirection(), minorAxisIndex);
    794         if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
    795             insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
    796             return;
    797         }
    798     } else {
    799         const size_t endOfMajorAxis = (autoPlacementMajorAxisDirection() == ForColumns) ? gridColumnCount() : gridRowCount();
    800         for (size_t majorAxisIndex = 0; majorAxisIndex < endOfMajorAxis; ++majorAxisIndex) {
    801             GridIterator iterator(m_grid, autoPlacementMajorAxisDirection(), majorAxisIndex);
    802             if (OwnPtr<GridCoordinate> emptyGridArea = iterator.nextEmptyGridArea()) {
    803                 insertItemIntoGrid(gridItem, emptyGridArea->rows.initialPositionIndex, emptyGridArea->columns.initialPositionIndex);
    804                 return;
    805             }
    806         }
    807     }
    808 
    809     // We didn't find an empty grid area so we need to create an extra major axis line and insert our gridItem in it.
    810     const size_t columnIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? m_grid[0].size() : minorAxisIndex;
    811     const size_t rowIndex = (autoPlacementMajorAxisDirection() == ForColumns) ? minorAxisIndex : m_grid.size();
    812     growGrid(autoPlacementMajorAxisDirection());
    813     insertItemIntoGrid(gridItem, rowIndex, columnIndex);
    814 }
    815 
    816 GridTrackSizingDirection RenderGrid::autoPlacementMajorAxisDirection() const
    817 {
    818     GridAutoFlow flow = style()->gridAutoFlow();
    819     ASSERT(flow != AutoFlowNone);
    820     return (flow == AutoFlowColumn) ? ForColumns : ForRows;
    821 }
    822 
    823 GridTrackSizingDirection RenderGrid::autoPlacementMinorAxisDirection() const
    824 {
    825     GridAutoFlow flow = style()->gridAutoFlow();
    826     ASSERT(flow != AutoFlowNone);
    827     return (flow == AutoFlowColumn) ? ForRows : ForColumns;
    828 }
    829 
    830 void RenderGrid::dirtyGrid()
    831 {
    832     m_grid.resize(0);
    833     m_gridItemCoordinate.clear();
    834     m_gridIsDirty = true;
    835 }
    836 
    837 void RenderGrid::layoutGridItems()
    838 {
    839     placeItemsOnGrid();
    840 
    841     GridSizingData sizingData(gridColumnCount(), gridRowCount());
    842     computedUsedBreadthOfGridTracks(ForColumns, sizingData);
    843     ASSERT(tracksAreWiderThanMinTrackBreadth(ForColumns, sizingData.columnTracks));
    844     computedUsedBreadthOfGridTracks(ForRows, sizingData);
    845     ASSERT(tracksAreWiderThanMinTrackBreadth(ForRows, sizingData.rowTracks));
    846 
    847     populateGridPositions(sizingData);
    848 
    849     for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) {
    850         // Because the grid area cannot be styled, we don't need to adjust
    851         // the grid breadth to account for 'box-sizing'.
    852         LayoutUnit oldOverrideContainingBlockContentLogicalWidth = child->hasOverrideContainingBlockLogicalWidth() ? child->overrideContainingBlockContentLogicalWidth() : LayoutUnit();
    853         LayoutUnit oldOverrideContainingBlockContentLogicalHeight = child->hasOverrideContainingBlockLogicalHeight() ? child->overrideContainingBlockContentLogicalHeight() : LayoutUnit();
    854 
    855         LayoutUnit overrideContainingBlockContentLogicalWidth = gridAreaBreadthForChild(child, ForColumns, sizingData.columnTracks);
    856         LayoutUnit overrideContainingBlockContentLogicalHeight = gridAreaBreadthForChild(child, ForRows, sizingData.rowTracks);
    857 
    858         SubtreeLayoutScope layoutScope(child);
    859         if (oldOverrideContainingBlockContentLogicalWidth != overrideContainingBlockContentLogicalWidth || (oldOverrideContainingBlockContentLogicalHeight != overrideContainingBlockContentLogicalHeight && child->hasRelativeLogicalHeight()))
    860             layoutScope.setNeedsLayout(child);
    861 
    862         child->setOverrideContainingBlockContentLogicalWidth(overrideContainingBlockContentLogicalWidth);
    863         child->setOverrideContainingBlockContentLogicalHeight(overrideContainingBlockContentLogicalHeight);
    864 
    865         LayoutRect oldChildRect = child->frameRect();
    866 
    867         // FIXME: Grid items should stretch to fill their cells. Once we
    868         // implement grid-{column,row}-align, we can also shrink to fit. For
    869         // now, just size as if we were a regular child.
    870         child->layoutIfNeeded();
    871 
    872         child->setLogicalLocation(findChildLogicalPosition(child, sizingData));
    873 
    874         // For correctness, we disable some painting optimizations if we have a child overflowing its grid area.
    875         m_gridItemOverflowGridArea = child->logicalHeight() > overrideContainingBlockContentLogicalHeight
    876             || child->logicalWidth() > overrideContainingBlockContentLogicalWidth;
    877 
    878         // If the child moved, we have to repaint it as well as any floating/positioned
    879         // descendants. An exception is if we need a layout. In this case, we know we're going to
    880         // repaint ourselves (and the child) anyway.
    881         if (!selfNeedsLayout() && child->checkForRepaintDuringLayout())
    882             child->repaintDuringLayoutIfMoved(oldChildRect);
    883     }
    884 
    885     for (size_t i = 0; i < sizingData.rowTracks.size(); ++i)
    886         setLogicalHeight(logicalHeight() + sizingData.rowTracks[i].m_usedBreadth);
    887 
    888     // Min / max logical height is handled by the call to updateLogicalHeight in layoutBlock.
    889 
    890     setLogicalHeight(logicalHeight() + borderAndPaddingLogicalHeight());
    891 }
    892 
    893 GridCoordinate RenderGrid::cachedGridCoordinate(const RenderBox* gridItem) const
    894 {
    895     ASSERT(m_gridItemCoordinate.contains(gridItem));
    896     return m_gridItemCoordinate.get(gridItem);
    897 }
    898 
    899 GridSpan RenderGrid::resolveGridPositionsFromAutoPlacementPosition(const RenderBox*, GridTrackSizingDirection, size_t initialPosition) const
    900 {
    901     // FIXME: We don't support spanning with auto positions yet. Once we do, this is wrong. Also we should make
    902     // sure the grid can accomodate the new item as we only grow 1 position in a given direction.
    903     return GridSpan(initialPosition, initialPosition);
    904 }
    905 
    906 PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionsFromStyle(const RenderBox* gridItem, GridTrackSizingDirection direction) const
    907 {
    908     const GridPosition& initialPosition = (direction == ForColumns) ? gridItem->style()->gridColumnStart() : gridItem->style()->gridRowStart();
    909     const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
    910     const GridPosition& finalPosition = (direction == ForColumns) ? gridItem->style()->gridColumnEnd() : gridItem->style()->gridRowEnd();
    911     const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
    912 
    913     // We should NEVER see both spans as they should have been handled during style resolve.
    914     ASSERT(!initialPosition.isSpan() || !finalPosition.isSpan());
    915 
    916     if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
    917         if (style()->gridAutoFlow() == AutoFlowNone)
    918             return adoptPtr(new GridSpan(0, 0));
    919 
    920         // We can't get our grid positions without running the auto placement algorithm.
    921         return nullptr;
    922     }
    923 
    924     if (initialPosition.shouldBeResolvedAgainstOppositePosition()) {
    925         // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case).
    926         const size_t finalResolvedPosition = resolveGridPositionFromStyle(finalPosition, finalPositionSide);
    927         return resolveGridPositionAgainstOppositePosition(finalResolvedPosition, initialPosition, initialPositionSide);
    928     }
    929 
    930     if (finalPosition.shouldBeResolvedAgainstOppositePosition()) {
    931         // Infer our position from the initial position ('1 / auto' or '3 / span 2' case).
    932         const size_t initialResolvedPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
    933         return resolveGridPositionAgainstOppositePosition(initialResolvedPosition, finalPosition, finalPositionSide);
    934     }
    935 
    936     size_t resolvedInitialPosition = resolveGridPositionFromStyle(initialPosition, initialPositionSide);
    937     size_t resolvedFinalPosition = resolveGridPositionFromStyle(finalPosition, finalPositionSide);
    938 
    939     // If 'grid-after' specifies a line at or before that specified by 'grid-before', it computes to 'span 1'.
    940     if (resolvedFinalPosition < resolvedInitialPosition)
    941         resolvedFinalPosition = resolvedInitialPosition;
    942 
    943     return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition));
    944 }
    945 
    946 size_t RenderGrid::resolveNamedGridLinePositionFromStyle(const GridPosition& position, GridPositionSide side) const
    947 {
    948     ASSERT(!position.namedGridLine().isNull());
    949 
    950     const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
    951     NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
    952     if (it == gridLinesNames.end()) {
    953         if (position.isPositive())
    954             return 0;
    955         const size_t lastLine = explicitGridSizeForSide(side);
    956         return GridPosition::adjustGridPositionForSide(lastLine, side);
    957     }
    958 
    959     size_t namedGridLineIndex;
    960     if (position.isPositive())
    961         namedGridLineIndex = std::min<size_t>(position.integerPosition(), it->value.size()) - 1;
    962     else
    963         namedGridLineIndex = std::max<int>(it->value.size() - abs(position.integerPosition()), 0);
    964     return GridPosition::adjustGridPositionForSide(it->value[namedGridLineIndex], side);
    965 }
    966 
    967 size_t RenderGrid::resolveGridPositionFromStyle(const GridPosition& position, GridPositionSide side) const
    968 {
    969     switch (position.type()) {
    970     case ExplicitPosition: {
    971         ASSERT(position.integerPosition());
    972 
    973         if (!position.namedGridLine().isNull())
    974             return resolveNamedGridLinePositionFromStyle(position, side);
    975 
    976         // Handle <integer> explicit position.
    977         if (position.isPositive())
    978             return GridPosition::adjustGridPositionForSide(position.integerPosition() - 1, side);
    979 
    980         size_t resolvedPosition = abs(position.integerPosition()) - 1;
    981         const size_t endOfTrack = explicitGridSizeForSide(side);
    982 
    983         // Per http://lists.w3.org/Archives/Public/www-style/2013Mar/0589.html, we clamp negative value to the first line.
    984         if (endOfTrack < resolvedPosition)
    985             return 0;
    986 
    987         return GridPosition::adjustGridPositionForSide(endOfTrack - resolvedPosition, side);
    988     }
    989     case NamedGridAreaPosition:
    990     {
    991         NamedGridAreaMap::const_iterator it = style()->namedGridArea().find(position.namedGridLine());
    992         // Unknown grid area should have been computed to 'auto' by now.
    993         ASSERT_WITH_SECURITY_IMPLICATION(it != style()->namedGridArea().end());
    994         const GridCoordinate& gridAreaCoordinate = it->value;
    995         switch (side) {
    996         case ColumnStartSide:
    997             return gridAreaCoordinate.columns.initialPositionIndex;
    998         case ColumnEndSide:
    999             return gridAreaCoordinate.columns.finalPositionIndex;
   1000         case RowStartSide:
   1001             return gridAreaCoordinate.rows.initialPositionIndex;
   1002         case RowEndSide:
   1003             return gridAreaCoordinate.rows.finalPositionIndex;
   1004         }
   1005         ASSERT_NOT_REACHED();
   1006         return 0;
   1007     }
   1008     case AutoPosition:
   1009     case SpanPosition:
   1010         // 'auto' and span depend on the opposite position for resolution (e.g. grid-row: auto / 1 or grid-column: span 3 / "myHeader").
   1011         ASSERT_NOT_REACHED();
   1012         return 0;
   1013     }
   1014     ASSERT_NOT_REACHED();
   1015     return 0;
   1016 }
   1017 
   1018 PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
   1019 {
   1020     if (position.isAuto())
   1021         return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
   1022 
   1023     ASSERT(position.isSpan());
   1024     ASSERT(position.spanPosition() > 0);
   1025 
   1026     if (!position.namedGridLine().isNull()) {
   1027         // span 2 'c' -> we need to find the appropriate grid line before / after our opposite position.
   1028         return resolveNamedGridLinePositionAgainstOppositePosition(resolvedOppositePosition, position, side);
   1029     }
   1030 
   1031     return GridSpan::createWithSpanAgainstOpposite(resolvedOppositePosition, position, side);
   1032 }
   1033 
   1034 PassOwnPtr<GridSpan> RenderGrid::resolveNamedGridLinePositionAgainstOppositePosition(size_t resolvedOppositePosition, const GridPosition& position, GridPositionSide side) const
   1035 {
   1036     ASSERT(position.isSpan());
   1037     ASSERT(!position.namedGridLine().isNull());
   1038     // Negative positions are not allowed per the specification and should have been handled during parsing.
   1039     ASSERT(position.spanPosition() > 0);
   1040 
   1041     const NamedGridLinesMap& gridLinesNames = (side == ColumnStartSide || side == ColumnEndSide) ? style()->namedGridColumnLines() : style()->namedGridRowLines();
   1042     NamedGridLinesMap::const_iterator it = gridLinesNames.find(position.namedGridLine());
   1043 
   1044     // If there is no named grid line of that name, we resolve the position to 'auto' (which is equivalent to 'span 1' in this case).
   1045     // See http://lists.w3.org/Archives/Public/www-style/2013Jun/0394.html.
   1046     if (it == gridLinesNames.end())
   1047         return GridSpan::create(resolvedOppositePosition, resolvedOppositePosition);
   1048 
   1049     return GridSpan::createWithNamedSpanAgainstOpposite(resolvedOppositePosition, position, side, it->value);
   1050 }
   1051 
   1052 LayoutUnit RenderGrid::gridAreaBreadthForChild(const RenderBox* child, GridTrackSizingDirection direction, const Vector<GridTrack>& tracks) const
   1053 {
   1054     const GridCoordinate& coordinate = cachedGridCoordinate(child);
   1055     const GridSpan& span = (direction == ForColumns) ? coordinate.columns : coordinate.rows;
   1056     LayoutUnit gridAreaBreadth = 0;
   1057     for (size_t trackIndex = span.initialPositionIndex; trackIndex <= span.finalPositionIndex; ++trackIndex)
   1058         gridAreaBreadth += tracks[trackIndex].m_usedBreadth;
   1059     return gridAreaBreadth;
   1060 }
   1061 
   1062 void RenderGrid::populateGridPositions(const GridSizingData& sizingData)
   1063 {
   1064     m_columnPositions.resize(sizingData.columnTracks.size() + 1);
   1065     m_columnPositions[0] = borderAndPaddingStart();
   1066     for (size_t i = 0; i < m_columnPositions.size() - 1; ++i)
   1067         m_columnPositions[i + 1] = m_columnPositions[i] + sizingData.columnTracks[i].m_usedBreadth;
   1068 
   1069     m_rowPositions.resize(sizingData.rowTracks.size() + 1);
   1070     m_rowPositions[0] = borderAndPaddingBefore();
   1071     for (size_t i = 0; i < m_rowPositions.size() - 1; ++i)
   1072         m_rowPositions[i + 1] = m_rowPositions[i] + sizingData.rowTracks[i].m_usedBreadth;
   1073 }
   1074 
   1075 LayoutPoint RenderGrid::findChildLogicalPosition(RenderBox* child, const GridSizingData& sizingData)
   1076 {
   1077     const GridCoordinate& coordinate = cachedGridCoordinate(child);
   1078     ASSERT(coordinate.columns.initialPositionIndex < sizingData.columnTracks.size());
   1079     ASSERT(coordinate.rows.initialPositionIndex < sizingData.rowTracks.size());
   1080 
   1081     // The grid items should be inside the grid container's border box, that's why they need to be shifted.
   1082     return LayoutPoint(m_columnPositions[coordinate.columns.initialPositionIndex] + marginStartForChild(child), m_rowPositions[coordinate.rows.initialPositionIndex] + marginBeforeForChild(child));
   1083 }
   1084 
   1085 static GridSpan dirtiedGridAreas(const Vector<LayoutUnit>& coordinates, LayoutUnit start, LayoutUnit end)
   1086 {
   1087     // This function does a binary search over the coordinates.
   1088     // FIXME: This doesn't work with grid items overflowing their grid areas and should be tested & fixed.
   1089 
   1090     size_t startGridAreaIndex = std::upper_bound(coordinates.begin(), coordinates.end() - 1, start) - coordinates.begin();
   1091     if (startGridAreaIndex > 0)
   1092         --startGridAreaIndex;
   1093 
   1094     size_t endGridAreaIndex = std::upper_bound(coordinates.begin() + startGridAreaIndex, coordinates.end() - 1, end) - coordinates.begin();
   1095     return GridSpan(startGridAreaIndex, endGridAreaIndex);
   1096 }
   1097 
   1098 void RenderGrid::paintChildrenSlowCase(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   1099 {
   1100     for (RenderBox* child = m_orderIterator.first(); child; child = m_orderIterator.next())
   1101         paintChild(child, paintInfo, paintOffset);
   1102 }
   1103 
   1104 void RenderGrid::paintChildren(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
   1105 {
   1106     ASSERT_WITH_SECURITY_IMPLICATION(!gridIsDirty());
   1107 
   1108     if (m_gridItemOverflowGridArea) {
   1109         paintChildrenSlowCase(paintInfo, paintOffset);
   1110         return;
   1111     }
   1112 
   1113     LayoutRect localRepaintRect = paintInfo.rect;
   1114     localRepaintRect.moveBy(-paintOffset);
   1115 
   1116     GridSpan dirtiedColumns = dirtiedGridAreas(m_columnPositions, localRepaintRect.x(), localRepaintRect.maxX());
   1117     GridSpan dirtiedRows = dirtiedGridAreas(m_rowPositions, localRepaintRect.y(), localRepaintRect.maxY());
   1118 
   1119     OrderIterator paintIterator(this);
   1120     {
   1121         OrderIteratorPopulator populator(paintIterator);
   1122 
   1123         for (size_t row = dirtiedRows.initialPositionIndex; row < dirtiedRows.finalPositionIndex; ++row) {
   1124             for (size_t column = dirtiedColumns.initialPositionIndex; column < dirtiedColumns.finalPositionIndex; ++column) {
   1125                 const Vector<RenderBox*, 1>& children = m_grid[row][column];
   1126                 // FIXME: If we start adding spanning children in all grid areas they span, this
   1127                 // would make us paint them several times, which is wrong!
   1128                 for (size_t j = 0; j < children.size(); ++j)
   1129                     populator.storeChild(children[j]);
   1130             }
   1131         }
   1132     }
   1133 
   1134     for (RenderBox* child = paintIterator.first(); child; child = paintIterator.next())
   1135         paintChild(child, paintInfo, paintOffset);
   1136 }
   1137 
   1138 const char* RenderGrid::renderName() const
   1139 {
   1140     if (isFloating())
   1141         return "RenderGrid (floating)";
   1142     if (isOutOfFlowPositioned())
   1143         return "RenderGrid (positioned)";
   1144     if (isAnonymous())
   1145         return "RenderGrid (generated)";
   1146     if (isRelPositioned())
   1147         return "RenderGrid (relative positioned)";
   1148     return "RenderGrid";
   1149 }
   1150 
   1151 } // namespace WebCore
   1152