Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: third_party/WebKit/Source/core/layout/LayoutTable.cpp

Issue 2884573002: Replace LayoutTableCell::AbsoluteColumnIndex() with EffectiveColumnIndex()
Patch Set: - Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) 9 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
10 * 10 *
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 51
52 using namespace HTMLNames; 52 using namespace HTMLNames;
53 53
54 LayoutTable::LayoutTable(Element* element) 54 LayoutTable::LayoutTable(Element* element)
55 : LayoutBlock(element), 55 : LayoutBlock(element),
56 head_(nullptr), 56 head_(nullptr),
57 foot_(nullptr), 57 foot_(nullptr),
58 first_body_(nullptr), 58 first_body_(nullptr),
59 collapsed_borders_valid_(false), 59 collapsed_borders_valid_(false),
60 needs_invalidate_collapsed_borders_for_all_cells_(false), 60 needs_invalidate_collapsed_borders_for_all_cells_(false),
61 has_col_elements_(false),
62 needs_section_recalc_(false), 61 needs_section_recalc_(false),
63 column_logical_width_changed_(false), 62 column_logical_width_changed_(false),
64 column_layout_objects_valid_(false), 63 // This is initially true because we don't have column elements initially.
64 cols_at_effective_columns_valid_(true),
65 no_cell_colspan_at_least_(0), 65 no_cell_colspan_at_least_(0),
66 h_spacing_(0), 66 h_spacing_(0),
67 v_spacing_(0), 67 v_spacing_(0),
68 border_start_(0), 68 border_start_(0),
69 border_end_(0) { 69 border_end_(0) {
70 DCHECK(!ChildrenInline()); 70 DCHECK(!ChildrenInline());
71 effective_column_positions_.Fill(0, 1); 71 effective_column_positions_.Fill(0, 1);
72 } 72 }
73 73
74 LayoutTable::~LayoutTable() {} 74 LayoutTable::~LayoutTable() {}
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 // wrapped in a table section box. 129 // wrapped in a table section box.
130 EDisplay display = object->Style()->Display(); 130 EDisplay display = object->Style()->Display();
131 return display != EDisplay::kTableCaption && 131 return display != EDisplay::kTableCaption &&
132 display != EDisplay::kTableColumnGroup && 132 display != EDisplay::kTableColumnGroup &&
133 display != EDisplay::kTableColumn; 133 display != EDisplay::kTableColumn;
134 } 134 }
135 135
136 void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) { 136 void LayoutTable::AddChild(LayoutObject* child, LayoutObject* before_child) {
137 bool wrap_in_anonymous_section = !child->IsOutOfFlowPositioned(); 137 bool wrap_in_anonymous_section = !child->IsOutOfFlowPositioned();
138 138
139 if (child->IsTableCaption()) { 139 if (child->IsTableCaption() || child->IsLayoutTableCol()) {
140 wrap_in_anonymous_section = false;
141 } else if (child->IsLayoutTableCol()) {
142 has_col_elements_ = true;
143 wrap_in_anonymous_section = false; 140 wrap_in_anonymous_section = false;
144 } else if (child->IsTableSection()) { 141 } else if (child->IsTableSection()) {
145 switch (child->Style()->Display()) { 142 switch (child->Style()->Display()) {
146 case EDisplay::kTableHeaderGroup: 143 case EDisplay::kTableHeaderGroup:
147 ResetSectionPointerIfNotBefore(head_, before_child); 144 ResetSectionPointerIfNotBefore(head_, before_child);
148 if (!head_) { 145 if (!head_) {
149 head_ = ToLayoutTableSection(child); 146 head_ = ToLayoutTableSection(child);
150 } else { 147 } else {
151 ResetSectionPointerIfNotBefore(first_body_, before_child); 148 ResetSectionPointerIfNotBefore(first_body_, before_child);
152 if (!first_body_) 149 if (!first_body_)
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 226
230 void LayoutTable::RemoveCaption(const LayoutTableCaption* old_caption) { 227 void LayoutTable::RemoveCaption(const LayoutTableCaption* old_caption) {
231 size_t index = captions_.Find(old_caption); 228 size_t index = captions_.Find(old_caption);
232 DCHECK_NE(index, kNotFound); 229 DCHECK_NE(index, kNotFound);
233 if (index == kNotFound) 230 if (index == kNotFound)
234 return; 231 return;
235 232
236 captions_.erase(index); 233 captions_.erase(index);
237 } 234 }
238 235
239 void LayoutTable::InvalidateCachedColumns() { 236 void LayoutTable::InvalidateColsAtEffectiveColumns() const {
240 column_layout_objects_valid_ = false; 237 cols_at_effective_columns_valid_ = false;
241 column_layout_objects_.resize(0); 238 cols_at_effective_columns_ = nullptr;
242 } 239 }
243 240
244 void LayoutTable::AddColumn(const LayoutTableCol*) { 241 void LayoutTable::AddColumn(const LayoutTableCol*) {
245 InvalidateCachedColumns(); 242 InvalidateColsAtEffectiveColumns();
246 } 243 }
247 244
248 void LayoutTable::RemoveColumn(const LayoutTableCol*) { 245 void LayoutTable::RemoveColumn(const LayoutTableCol*) {
249 InvalidateCachedColumns(); 246 InvalidateColsAtEffectiveColumns();
250 // We don't really need to recompute our sections, but we need to update our
251 // column count and whether we have a column. Currently, we only have one
252 // size-fit-all flag but we may have to consider splitting it.
253 SetNeedsSectionRecalc();
254 } 247 }
255 248
256 bool LayoutTable::IsLogicalWidthAuto() const { 249 bool LayoutTable::IsLogicalWidthAuto() const {
257 Length style_logical_width = Style()->LogicalWidth(); 250 Length style_logical_width = Style()->LogicalWidth();
258 return (!style_logical_width.IsSpecified() || 251 return (!style_logical_width.IsSpecified() ||
259 !style_logical_width.IsPositive()) && 252 !style_logical_width.IsPositive()) &&
260 !style_logical_width.IsIntrinsic(); 253 !style_logical_width.IsIntrinsic();
261 } 254 }
262 255
263 void LayoutTable::UpdateLogicalWidth() { 256 void LayoutTable::UpdateLogicalWidth() {
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 continue; 995 continue;
1003 996
1004 LayoutTableSection* section = ToLayoutTableSection(child); 997 LayoutTableSection* section = ToLayoutTableSection(child);
1005 if (section->NeedsCellRecalc()) 998 if (section->NeedsCellRecalc())
1006 continue; 999 continue;
1007 1000
1008 section->SplitEffectiveColumn(index, first_span); 1001 section->SplitEffectiveColumn(index, first_span);
1009 } 1002 }
1010 1003
1011 effective_column_positions_.Grow(NumEffectiveColumns() + 1); 1004 effective_column_positions_.Grow(NumEffectiveColumns() + 1);
1005
1006 InvalidateColsAtEffectiveColumns();
1012 } 1007 }
1013 1008
1014 void LayoutTable::AppendEffectiveColumn(unsigned span) { 1009 void LayoutTable::AppendEffectiveColumn(unsigned span) {
1015 unsigned new_column_index = effective_columns_.size(); 1010 unsigned new_column_index = effective_columns_.size();
1016 effective_columns_.push_back(span); 1011 effective_columns_.push_back(span);
1017 1012
1018 // Unless the table has cell(s) with colspan that exceed the number of columns 1013 // Unless the table has cell(s) with colspan that exceed the number of columns
1019 // afforded by the other rows in the table we can use the fast path when 1014 // afforded by the other rows in the table we can use the fast path when
1020 // mapping columns to effective columns. 1015 // mapping columns to effective columns.
1021 if (span == 1 && no_cell_colspan_at_least_ + 1 == NumEffectiveColumns()) { 1016 if (span == 1 && no_cell_colspan_at_least_ + 1 == NumEffectiveColumns()) {
1022 no_cell_colspan_at_least_++; 1017 no_cell_colspan_at_least_++;
1023 } 1018 }
1024 1019
1025 // Propagate the change in our columns representation to the sections that 1020 // Propagate the change in our columns representation to the sections that
1026 // don't need cell recalc. If they do, they will be synced up directly with 1021 // don't need cell recalc. If they do, they will be synced up directly with
1027 // m_columns later. 1022 // m_columns later.
1028 for (LayoutObject* child = FirstChild(); child; 1023 for (LayoutObject* child = FirstChild(); child;
1029 child = child->NextSibling()) { 1024 child = child->NextSibling()) {
1030 if (!child->IsTableSection()) 1025 if (!child->IsTableSection())
1031 continue; 1026 continue;
1032 1027
1033 LayoutTableSection* section = ToLayoutTableSection(child); 1028 LayoutTableSection* section = ToLayoutTableSection(child);
1034 if (section->NeedsCellRecalc()) 1029 if (section->NeedsCellRecalc())
1035 continue; 1030 continue;
1036 1031
1037 section->AppendEffectiveColumn(new_column_index); 1032 section->AppendEffectiveColumn(new_column_index);
1038 } 1033 }
1039 1034
1040 effective_column_positions_.Grow(NumEffectiveColumns() + 1); 1035 effective_column_positions_.Grow(NumEffectiveColumns() + 1);
1036
1037 InvalidateColsAtEffectiveColumns();
1041 } 1038 }
1042 1039
1043 LayoutTableCol* LayoutTable::FirstColumn() const { 1040 LayoutTableCol* LayoutTable::FirstColumn() const {
1044 for (LayoutObject* child = FirstChild(); child; 1041 for (LayoutObject* child = FirstChild(); child;
1045 child = child->NextSibling()) { 1042 child = child->NextSibling()) {
1046 if (child->IsLayoutTableCol()) 1043 if (child->IsLayoutTableCol())
1047 return ToLayoutTableCol(child); 1044 return ToLayoutTableCol(child);
1048 } 1045 }
1049 1046
1050 return nullptr; 1047 return nullptr;
1051 } 1048 }
1052 1049
1053 void LayoutTable::UpdateColumnCache() const { 1050 LayoutTableCol* LayoutTable::FirstInnermostColumn() const {
1054 DCHECK(has_col_elements_); 1051 auto* col = FirstColumn();
1055 DCHECK(column_layout_objects_.IsEmpty()); 1052 return !col || col->IsInnermost() ? col : col->NextInnermostColumn();
1056 DCHECK(!column_layout_objects_valid_);
1057
1058 for (LayoutTableCol* column_layout_object = FirstColumn();
1059 column_layout_object;
1060 column_layout_object = column_layout_object->NextColumn()) {
1061 if (column_layout_object->IsTableColumnGroupWithColumnChildren())
1062 continue;
1063 column_layout_objects_.push_back(column_layout_object);
1064 }
1065 column_layout_objects_valid_ = true;
1066 } 1053 }
1067 1054
1068 LayoutTable::ColAndColGroup LayoutTable::SlowColElementAtAbsoluteColumn( 1055 void LayoutTable::UpdateColsAtEffectiveColumns() const {
1069 unsigned absolute_column_index) const { 1056 DCHECK(!NeedsSectionRecalc());
1070 DCHECK(has_col_elements_); 1057 DCHECK(!cols_at_effective_columns_valid_);
1058 DCHECK(!cols_at_effective_columns_);
1071 1059
1072 if (!column_layout_objects_valid_) 1060 cols_at_effective_columns_valid_ = true;
1073 UpdateColumnCache(); 1061 auto* col = FirstInnermostColumn();
1062 if (!col)
1063 return;
1074 1064
1075 unsigned column_count = 0; 1065 cols_at_effective_columns_ = WTF::MakeUnique<Vector<ColAndColGroup>>();
1076 for (unsigned i = 0; i < column_layout_objects_.size(); i++) { 1066
1077 LayoutTableCol* column_layout_object = column_layout_objects_[i]; 1067 unsigned absolute_column_index = 0;
1078 DCHECK(!column_layout_object->IsTableColumnGroupWithColumnChildren()); 1068 unsigned col_absolute_column_index = 0;
1079 unsigned span = column_layout_object->Span(); 1069 unsigned next_col_absolute_column_index = col->Span();
1080 unsigned start_col = column_count; 1070 for (unsigned effective_column_index = 0;
1081 DCHECK_GE(span, 1u); 1071 col && effective_column_index < effective_columns_.size();
1082 unsigned end_col = column_count + span - 1; 1072 effective_column_index++) {
1083 column_count += span; 1073 unsigned next_absolute_column_index =
1084 if (column_count > absolute_column_index) { 1074 absolute_column_index + effective_columns_[effective_column_index].span;
1085 ColAndColGroup col_and_col_group; 1075 bool is_at_start_edge = absolute_column_index == col_absolute_column_index;
1086 bool is_at_start_edge = start_col == absolute_column_index; 1076 bool is_at_end_edge =
1087 bool is_at_end_edge = end_col == absolute_column_index; 1077 next_absolute_column_index == next_col_absolute_column_index;
1088 if (column_layout_object->IsTableColumnGroup()) { 1078 ColAndColGroup col_and_col_group;
1089 col_and_col_group.colgroup = column_layout_object; 1079 if (col->IsTableColumnGroup()) {
1090 col_and_col_group.adjoins_start_border_of_col_group = is_at_start_edge; 1080 col_and_col_group.colgroup = col;
1091 col_and_col_group.adjoins_end_border_of_col_group = is_at_end_edge; 1081 col_and_col_group.adjoins_start_border_of_col_group = is_at_start_edge;
1092 } else { 1082 col_and_col_group.adjoins_end_border_of_col_group = is_at_end_edge;
1093 col_and_col_group.col = column_layout_object; 1083 } else {
1094 col_and_col_group.colgroup = 1084 col_and_col_group.col = col;
1095 column_layout_object->EnclosingColumnGroup(); 1085 col_and_col_group.colgroup = col->EnclosingColumnGroup();
1096 if (col_and_col_group.colgroup) { 1086 if (col_and_col_group.colgroup) {
1097 col_and_col_group.adjoins_start_border_of_col_group = 1087 col_and_col_group.adjoins_start_border_of_col_group =
1098 is_at_start_edge && !col_and_col_group.col->PreviousSibling(); 1088 is_at_start_edge && !col->PreviousSibling();
1099 col_and_col_group.adjoins_end_border_of_col_group = 1089 col_and_col_group.adjoins_end_border_of_col_group =
1100 is_at_end_edge && !col_and_col_group.col->NextSibling(); 1090 is_at_end_edge && !col->NextSibling();
1101 }
1102 } 1091 }
1103 return col_and_col_group;
1104 } 1092 }
1093
1094 // Skip useless col objects that don't generate effective columns.
1095 while (next_absolute_column_index >= next_col_absolute_column_index) {
1096 if (next_col_absolute_column_index == next_absolute_column_index &&
1097 !col_and_col_group.adjoins_end_border_of_col_group &&
1098 col_and_col_group.colgroup == col->EnclosingColumnGroup()) {
1099 // Special case: the effective column adjoins the end border of
1100 // col_and_col_group.colgroup though it doesn't adjoin the end border of
1101 // col_and_col_group.col. All subsequent cols of col_and_col_group.col
1102 // don't generate new effective columns.
1103 col_and_col_group.adjoins_end_border_of_col_group = true;
1104 }
1105
1106 col_absolute_column_index = next_col_absolute_column_index;
1107 col = col->NextInnermostColumn();
1108 if (!col)
1109 break;
1110 next_col_absolute_column_index += col->Span();
1111 }
1112
1113 absolute_column_index = next_absolute_column_index;
1114 cols_at_effective_columns_->push_back(col_and_col_group);
1105 } 1115 }
1106 return ColAndColGroup();
1107 } 1116 }
1108 1117
1109 void LayoutTable::RecalcSections() const { 1118 void LayoutTable::RecalcSections() const {
1110 DCHECK(needs_section_recalc_); 1119 DCHECK(needs_section_recalc_);
1111 1120
1112 head_ = nullptr; 1121 head_ = nullptr;
1113 foot_ = nullptr; 1122 foot_ = nullptr;
1114 first_body_ = nullptr; 1123 first_body_ = nullptr;
1115 has_col_elements_ = false;
1116 1124
1117 // We need to get valid pointers to caption, head, foot and first body again 1125 // We need to get valid pointers to caption, head, foot and first body again
1118 LayoutObject* next_sibling; 1126 LayoutObject* next_sibling;
1119 for (LayoutObject* child = FirstChild(); child; child = next_sibling) { 1127 for (LayoutObject* child = FirstChild(); child; child = next_sibling) {
1120 next_sibling = child->NextSibling(); 1128 next_sibling = child->NextSibling();
1121 switch (child->Style()->Display()) { 1129 switch (child->Style()->Display()) {
1122 case EDisplay::kTableColumn:
1123 case EDisplay::kTableColumnGroup:
1124 has_col_elements_ = true;
1125 break;
1126 case EDisplay::kTableHeaderGroup: 1130 case EDisplay::kTableHeaderGroup:
1127 if (child->IsTableSection()) { 1131 if (child->IsTableSection()) {
1128 LayoutTableSection* section = ToLayoutTableSection(child); 1132 LayoutTableSection* section = ToLayoutTableSection(child);
1129 if (!head_) 1133 if (!head_)
1130 head_ = section; 1134 head_ = section;
1131 else if (!first_body_) 1135 else if (!first_body_)
1132 first_body_ = section; 1136 first_body_ = section;
1133 section->RecalcCellsIfNeeded(); 1137 section->RecalcCellsIfNeeded();
1134 } 1138 }
1135 break; 1139 break;
(...skipping 20 matching lines...) Expand all
1156 } 1160 }
1157 } 1161 }
1158 1162
1159 // repair column count (addChild can grow it too much, because it always adds 1163 // repair column count (addChild can grow it too much, because it always adds
1160 // elements to the last row of a section) 1164 // elements to the last row of a section)
1161 unsigned max_cols = 0; 1165 unsigned max_cols = 0;
1162 for (LayoutObject* child = FirstChild(); child; 1166 for (LayoutObject* child = FirstChild(); child;
1163 child = child->NextSibling()) { 1167 child = child->NextSibling()) {
1164 if (child->IsTableSection()) { 1168 if (child->IsTableSection()) {
1165 LayoutTableSection* section = ToLayoutTableSection(child); 1169 LayoutTableSection* section = ToLayoutTableSection(child);
1166 unsigned section_cols = section->NumEffectiveColumns(); 1170 unsigned section_cols = section->MaxNumEffectiveColumnsOfRows();
1167 if (section_cols > max_cols) 1171 if (section_cols > max_cols)
1168 max_cols = section_cols; 1172 max_cols = section_cols;
1169 } 1173 }
1170 } 1174 }
1171 1175
1172 effective_columns_.resize(max_cols); 1176 effective_columns_.resize(max_cols);
1173 effective_column_positions_.resize(max_cols + 1); 1177 effective_column_positions_.resize(max_cols + 1);
1174 no_cell_colspan_at_least_ = CalcNoCellColspanAtLeast(); 1178 no_cell_colspan_at_least_ = CalcNoCellColspanAtLeast();
1175 1179
1180 InvalidateColsAtEffectiveColumns();
1181
1176 DCHECK(SelfNeedsLayout()); 1182 DCHECK(SelfNeedsLayout());
1177 1183
1178 needs_section_recalc_ = false; 1184 needs_section_recalc_ = false;
1179 } 1185 }
1180 1186
1181 int LayoutTable::CalcBorderStart() const { 1187 int LayoutTable::CalcBorderStart() const {
1182 if (!ShouldCollapseBorders()) 1188 if (!ShouldCollapseBorders())
1183 return LayoutBlock::BorderStart().ToInt(); 1189 return LayoutBlock::BorderStart().ToInt();
1184 1190
1185 // Determined by the first cell of the first row. See the CSS 2.1 spec, 1191 // Determined by the first cell of the first row. See the CSS 2.1 spec,
1186 // section 17.6.2. 1192 // section 17.6.2.
1187 if (!NumEffectiveColumns()) 1193 if (!NumEffectiveColumns())
1188 return 0; 1194 return 0;
1189 1195
1190 int border_width = 0; 1196 int border_width = 0;
1191 1197
1192 const BorderValue& table_start_border = Style()->BorderStart(); 1198 const BorderValue& table_start_border = Style()->BorderStart();
1193 if (table_start_border.Style() == EBorderStyle::kHidden) 1199 if (table_start_border.Style() == EBorderStyle::kHidden)
1194 return 0; 1200 return 0;
1195 if (table_start_border.Style() > EBorderStyle::kHidden) 1201 if (table_start_border.Style() > EBorderStyle::kHidden)
1196 border_width = table_start_border.Width(); 1202 border_width = table_start_border.Width();
1197 1203
1198 // TODO(dgrogan): This logic doesn't properly account for the first column in 1204 // TODO(dgrogan): This logic doesn't properly account for the first column in
1199 // the first column-group case. 1205 // the first column-group case.
1200 if (LayoutTableCol* column = 1206 if (LayoutTableCol* column =
1201 ColElementAtAbsoluteColumn(0).InnermostColOrColGroup()) { 1207 ColAndColGroupAtEffectiveColumn(0).InnermostColOrColGroup()) {
1202 // FIXME: We don't account for direction on columns and column groups. 1208 // FIXME: We don't account for direction on columns and column groups.
1203 const BorderValue& column_adjoining_border = column->Style()->BorderStart(); 1209 const BorderValue& column_adjoining_border = column->Style()->BorderStart();
1204 if (column_adjoining_border.Style() == EBorderStyle::kHidden) 1210 if (column_adjoining_border.Style() == EBorderStyle::kHidden)
1205 return 0; 1211 return 0;
1206 if (column_adjoining_border.Style() > EBorderStyle::kHidden) 1212 if (column_adjoining_border.Style() > EBorderStyle::kHidden)
1207 border_width = 1213 border_width =
1208 std::max<int>(border_width, column_adjoining_border.Width()); 1214 std::max<int>(border_width, column_adjoining_border.Width());
1209 } 1215 }
1210 1216
1211 if (const LayoutTableSection* top_non_empty_section = 1217 if (const LayoutTableSection* top_non_empty_section =
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1259 const BorderValue& table_end_border = Style()->BorderEnd(); 1265 const BorderValue& table_end_border = Style()->BorderEnd();
1260 if (table_end_border.Style() == EBorderStyle::kHidden) 1266 if (table_end_border.Style() == EBorderStyle::kHidden)
1261 return 0; 1267 return 0;
1262 if (table_end_border.Style() > EBorderStyle::kHidden) 1268 if (table_end_border.Style() > EBorderStyle::kHidden)
1263 border_width = table_end_border.Width(); 1269 border_width = table_end_border.Width();
1264 1270
1265 unsigned end_column = NumEffectiveColumns() - 1; 1271 unsigned end_column = NumEffectiveColumns() - 1;
1266 1272
1267 // TODO(dgrogan): This logic doesn't properly account for the last column in 1273 // TODO(dgrogan): This logic doesn't properly account for the last column in
1268 // the last column-group case. 1274 // the last column-group case.
1269 if (LayoutTableCol* column = 1275 if (LayoutTableCol* column = ColAndColGroupAtEffectiveColumn(end_column)
1270 ColElementAtAbsoluteColumn(end_column).InnermostColOrColGroup()) { 1276 .InnermostColOrColGroup()) {
1271 // FIXME: We don't account for direction on columns and column groups. 1277 // FIXME: We don't account for direction on columns and column groups.
1272 const BorderValue& column_adjoining_border = column->Style()->BorderEnd(); 1278 const BorderValue& column_adjoining_border = column->Style()->BorderEnd();
1273 if (column_adjoining_border.Style() == EBorderStyle::kHidden) 1279 if (column_adjoining_border.Style() == EBorderStyle::kHidden)
1274 return 0; 1280 return 0;
1275 if (column_adjoining_border.Style() > EBorderStyle::kHidden) 1281 if (column_adjoining_border.Style() > EBorderStyle::kHidden)
1276 border_width = 1282 border_width =
1277 std::max<int>(border_width, column_adjoining_border.Width()); 1283 std::max<int>(border_width, column_adjoining_border.Width());
1278 } 1284 }
1279 1285
1280 if (const LayoutTableSection* top_non_empty_section = 1286 if (const LayoutTableSection* top_non_empty_section =
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 r_above = r - 1; 1510 r_above = r - 1;
1505 } else { 1511 } else {
1506 section = SectionAbove(cell->Section(), kSkipEmptySections); 1512 section = SectionAbove(cell->Section(), kSkipEmptySections);
1507 if (section) { 1513 if (section) {
1508 DCHECK(section->NumRows()); 1514 DCHECK(section->NumRows());
1509 r_above = section->NumRows() - 1; 1515 r_above = section->NumRows() - 1;
1510 } 1516 }
1511 } 1517 }
1512 1518
1513 // Look up the cell in the section's grid, which requires effective col index 1519 // Look up the cell in the section's grid, which requires effective col index
1514 if (section) { 1520 if (section)
1515 unsigned eff_col = 1521 return section->PrimaryCellAt(r_above, cell->EffectiveColumnIndex());
1516 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1517 return section->PrimaryCellAt(r_above, eff_col);
1518 }
1519 return nullptr; 1522 return nullptr;
1520 } 1523 }
1521 1524
1522 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const { 1525 LayoutTableCell* LayoutTable::CellBelow(const LayoutTableCell* cell) const {
1523 RecalcSectionsIfNeeded(); 1526 RecalcSectionsIfNeeded();
1524 1527
1525 // Find the section and row to look in 1528 // Find the section and row to look in
1526 unsigned r = cell->RowIndex() + cell->RowSpan() - 1; 1529 unsigned r = cell->RowIndex() + cell->RowSpan() - 1;
1527 LayoutTableSection* section = nullptr; 1530 LayoutTableSection* section = nullptr;
1528 unsigned r_below = 0; 1531 unsigned r_below = 0;
1529 if (r < cell->Section()->NumRows() - 1) { 1532 if (r < cell->Section()->NumRows() - 1) {
1530 // The cell is not in the last row, so use the next row in the section. 1533 // The cell is not in the last row, so use the next row in the section.
1531 section = cell->Section(); 1534 section = cell->Section();
1532 r_below = r + 1; 1535 r_below = r + 1;
1533 } else { 1536 } else {
1534 section = SectionBelow(cell->Section(), kSkipEmptySections); 1537 section = SectionBelow(cell->Section(), kSkipEmptySections);
1535 if (section) 1538 if (section)
1536 r_below = 0; 1539 r_below = 0;
1537 } 1540 }
1538 1541
1539 // Look up the cell in the section's grid, which requires effective col index 1542 // Look up the cell in the section's grid, which requires effective col index
1540 if (section) { 1543 if (section)
1541 unsigned eff_col = 1544 return section->PrimaryCellAt(r_below, cell->EffectiveColumnIndex());
1542 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1543 return section->PrimaryCellAt(r_below, eff_col);
1544 }
1545 return nullptr; 1545 return nullptr;
1546 } 1546 }
1547 1547
1548 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const { 1548 LayoutTableCell* LayoutTable::CellBefore(const LayoutTableCell* cell) const {
1549 RecalcSectionsIfNeeded(); 1549 RecalcSectionsIfNeeded();
1550 1550
1551 LayoutTableSection* section = cell->Section(); 1551 unsigned eff_col = cell->EffectiveColumnIndex();
1552 unsigned eff_col =
1553 AbsoluteColumnToEffectiveColumn(cell->AbsoluteColumnIndex());
1554 if (!eff_col) 1552 if (!eff_col)
1555 return nullptr; 1553 return nullptr;
1556 1554
1557 // If we hit a colspan back up to a real cell. 1555 // If we hit a colspan back up to a real cell.
1558 return section->PrimaryCellAt(cell->RowIndex(), eff_col - 1); 1556 return cell->Section()->PrimaryCellAt(cell->RowIndex(), eff_col - 1);
1559 } 1557 }
1560 1558
1561 LayoutTableCell* LayoutTable::CellAfter(const LayoutTableCell* cell) const { 1559 LayoutTableCell* LayoutTable::CellAfter(const LayoutTableCell* cell) const {
1562 RecalcSectionsIfNeeded(); 1560 RecalcSectionsIfNeeded();
1563 1561
1564 unsigned eff_col = AbsoluteColumnToEffectiveColumn( 1562 return cell->Section()->PrimaryCellAt(
1565 cell->AbsoluteColumnIndex() + cell->ColSpan()); 1563 cell->RowIndex(), cell->EffectiveColumnIndexOfCellAfter());
1566 return cell->Section()->PrimaryCellAt(cell->RowIndex(), eff_col);
1567 } 1564 }
1568 1565
1569 int LayoutTable::BaselinePosition(FontBaseline baseline_type, 1566 int LayoutTable::BaselinePosition(FontBaseline baseline_type,
1570 bool first_line, 1567 bool first_line,
1571 LineDirectionMode direction, 1568 LineDirectionMode direction,
1572 LinePositionMode line_position_mode) const { 1569 LinePositionMode line_position_mode) const {
1573 DCHECK_EQ(line_position_mode, kPositionOnContainingLine); 1570 DCHECK_EQ(line_position_mode, kPositionOnContainingLine);
1574 int baseline = FirstLineBoxBaseline(); 1571 int baseline = FirstLineBoxBaseline();
1575 if (baseline != -1) { 1572 if (baseline != -1) {
1576 if (IsInline()) 1573 if (IsInline())
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
1760 } 1757 }
1761 1758
1762 LayoutUnit LayoutTable::PaddingRight() const { 1759 LayoutUnit LayoutTable::PaddingRight() const {
1763 if (ShouldCollapseBorders()) 1760 if (ShouldCollapseBorders())
1764 return LayoutUnit(); 1761 return LayoutUnit();
1765 1762
1766 return LayoutBlock::PaddingRight(); 1763 return LayoutBlock::PaddingRight();
1767 } 1764 }
1768 1765
1769 } // namespace blink 1766 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/core/layout/LayoutTable.h ('k') | third_party/WebKit/Source/core/layout/LayoutTableCell.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698