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.
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.
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.
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.
28 #include "CSSPropertyNames.h"
29 #include "RenderBlock.h"
30 #include <wtf/Vector.h>
34 class CollapsedBorderValue;
36 class RenderTableCell;
37 class RenderTableSection;
40 enum SkipEmptySectionsValue { DoNotSkipEmptySections, SkipEmptySections };
42 class RenderTable : public RenderBlock {
44 explicit RenderTable(Node*);
45 virtual ~RenderTable();
47 int getColumnPos(int col) const { return m_columnPos[col]; }
49 int hBorderSpacing() const { return m_hSpacing; }
50 int vBorderSpacing() const { return m_vSpacing; }
52 bool collapseBorders() const { return style()->borderCollapse(); }
54 LayoutUnit borderStart() const { return m_borderStart; }
55 LayoutUnit borderEnd() const { return m_borderEnd; }
56 LayoutUnit borderBefore() const;
57 LayoutUnit borderAfter() const;
59 LayoutUnit borderLeft() const
61 if (style()->isHorizontalWritingMode())
62 return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
63 return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
66 LayoutUnit borderRight() const
68 if (style()->isHorizontalWritingMode())
69 return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
70 return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
73 LayoutUnit borderTop() const
75 if (style()->isHorizontalWritingMode())
76 return style()->isFlippedBlocksWritingMode() ? borderAfter() : borderBefore();
77 return style()->isLeftToRightDirection() ? borderStart() : borderEnd();
80 LayoutUnit borderBottom() const
82 if (style()->isHorizontalWritingMode())
83 return style()->isFlippedBlocksWritingMode() ? borderBefore() : borderAfter();
84 return style()->isLeftToRightDirection() ? borderEnd() : borderStart();
87 const Color bgColor() const { return style()->visitedDependentColor(CSSPropertyBackgroundColor); }
89 LayoutUnit outerBorderBefore() const;
90 LayoutUnit outerBorderAfter() const;
91 LayoutUnit outerBorderStart() const;
92 LayoutUnit outerBorderEnd() const;
94 LayoutUnit outerBorderLeft() const
96 if (style()->isHorizontalWritingMode())
97 return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
98 return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
101 LayoutUnit outerBorderRight() const
103 if (style()->isHorizontalWritingMode())
104 return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
105 return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
108 LayoutUnit outerBorderTop() const
110 if (style()->isHorizontalWritingMode())
111 return style()->isFlippedBlocksWritingMode() ? outerBorderAfter() : outerBorderBefore();
112 return style()->isLeftToRightDirection() ? outerBorderStart() : outerBorderEnd();
115 LayoutUnit outerBorderBottom() const
117 if (style()->isHorizontalWritingMode())
118 return style()->isFlippedBlocksWritingMode() ? outerBorderBefore() : outerBorderAfter();
119 return style()->isLeftToRightDirection() ? outerBorderEnd() : outerBorderStart();
122 LayoutUnit calcBorderStart() const;
123 LayoutUnit calcBorderEnd() const;
124 void recalcBordersInRowDirection();
126 virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
128 struct ColumnStruct {
130 WidthUndefined = 0xffff
135 , width(WidthUndefined)
140 unsigned width; // the calculated position of the column
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; }
149 // This function returns 0 if the table has no section.
150 RenderTableSection* topSection() const;
152 // This function returns 0 if the table has no non-empty sections.
153 RenderTableSection* topNonEmptySection() const;
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; }
160 int colToEffCol(int col) const
163 int effCol = numEffCols();
164 for (int c = 0; c < col && i < effCol; ++i)
165 c += m_columns[i].span;
169 int effColToCol(int effCol) const
172 for (int i = 0; i < effCol; i++)
173 c += m_columns[i].span;
177 int bordersPaddingAndSpacingInRowDirection() const
179 return borderStart() + borderEnd() +
180 (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
183 RenderTableCol* colElement(int col, bool* startEdge = 0, bool* endEdge = 0) const;
184 RenderTableCol* nextColElement(RenderTableCol* current) const;
186 bool needsSectionRecalc() const { return m_needsSectionRecalc; }
187 void setNeedsSectionRecalc()
189 if (documentBeingDestroyed())
191 m_needsSectionRecalc = true;
192 setNeedsLayout(true);
195 RenderTableSection* sectionAbove(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
196 RenderTableSection* sectionBelow(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
198 RenderTableCell* cellAbove(const RenderTableCell*) const;
199 RenderTableCell* cellBelow(const RenderTableCell*) const;
200 RenderTableCell* cellBefore(const RenderTableCell*) const;
201 RenderTableCell* cellAfter(const RenderTableCell*) const;
203 const CollapsedBorderValue* currentBorderStyle() const { return m_currentBorder; }
205 bool hasSections() const { return m_head || m_foot || m_firstBody; }
207 void recalcSectionsIfNeeded() const
209 if (m_needsSectionRecalc)
214 virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
217 virtual const char* renderName() const { return "RenderTable"; }
219 virtual bool isTable() const { return true; }
221 virtual bool avoidsFloats() const { return true; }
223 virtual void removeChild(RenderObject* oldChild);
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);
233 virtual LayoutUnit firstLineBoxBaseline() const;
235 virtual RenderBlock* firstLineBlock() const;
236 virtual void updateFirstLetter();
238 virtual void setCellLogicalWidths();
240 virtual void computeLogicalWidth();
242 virtual LayoutRect overflowClipRect(const LayoutPoint& location, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
244 virtual void addOverflowFromChildren();
246 void subtractCaptionRect(LayoutRect&) const;
248 void recalcCaption(RenderBlock*) const;
249 void recalcSections() const;
250 void adjustLogicalHeightForCaption();
252 mutable Vector<LayoutUnit> m_columnPos;
253 mutable Vector<ColumnStruct> m_columns;
255 mutable RenderBlock* m_caption;
256 mutable RenderTableSection* m_head;
257 mutable RenderTableSection* m_foot;
258 mutable RenderTableSection* m_firstBody;
260 OwnPtr<TableLayout> m_tableLayout;
262 const CollapsedBorderValue* m_currentBorder;
264 mutable bool m_hasColElements : 1;
265 mutable bool m_needsSectionRecalc : 1;
269 LayoutUnit m_borderStart;
270 LayoutUnit m_borderEnd;
273 inline RenderTableSection* RenderTable::topSection() const
282 inline RenderTable* toRenderTable(RenderObject* object)
284 ASSERT(!object || object->isTable());
285 return static_cast<RenderTable*>(object);
288 inline const RenderTable* toRenderTable(const RenderObject* object)
290 ASSERT(!object || object->isTable());
291 return static_cast<const RenderTable*>(object);
294 // This will catch anyone doing an unnecessary cast.
295 void toRenderTable(const RenderTable*);
297 } // namespace WebCore
299 #endif // RenderTable_h