initial import
[vuplus_webkit] / 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 enum SkipEmptySectionsValue { DoNotSkipEmptySections, SkipEmptySections };
41
42 class RenderTable : public RenderBlock {
43 public:
44     explicit RenderTable(Node*);
45     virtual ~RenderTable();
46
47     int getColumnPos(int col) const { return m_columnPos[col]; }
48
49     int hBorderSpacing() const { return m_hSpacing; }
50     int vBorderSpacing() const { return m_vSpacing; }
51     
52     bool collapseBorders() const { return style()->borderCollapse(); }
53
54     LayoutUnit borderStart() const { return m_borderStart; }
55     LayoutUnit borderEnd() const { return m_borderEnd; }
56     LayoutUnit borderBefore() const;
57     LayoutUnit borderAfter() const;
58
59     LayoutUnit borderLeft() const
60     {
61         if (style()->isHorizontalWritingMode())
62             return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
63         return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
64     }
65
66     LayoutUnit borderRight() const
67     {
68         if (style()->isHorizontalWritingMode())
69             return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
70         return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
71     }
72
73     LayoutUnit borderTop() const
74     {
75         if (style()->isHorizontalWritingMode())
76             return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
77         return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
78     }
79
80     LayoutUnit borderBottom() const
81     {
82         if (style()->isHorizontalWritingMode())
83             return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
84         return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
85     }
86
87     const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
88
89     LayoutUnit outerBorderBefore() const;
90     LayoutUnit outerBorderAfter() const;
91     LayoutUnit outerBorderStart() const;
92     LayoutUnit outerBorderEnd() const;
93
94     LayoutUnit outerBorderLeft() const
95     {
96         if (style()->isHorizontalWritingMode())
97             return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
98         return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
99     }
100
101     LayoutUnit outerBorderRight() const
102     {
103         if (style()->isHorizontalWritingMode())
104             return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
105         return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
106     }
107
108     LayoutUnit outerBorderTop() const
109     {
110         if (style()->isHorizontalWritingMode())
111             return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
112         return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
113     }
114
115     LayoutUnit outerBorderBottom() const
116     {
117         if (style()->isHorizontalWritingMode())
118             return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
119         return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
120     }
121
122     LayoutUnit calcBorderStart() const;
123     LayoutUnit calcBorderEnd() const;
124     void recalcBordersInRowDirection();
125
126     virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
127
128     struct ColumnStruct {
129         enum {
130             WidthUndefined = 0xffff
131         };
132
133         ColumnStruct()
134             : span(1)
135             , width(WidthUndefined)
136         {
137         }
138
139         unsigned span;
140         unsigned width; // the calculated position of the column
141     };
142
143     Vector<ColumnStruct>& columns() { return m_columns; }
144     Vector<LayoutUnit>& columnPositions() { return m_columnPos; }
145     RenderTableSection* header() const { return m_head; }
146     RenderTableSection* footer() const { return m_foot; }
147     RenderTableSection* firstBody() const { return m_firstBody; }
148
149     // This function returns 0 if the table has no section.
150     RenderTableSection* topSection() const;
151
152     // This function returns 0 if the table has no non-empty sections.
153     RenderTableSection* topNonEmptySection() const;
154
155     void splitColumn(int pos, int firstSpan);
156     void appendColumn(int span);
157     int numEffCols() const { return m_columns.size(); }
158     int spanOfEffCol(int effCol) const { return m_columns[effCol].span; }
159     
160     int colToEffCol(int col) const
161     {
162         int i = 0;
163         int effCol = numEffCols();
164         for (int c = 0; c < col && i < effCol; ++i)
165             c += m_columns[i].span;
166         return i;
167     }
168     
169     int effColToCol(int effCol) const
170     {
171         int c = 0;
172         for (int i = 0; i < effCol; i++)
173             c += m_columns[i].span;
174         return c;
175     }
176
177     int bordersPaddingAndSpacingInRowDirection() const
178     {
179         return borderStart() + borderEnd() +
180                (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
181     }
182
183     RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
184     RenderTableCol* nextColElement(RenderTableCol* current) const;
185
186     bool needsSectionRecalc() const { return m_needsSectionRecalc; }
187     void setNeedsSectionRecalc()
188     {
189         if (documentBeingDestroyed())
190             return;
191         m_needsSectionRecalc = true;
192         setNeedsLayout(true);
193     }
194
195     RenderTableSection* sectionAbove(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
196     RenderTableSection* sectionBelow(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
197
198     RenderTableCell* cellAbove(const RenderTableCell*) const;
199     RenderTableCell* cellBelow(const RenderTableCell*) const;
200     RenderTableCell* cellBefore(const RenderTableCell*) const;
201     RenderTableCell* cellAfter(const RenderTableCell*) const;
202  
203     const CollapsedBorderValue* currentBorderStyle() const { return m_currentBorder; }
204     
205     bool hasSections() const { return m_head || m_foot || m_firstBody; }
206
207     void recalcSectionsIfNeeded() const
208     {
209         if (m_needsSectionRecalc)
210             recalcSections();
211     }
212
213 protected:
214     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
215
216 private:
217     virtual const char* renderName() const { return "RenderTable"; }
218
219     virtual bool isTable() const { return true; }
220
221     virtual bool avoidsFloats() const { return true; }
222
223     virtual void removeChild(RenderObject* oldChild);
224
225     virtual void paint(PaintInfo&, const LayoutPoint&);
226     virtual void paintObject(PaintInfo&, const LayoutPoint&);
227     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
228     virtual void paintMask(PaintInfo&, const LayoutPoint&);
229     virtual void layout();
230     virtual void computePreferredLogicalWidths();
231     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const LayoutPoint& pointInContainer, const LayoutPoint& accumulatedOffset, HitTestAction);
232     
233     virtual LayoutUnit firstLineBoxBaseline() const;
234
235     virtual RenderBlock* firstLineBlock() const;
236     virtual void updateFirstLetter();
237     
238     virtual void setCellLogicalWidths();
239
240     virtual void computeLogicalWidth();
241
242     virtual LayoutRect overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
243
244     virtual void addOverflowFromChildren();
245
246     void subtractCaptionRect(LayoutRect&) const;
247
248     void recalcCaption(RenderBlock*) const;
249     void recalcSections() const;
250     void adjustLogicalHeightForCaption();
251
252     mutable Vector<LayoutUnit> m_columnPos;
253     mutable Vector<ColumnStruct> m_columns;
254
255     mutable RenderBlock* m_caption;
256     mutable RenderTableSection* m_head;
257     mutable RenderTableSection* m_foot;
258     mutable RenderTableSection* m_firstBody;
259
260     OwnPtr<TableLayout> m_tableLayout;
261
262     const CollapsedBorderValue* m_currentBorder;
263     
264     mutable bool m_hasColElements : 1;
265     mutable bool m_needsSectionRecalc : 1;
266     
267     short m_hSpacing;
268     short m_vSpacing;
269     LayoutUnit m_borderStart;
270     LayoutUnit m_borderEnd;
271 };
272
273 inline RenderTableSection* RenderTable::topSection() const
274 {
275     if (m_head)
276         return m_head;
277     if (m_firstBody)
278         return m_firstBody;
279     return m_foot;
280 }
281
282 inline RenderTable* toRenderTable(RenderObject* object)
283 {
284     ASSERT(!object || object->isTable());
285     return static_cast<RenderTable*>(object);
286 }
287
288 inline const RenderTable* toRenderTable(const RenderObject* object)
289 {
290     ASSERT(!object || object->isTable());
291     return static_cast<const RenderTable*>(object);
292 }
293
294 // This will catch anyone doing an unnecessary cast.
295 void toRenderTable(const RenderTable*);
296
297 } // namespace WebCore
298
299 #endif // RenderTable_h