Switch RenderTable* to new layout types
[WebKit-https.git] / Source / WebCore / rendering / RenderTable.h
1 /*
2  * Copyright (C) 1997 Martin Jones (mjones@kde.org)
3  *           (C) 1997 Torben Weis (weis@kde.org)
4  *           (C) 1998 Waldo Bastian (bastian@kde.org)
5  *           (C) 1999 Lars Knoll (knoll@kde.org)
6  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
7  * Copyright (C) 2003, 2004, 2005, 2006, 2009, 2010 Apple Inc. All rights reserved.
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public License
20  * along with this library; see the file COPYING.LIB.  If not, write to
21  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  */
24
25 #ifndef RenderTable_h
26 #define RenderTable_h
27
28 #include "CSSPropertyNames.h"
29 #include "RenderBlock.h"
30 #include <wtf/Vector.h>
31
32 namespace WebCore {
33
34 class CollapsedBorderValue;
35 class RenderTableCol;
36 class RenderTableCell;
37 class RenderTableSection;
38 class TableLayout;
39
40 class RenderTable : public RenderBlock {
41 public:
42     explicit RenderTable(Node*);
43     virtual ~RenderTable();
44
45     int getColumnPos(int col) const { return m_columnPos[col]; }
46
47     int hBorderSpacing() const { return m_hSpacing; }
48     int vBorderSpacing() const { return m_vSpacing; }
49     
50     bool collapseBorders() const { return style()->borderCollapse(); }
51
52     LayoutUnit borderStart() const { return m_borderStart; }
53     LayoutUnit borderEnd() const { return m_borderEnd; }
54     LayoutUnit borderBefore() const;
55     LayoutUnit borderAfter() const;
56
57     LayoutUnit borderLeft() const
58     {
59         if (style()->isHorizontalWritingMode())
60             return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
61         return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
62     }
63
64     LayoutUnit borderRight() const
65     {
66         if (style()->isHorizontalWritingMode())
67             return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
68         return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
69     }
70
71     LayoutUnit borderTop() const
72     {
73         if (style()->isHorizontalWritingMode())
74             return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
75         return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
76     }
77
78     LayoutUnit borderBottom() const
79     {
80         if (style()->isHorizontalWritingMode())
81             return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
82         return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
83     }
84
85     const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
86
87     LayoutUnit outerBorderBefore() const;
88     LayoutUnit outerBorderAfter() const;
89     LayoutUnit outerBorderStart() const;
90     LayoutUnit outerBorderEnd() const;
91
92     LayoutUnit outerBorderLeft() const
93     {
94         if (style()->isHorizontalWritingMode())
95             return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
96         return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
97     }
98
99     LayoutUnit outerBorderRight() const
100     {
101         if (style()->isHorizontalWritingMode())
102             return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
103         return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
104     }
105
106     LayoutUnit outerBorderTop() const
107     {
108         if (style()->isHorizontalWritingMode())
109             return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
110         return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
111     }
112
113     LayoutUnit outerBorderBottom() const
114     {
115         if (style()->isHorizontalWritingMode())
116             return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
117         return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
118     }
119
120     LayoutUnit calcBorderStart() const;
121     LayoutUnit calcBorderEnd() const;
122     void recalcBordersInRowDirection();
123
124     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
125
126     struct ColumnStruct {
127         enum {
128             WidthUndefined = 0xffff
129         };
130
131         ColumnStruct()
132             : span(1)
133             , width(WidthUndefined)
134         {
135         }
136
137         unsigned span;
138         unsigned width; // the calculated position of the column
139     };
140
141     Vector<ColumnStruct>& columns() { return m_columns; }
142     Vector<LayoutUnit>& columnPositions() { return m_columnPos; }
143     RenderTableSection* header() const { return m_head; }
144     RenderTableSection* footer() const { return m_foot; }
145     RenderTableSection* firstBody() const { return m_firstBody; }
146
147     void splitColumn(int pos, int firstSpan);
148     void appendColumn(int span);
149     int numEffCols() const { return m_columns.size(); }
150     int spanOfEffCol(int effCol) const { return m_columns[effCol].span; }
151     
152     int colToEffCol(int col) const
153     {
154         int i = 0;
155         int effCol = numEffCols();
156         for (int c = 0; c < col && i < effCol; ++i)
157             c += m_columns[i].span;
158         return i;
159     }
160     
161     int effColToCol(int effCol) const
162     {
163         int c = 0;
164         for (int i = 0; i < effCol; i++)
165             c += m_columns[i].span;
166         return c;
167     }
168
169     int bordersPaddingAndSpacingInRowDirection() const
170     {
171         return borderStart() + borderEnd() +
172                (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
173     }
174
175     RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
176     RenderTableCol* nextColElement(RenderTableCol* current) const;
177
178     bool needsSectionRecalc() const { return m_needsSectionRecalc; }
179     void setNeedsSectionRecalc()
180     {
181         if (documentBeingDestroyed())
182             return;
183         m_needsSectionRecalc = true;
184         setNeedsLayout(true);
185     }
186
187     RenderTableSection* sectionAbove(const RenderTableSection*, bool skipEmptySections = false) const;
188     RenderTableSection* sectionBelow(const RenderTableSection*, bool skipEmptySections = false) const;
189
190     RenderTableCell* cellAbove(const RenderTableCell*) const;
191     RenderTableCell* cellBelow(const RenderTableCell*) const;
192     RenderTableCell* cellBefore(const RenderTableCell*) const;
193     RenderTableCell* cellAfter(const RenderTableCell*) const;
194  
195     const CollapsedBorderValue* currentBorderStyle() const { return m_currentBorder; }
196     
197     bool hasSections() const { return m_head || m_foot || m_firstBody; }
198
199     void recalcSectionsIfNeeded() const
200     {
201         if (m_needsSectionRecalc)
202             recalcSections();
203     }
204
205 protected:
206     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
207
208 private:
209     virtual const char* renderName() const { return "RenderTable"; }
210
211     virtual bool isTable() const { return true; }
212
213     virtual bool avoidsFloats() const { return true; }
214
215     virtual void removeChild(RenderObject* oldChild);
216
217     virtual void paint(PaintInfo&, const LayoutPoint&);
218     virtual void paintObject(PaintInfo&, const LayoutPoint&);
219     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
220     virtual void paintMask(PaintInfo&, const LayoutPoint&);
221     virtual void layout();
222     virtual void computePreferredLogicalWidths();
223     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
224     
225     virtual LayoutUnit firstLineBoxBaseline() const;
226
227     virtual RenderBlock* firstLineBlock() const;
228     virtual void updateFirstLetter();
229     
230     virtual void setCellLogicalWidths();
231
232     virtual void computeLogicalWidth();
233
234     virtual LayoutRect overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
235
236     virtual void addOverflowFromChildren();
237
238     void subtractCaptionRect(LayoutRect&) const;
239
240     void recalcCaption(RenderBlock*) const;
241     void recalcSections() const;
242     void adjustLogicalHeightForCaption();
243
244     mutable Vector<LayoutUnit> m_columnPos;
245     mutable Vector<ColumnStruct> m_columns;
246
247     mutable RenderBlock* m_caption;
248     mutable RenderTableSection* m_head;
249     mutable RenderTableSection* m_foot;
250     mutable RenderTableSection* m_firstBody;
251
252     OwnPtr<TableLayout> m_tableLayout;
253
254     const CollapsedBorderValue* m_currentBorder;
255     
256     mutable bool m_hasColElements : 1;
257     mutable bool m_needsSectionRecalc : 1;
258     
259     short m_hSpacing;
260     short m_vSpacing;
261     LayoutUnit m_borderStart;
262     LayoutUnit m_borderEnd;
263 };
264
265 inline RenderTable* toRenderTable(RenderObject* object)
266 {
267     ASSERT(!object || object->isTable());
268     return static_cast<RenderTable*>(object);
269 }
270
271 inline const RenderTable* toRenderTable(const RenderObject* object)
272 {
273     ASSERT(!object || object->isTable());
274     return static_cast<const RenderTable*>(object);
275 }
276
277 // This will catch anyone doing an unnecessary cast.
278 void toRenderTable(const RenderTable*);
279
280 } // namespace WebCore
281
282 #endif // RenderTable_h