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 "CollapsedBorderValue.h"
30 #include "RenderBlock.h"
31 #include <wtf/Vector.h>
36 class RenderTableCell;
37 class RenderTableSection;
40 enum SkipEmptySectionsValue { DoNotSkipEmptySections, SkipEmptySections };
42 class RenderTable : public RenderBlock {
44 explicit RenderTable(Node*);
45 virtual ~RenderTable();
47 LayoutUnit getColumnPos(unsigned 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 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 {
137 Vector<ColumnStruct>& columns() { return m_columns; }
138 Vector<LayoutUnit>& columnPositions() { return m_columnPos; }
139 RenderTableSection* header() const { return m_head; }
140 RenderTableSection* footer() const { return m_foot; }
141 RenderTableSection* firstBody() const { return m_firstBody; }
143 // This function returns 0 if the table has no section.
144 RenderTableSection* topSection() const;
146 // This function returns 0 if the table has no non-empty sections.
147 RenderTableSection* topNonEmptySection() const;
149 void splitColumn(unsigned position, unsigned firstSpan);
150 void appendColumn(unsigned span);
151 unsigned numEffCols() const { return m_columns.size(); }
152 unsigned spanOfEffCol(unsigned effCol) const { return m_columns[effCol].span; }
154 unsigned colToEffCol(unsigned column) const
156 unsigned effColumn = 0;
157 unsigned numColumns = numEffCols();
158 for (unsigned c = 0; effColumn < numColumns && c + m_columns[effColumn].span - 1 < column; ++effColumn)
159 c += m_columns[effColumn].span;
163 unsigned effColToCol(unsigned effCol) const
166 for (unsigned i = 0; i < effCol; i++)
167 c += m_columns[i].span;
171 LayoutUnit bordersPaddingAndSpacingInRowDirection() const
173 return borderStart() + borderEnd() +
174 (collapseBorders() ? 0 : (paddingStart() + paddingEnd() + (numEffCols() + 1) * hBorderSpacing()));
177 RenderTableCol* colElement(unsigned col, bool* startEdge = 0, bool* endEdge = 0) const;
178 RenderTableCol* nextColElement(RenderTableCol* current) const;
180 bool needsSectionRecalc() const { return m_needsSectionRecalc; }
181 void setNeedsSectionRecalc()
183 if (documentBeingDestroyed())
185 m_needsSectionRecalc = true;
186 setNeedsLayout(true);
189 RenderTableSection* sectionAbove(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
190 RenderTableSection* sectionBelow(const RenderTableSection*, SkipEmptySectionsValue = DoNotSkipEmptySections) const;
192 RenderTableCell* cellAbove(const RenderTableCell*) const;
193 RenderTableCell* cellBelow(const RenderTableCell*) const;
194 RenderTableCell* cellBefore(const RenderTableCell*) const;
195 RenderTableCell* cellAfter(const RenderTableCell*) const;
197 typedef Vector<CollapsedBorderValue> CollapsedBorderValues;
198 void invalidateCollapsedBorders()
200 m_collapsedBordersValid = false;
201 m_collapsedBorders.clear();
203 const CollapsedBorderValue* currentBorderValue() 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, RenderRegion*, OverlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize);
244 virtual void addOverflowFromChildren();
246 void subtractCaptionRect(LayoutRect&) const;
248 void recalcCollapsedBorders();
249 void recalcSections() const;
250 void adjustLogicalHeightForCaption(RenderBlock*);
252 mutable Vector<LayoutUnit> m_columnPos;
253 mutable Vector<ColumnStruct> m_columns;
255 mutable Vector<RenderBlock*> m_captions;
256 mutable RenderTableSection* m_head;
257 mutable RenderTableSection* m_foot;
258 mutable RenderTableSection* m_firstBody;
260 OwnPtr<TableLayout> m_tableLayout;
262 CollapsedBorderValues m_collapsedBorders;
263 const CollapsedBorderValue* m_currentBorder;
264 bool m_collapsedBordersValid : 1;
266 mutable bool m_hasColElements : 1;
267 mutable bool m_needsSectionRecalc : 1;
271 LayoutUnit m_borderStart;
272 LayoutUnit m_borderEnd;
275 inline RenderTableSection* RenderTable::topSection() const
284 inline RenderTable* toRenderTable(RenderObject* object)
286 ASSERT(!object || object->isTable());
287 return static_cast<RenderTable*>(object);
290 inline const RenderTable* toRenderTable(const RenderObject* object)
292 ASSERT(!object || object->isTable());
293 return static_cast<const RenderTable*>(object);
296 // This will catch anyone doing an unnecessary cast.
297 void toRenderTable(const RenderTable*);
299 } // namespace WebCore
301 #endif // RenderTable_h