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 Apple Inc.
All rights reserved. |
8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) | 8 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) |
9 * | 9 * |
10 * This library is free software; you can redistribute it and/or | 10 * This library is free software; you can redistribute it and/or |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 #include "core/paint/BoxPainter.h" | 45 #include "core/paint/BoxPainter.h" |
46 #include "core/paint/DeprecatedPaintLayer.h" | 46 #include "core/paint/DeprecatedPaintLayer.h" |
47 #include "core/paint/TablePainter.h" | 47 #include "core/paint/TablePainter.h" |
48 | 48 |
49 namespace blink { | 49 namespace blink { |
50 | 50 |
51 using namespace HTMLNames; | 51 using namespace HTMLNames; |
52 | 52 |
53 LayoutTable::LayoutTable(Element* element) | 53 LayoutTable::LayoutTable(Element* element) |
54 : LayoutBlock(element) | 54 : LayoutBlock(element) |
55 , m_head(0) | 55 , m_head(nullptr) |
56 , m_foot(0) | 56 , m_foot(nullptr) |
57 , m_firstBody(0) | 57 , m_firstBody(nullptr) |
58 , m_currentBorder(0) | 58 , m_currentBorder(nullptr) |
59 , m_collapsedBordersValid(false) | 59 , m_collapsedBordersValid(false) |
60 , m_hasColElements(false) | 60 , m_hasColElements(false) |
61 , m_needsSectionRecalc(false) | 61 , m_needsSectionRecalc(false) |
62 , m_columnLogicalWidthChanged(false) | 62 , m_columnLogicalWidthChanged(false) |
63 , m_columnLayoutObjectsValid(false) | 63 , m_columnLayoutObjectsValid(false) |
64 , m_hasCellColspanThatDeterminesTableWidth(false) | 64 , m_hasCellColspanThatDeterminesTableWidth(false) |
65 , m_hSpacing(0) | 65 , m_hSpacing(0) |
66 , m_vSpacing(0) | 66 , m_vSpacing(0) |
67 , m_borderStart(0) | 67 , m_borderStart(0) |
68 , m_borderEnd(0) | 68 , m_borderEnd(0) |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 m_columnPos.grow(numEffCols() + 1); | 787 m_columnPos.grow(numEffCols() + 1); |
788 } | 788 } |
789 | 789 |
790 LayoutTableCol* LayoutTable::firstColumn() const | 790 LayoutTableCol* LayoutTable::firstColumn() const |
791 { | 791 { |
792 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { | 792 for (LayoutObject* child = firstChild(); child; child = child->nextSibling()
) { |
793 if (child->isLayoutTableCol()) | 793 if (child->isLayoutTableCol()) |
794 return toLayoutTableCol(child); | 794 return toLayoutTableCol(child); |
795 } | 795 } |
796 | 796 |
797 return 0; | 797 return nullptr; |
798 } | 798 } |
799 | 799 |
800 void LayoutTable::updateColumnCache() const | 800 void LayoutTable::updateColumnCache() const |
801 { | 801 { |
802 ASSERT(m_hasColElements); | 802 ASSERT(m_hasColElements); |
803 ASSERT(m_columnLayoutObjects.isEmpty()); | 803 ASSERT(m_columnLayoutObjects.isEmpty()); |
804 ASSERT(!m_columnLayoutObjectsValid); | 804 ASSERT(!m_columnLayoutObjectsValid); |
805 | 805 |
806 for (LayoutTableCol* columnLayoutObject = firstColumn(); columnLayoutObject;
columnLayoutObject = columnLayoutObject->nextColumn()) { | 806 for (LayoutTableCol* columnLayoutObject = firstColumn(); columnLayoutObject;
columnLayoutObject = columnLayoutObject->nextColumn()) { |
807 if (columnLayoutObject->isTableColumnGroupWithColumnChildren()) | 807 if (columnLayoutObject->isTableColumnGroupWithColumnChildren()) |
(...skipping 19 matching lines...) Expand all Loading... |
827 unsigned endCol = columnCount + span - 1; | 827 unsigned endCol = columnCount + span - 1; |
828 columnCount += span; | 828 columnCount += span; |
829 if (columnCount > col) { | 829 if (columnCount > col) { |
830 if (startEdge) | 830 if (startEdge) |
831 *startEdge = startCol == col; | 831 *startEdge = startCol == col; |
832 if (endEdge) | 832 if (endEdge) |
833 *endEdge = endCol == col; | 833 *endEdge = endCol == col; |
834 return columnLayoutObject; | 834 return columnLayoutObject; |
835 } | 835 } |
836 } | 836 } |
837 return 0; | 837 return nullptr; |
838 } | 838 } |
839 | 839 |
840 void LayoutTable::recalcSections() const | 840 void LayoutTable::recalcSections() const |
841 { | 841 { |
842 ASSERT(m_needsSectionRecalc); | 842 ASSERT(m_needsSectionRecalc); |
843 | 843 |
844 m_head = 0; | 844 m_head = nullptr; |
845 m_foot = 0; | 845 m_foot = nullptr; |
846 m_firstBody = 0; | 846 m_firstBody = nullptr; |
847 m_hasColElements = false; | 847 m_hasColElements = false; |
848 m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTable
Width(); | 848 m_hasCellColspanThatDeterminesTableWidth = hasCellColspanThatDeterminesTable
Width(); |
849 | 849 |
850 // We need to get valid pointers to caption, head, foot and first body again | 850 // We need to get valid pointers to caption, head, foot and first body again |
851 LayoutObject* nextSibling; | 851 LayoutObject* nextSibling; |
852 for (LayoutObject* child = firstChild(); child; child = nextSibling) { | 852 for (LayoutObject* child = firstChild(); child; child = nextSibling) { |
853 nextSibling = child->nextSibling(); | 853 nextSibling = child->nextSibling(); |
854 switch (child->style()->display()) { | 854 switch (child->style()->display()) { |
855 case TABLE_COLUMN: | 855 case TABLE_COLUMN: |
856 case TABLE_COLUMN_GROUP: | 856 case TABLE_COLUMN_GROUP: |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1149 if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections |
| m_head->numRows())) | 1149 if (!prevSection && m_head && (skipEmptySections == DoNotSkipEmptySections |
| m_head->numRows())) |
1150 prevSection = m_head; | 1150 prevSection = m_head; |
1151 return toLayoutTableSection(prevSection); | 1151 return toLayoutTableSection(prevSection); |
1152 } | 1152 } |
1153 | 1153 |
1154 LayoutTableSection* LayoutTable::sectionBelow(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const | 1154 LayoutTableSection* LayoutTable::sectionBelow(const LayoutTableSection* section,
SkipEmptySectionsValue skipEmptySections) const |
1155 { | 1155 { |
1156 recalcSectionsIfNeeded(); | 1156 recalcSectionsIfNeeded(); |
1157 | 1157 |
1158 if (section == m_foot) | 1158 if (section == m_foot) |
1159 return 0; | 1159 return nullptr; |
1160 | 1160 |
1161 LayoutObject* nextSection = section == m_head ? firstChild() : section->next
Sibling(); | 1161 LayoutObject* nextSection = section == m_head ? firstChild() : section->next
Sibling(); |
1162 while (nextSection) { | 1162 while (nextSection) { |
1163 if (nextSection->isTableSection() && nextSection != m_head && nextSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSec
tion(nextSection)->numRows())) | 1163 if (nextSection->isTableSection() && nextSection != m_head && nextSectio
n != m_foot && (skipEmptySections == DoNotSkipEmptySections || toLayoutTableSec
tion(nextSection)->numRows())) |
1164 break; | 1164 break; |
1165 nextSection = nextSection->nextSibling(); | 1165 nextSection = nextSection->nextSibling(); |
1166 } | 1166 } |
1167 if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections |
| m_foot->numRows())) | 1167 if (!nextSection && m_foot && (skipEmptySections == DoNotSkipEmptySections |
| m_foot->numRows())) |
1168 nextSection = m_foot; | 1168 nextSection = m_foot; |
1169 return toLayoutTableSection(nextSection); | 1169 return toLayoutTableSection(nextSection); |
1170 } | 1170 } |
1171 | 1171 |
1172 LayoutTableSection* LayoutTable::bottomSection() const | 1172 LayoutTableSection* LayoutTable::bottomSection() const |
1173 { | 1173 { |
1174 recalcSectionsIfNeeded(); | 1174 recalcSectionsIfNeeded(); |
1175 | 1175 |
1176 if (m_foot) | 1176 if (m_foot) |
1177 return m_foot; | 1177 return m_foot; |
1178 | 1178 |
1179 for (LayoutObject* child = lastChild(); child; child = child->previousSiblin
g()) { | 1179 for (LayoutObject* child = lastChild(); child; child = child->previousSiblin
g()) { |
1180 if (child->isTableSection()) | 1180 if (child->isTableSection()) |
1181 return toLayoutTableSection(child); | 1181 return toLayoutTableSection(child); |
1182 } | 1182 } |
1183 | 1183 |
1184 return 0; | 1184 return nullptr; |
1185 } | 1185 } |
1186 | 1186 |
1187 LayoutTableCell* LayoutTable::cellAbove(const LayoutTableCell* cell) const | 1187 LayoutTableCell* LayoutTable::cellAbove(const LayoutTableCell* cell) const |
1188 { | 1188 { |
1189 recalcSectionsIfNeeded(); | 1189 recalcSectionsIfNeeded(); |
1190 | 1190 |
1191 // Find the section and row to look in | 1191 // Find the section and row to look in |
1192 unsigned r = cell->rowIndex(); | 1192 unsigned r = cell->rowIndex(); |
1193 LayoutTableSection* section = 0; | 1193 LayoutTableSection* section = nullptr; |
1194 unsigned rAbove = 0; | 1194 unsigned rAbove = 0; |
1195 if (r > 0) { | 1195 if (r > 0) { |
1196 // cell is not in the first row, so use the above row in its own section | 1196 // cell is not in the first row, so use the above row in its own section |
1197 section = cell->section(); | 1197 section = cell->section(); |
1198 rAbove = r - 1; | 1198 rAbove = r - 1; |
1199 } else { | 1199 } else { |
1200 section = sectionAbove(cell->section(), SkipEmptySections); | 1200 section = sectionAbove(cell->section(), SkipEmptySections); |
1201 if (section) { | 1201 if (section) { |
1202 ASSERT(section->numRows()); | 1202 ASSERT(section->numRows()); |
1203 rAbove = section->numRows() - 1; | 1203 rAbove = section->numRows() - 1; |
1204 } | 1204 } |
1205 } | 1205 } |
1206 | 1206 |
1207 // Look up the cell in the section's grid, which requires effective col inde
x | 1207 // Look up the cell in the section's grid, which requires effective col inde
x |
1208 if (section) { | 1208 if (section) { |
1209 unsigned effCol = colToEffCol(cell->col()); | 1209 unsigned effCol = colToEffCol(cell->col()); |
1210 LayoutTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effC
ol); | 1210 LayoutTableSection::CellStruct& aboveCell = section->cellAt(rAbove, effC
ol); |
1211 return aboveCell.primaryCell(); | 1211 return aboveCell.primaryCell(); |
1212 } | 1212 } |
1213 return 0; | 1213 return nullptr; |
1214 } | 1214 } |
1215 | 1215 |
1216 LayoutTableCell* LayoutTable::cellBelow(const LayoutTableCell* cell) const | 1216 LayoutTableCell* LayoutTable::cellBelow(const LayoutTableCell* cell) const |
1217 { | 1217 { |
1218 recalcSectionsIfNeeded(); | 1218 recalcSectionsIfNeeded(); |
1219 | 1219 |
1220 // Find the section and row to look in | 1220 // Find the section and row to look in |
1221 unsigned r = cell->rowIndex() + cell->rowSpan() - 1; | 1221 unsigned r = cell->rowIndex() + cell->rowSpan() - 1; |
1222 LayoutTableSection* section = 0; | 1222 LayoutTableSection* section = nullptr; |
1223 unsigned rBelow = 0; | 1223 unsigned rBelow = 0; |
1224 if (r < cell->section()->numRows() - 1) { | 1224 if (r < cell->section()->numRows() - 1) { |
1225 // The cell is not in the last row, so use the next row in the section. | 1225 // The cell is not in the last row, so use the next row in the section. |
1226 section = cell->section(); | 1226 section = cell->section(); |
1227 rBelow = r + 1; | 1227 rBelow = r + 1; |
1228 } else { | 1228 } else { |
1229 section = sectionBelow(cell->section(), SkipEmptySections); | 1229 section = sectionBelow(cell->section(), SkipEmptySections); |
1230 if (section) | 1230 if (section) |
1231 rBelow = 0; | 1231 rBelow = 0; |
1232 } | 1232 } |
1233 | 1233 |
1234 // Look up the cell in the section's grid, which requires effective col inde
x | 1234 // Look up the cell in the section's grid, which requires effective col inde
x |
1235 if (section) { | 1235 if (section) { |
1236 unsigned effCol = colToEffCol(cell->col()); | 1236 unsigned effCol = colToEffCol(cell->col()); |
1237 LayoutTableSection::CellStruct& belowCell = section->cellAt(rBelow, effC
ol); | 1237 LayoutTableSection::CellStruct& belowCell = section->cellAt(rBelow, effC
ol); |
1238 return belowCell.primaryCell(); | 1238 return belowCell.primaryCell(); |
1239 } | 1239 } |
1240 return 0; | 1240 return nullptr; |
1241 } | 1241 } |
1242 | 1242 |
1243 LayoutTableCell* LayoutTable::cellBefore(const LayoutTableCell* cell) const | 1243 LayoutTableCell* LayoutTable::cellBefore(const LayoutTableCell* cell) const |
1244 { | 1244 { |
1245 recalcSectionsIfNeeded(); | 1245 recalcSectionsIfNeeded(); |
1246 | 1246 |
1247 LayoutTableSection* section = cell->section(); | 1247 LayoutTableSection* section = cell->section(); |
1248 unsigned effCol = colToEffCol(cell->col()); | 1248 unsigned effCol = colToEffCol(cell->col()); |
1249 if (!effCol) | 1249 if (!effCol) |
1250 return 0; | 1250 return nullptr; |
1251 | 1251 |
1252 // If we hit a colspan back up to a real cell. | 1252 // If we hit a colspan back up to a real cell. |
1253 LayoutTableSection::CellStruct& prevCell = section->cellAt(cell->rowIndex(),
effCol - 1); | 1253 LayoutTableSection::CellStruct& prevCell = section->cellAt(cell->rowIndex(),
effCol - 1); |
1254 return prevCell.primaryCell(); | 1254 return prevCell.primaryCell(); |
1255 } | 1255 } |
1256 | 1256 |
1257 LayoutTableCell* LayoutTable::cellAfter(const LayoutTableCell* cell) const | 1257 LayoutTableCell* LayoutTable::cellAfter(const LayoutTableCell* cell) const |
1258 { | 1258 { |
1259 recalcSectionsIfNeeded(); | 1259 recalcSectionsIfNeeded(); |
1260 | 1260 |
1261 unsigned effCol = colToEffCol(cell->col() + cell->colSpan()); | 1261 unsigned effCol = colToEffCol(cell->col() + cell->colSpan()); |
1262 if (effCol >= numEffCols()) | 1262 if (effCol >= numEffCols()) |
1263 return 0; | 1263 return nullptr; |
1264 return cell->section()->primaryCellAt(cell->rowIndex(), effCol); | 1264 return cell->section()->primaryCellAt(cell->rowIndex(), effCol); |
1265 } | 1265 } |
1266 | 1266 |
1267 int LayoutTable::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
eDirectionMode direction, LinePositionMode linePositionMode) const | 1267 int LayoutTable::baselinePosition(FontBaseline baselineType, bool firstLine, Lin
eDirectionMode direction, LinePositionMode linePositionMode) const |
1268 { | 1268 { |
1269 ASSERT(linePositionMode == PositionOnContainingLine); | 1269 ASSERT(linePositionMode == PositionOnContainingLine); |
1270 int baseline = firstLineBoxBaseline(); | 1270 int baseline = firstLineBoxBaseline(); |
1271 if (baseline != -1) { | 1271 if (baseline != -1) { |
1272 if (isInline()) | 1272 if (isInline()) |
1273 return beforeMarginInLineDirection(direction) + baseline; | 1273 return beforeMarginInLineDirection(direction) + baseline; |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1357 if (!result.addNodeToListBasedTestResult(node(), locationInContainer, bo
undsRect)) | 1357 if (!result.addNodeToListBasedTestResult(node(), locationInContainer, bo
undsRect)) |
1358 return true; | 1358 return true; |
1359 } | 1359 } |
1360 | 1360 |
1361 return false; | 1361 return false; |
1362 } | 1362 } |
1363 | 1363 |
1364 LayoutTable* LayoutTable::createAnonymousWithParent(const LayoutObject* parent) | 1364 LayoutTable* LayoutTable::createAnonymousWithParent(const LayoutObject* parent) |
1365 { | 1365 { |
1366 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp
lay(parent->styleRef(), TABLE); | 1366 RefPtr<ComputedStyle> newStyle = ComputedStyle::createAnonymousStyleWithDisp
lay(parent->styleRef(), TABLE); |
1367 LayoutTable* newTable = new LayoutTable(0); | 1367 LayoutTable* newTable = new LayoutTable(nullptr); |
1368 newTable->setDocumentForAnonymous(&parent->document()); | 1368 newTable->setDocumentForAnonymous(&parent->document()); |
1369 newTable->setStyle(newStyle.release()); | 1369 newTable->setStyle(newStyle.release()); |
1370 return newTable; | 1370 return newTable; |
1371 } | 1371 } |
1372 | 1372 |
1373 const BorderValue& LayoutTable::tableStartBorderAdjoiningCell(const LayoutTableC
ell* cell) const | 1373 const BorderValue& LayoutTable::tableStartBorderAdjoiningCell(const LayoutTableC
ell* cell) const |
1374 { | 1374 { |
1375 ASSERT(cell->isFirstOrLastCellInRow()); | 1375 ASSERT(cell->isFirstOrLastCellInRow()); |
1376 if (hasSameDirectionAs(cell->row())) | 1376 if (hasSameDirectionAs(cell->row())) |
1377 return style()->borderStart(); | 1377 return style()->borderStart(); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1416 cell->invalidateDisplayItemClient(*cell); | 1416 cell->invalidateDisplayItemClient(*cell); |
1417 } | 1417 } |
1418 } | 1418 } |
1419 } | 1419 } |
1420 } | 1420 } |
1421 | 1421 |
1422 LayoutBlock::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState); | 1422 LayoutBlock::invalidatePaintOfSubtreesIfNeeded(childPaintInvalidationState); |
1423 } | 1423 } |
1424 | 1424 |
1425 } | 1425 } |
OLD | NEW |