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 Apple Inc. All rights
reserved. | 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights
reserved. |
8 * | 8 * |
9 * This library is free software; you can redistribute it and/or | 9 * This library is free software; you can redistribute it and/or |
10 * modify it under the terms of the GNU Library General Public | 10 * modify it under the terms of the GNU Library General Public |
(...skipping 19 matching lines...) Expand all Loading... |
30 #include "core/html/HTMLTableCellElement.h" | 30 #include "core/html/HTMLTableCellElement.h" |
31 #include "core/rendering/PaintInfo.h" | 31 #include "core/rendering/PaintInfo.h" |
32 #include "core/rendering/RenderTableCol.h" | 32 #include "core/rendering/RenderTableCol.h" |
33 #include "core/rendering/RenderView.h" | 33 #include "core/rendering/RenderView.h" |
34 #include "core/rendering/SubtreeLayoutScope.h" | 34 #include "core/rendering/SubtreeLayoutScope.h" |
35 #include "core/rendering/style/CollapsedBorderValue.h" | 35 #include "core/rendering/style/CollapsedBorderValue.h" |
36 #include "platform/geometry/FloatQuad.h" | 36 #include "platform/geometry/FloatQuad.h" |
37 #include "platform/geometry/TransformState.h" | 37 #include "platform/geometry/TransformState.h" |
38 #include "platform/graphics/GraphicsContextStateSaver.h" | 38 #include "platform/graphics/GraphicsContextStateSaver.h" |
39 | 39 |
40 using namespace std; | |
41 | |
42 namespace WebCore { | 40 namespace WebCore { |
43 | 41 |
44 using namespace HTMLNames; | 42 using namespace HTMLNames; |
45 | 43 |
46 struct SameSizeAsRenderTableCell : public RenderBlockFlow { | 44 struct SameSizeAsRenderTableCell : public RenderBlockFlow { |
47 unsigned bitfields; | 45 unsigned bitfields; |
48 int paddings[2]; | 46 int paddings[2]; |
49 }; | 47 }; |
50 | 48 |
51 COMPILE_ASSERT(sizeof(RenderTableCell) == sizeof(SameSizeAsRenderTableCell), Ren
derTableCell_should_stay_small); | 49 COMPILE_ASSERT(sizeof(RenderTableCell) == sizeof(SameSizeAsRenderTableCell), Ren
derTableCell_should_stay_small); |
(...skipping 16 matching lines...) Expand all Loading... |
68 RenderBlockFlow::willBeRemovedFromTree(); | 66 RenderBlockFlow::willBeRemovedFromTree(); |
69 | 67 |
70 section()->setNeedsCellRecalc(); | 68 section()->setNeedsCellRecalc(); |
71 section()->removeCachedCollapsedBorders(this); | 69 section()->removeCachedCollapsedBorders(this); |
72 } | 70 } |
73 | 71 |
74 unsigned RenderTableCell::parseColSpanFromDOM() const | 72 unsigned RenderTableCell::parseColSpanFromDOM() const |
75 { | 73 { |
76 ASSERT(node()); | 74 ASSERT(node()); |
77 if (isHTMLTableCellElement(*node())) | 75 if (isHTMLTableCellElement(*node())) |
78 return min<unsigned>(toHTMLTableCellElement(*node()).colSpan(), maxColum
nIndex); | 76 return std::min<unsigned>(toHTMLTableCellElement(*node()).colSpan(), max
ColumnIndex); |
79 return 1; | 77 return 1; |
80 } | 78 } |
81 | 79 |
82 unsigned RenderTableCell::parseRowSpanFromDOM() const | 80 unsigned RenderTableCell::parseRowSpanFromDOM() const |
83 { | 81 { |
84 ASSERT(node()); | 82 ASSERT(node()); |
85 if (isHTMLTableCellElement(*node())) | 83 if (isHTMLTableCellElement(*node())) |
86 return min<unsigned>(toHTMLTableCellElement(*node()).rowSpan(), maxRowIn
dex); | 84 return std::min<unsigned>(toHTMLTableCellElement(*node()).rowSpan(), max
RowIndex); |
87 return 1; | 85 return 1; |
88 } | 86 } |
89 | 87 |
90 void RenderTableCell::updateColAndRowSpanFlags() | 88 void RenderTableCell::updateColAndRowSpanFlags() |
91 { | 89 { |
92 // The vast majority of table cells do not have a colspan or rowspan, | 90 // The vast majority of table cells do not have a colspan or rowspan, |
93 // so we keep a bool to know if we need to bother reading from the DOM. | 91 // so we keep a bool to know if we need to bother reading from the DOM. |
94 m_hasColSpan = node() && parseColSpanFromDOM() != 1; | 92 m_hasColSpan = node() && parseColSpanFromDOM() != 1; |
95 m_hasRowSpan = node() && parseRowSpanFromDOM() != 1; | 93 m_hasRowSpan = node() && parseRowSpanFromDOM() != 1; |
96 } | 94 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 colWidthSum += colWidth.value(); | 128 colWidthSum += colWidth.value(); |
131 tableCol = tableCol->nextColumn(); | 129 tableCol = tableCol->nextColumn(); |
132 // If no next <col> tag found for the span we just return what we have f
or now. | 130 // If no next <col> tag found for the span we just return what we have f
or now. |
133 if (!tableCol) | 131 if (!tableCol) |
134 break; | 132 break; |
135 } | 133 } |
136 | 134 |
137 // Column widths specified on <col> apply to the border box of the cell, see
bug 8126. | 135 // Column widths specified on <col> apply to the border box of the cell, see
bug 8126. |
138 // FIXME: Why is border/padding ignored in the negative width case? | 136 // FIXME: Why is border/padding ignored in the negative width case? |
139 if (colWidthSum > 0) | 137 if (colWidthSum > 0) |
140 return Length(max(0, colWidthSum - borderAndPaddingLogicalWidth().ceil()
), Fixed); | 138 return Length(std::max(0, colWidthSum - borderAndPaddingLogicalWidth().c
eil()), Fixed); |
141 return Length(colWidthSum, Fixed); | 139 return Length(colWidthSum, Fixed); |
142 } | 140 } |
143 | 141 |
144 void RenderTableCell::computePreferredLogicalWidths() | 142 void RenderTableCell::computePreferredLogicalWidths() |
145 { | 143 { |
146 // The child cells rely on the grids up in the sections to do their computeP
referredLogicalWidths work. Normally the sections are set up early, as table | 144 // The child cells rely on the grids up in the sections to do their computeP
referredLogicalWidths work. Normally the sections are set up early, as table |
147 // cells are added, but relayout can cause the cells to be freed, leaving st
ale pointers in the sections' | 145 // cells are added, but relayout can cause the cells to be freed, leaving st
ale pointers in the sections' |
148 // grids. We must refresh those grids before the child cells try to use the
m. | 146 // grids. We must refresh those grids before the child cells try to use the
m. |
149 table()->recalcSectionsIfNeeded(); | 147 table()->recalcSectionsIfNeeded(); |
150 | 148 |
151 RenderBlockFlow::computePreferredLogicalWidths(); | 149 RenderBlockFlow::computePreferredLogicalWidths(); |
152 if (node() && style()->autoWrap()) { | 150 if (node() && style()->autoWrap()) { |
153 // See if nowrap was set. | 151 // See if nowrap was set. |
154 Length w = styleOrColLogicalWidth(); | 152 Length w = styleOrColLogicalWidth(); |
155 const AtomicString& nowrap = toElement(node())->getAttribute(nowrapAttr)
; | 153 const AtomicString& nowrap = toElement(node())->getAttribute(nowrapAttr)
; |
156 if (!nowrap.isNull() && w.isFixed()) | 154 if (!nowrap.isNull() && w.isFixed()) { |
157 // Nowrap is set, but we didn't actually use it because of the | 155 // Nowrap is set, but we didn't actually use it because of the |
158 // fixed width set on the cell. Even so, it is a WinIE/Moz trait | 156 // fixed width set on the cell. Even so, it is a WinIE/Moz trait |
159 // to make the minwidth of the cell into the fixed width. They do t
his | 157 // to make the minwidth of the cell into the fixed width. They do t
his |
160 // even in strict mode, so do not make this a quirk. Affected the t
op | 158 // even in strict mode, so do not make this a quirk. Affected the t
op |
161 // of hiptop.com. | 159 // of hiptop.com. |
162 m_minPreferredLogicalWidth = max<LayoutUnit>(w.value(), m_minPreferr
edLogicalWidth); | 160 m_minPreferredLogicalWidth = std::max<LayoutUnit>(w.value(), m_minPr
eferredLogicalWidth); |
| 161 } |
163 } | 162 } |
164 } | 163 } |
165 | 164 |
166 void RenderTableCell::addLayerHitTestRects(LayerHitTestRects& layerRects, const
RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& con
tainerRect) const | 165 void RenderTableCell::addLayerHitTestRects(LayerHitTestRects& layerRects, const
RenderLayer* currentLayer, const LayoutPoint& layerOffset, const LayoutRect& con
tainerRect) const |
167 { | 166 { |
168 LayoutPoint adjustedLayerOffset = layerOffset; | 167 LayoutPoint adjustedLayerOffset = layerOffset; |
169 // RenderTableCell's location includes the offset of it's containing RenderT
ableRow, so | 168 // RenderTableCell's location includes the offset of it's containing RenderT
ableRow, so |
170 // we need to subtract that again here (as for RenderTableCell::offsetFromCo
ntainer. | 169 // we need to subtract that again here (as for RenderTableCell::offsetFromCo
ntainer. |
171 if (parent()) | 170 if (parent()) |
172 adjustedLayerOffset -= parentBox()->locationOffset(); | 171 adjustedLayerOffset -= parentBox()->locationOffset(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
239 updateFirstLetter(); | 238 updateFirstLetter(); |
240 | 239 |
241 int oldCellBaseline = cellBaselinePosition(); | 240 int oldCellBaseline = cellBaselinePosition(); |
242 layoutBlock(cellWidthChanged()); | 241 layoutBlock(cellWidthChanged()); |
243 | 242 |
244 // If we have replaced content, the intrinsic height of our content may have
changed since the last time we laid out. If that's the case the intrinsic paddi
ng we used | 243 // If we have replaced content, the intrinsic height of our content may have
changed since the last time we laid out. If that's the case the intrinsic paddi
ng we used |
245 // for layout (the padding required to push the contents of the cell down to
the row's baseline) is included in our new height and baseline and makes both | 244 // for layout (the padding required to push the contents of the cell down to
the row's baseline) is included in our new height and baseline and makes both |
246 // of them wrong. So if our content's intrinsic height has changed push the
new content up into the intrinsic padding and relayout so that the rest of | 245 // of them wrong. So if our content's intrinsic height has changed push the
new content up into the intrinsic padding and relayout so that the rest of |
247 // table and row layout can use the correct baseline and height for this cel
l. | 246 // table and row layout can use the correct baseline and height for this cel
l. |
248 if (isBaselineAligned() && section()->rowBaseline(rowIndex()) && cellBaselin
ePosition() > section()->rowBaseline(rowIndex())) { | 247 if (isBaselineAligned() && section()->rowBaseline(rowIndex()) && cellBaselin
ePosition() > section()->rowBaseline(rowIndex())) { |
249 int newIntrinsicPaddingBefore = max<LayoutUnit>(0, intrinsicPaddingBefor
e() - max<LayoutUnit>(0, cellBaselinePosition() - oldCellBaseline)); | 248 int newIntrinsicPaddingBefore = std::max<LayoutUnit>(0, intrinsicPadding
Before() - std::max<LayoutUnit>(0, cellBaselinePosition() - oldCellBaseline)); |
250 setIntrinsicPaddingBefore(newIntrinsicPaddingBefore); | 249 setIntrinsicPaddingBefore(newIntrinsicPaddingBefore); |
251 SubtreeLayoutScope layouter(*this); | 250 SubtreeLayoutScope layouter(*this); |
252 layouter.setNeedsLayout(this); | 251 layouter.setNeedsLayout(this); |
253 layoutBlock(cellWidthChanged()); | 252 layoutBlock(cellWidthChanged()); |
254 } | 253 } |
255 | 254 |
256 // FIXME: This value isn't the intrinsic content logical height, but we need | 255 // FIXME: This value isn't the intrinsic content logical height, but we need |
257 // to update the value as its used by flexbox layout. crbug.com/367324 | 256 // to update the value as its used by flexbox layout. crbug.com/367324 |
258 updateIntrinsicContentLogicalHeight(contentLogicalHeight()); | 257 updateIntrinsicContentLogicalHeight(contentLogicalHeight()); |
259 | 258 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 } | 297 } |
299 | 298 |
300 LayoutUnit RenderTableCell::paddingAfter() const | 299 LayoutUnit RenderTableCell::paddingAfter() const |
301 { | 300 { |
302 return static_cast<int>(computedCSSPaddingAfter()) + intrinsicPaddingAfter()
; | 301 return static_cast<int>(computedCSSPaddingAfter()) + intrinsicPaddingAfter()
; |
303 } | 302 } |
304 | 303 |
305 void RenderTableCell::setOverrideLogicalContentHeightFromRowHeight(LayoutUnit ro
wHeight) | 304 void RenderTableCell::setOverrideLogicalContentHeightFromRowHeight(LayoutUnit ro
wHeight) |
306 { | 305 { |
307 clearIntrinsicPadding(); | 306 clearIntrinsicPadding(); |
308 setOverrideLogicalContentHeight(max<LayoutUnit>(0, rowHeight - borderAndPadd
ingLogicalHeight())); | 307 setOverrideLogicalContentHeight(std::max<LayoutUnit>(0, rowHeight - borderAn
dPaddingLogicalHeight())); |
309 } | 308 } |
310 | 309 |
311 LayoutSize RenderTableCell::offsetFromContainer(const RenderObject* o, const Lay
outPoint& point, bool* offsetDependsOnPoint) const | 310 LayoutSize RenderTableCell::offsetFromContainer(const RenderObject* o, const Lay
outPoint& point, bool* offsetDependsOnPoint) const |
312 { | 311 { |
313 ASSERT(o == container()); | 312 ASSERT(o == container()); |
314 | 313 |
315 LayoutSize offset = RenderBlockFlow::offsetFromContainer(o, point, offsetDep
endsOnPoint); | 314 LayoutSize offset = RenderBlockFlow::offsetFromContainer(o, point, offsetDep
endsOnPoint); |
316 if (parent()) | 315 if (parent()) |
317 offset -= parentBox()->locationOffset(); | 316 offset -= parentBox()->locationOffset(); |
318 | 317 |
319 return offset; | 318 return offset; |
320 } | 319 } |
321 | 320 |
322 LayoutRect RenderTableCell::clippedOverflowRectForPaintInvalidation(const Render
LayerModelObject* paintInvalidationContainer) const | 321 LayoutRect RenderTableCell::clippedOverflowRectForPaintInvalidation(const Render
LayerModelObject* paintInvalidationContainer) const |
323 { | 322 { |
324 // If the table grid is dirty, we cannot get reliable information about adjo
ining cells, | 323 // If the table grid is dirty, we cannot get reliable information about adjo
ining cells, |
325 // so we ignore outside borders. This should not be a problem because it mea
ns that | 324 // so we ignore outside borders. This should not be a problem because it mea
ns that |
326 // the table is going to recalculate the grid, relayout and repaint its curr
ent rect, which | 325 // the table is going to recalculate the grid, relayout and repaint its curr
ent rect, which |
327 // includes any outside borders of this cell. | 326 // includes any outside borders of this cell. |
328 if (!table()->collapseBorders() || table()->needsSectionRecalc()) | 327 if (!table()->collapseBorders() || table()->needsSectionRecalc()) |
329 return RenderBlockFlow::clippedOverflowRectForPaintInvalidation(paintInv
alidationContainer); | 328 return RenderBlockFlow::clippedOverflowRectForPaintInvalidation(paintInv
alidationContainer); |
330 | 329 |
331 bool rtl = !styleForCellFlow()->isLeftToRightDirection(); | 330 bool rtl = !styleForCellFlow()->isLeftToRightDirection(); |
332 int outlineSize = style()->outlineSize(); | 331 int outlineSize = style()->outlineSize(); |
333 int left = max(borderHalfLeft(true), outlineSize); | 332 int left = std::max(borderHalfLeft(true), outlineSize); |
334 int right = max(borderHalfRight(true), outlineSize); | 333 int right = std::max(borderHalfRight(true), outlineSize); |
335 int top = max(borderHalfTop(true), outlineSize); | 334 int top = std::max(borderHalfTop(true), outlineSize); |
336 int bottom = max(borderHalfBottom(true), outlineSize); | 335 int bottom = std::max(borderHalfBottom(true), outlineSize); |
337 if ((left && !rtl) || (right && rtl)) { | 336 if ((left && !rtl) || (right && rtl)) { |
338 if (RenderTableCell* before = table()->cellBefore(this)) { | 337 if (RenderTableCell* before = table()->cellBefore(this)) { |
339 top = max(top, before->borderHalfTop(true)); | 338 top = std::max(top, before->borderHalfTop(true)); |
340 bottom = max(bottom, before->borderHalfBottom(true)); | 339 bottom = std::max(bottom, before->borderHalfBottom(true)); |
341 } | 340 } |
342 } | 341 } |
343 if ((left && rtl) || (right && !rtl)) { | 342 if ((left && rtl) || (right && !rtl)) { |
344 if (RenderTableCell* after = table()->cellAfter(this)) { | 343 if (RenderTableCell* after = table()->cellAfter(this)) { |
345 top = max(top, after->borderHalfTop(true)); | 344 top = std::max(top, after->borderHalfTop(true)); |
346 bottom = max(bottom, after->borderHalfBottom(true)); | 345 bottom = std::max(bottom, after->borderHalfBottom(true)); |
347 } | 346 } |
348 } | 347 } |
349 if (top) { | 348 if (top) { |
350 if (RenderTableCell* above = table()->cellAbove(this)) { | 349 if (RenderTableCell* above = table()->cellAbove(this)) { |
351 left = max(left, above->borderHalfLeft(true)); | 350 left = std::max(left, above->borderHalfLeft(true)); |
352 right = max(right, above->borderHalfRight(true)); | 351 right = std::max(right, above->borderHalfRight(true)); |
353 } | 352 } |
354 } | 353 } |
355 if (bottom) { | 354 if (bottom) { |
356 if (RenderTableCell* below = table()->cellBelow(this)) { | 355 if (RenderTableCell* below = table()->cellBelow(this)) { |
357 left = max(left, below->borderHalfLeft(true)); | 356 left = std::max(left, below->borderHalfLeft(true)); |
358 right = max(right, below->borderHalfRight(true)); | 357 right = std::max(right, below->borderHalfRight(true)); |
359 } | 358 } |
360 } | 359 } |
361 LayoutPoint location(max<LayoutUnit>(left, -visualOverflowRect().x()), max<L
ayoutUnit>(top, -visualOverflowRect().y())); | 360 LayoutPoint location(std::max<LayoutUnit>(left, -visualOverflowRect().x()),
std::max<LayoutUnit>(top, -visualOverflowRect().y())); |
362 LayoutRect r(-location.x(), -location.y(), location.x() + max(width() + righ
t, visualOverflowRect().maxX()), location.y() + max(height() + bottom, visualOve
rflowRect().maxY())); | 361 LayoutRect r(-location.x(), -location.y(), location.x() + std::max(width() +
right, visualOverflowRect().maxX()), location.y() + std::max(height() + bottom,
visualOverflowRect().maxY())); |
363 | 362 |
364 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { | 363 if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) { |
365 if (RenderView* v = view()) { | 364 if (RenderView* v = view()) { |
366 // FIXME: layoutDelta needs to be applied in parts before/after tran
sforms and | 365 // FIXME: layoutDelta needs to be applied in parts before/after tran
sforms and |
367 // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 | 366 // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 |
368 r.move(v->layoutDelta()); | 367 r.move(v->layoutDelta()); |
369 } | 368 } |
370 } | 369 } |
371 mapRectToPaintInvalidationBacking(paintInvalidationContainer, r); | 370 mapRectToPaintInvalidationBacking(paintInvalidationContainer, r); |
372 return r; | 371 return r; |
(...skipping 900 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1273 | 1272 |
1274 RenderTableCell* RenderTableCell::createAnonymousWithParentRenderer(const Render
Object* parent) | 1273 RenderTableCell* RenderTableCell::createAnonymousWithParentRenderer(const Render
Object* parent) |
1275 { | 1274 { |
1276 RenderTableCell* newCell = RenderTableCell::createAnonymous(&parent->documen
t()); | 1275 RenderTableCell* newCell = RenderTableCell::createAnonymous(&parent->documen
t()); |
1277 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parent->style(), TABLE_CELL); | 1276 RefPtr<RenderStyle> newStyle = RenderStyle::createAnonymousStyleWithDisplay(
parent->style(), TABLE_CELL); |
1278 newCell->setStyle(newStyle.release()); | 1277 newCell->setStyle(newStyle.release()); |
1279 return newCell; | 1278 return newCell; |
1280 } | 1279 } |
1281 | 1280 |
1282 } // namespace WebCore | 1281 } // namespace WebCore |
OLD | NEW |