45db7aa19c797d712138a81292b8b8a4f615c257
[WebKit-https.git] / Source / WebCore / rendering / RenderTableCell.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, 2007, 2009 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 RenderTableCell_h
26 #define RenderTableCell_h
27
28 #include "RenderTableRow.h"
29 #include "RenderTableSection.h"
30
31 namespace WebCore {
32
33 static const unsigned unsetColumnIndex = 0x3FFFFFFF;
34 static const unsigned maxColumnIndex = 0x3FFFFFFE; // 1,073,741,823
35
36 enum IncludeBorderColorOrNot { DoNotIncludeBorderColor, IncludeBorderColor };
37
38 class RenderTableCell : public RenderBlock {
39 public:
40     explicit RenderTableCell(Node*);
41     
42     unsigned colSpan() const;
43     unsigned rowSpan() const;
44
45     // Called from HTMLTableCellElement.
46     void colSpanOrRowSpanChanged();
47
48     void setCol(unsigned column)
49     {
50         if (UNLIKELY(column > maxColumnIndex))
51             CRASH();
52
53         m_column = column;
54     }
55
56     unsigned col() const
57     {
58         ASSERT(m_column != unsetColumnIndex);
59         return m_column;
60     }
61
62     RenderTableRow* row() const { return toRenderTableRow(parent()); }
63     RenderTableSection* section() const { return toRenderTableSection(parent()->parent()); }
64     RenderTable* table() const { return toRenderTable(parent()->parent()->parent()); }
65
66     unsigned rowIndex() const
67     {
68         // This function shouldn't be called on a detached cell.
69         ASSERT(row());
70         return row()->rowIndex();
71     }
72
73     Length styleOrColLogicalWidth() const;
74
75     LayoutUnit logicalHeightForRowSizing() const;
76
77     virtual void computePreferredLogicalWidths();
78
79     void setCellLogicalWidth(LayoutUnit);
80
81     virtual int borderLeft() const;
82     virtual int borderRight() const;
83     virtual int borderTop() const;
84     virtual int borderBottom() const;
85     virtual int borderStart() const;
86     virtual int borderEnd() const;
87     virtual int borderBefore() const;
88     virtual int borderAfter() const;
89
90     void collectBorderValues(RenderTable::CollapsedBorderValues&) const;
91     static void sortBorderValues(RenderTable::CollapsedBorderValues&);
92
93     virtual void layout();
94
95     virtual void paint(PaintInfo&, const LayoutPoint&);
96
97     void paintCollapsedBorders(PaintInfo&, const LayoutPoint&);
98     void paintBackgroundsBehindCell(PaintInfo&, const LayoutPoint&, RenderObject* backgroundObject);
99
100     LayoutUnit cellBaselinePosition() const;
101
102     void setIntrinsicPaddingBefore(int p) { m_intrinsicPaddingBefore = p; }
103     void setIntrinsicPaddingAfter(int p) { m_intrinsicPaddingAfter = p; }
104     void setIntrinsicPadding(int before, int after) { setIntrinsicPaddingBefore(before); setIntrinsicPaddingAfter(after); }
105     void clearIntrinsicPadding() { setIntrinsicPadding(0, 0); }
106
107     int intrinsicPaddingBefore() const { return m_intrinsicPaddingBefore; }
108     int intrinsicPaddingAfter() const { return m_intrinsicPaddingAfter; }
109
110     virtual LayoutUnit paddingTop() const OVERRIDE;
111     virtual LayoutUnit paddingBottom() const OVERRIDE;
112     virtual LayoutUnit paddingLeft() const OVERRIDE;
113     virtual LayoutUnit paddingRight() const OVERRIDE;
114     
115     // FIXME: For now we just assume the cell has the same block flow direction as the table. It's likely we'll
116     // create an extra anonymous RenderBlock to handle mixing directionality anyway, in which case we can lock
117     // the block flow directionality of the cells to the table's directionality.
118     virtual LayoutUnit paddingBefore() const OVERRIDE;
119     virtual LayoutUnit paddingAfter() const OVERRIDE;
120
121     void setOverrideLogicalContentHeightFromRowHeight(LayoutUnit);
122
123     virtual void scrollbarsChanged(bool horizontalScrollbarChanged, bool verticalScrollbarChanged);
124
125     bool cellWidthChanged() const { return m_cellWidthChanged; }
126     void setCellWidthChanged(bool b = true) { m_cellWidthChanged = b; }
127
128     static RenderTableCell* createAnonymousWithParentRenderer(const RenderObject*);
129     virtual RenderBox* createAnonymousBoxWithSameTypeAs(const RenderObject* parent) const OVERRIDE
130     {
131         return createAnonymousWithParentRenderer(parent);
132     }
133
134     // This function is used to unify which table part's style we use for computing direction and
135     // writing mode. Writing modes are not allowed on row group and row but direction is.
136     // This means we can safely use the same style in all cases to simplify our code.
137     // FIXME: Eventually this function should replaced by style() once we support direction
138     // on all table parts and writing-mode on cells.
139     const RenderStyle* styleForCellFlow() const
140     {
141         return section()->style();
142     }
143
144     const BorderValue& borderAdjoiningTableStart() const
145     {
146         ASSERT(isFirstOrLastCellInRow());
147         if (section()->hasSameDirectionAs(table()))
148             return style()->borderStart();
149
150         return style()->borderEnd();
151     }
152
153     const BorderValue& borderAdjoiningTableEnd() const
154     {
155         ASSERT(isFirstOrLastCellInRow());
156         if (section()->hasSameDirectionAs(table()))
157             return style()->borderEnd();
158
159         return style()->borderStart();
160     }
161
162     const BorderValue& borderAdjoiningCellBefore(const RenderTableCell* cell)
163     {
164         ASSERT_UNUSED(cell, table()->cellAfter(cell) == this);
165         // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at the cell level.
166         return style()->borderStart();
167     }
168
169     const BorderValue& borderAdjoiningCellAfter(const RenderTableCell* cell)
170     {
171         ASSERT_UNUSED(cell, table()->cellBefore(cell) == this);
172         // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at the cell level.
173         return style()->borderEnd();
174     }
175
176 #ifndef NDEBUG
177     bool isFirstOrLastCellInRow() const
178     {
179         return !table()->cellAfter(this) || !table()->cellBefore(this);
180     }
181 #endif
182 protected:
183     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
184
185 private:
186     virtual const char* renderName() const { return isAnonymous() ? "RenderTableCell (anonymous)" : "RenderTableCell"; }
187
188     virtual bool isTableCell() const { return true; }
189
190     virtual void willBeRemovedFromTree() OVERRIDE;
191
192     virtual void updateLogicalWidth() OVERRIDE;
193
194     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&);
195     virtual void paintMask(PaintInfo&, const LayoutPoint&);
196
197     virtual bool boxShadowShouldBeAppliedToBackground(BackgroundBleedAvoidance, InlineFlowBox*) const OVERRIDE;
198
199     virtual LayoutSize offsetFromContainer(RenderObject*, const LayoutPoint&, bool* offsetDependsOnPoint = 0) const;
200     virtual LayoutRect clippedOverflowRectForRepaint(RenderLayerModelObject* repaintContainer) const OVERRIDE;
201     virtual void computeRectForRepaint(RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
202
203     int borderHalfLeft(bool outer) const;
204     int borderHalfRight(bool outer) const;
205     int borderHalfTop(bool outer) const;
206     int borderHalfBottom(bool outer) const;
207
208     int borderHalfStart(bool outer) const;
209     int borderHalfEnd(bool outer) const;
210     int borderHalfBefore(bool outer) const;
211     int borderHalfAfter(bool outer) const;
212
213     CollapsedBorderValue collapsedStartBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
214     CollapsedBorderValue collapsedEndBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
215     CollapsedBorderValue collapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
216     CollapsedBorderValue collapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
217
218     CollapsedBorderValue cachedCollapsedLeftBorder(const RenderStyle*) const;
219     CollapsedBorderValue cachedCollapsedRightBorder(const RenderStyle*) const;
220     CollapsedBorderValue cachedCollapsedTopBorder(const RenderStyle*) const;
221     CollapsedBorderValue cachedCollapsedBottomBorder(const RenderStyle*) const;
222
223     CollapsedBorderValue computeCollapsedStartBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
224     CollapsedBorderValue computeCollapsedEndBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
225     CollapsedBorderValue computeCollapsedBeforeBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
226     CollapsedBorderValue computeCollapsedAfterBorder(IncludeBorderColorOrNot = IncludeBorderColor) const;
227
228     unsigned m_column : 30;
229     bool m_cellWidthChanged : 1;
230     bool m_hasHTMLTableCellElement : 1;
231     int m_intrinsicPaddingBefore;
232     int m_intrinsicPaddingAfter;
233 };
234
235 inline RenderTableCell* toRenderTableCell(RenderObject* object)
236 {
237     ASSERT(!object || object->isTableCell());
238     return static_cast<RenderTableCell*>(object);
239 }
240
241 inline const RenderTableCell* toRenderTableCell(const RenderObject* object)
242 {
243     ASSERT(!object || object->isTableCell());
244     return static_cast<const RenderTableCell*>(object);
245 }
246
247 // This will catch anyone doing an unnecessary cast.
248 void toRenderTableCell(const RenderTableCell*);
249
250 } // namespace WebCore
251
252 #endif // RenderTableCell_h