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#ifndef RenderGrid_h
27#define RenderGrid_h
28
29#include "core/rendering/OrderIterator.h"
30#include "core/rendering/RenderBlock.h"
31#include "core/rendering/style/GridResolvedPosition.h"
32
33namespace blink {
34
35struct GridCoordinate;
36struct GridSpan;
37class GridTrack;
38
39class RenderGrid FINAL : public RenderBlock {
40public:
41    RenderGrid(Element*);
42    virtual ~RenderGrid();
43
44    virtual const char* renderName() const OVERRIDE;
45
46    virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
47
48    virtual bool canCollapseAnonymousBlockChild() const OVERRIDE { return false; }
49
50    void dirtyGrid();
51
52    const Vector<LayoutUnit>& columnPositions() const { return m_columnPositions; }
53    const Vector<LayoutUnit>& rowPositions() const { return m_rowPositions; }
54
55    typedef Vector<RenderBox*, 1> GridCell;
56    const GridCell& gridCell(int row, int column) { return m_grid[row][column]; }
57    const Vector<RenderBox*>& itemsOverflowingGridArea() { return m_gridItemsOverflowingGridArea; }
58    int paintIndexForGridItem(const RenderBox* renderBox) { return m_gridItemsIndexesMap.get(renderBox); }
59
60    bool gridIsDirty() const { return m_gridIsDirty; }
61
62private:
63    virtual bool isRenderGrid() const OVERRIDE { return true; }
64    virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
65    virtual void computePreferredLogicalWidths() OVERRIDE;
66
67    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
68    void addChildToIndexesMap(RenderBox&);
69    virtual void removeChild(RenderObject*) OVERRIDE;
70
71    virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
72
73    bool explicitGridDidResize(const RenderStyle*) const;
74    bool namedGridLinesDefinitionDidChange(const RenderStyle*) const;
75
76    class GridIterator;
77    struct GridSizingData;
78    bool gridElementIsShrinkToFit();
79    void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&);
80    void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
81    LayoutUnit computeUsedBreadthOfMinLength(GridTrackSizingDirection, const GridLength&) const;
82    LayoutUnit computeUsedBreadthOfMaxLength(GridTrackSizingDirection, const GridLength&, LayoutUnit usedBreadth) const;
83    LayoutUnit computeUsedBreadthOfSpecifiedLength(GridTrackSizingDirection, const Length&) const;
84    void resolveContentBasedTrackSizingFunctions(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
85
86    void ensureGridSize(size_t maximumRowIndex, size_t maximumColumnIndex);
87    void insertItemIntoGrid(RenderBox&, const GridCoordinate&);
88    void placeItemsOnGrid();
89    void populateExplicitGridAndOrderIterator();
90    PassOwnPtr<GridCoordinate> createEmptyGridAreaAtSpecifiedPositionsOutsideGrid(const RenderBox&, GridTrackSizingDirection, const GridSpan& specifiedPositions) const;
91    void placeSpecifiedMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
92    void placeAutoMajorAxisItemsOnGrid(const Vector<RenderBox*>&);
93    void placeAutoMajorAxisItemOnGrid(RenderBox&, std::pair<size_t, size_t>& autoPlacementCursor);
94    GridTrackSizingDirection autoPlacementMajorAxisDirection() const;
95    GridTrackSizingDirection autoPlacementMinorAxisDirection() const;
96
97    void layoutGridItems();
98    void populateGridPositions(const GridSizingData&);
99
100    typedef LayoutUnit (RenderGrid::* SizingFunction)(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>&);
101    typedef LayoutUnit (GridTrack::* AccumulatorGetter)() const;
102    typedef void (GridTrack::* AccumulatorGrowFunction)(LayoutUnit);
103    typedef bool (GridTrackSize::* FilterFunction)() const;
104    void resolveContentBasedTrackSizingFunctionsForItems(GridTrackSizingDirection, GridSizingData&, RenderBox&, FilterFunction, SizingFunction, AccumulatorGetter, AccumulatorGrowFunction);
105    void distributeSpaceToTracks(Vector<GridTrack*>&, Vector<GridTrack*>* tracksForGrowthAboveMaxBreadth, AccumulatorGetter, AccumulatorGrowFunction, GridSizingData&, LayoutUnit& availableLogicalSpace);
106
107    double computeNormalizedFractionBreadth(Vector<GridTrack>&, const GridSpan& tracksSpan, GridTrackSizingDirection, LayoutUnit availableLogicalSpace) const;
108
109    GridTrackSize gridTrackSize(GridTrackSizingDirection, size_t) const;
110
111    LayoutUnit logicalHeightForChild(RenderBox&, Vector<GridTrack>&);
112    LayoutUnit minContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
113    LayoutUnit maxContentForChild(RenderBox&, GridTrackSizingDirection, Vector<GridTrack>& columnTracks);
114    LayoutUnit startOfColumnForChild(const RenderBox& child) const;
115    LayoutUnit endOfColumnForChild(const RenderBox& child) const;
116    LayoutUnit columnPositionAlignedWithGridContainerStart(const RenderBox&) const;
117    LayoutUnit columnPositionAlignedWithGridContainerEnd(const RenderBox&) const;
118    LayoutUnit centeredColumnPositionForChild(const RenderBox&) const;
119    LayoutUnit columnPositionForChild(const RenderBox&) const;
120    LayoutUnit startOfRowForChild(const RenderBox& child) const;
121    LayoutUnit endOfRowForChild(const RenderBox& child) const;
122    LayoutUnit centeredRowPositionForChild(const RenderBox&) const;
123    LayoutUnit rowPositionForChild(const RenderBox&) const;
124    LayoutPoint findChildLogicalPosition(const RenderBox&) const;
125    GridCoordinate cachedGridCoordinate(const RenderBox&) const;
126
127    LayoutUnit gridAreaBreadthForChild(const RenderBox& child, GridTrackSizingDirection, const Vector<GridTrack>&) const;
128
129    virtual void paintChildren(PaintInfo&, const LayoutPoint&) OVERRIDE;
130
131#if ENABLE(ASSERT)
132    bool tracksAreWiderThanMinTrackBreadth(GridTrackSizingDirection, const Vector<GridTrack>&);
133#endif
134
135    size_t gridItemSpan(const RenderBox&, GridTrackSizingDirection);
136
137    size_t gridColumnCount() const
138    {
139        ASSERT(!gridIsDirty());
140        return m_grid[0].size();
141    }
142    size_t gridRowCount() const
143    {
144        ASSERT(!gridIsDirty());
145        return m_grid.size();
146    }
147
148    typedef Vector<Vector<GridCell> > GridRepresentation;
149    GridRepresentation m_grid;
150    bool m_gridIsDirty;
151    Vector<LayoutUnit> m_rowPositions;
152    Vector<LayoutUnit> m_columnPositions;
153    HashMap<const RenderBox*, GridCoordinate> m_gridItemCoordinate;
154    OrderIterator m_orderIterator;
155    Vector<RenderBox*> m_gridItemsOverflowingGridArea;
156    HashMap<const RenderBox*, size_t> m_gridItemsIndexesMap;
157};
158
159DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderGrid, isRenderGrid());
160
161} // namespace blink
162
163#endif // RenderGrid_h
164