• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getColumnPos(int col)45     int getColumnPos(int col) const { return m_columnPos[col]; }
46 
hBorderSpacing()47     int hBorderSpacing() const { return m_hSpacing; }
vBorderSpacing()48     int vBorderSpacing() const { return m_vSpacing; }
49 
collapseBorders()50     bool collapseBorders() const { return style()->borderCollapse(); }
51 
borderStart()52     int borderStart() const { return m_borderStart; }
borderEnd()53     int borderEnd() const { return m_borderEnd; }
54     int borderBefore() const;
55     int borderAfter() const;
56 
borderLeft()57     int borderLeft() const
58     {
59         if (style()->isHorizontalWritingMode())
60             return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
61         return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
62     }
63 
borderRight()64     int borderRight() const
65     {
66         if (style()->isHorizontalWritingMode())
67             return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
68         return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
69     }
70 
borderTop()71     int borderTop() const
72     {
73         if (style()->isHorizontalWritingMode())
74             return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
75         return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
76     }
77 
borderBottom()78     int borderBottom() const
79     {
80         if (style()->isHorizontalWritingMode())
81             return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
82         return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
83     }
84 
bgColor()85     const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
86 
87     int outerBorderBefore() const;
88     int outerBorderAfter() const;
89     int outerBorderStart() const;
90     int outerBorderEnd() const;
91 
outerBorderLeft()92     int outerBorderLeft() const
93     {
94         if (style()->isHorizontalWritingMode())
95             return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
96         return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
97     }
98 
outerBorderRight()99     int outerBorderRight() const
100     {
101         if (style()->isHorizontalWritingMode())
102             return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
103         return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
104     }
105 
outerBorderTop()106     int outerBorderTop() const
107     {
108         if (style()->isHorizontalWritingMode())
109             return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
110         return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
111     }
112 
outerBorderBottom()113     int outerBorderBottom() const
114     {
115         if (style()->isHorizontalWritingMode())
116             return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
117         return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
118     }
119 
120     int calcBorderStart() const;
121     int 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 
ColumnStructColumnStruct131         ColumnStruct()
132             : span(1)
133             , width(WidthUndefined)
134         {
135         }
136 
137         unsigned span;
138         unsigned width; // the calculated position of the column
139     };
140 
columns()141     Vector<ColumnStruct>& columns() { return m_columns; }
columnPositions()142     Vector<int>& columnPositions() { return m_columnPos; }
header()143     RenderTableSection* header() const { return m_head; }
footer()144     RenderTableSection* footer() const { return m_foot; }
firstBody()145     RenderTableSection* firstBody() const { return m_firstBody; }
146 
147     void splitColumn(int pos, int firstSpan);
148     void appendColumn(int span);
numEffCols()149     int numEffCols() const { return m_columns.size(); }
spanOfEffCol(int effCol)150     int spanOfEffCol(int effCol) const { return m_columns[effCol].span; }
151 
colToEffCol(int col)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 
effColToCol(int effCol)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 
bordersPaddingAndSpacingInRowDirection()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 
needsSectionRecalc()178     bool needsSectionRecalc() const { return m_needsSectionRecalc; }
setNeedsSectionRecalc()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 
currentBorderStyle()195     const CollapsedBorderValue* currentBorderStyle() const { return m_currentBorder; }
196 
hasSections()197     bool hasSections() const { return m_head || m_foot || m_firstBody; }
198 
recalcSectionsIfNeeded()199     void recalcSectionsIfNeeded() const
200     {
201         if (m_needsSectionRecalc)
202             recalcSections();
203     }
204 
205 #ifdef ANDROID_LAYOUT
clearSingleColumn()206     void clearSingleColumn() { m_singleColumn = false; }
isSingleColumn()207     bool isSingleColumn() const { return m_singleColumn; }
208 #endif
209 
210 protected:
211     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
212 
213 private:
renderName()214     virtual const char* renderName() const { return "RenderTable"; }
215 
isTable()216     virtual bool isTable() const { return true; }
217 
avoidsFloats()218     virtual bool avoidsFloats() const { return true; }
219 
220     virtual void removeChild(RenderObject* oldChild);
221 
222     virtual void paint(PaintInfo&, int tx, int ty);
223     virtual void paintObject(PaintInfo&, int tx, int ty);
224     virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
225     virtual void paintMask(PaintInfo&, int tx, int ty);
226     virtual void layout();
227     virtual void computePreferredLogicalWidths();
228     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, int xPos, int yPos, int tx, int ty, HitTestAction);
229 
230     virtual int firstLineBoxBaseline() const;
231 
232     virtual RenderBlock* firstLineBlock() const;
233     virtual void updateFirstLetter();
234 
235     virtual void setCellLogicalWidths();
236 
237     virtual void computeLogicalWidth();
238 
239     virtual IntRect overflowClipRect(int tx, int ty, OverlayScrollbarSizeRelevancy relevancy = IgnoreOverlayScrollbarSize);
240 
241     virtual void addOverflowFromChildren();
242 
243     void subtractCaptionRect(IntRect&) const;
244 
245     void recalcCaption(RenderBlock*) const;
246     void recalcSections() const;
247     void adjustLogicalHeightForCaption();
248 
249     mutable Vector<int> m_columnPos;
250     mutable Vector<ColumnStruct> m_columns;
251 
252     mutable RenderBlock* m_caption;
253     mutable RenderTableSection* m_head;
254     mutable RenderTableSection* m_foot;
255     mutable RenderTableSection* m_firstBody;
256 
257     OwnPtr<TableLayout> m_tableLayout;
258 
259     const CollapsedBorderValue* m_currentBorder;
260 
261     mutable bool m_hasColElements : 1;
262     mutable bool m_needsSectionRecalc : 1;
263 
264 #ifdef ANDROID_LAYOUT
265     bool m_singleColumn;        // BS(Grace): should I use compact version?
266 #endif
267     short m_hSpacing;
268     short m_vSpacing;
269     int m_borderStart;
270     int m_borderEnd;
271 };
272 
toRenderTable(RenderObject * object)273 inline RenderTable* toRenderTable(RenderObject* object)
274 {
275     ASSERT(!object || object->isTable());
276     return static_cast<RenderTable*>(object);
277 }
278 
toRenderTable(const RenderObject * object)279 inline const RenderTable* toRenderTable(const RenderObject* object)
280 {
281     ASSERT(!object || object->isTable());
282     return static_cast<const RenderTable*>(object);
283 }
284 
285 // This will catch anyone doing an unnecessary cast.
286 void toRenderTable(const RenderTable*);
287 
288 } // namespace WebCore
289 
290 #endif // RenderTable_h
291