OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) | 2 * Copyright (C) 1997 Martin Jones (mjones@kde.org) |
3 * (C) 1997 Torben Weis (weis@kde.org) | 3 * (C) 1997 Torben Weis (weis@kde.org) |
4 * (C) 1998 Waldo Bastian (bastian@kde.org) | 4 * (C) 1998 Waldo Bastian (bastian@kde.org) |
5 * (C) 1999 Lars Knoll (knoll@kde.org) | 5 * (C) 1999 Lars Knoll (knoll@kde.org) |
6 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 6 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
All rights reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 zApple Inc
. |
| 8 * All rights reserved. |
8 * | 9 * |
9 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 11 * modify it under the terms of the GNU Library General Public |
11 * License as published by the Free Software Foundation; either | 12 * License as published by the Free Software Foundation; either |
12 * version 2 of the License, or (at your option) any later version. | 13 * version 2 of the License, or (at your option) any later version. |
13 * | 14 * |
14 * This library is distributed in the hope that it will be useful, | 15 * This library is distributed in the hope that it will be useful, |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 * Library General Public License for more details. | 18 * Library General Public License for more details. |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 LayoutTable* table = this->table(); | 69 LayoutTable* table = this->table(); |
69 if (!table) | 70 if (!table) |
70 return; | 71 return; |
71 | 72 |
72 if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && | 73 if (!table->selfNeedsLayout() && !table->normalChildNeedsLayout() && |
73 oldStyle->border() != style()->border()) | 74 oldStyle->border() != style()->border()) |
74 table->invalidateCollapsedBorders(); | 75 table->invalidateCollapsedBorders(); |
75 | 76 |
76 if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, | 77 if (LayoutTableBoxComponent::doCellsHaveDirtyWidth(*this, *table, diff, |
77 *oldStyle)) { | 78 *oldStyle)) { |
78 // If the border width changes on a row, we need to make sure the cells in t
he row know to lay out again. | 79 // If the border width changes on a row, we need to make sure the cells in |
79 // This only happens when borders are collapsed, since they end up affecting
the border sides of the cell | 80 // the row know to lay out again. |
80 // itself. | 81 // This only happens when borders are collapsed, since they end up affecting |
| 82 // the border sides of the cell itself. |
81 for (LayoutBox* childBox = firstChildBox(); childBox; | 83 for (LayoutBox* childBox = firstChildBox(); childBox; |
82 childBox = childBox->nextSiblingBox()) { | 84 childBox = childBox->nextSiblingBox()) { |
83 if (!childBox->isTableCell()) | 85 if (!childBox->isTableCell()) |
84 continue; | 86 continue; |
85 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is nee
ded instead of setNeedsLayout. | 87 // TODO(dgrogan) Add a layout test showing that setChildNeedsLayout is |
| 88 // needed instead of setNeedsLayout. |
86 childBox->setChildNeedsLayout(); | 89 childBox->setChildNeedsLayout(); |
87 childBox->setPreferredLogicalWidthsDirty(MarkOnlyThis); | 90 childBox->setPreferredLogicalWidthsDirty(MarkOnlyThis); |
88 } | 91 } |
89 // Most table componenents can rely on LayoutObject::styleDidChange | 92 // Most table componenents can rely on LayoutObject::styleDidChange |
90 // to mark the container chain dirty. But LayoutTableSection seems | 93 // to mark the container chain dirty. But LayoutTableSection seems |
91 // to never clear its dirty bit, which stops the propagation. So | 94 // to never clear its dirty bit, which stops the propagation. So |
92 // anything under LayoutTableSection has to restart the propagation | 95 // anything under LayoutTableSection has to restart the propagation |
93 // at the table. | 96 // at the table. |
94 // TODO(dgrogan): Make LayoutTableSection clear its dirty bit. | 97 // TODO(dgrogan): Make LayoutTableSection clear its dirty bit. |
95 table->setPreferredLogicalWidthsDirty(); | 98 table->setPreferredLogicalWidthsDirty(); |
96 } | 99 } |
97 } | 100 } |
98 | 101 |
99 const BorderValue& LayoutTableRow::borderAdjoiningStartCell( | 102 const BorderValue& LayoutTableRow::borderAdjoiningStartCell( |
100 const LayoutTableCell* cell) const { | 103 const LayoutTableCell* cell) const { |
101 #if DCHECK_IS_ON() | 104 #if DCHECK_IS_ON() |
102 DCHECK(cell->isFirstOrLastCellInRow()); | 105 DCHECK(cell->isFirstOrLastCellInRow()); |
103 #endif | 106 #endif |
104 // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at
the cell level. | 107 // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at |
| 108 // the cell level. |
105 return style()->borderStart(); | 109 return style()->borderStart(); |
106 } | 110 } |
107 | 111 |
108 const BorderValue& LayoutTableRow::borderAdjoiningEndCell( | 112 const BorderValue& LayoutTableRow::borderAdjoiningEndCell( |
109 const LayoutTableCell* cell) const { | 113 const LayoutTableCell* cell) const { |
110 #if DCHECK_IS_ON() | 114 #if DCHECK_IS_ON() |
111 DCHECK(cell->isFirstOrLastCellInRow()); | 115 DCHECK(cell->isFirstOrLastCellInRow()); |
112 #endif | 116 #endif |
113 // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at
the cell level. | 117 // FIXME: https://webkit.org/b/79272 - Add support for mixed directionality at |
| 118 // the cell level. |
114 return style()->borderEnd(); | 119 return style()->borderEnd(); |
115 } | 120 } |
116 | 121 |
117 void LayoutTableRow::addChild(LayoutObject* child, LayoutObject* beforeChild) { | 122 void LayoutTableRow::addChild(LayoutObject* child, LayoutObject* beforeChild) { |
118 if (!child->isTableCell()) { | 123 if (!child->isTableCell()) { |
119 LayoutObject* last = beforeChild; | 124 LayoutObject* last = beforeChild; |
120 if (!last) | 125 if (!last) |
121 last = lastCell(); | 126 last = lastCell(); |
122 if (last && last->isAnonymous() && last->isTableCell() && | 127 if (last && last->isAnonymous() && last->isTableCell() && |
123 !last->isBeforeOrAfterContent()) { | 128 !last->isBeforeOrAfterContent()) { |
(...skipping 28 matching lines...) Expand all Loading... |
152 } | 157 } |
153 | 158 |
154 if (beforeChild && beforeChild->parent() != this) | 159 if (beforeChild && beforeChild->parent() != this) |
155 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); | 160 beforeChild = splitAnonymousBoxesAroundChild(beforeChild); |
156 | 161 |
157 LayoutTableCell* cell = toLayoutTableCell(child); | 162 LayoutTableCell* cell = toLayoutTableCell(child); |
158 | 163 |
159 ASSERT(!beforeChild || beforeChild->isTableCell()); | 164 ASSERT(!beforeChild || beforeChild->isTableCell()); |
160 LayoutTableBoxComponent::addChild(cell, beforeChild); | 165 LayoutTableBoxComponent::addChild(cell, beforeChild); |
161 | 166 |
162 // Generated content can result in us having a null section so make sure to nu
ll check our parent. | 167 // Generated content can result in us having a null section so make sure to |
| 168 // null check our parent. |
163 if (parent()) { | 169 if (parent()) { |
164 section()->addCell(cell, this); | 170 section()->addCell(cell, this); |
165 // When borders collapse, adding a cell can affect the the width of neighbor
ing cells. | 171 // When borders collapse, adding a cell can affect the the width of |
| 172 // neighboring cells. |
166 LayoutTable* enclosingTable = table(); | 173 LayoutTable* enclosingTable = table(); |
167 if (enclosingTable && enclosingTable->collapseBorders()) { | 174 if (enclosingTable && enclosingTable->collapseBorders()) { |
168 if (LayoutTableCell* previousCell = cell->previousCell()) | 175 if (LayoutTableCell* previousCell = cell->previousCell()) |
169 previousCell->setNeedsLayoutAndPrefWidthsRecalc( | 176 previousCell->setNeedsLayoutAndPrefWidthsRecalc( |
170 LayoutInvalidationReason::TableChanged); | 177 LayoutInvalidationReason::TableChanged); |
171 if (LayoutTableCell* nextCell = cell->nextCell()) | 178 if (LayoutTableCell* nextCell = cell->nextCell()) |
172 nextCell->setNeedsLayoutAndPrefWidthsRecalc( | 179 nextCell->setNeedsLayoutAndPrefWidthsRecalc( |
173 LayoutInvalidationReason::TableChanged); | 180 LayoutInvalidationReason::TableChanged); |
174 } | 181 } |
175 } | 182 } |
176 | 183 |
177 if (beforeChild || nextRow()) | 184 if (beforeChild || nextRow()) |
178 section()->setNeedsCellRecalc(); | 185 section()->setNeedsCellRecalc(); |
179 } | 186 } |
180 | 187 |
181 void LayoutTableRow::layout() { | 188 void LayoutTableRow::layout() { |
182 ASSERT(needsLayout()); | 189 ASSERT(needsLayout()); |
183 LayoutAnalyzer::Scope analyzer(*this); | 190 LayoutAnalyzer::Scope analyzer(*this); |
184 | 191 |
185 // Table rows do not add translation. | 192 // Table rows do not add translation. |
186 LayoutState state(*this, LayoutSize()); | 193 LayoutState state(*this, LayoutSize()); |
187 | 194 |
188 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) { | 195 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) { |
189 SubtreeLayoutScope layouter(*cell); | 196 SubtreeLayoutScope layouter(*cell); |
190 if (!cell->needsLayout()) | 197 if (!cell->needsLayout()) |
191 markChildForPaginationRelayoutIfNeeded(*cell, layouter); | 198 markChildForPaginationRelayoutIfNeeded(*cell, layouter); |
192 if (cell->needsLayout()) | 199 if (cell->needsLayout()) |
193 cell->layout(); | 200 cell->layout(); |
194 // We're laying out each cell here to establish its raw logical height so it
can be used to | 201 // We're laying out each cell here to establish its raw logical height so it |
195 // figure out the row's height and baseline later on in layoutRows(). As par
t of that we | 202 // can be used to figure out the row's height and baseline later on in |
196 // will layout the cell again if we're in a paginated context and come up wi
th the | 203 // layoutRows(). As part of that we will layout the cell again if we're in a |
197 // correct strut. Any strut we come up with here will depend on the old page
d layout and will | 204 // paginated context and come up with the correct strut. Any strut we come |
198 // give the cell an invalid height that is not useful for figuring out the r
aw height of the row. | 205 // up with here will depend on the old paged layout and will give the cell |
| 206 // an invalid height that is not useful for figuring out the raw height of |
| 207 // the row. |
199 if (cell->firstRootBox() && cell->firstRootBox()->paginationStrut()) | 208 if (cell->firstRootBox() && cell->firstRootBox()->paginationStrut()) |
200 cell->setLogicalHeight(cell->logicalHeight() - | 209 cell->setLogicalHeight(cell->logicalHeight() - |
201 cell->firstRootBox()->paginationStrut()); | 210 cell->firstRootBox()->paginationStrut()); |
202 } | 211 } |
203 | 212 |
204 m_overflow.reset(); | 213 m_overflow.reset(); |
205 addVisualEffectOverflow(); | 214 addVisualEffectOverflow(); |
206 // We do not call addOverflowFromCell here. The cell are laid out to be | 215 // We do not call addOverflowFromCell here. The cell are laid out to be |
207 // measured above and will be sized correctly in a follow-up phase. | 216 // measured above and will be sized correctly in a follow-up phase. |
208 | 217 |
209 // We only ever need to issue paint invalidations if our cells didn't, which m
eans that they didn't need | 218 // We only ever need to issue paint invalidations if our cells didn't, which |
210 // layout, so we know that our bounds didn't change. This code is just making
up for | 219 // means that they didn't need layout, so we know that our bounds didn't |
211 // the fact that we did not invalidate paints in setStyle() because we had a l
ayout hint. | 220 // change. This code is just making up for the fact that we did not invalidate |
| 221 // paints in setStyle() because we had a layout hint. |
212 if (selfNeedsLayout()) { | 222 if (selfNeedsLayout()) { |
213 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) { | 223 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) { |
214 // FIXME: Is this needed when issuing paint invalidations after layout? | 224 // FIXME: Is this needed when issuing paint invalidations after layout? |
215 cell->setShouldDoFullPaintInvalidation(); | 225 cell->setShouldDoFullPaintInvalidation(); |
216 } | 226 } |
217 } | 227 } |
218 | 228 |
219 // LayoutTableSection::layoutRows will set our logical height and width later,
so it calls updateLayerTransform(). | 229 // LayoutTableSection::layoutRows will set our logical height and width later, |
| 230 // so it calls updateLayerTransform(). |
220 clearNeedsLayout(); | 231 clearNeedsLayout(); |
221 } | 232 } |
222 | 233 |
223 // Hit Testing | 234 // Hit Testing |
224 bool LayoutTableRow::nodeAtPoint(HitTestResult& result, | 235 bool LayoutTableRow::nodeAtPoint(HitTestResult& result, |
225 const HitTestLocation& locationInContainer, | 236 const HitTestLocation& locationInContainer, |
226 const LayoutPoint& accumulatedOffset, | 237 const LayoutPoint& accumulatedOffset, |
227 HitTestAction action) { | 238 HitTestAction action) { |
228 // Table rows cannot ever be hit tested. Effectively they do not exist. | 239 // Table rows cannot ever be hit tested. Effectively they do not exist. |
229 // Just forward to our children always. | 240 // Just forward to our children always. |
230 for (LayoutTableCell* cell = lastCell(); cell; cell = cell->previousCell()) { | 241 for (LayoutTableCell* cell = lastCell(); cell; cell = cell->previousCell()) { |
231 // FIXME: We have to skip over inline flows, since they can show up inside t
able rows | 242 // FIXME: We have to skip over inline flows, since they can show up inside |
232 // at the moment (a demoted inline <form> for example). If we ever implement
a | 243 // table rows at the moment (a demoted inline <form> for example). If we |
233 // table-specific hit-test method (which we should do for performance reason
s anyway), | 244 // ever implement a table-specific hit-test method (which we should do for |
234 // then we can remove this check. | 245 // performance reasons anyway), then we can remove this check. |
235 if (!cell->hasSelfPaintingLayer()) { | 246 if (!cell->hasSelfPaintingLayer()) { |
236 LayoutPoint cellPoint = | 247 LayoutPoint cellPoint = |
237 flipForWritingModeForChild(cell, accumulatedOffset); | 248 flipForWritingModeForChild(cell, accumulatedOffset); |
238 if (cell->nodeAtPoint(result, locationInContainer, cellPoint, action)) { | 249 if (cell->nodeAtPoint(result, locationInContainer, cellPoint, action)) { |
239 updateHitTestResult( | 250 updateHitTestResult( |
240 result, locationInContainer.point() - toLayoutSize(cellPoint)); | 251 result, locationInContainer.point() - toLayoutSize(cellPoint)); |
241 return true; | 252 return true; |
242 } | 253 } |
243 } | 254 } |
244 } | 255 } |
(...skipping 23 matching lines...) Expand all Loading... |
268 } | 279 } |
269 | 280 |
270 void LayoutTableRow::computeOverflow() { | 281 void LayoutTableRow::computeOverflow() { |
271 clearAllOverflows(); | 282 clearAllOverflows(); |
272 addVisualEffectOverflow(); | 283 addVisualEffectOverflow(); |
273 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) | 284 for (LayoutTableCell* cell = firstCell(); cell; cell = cell->nextCell()) |
274 addOverflowFromCell(cell); | 285 addOverflowFromCell(cell); |
275 } | 286 } |
276 | 287 |
277 void LayoutTableRow::addOverflowFromCell(const LayoutTableCell* cell) { | 288 void LayoutTableRow::addOverflowFromCell(const LayoutTableCell* cell) { |
278 // Non-row-spanning-cells don't create overflow (they are fully contained with
in this row). | 289 // Non-row-spanning-cells don't create overflow (they are fully contained |
279 // TODO(crbug.com/603993): This seems incorrect because cell may have visual e
ffect overflow that should be included in this row. | 290 // within this row). |
| 291 // TODO(crbug.com/603993): This seems incorrect because cell may have visual |
| 292 // effect overflow that should be included in this row. |
280 if (cell->rowSpan() == 1) | 293 if (cell->rowSpan() == 1) |
281 return; | 294 return; |
282 | 295 |
283 // Cells only generates visual overflow. | 296 // Cells only generates visual overflow. |
284 LayoutRect cellVisualOverflowRect = | 297 LayoutRect cellVisualOverflowRect = |
285 cell->visualOverflowRectForPropagation(styleRef()); | 298 cell->visualOverflowRectForPropagation(styleRef()); |
286 | 299 |
287 // The cell and the row share the section's coordinate system. However | 300 // The cell and the row share the section's coordinate system. However |
288 // the visual overflow should be determined in the coordinate system of | 301 // the visual overflow should be determined in the coordinate system of |
289 // the row, that's why we shift it below. | 302 // the row, that's why we shift it below. |
290 LayoutUnit cellOffsetLogicalTopDifference = | 303 LayoutUnit cellOffsetLogicalTopDifference = |
291 cell->location().y() - location().y(); | 304 cell->location().y() - location().y(); |
292 cellVisualOverflowRect.move(LayoutUnit(), cellOffsetLogicalTopDifference); | 305 cellVisualOverflowRect.move(LayoutUnit(), cellOffsetLogicalTopDifference); |
293 | 306 |
294 addContentsVisualOverflow(cellVisualOverflowRect); | 307 addContentsVisualOverflow(cellVisualOverflowRect); |
295 } | 308 } |
296 | 309 |
297 } // namespace blink | 310 } // namespace blink |
OLD | NEW |