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

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

Issue 2890543002: Improve LayoutTable outer collapsed border calculation (Closed)
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 collapsed_outer_borders_valid_(false),
61 has_col_elements_(false), 62 has_col_elements_(false),
62 needs_section_recalc_(false), 63 needs_section_recalc_(false),
63 column_logical_width_changed_(false), 64 column_logical_width_changed_(false),
64 column_layout_objects_valid_(false), 65 column_layout_objects_valid_(false),
65 no_cell_colspan_at_least_(0), 66 no_cell_colspan_at_least_(0),
66 h_spacing_(0), 67 h_spacing_(0),
67 v_spacing_(0), 68 v_spacing_(0),
68 border_start_(0), 69 collapsed_outer_border_start_(0),
69 border_end_(0) { 70 collapsed_outer_border_end_(0),
71 collapsed_outer_border_before_(0),
72 collapsed_outer_border_after_(0) {
70 DCHECK(!ChildrenInline()); 73 DCHECK(!ChildrenInline());
71 effective_column_positions_.Fill(0, 1); 74 effective_column_positions_.Fill(0, 1);
72 } 75 }
73 76
74 LayoutTable::~LayoutTable() {} 77 LayoutTable::~LayoutTable() {}
75 78
76 void LayoutTable::StyleDidChange(StyleDifference diff, 79 void LayoutTable::StyleDidChange(StyleDifference diff,
77 const ComputedStyle* old_style) { 80 const ComputedStyle* old_style) {
78 LayoutBlock::StyleDidChange(diff, old_style); 81 LayoutBlock::StyleDidChange(diff, old_style);
79 82
(...skipping 493 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 576
574 if (SimplifiedLayout()) 577 if (SimplifiedLayout())
575 return; 578 return;
576 579
577 // Note: LayoutTable is handled differently than other LayoutBlocks and the 580 // Note: LayoutTable is handled differently than other LayoutBlocks and the
578 // LayoutScope 581 // LayoutScope
579 // must be created before the table begins laying out. 582 // must be created before the table begins laying out.
580 TextAutosizer::LayoutScope text_autosizer_layout_scope(this); 583 TextAutosizer::LayoutScope text_autosizer_layout_scope(this);
581 584
582 RecalcSectionsIfNeeded(); 585 RecalcSectionsIfNeeded();
583 // FIXME: We should do this recalc lazily in borderStart/borderEnd so that we
584 // don't have to make sure to call this before we call borderStart/borderEnd
585 // to avoid getting a stale value.
586 RecalcBordersInRowDirection();
587 586
588 SubtreeLayoutScope layouter(*this); 587 SubtreeLayoutScope layouter(*this);
589 588
590 { 589 {
591 LayoutState state(*this); 590 LayoutState state(*this);
592 LayoutUnit old_logical_width = LogicalWidth(); 591 LayoutUnit old_logical_width = LogicalWidth();
593 LayoutUnit old_logical_height = LogicalHeight(); 592 LayoutUnit old_logical_height = LogicalHeight();
594 593
595 SetLogicalHeight(LayoutUnit()); 594 SetLogicalHeight(LayoutUnit());
596 UpdateLogicalWidth(); 595 UpdateLogicalWidth();
(...skipping 20 matching lines...) Expand all
617 616
618 LayoutTableSection* top_section = this->TopSection(); 617 LayoutTableSection* top_section = this->TopSection();
619 LayoutTableSection* bottom_section = this->BottomSection(); 618 LayoutTableSection* bottom_section = this->BottomSection();
620 619
621 // This is the border-before edge of the "table box", relative to the "table 620 // This is the border-before edge of the "table box", relative to the "table
622 // wrapper box", i.e. right after all top captions. 621 // wrapper box", i.e. right after all top captions.
623 // https://www.w3.org/TR/2011/REC-CSS2-20110607/tables.html#model 622 // https://www.w3.org/TR/2011/REC-CSS2-20110607/tables.html#model
624 LayoutUnit table_box_logical_top = LogicalHeight(); 623 LayoutUnit table_box_logical_top = LogicalHeight();
625 624
626 bool collapsing = ShouldCollapseBorders(); 625 bool collapsing = ShouldCollapseBorders();
627 if (collapsing) {
628 // Need to set up the table borders before we can position the sections.
629 for (LayoutTableSection* section = top_section; section;
630 section = SectionBelow(section))
631 section->RecalcOuterBorder();
632 }
633
634 LayoutUnit border_and_padding_before = 626 LayoutUnit border_and_padding_before =
635 BorderBefore() + (collapsing ? LayoutUnit() : PaddingBefore()); 627 BorderBefore() + (collapsing ? LayoutUnit() : PaddingBefore());
636 LayoutUnit border_and_padding_after = 628 LayoutUnit border_and_padding_after =
637 BorderAfter() + (collapsing ? LayoutUnit() : PaddingAfter()); 629 BorderAfter() + (collapsing ? LayoutUnit() : PaddingAfter());
638 630
639 SetLogicalHeight(table_box_logical_top + border_and_padding_before); 631 SetLogicalHeight(table_box_logical_top + border_and_padding_before);
640 632
641 LayoutUnit section_logical_left = LayoutUnit( 633 LayoutUnit section_logical_left = LayoutUnit(
642 Style()->IsLeftToRightDirection() ? BorderStart() : BorderEnd()); 634 Style()->IsLeftToRightDirection() ? BorderStart() : BorderEnd());
643 if (!collapsing) { 635 if (!collapsing) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 SetIntrinsicContentLogicalHeight(ContentLogicalHeight()); 765 SetIntrinsicContentLogicalHeight(ContentLogicalHeight());
774 766
775 column_logical_width_changed_ = false; 767 column_logical_width_changed_ = false;
776 ClearNeedsLayout(); 768 ClearNeedsLayout();
777 } 769 }
778 770
779 void LayoutTable::InvalidateCollapsedBorders() { 771 void LayoutTable::InvalidateCollapsedBorders() {
780 collapsed_borders_.clear(); 772 collapsed_borders_.clear();
781 collapsed_borders_valid_ = false; 773 collapsed_borders_valid_ = false;
782 needs_invalidate_collapsed_borders_for_all_cells_ = true; 774 needs_invalidate_collapsed_borders_for_all_cells_ = true;
775 collapsed_outer_borders_valid_ = false;
783 SetMayNeedPaintInvalidation(); 776 SetMayNeedPaintInvalidation();
784 } 777 }
785 778
786 void LayoutTable::InvalidateCollapsedBordersForAllCellsIfNeeded() { 779 void LayoutTable::InvalidateCollapsedBordersForAllCellsIfNeeded() {
787 DCHECK(ShouldCollapseBorders()); 780 DCHECK(ShouldCollapseBorders());
788 781
789 if (!needs_invalidate_collapsed_borders_for_all_cells_) 782 if (!needs_invalidate_collapsed_borders_for_all_cells_)
790 return; 783 return;
791 needs_invalidate_collapsed_borders_for_all_cells_ = false; 784 needs_invalidate_collapsed_borders_for_all_cells_ = false;
792 785
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 cell = cell->NextCell()) { 817 cell = cell->NextCell()) {
825 DCHECK_EQ(cell->Table(), this); 818 DCHECK_EQ(cell->Table(), this);
826 cell->CollectCollapsedBorderValues(collapsed_borders_); 819 cell->CollectCollapsedBorderValues(collapsed_borders_);
827 } 820 }
828 } 821 }
829 } 822 }
830 LayoutTableCell::SortCollapsedBorderValues(collapsed_borders_); 823 LayoutTableCell::SortCollapsedBorderValues(collapsed_borders_);
831 } 824 }
832 825
833 void LayoutTable::AddOverflowFromChildren() { 826 void LayoutTable::AddOverflowFromChildren() {
827 /*
834 // Add overflow from borders. 828 // Add overflow from borders.
835 // Technically it's odd that we are incorporating the borders into layout 829 // Technically it's odd that we are incorporating the borders into layout
836 // overflow, which is only supposed to be about overflow from our 830 // overflow, which is only supposed to be about overflow from our
837 // descendant objects, but since tables don't support overflow:auto, this 831 // descendant objects, but since tables don't support overflow:auto, this
838 // works out fine. 832 // works out fine.
839 if (ShouldCollapseBorders()) { 833 if (ShouldCollapseBorders()) {
840 LayoutUnit right_border_overflow = 834 LayoutUnit right_border_overflow =
841 Size().Width() + OuterBorderRight() - BorderRight(); 835 Size().Width() + CollapsedOuterBorderRight() - BorderRight();
842 LayoutUnit left_border_overflow = BorderLeft() - OuterBorderLeft(); 836 LayoutUnit left_border_overflow = BorderLeft() - CollapsedOuterBorderLeft();
843 LayoutUnit bottom_border_overflow = 837 LayoutUnit bottom_border_overflow =
844 Size().Height() + OuterBorderBottom() - BorderBottom(); 838 Size().Height() + CollapsedOuterBorderBottom() - BorderBottom();
845 LayoutUnit top_border_overflow = BorderTop() - OuterBorderTop(); 839 LayoutUnit top_border_overflow = BorderTop() - CollapsedOuterBorderTop();
846 IntRect border_overflow_rect( 840 IntRect border_overflow_rect(
847 left_border_overflow.ToInt(), top_border_overflow.ToInt(), 841 left_border_overflow.ToInt(), top_border_overflow.ToInt(),
848 (right_border_overflow - left_border_overflow).ToInt(), 842 (right_border_overflow - left_border_overflow).ToInt(),
849 (bottom_border_overflow - top_border_overflow).ToInt()); 843 (bottom_border_overflow - top_border_overflow).ToInt());
850 if (border_overflow_rect != PixelSnappedBorderBoxRect()) { 844 if (border_overflow_rect != PixelSnappedBorderBoxRect()) {
851 LayoutRect border_layout_rect(border_overflow_rect); 845 LayoutRect border_layout_rect(border_overflow_rect);
852 AddLayoutOverflow(border_layout_rect); 846 AddLayoutOverflow(border_layout_rect);
853 AddContentsVisualOverflow(border_layout_rect); 847 AddContentsVisualOverflow(border_layout_rect);
854 } 848 }
855 } 849 }*/
850 // TODO: Add a test.
856 851
857 // Add overflow from our caption. 852 // Add overflow from our caption.
858 for (unsigned i = 0; i < captions_.size(); i++) 853 for (unsigned i = 0; i < captions_.size(); i++)
859 AddOverflowFromChild(*captions_[i]); 854 AddOverflowFromChild(*captions_[i]);
860 855
861 // Add overflow from our sections. 856 // Add overflow from our sections.
862 for (LayoutTableSection* section = TopSection(); section; 857 for (LayoutTableSection* section = TopSection(); section;
863 section = SectionBelow(section)) 858 section = SectionBelow(section))
864 AddOverflowFromChild(*section); 859 AddOverflowFromChild(*section);
865 } 860 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 } 902 }
908 903
909 void LayoutTable::PaintMask(const PaintInfo& paint_info, 904 void LayoutTable::PaintMask(const PaintInfo& paint_info,
910 const LayoutPoint& paint_offset) const { 905 const LayoutPoint& paint_offset) const {
911 TablePainter(*this).PaintMask(paint_info, paint_offset); 906 TablePainter(*this).PaintMask(paint_info, paint_offset);
912 } 907 }
913 908
914 void LayoutTable::ComputeIntrinsicLogicalWidths(LayoutUnit& min_width, 909 void LayoutTable::ComputeIntrinsicLogicalWidths(LayoutUnit& min_width,
915 LayoutUnit& max_width) const { 910 LayoutUnit& max_width) const {
916 RecalcSectionsIfNeeded(); 911 RecalcSectionsIfNeeded();
917 // FIXME: Do the recalc in borderStart/borderEnd and make those const_cast
918 // this call.
919 // Then m_borderStart/m_borderEnd will be transparent a cache and it removes
920 // the possibility of reading out stale values.
921 const_cast<LayoutTable*>(this)->RecalcBordersInRowDirection();
922 // FIXME: Restructure the table layout code so that we can make this method 912 // FIXME: Restructure the table layout code so that we can make this method
923 // const. 913 // const.
924 const_cast<LayoutTable*>(this)->table_layout_->ComputeIntrinsicLogicalWidths( 914 const_cast<LayoutTable*>(this)->table_layout_->ComputeIntrinsicLogicalWidths(
925 min_width, max_width); 915 min_width, max_width);
926 916
927 // FIXME: We should include captions widths here like we do in 917 // FIXME: We should include captions widths here like we do in
928 // computePreferredLogicalWidths. 918 // computePreferredLogicalWidths.
929 } 919 }
930 920
931 void LayoutTable::ComputePreferredLogicalWidths() { 921 void LayoutTable::ComputePreferredLogicalWidths() {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
980 ClearPreferredLogicalWidthsDirty(); 970 ClearPreferredLogicalWidthsDirty();
981 } 971 }
982 972
983 LayoutTableSection* LayoutTable::TopNonEmptySection() const { 973 LayoutTableSection* LayoutTable::TopNonEmptySection() const {
984 LayoutTableSection* section = TopSection(); 974 LayoutTableSection* section = TopSection();
985 if (section && !section->NumRows()) 975 if (section && !section->NumRows())
986 section = SectionBelow(section, kSkipEmptySections); 976 section = SectionBelow(section, kSkipEmptySections);
987 return section; 977 return section;
988 } 978 }
989 979
980 LayoutTableSection* LayoutTable::BottomNonEmptySection() const {
981 LayoutTableSection* section = BottomSection();
982 if (section && !section->NumRows())
983 section = SectionAbove(section, kSkipEmptySections);
984 return section;
985 }
986
990 void LayoutTable::SplitEffectiveColumn(unsigned index, unsigned first_span) { 987 void LayoutTable::SplitEffectiveColumn(unsigned index, unsigned first_span) {
991 // We split the column at |index|, taking |firstSpan| cells from the span. 988 // We split the column at |index|, taking |firstSpan| cells from the span.
992 DCHECK_GT(effective_columns_[index].span, first_span); 989 DCHECK_GT(effective_columns_[index].span, first_span);
993 effective_columns_.insert(index, first_span); 990 effective_columns_.insert(index, first_span);
994 effective_columns_[index + 1].span -= first_span; 991 effective_columns_[index + 1].span -= first_span;
995 992
996 // Propagate the change in our columns representation to the sections that 993 // Propagate the change in our columns representation to the sections that
997 // don't need cell recalc. If they do, they will be synced up directly with 994 // don't need cell recalc. If they do, they will be synced up directly with
998 // m_columns later. 995 // m_columns later.
999 for (LayoutObject* child = FirstChild(); child; 996 for (LayoutObject* child = FirstChild(); child;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 1168
1172 effective_columns_.resize(max_cols); 1169 effective_columns_.resize(max_cols);
1173 effective_column_positions_.resize(max_cols + 1); 1170 effective_column_positions_.resize(max_cols + 1);
1174 no_cell_colspan_at_least_ = CalcNoCellColspanAtLeast(); 1171 no_cell_colspan_at_least_ = CalcNoCellColspanAtLeast();
1175 1172
1176 DCHECK(SelfNeedsLayout()); 1173 DCHECK(SelfNeedsLayout());
1177 1174
1178 needs_section_recalc_ = false; 1175 needs_section_recalc_ = false;
1179 } 1176 }
1180 1177
1181 int LayoutTable::CalcBorderStart() const {
1182 if (!ShouldCollapseBorders())
1183 return LayoutBlock::BorderStart().ToInt();
1184
1185 // Determined by the first cell of the first row. See the CSS 2.1 spec,
1186 // section 17.6.2.
1187 if (!NumEffectiveColumns())
1188 return 0;
1189
1190 int border_width = 0;
1191
1192 const BorderValue& table_start_border = Style()->BorderStart();
1193 if (table_start_border.Style() == kBorderStyleHidden)
1194 return 0;
1195 if (table_start_border.Style() > kBorderStyleHidden)
1196 border_width = table_start_border.Width();
1197
1198 // TODO(dgrogan): This logic doesn't properly account for the first column in
1199 // the first column-group case.
1200 if (LayoutTableCol* column =
1201 ColElementAtEffectiveColumn(0).InnermostColOrColGroup()) {
1202 // FIXME: We don't account for direction on columns and column groups.
1203 const BorderValue& column_adjoining_border = column->Style()->BorderStart();
1204 if (column_adjoining_border.Style() == kBorderStyleHidden)
1205 return 0;
1206 if (column_adjoining_border.Style() > kBorderStyleHidden)
1207 border_width =
1208 std::max<int>(border_width, column_adjoining_border.Width());
1209 }
1210
1211 if (const LayoutTableSection* top_non_empty_section =
1212 this->TopNonEmptySection()) {
1213 const BorderValue& section_adjoining_border =
1214 top_non_empty_section->BorderAdjoiningTableStart();
1215 if (section_adjoining_border.Style() == kBorderStyleHidden)
1216 return 0;
1217
1218 if (section_adjoining_border.Style() > kBorderStyleHidden)
1219 border_width =
1220 std::max<int>(border_width, section_adjoining_border.Width());
1221
1222 if (const LayoutTableCell* adjoining_start_cell =
1223 top_non_empty_section->FirstRowCellAdjoiningTableStart()) {
1224 // FIXME: Make this work with perpendicular and flipped cells.
1225 const BorderValue& start_cell_adjoining_border =
1226 adjoining_start_cell->BorderAdjoiningTableStart();
1227 if (start_cell_adjoining_border.Style() == kBorderStyleHidden)
1228 return 0;
1229
1230 const BorderValue& first_row_adjoining_border =
1231 adjoining_start_cell->Row()->BorderAdjoiningTableStart();
1232 if (first_row_adjoining_border.Style() == kBorderStyleHidden)
1233 return 0;
1234
1235 if (start_cell_adjoining_border.Style() > kBorderStyleHidden) {
1236 border_width =
1237 std::max<int>(border_width, start_cell_adjoining_border.Width());
1238 }
1239 if (first_row_adjoining_border.Style() > kBorderStyleHidden) {
1240 border_width =
1241 std::max<int>(border_width, first_row_adjoining_border.Width());
1242 }
1243 }
1244 }
1245 return (border_width + (Style()->IsLeftToRightDirection() ? 0 : 1)) / 2;
1246 }
1247
1248 int LayoutTable::CalcBorderEnd() const {
1249 if (!ShouldCollapseBorders())
1250 return LayoutBlock::BorderEnd().ToInt();
1251
1252 // Determined by the last cell of the first row. See the CSS 2.1 spec, section
1253 // 17.6.2.
1254 if (!NumEffectiveColumns())
1255 return 0;
1256
1257 int border_width = 0;
1258
1259 const BorderValue& table_end_border = Style()->BorderEnd();
1260 if (table_end_border.Style() == kBorderStyleHidden)
1261 return 0;
1262 if (table_end_border.Style() > kBorderStyleHidden)
1263 border_width = table_end_border.Width();
1264
1265 unsigned end_column = NumEffectiveColumns() - 1;
1266
1267 // TODO(dgrogan): This logic doesn't properly account for the last column in
1268 // the last column-group case.
1269 if (LayoutTableCol* column =
1270 ColElementAtEffectiveColumn(end_column).InnermostColOrColGroup()) {
1271 // FIXME: We don't account for direction on columns and column groups.
1272 const BorderValue& column_adjoining_border = column->Style()->BorderEnd();
1273 if (column_adjoining_border.Style() == kBorderStyleHidden)
1274 return 0;
1275 if (column_adjoining_border.Style() > kBorderStyleHidden)
1276 border_width =
1277 std::max<int>(border_width, column_adjoining_border.Width());
1278 }
1279
1280 if (const LayoutTableSection* top_non_empty_section =
1281 this->TopNonEmptySection()) {
1282 const BorderValue& section_adjoining_border =
1283 top_non_empty_section->BorderAdjoiningTableEnd();
1284 if (section_adjoining_border.Style() == kBorderStyleHidden)
1285 return 0;
1286
1287 if (section_adjoining_border.Style() > kBorderStyleHidden)
1288 border_width =
1289 std::max<int>(border_width, section_adjoining_border.Width());
1290
1291 if (const LayoutTableCell* adjoining_end_cell =
1292 top_non_empty_section->FirstRowCellAdjoiningTableEnd()) {
1293 // FIXME: Make this work with perpendicular and flipped cells.
1294 const BorderValue& end_cell_adjoining_border =
1295 adjoining_end_cell->BorderAdjoiningTableEnd();
1296 if (end_cell_adjoining_border.Style() == kBorderStyleHidden)
1297 return 0;
1298
1299 const BorderValue& first_row_adjoining_border =
1300 adjoining_end_cell->Row()->BorderAdjoiningTableEnd();
1301 if (first_row_adjoining_border.Style() == kBorderStyleHidden)
1302 return 0;
1303
1304 if (end_cell_adjoining_border.Style() > kBorderStyleHidden) {
1305 border_width =
1306 std::max<int>(border_width, end_cell_adjoining_border.Width());
1307 }
1308 if (first_row_adjoining_border.Style() > kBorderStyleHidden) {
1309 border_width =
1310 std::max<int>(border_width, first_row_adjoining_border.Width());
1311 }
1312 }
1313 }
1314 return (border_width + (Style()->IsLeftToRightDirection() ? 1 : 0)) / 2;
1315 }
1316
1317 void LayoutTable::RecalcBordersInRowDirection() {
1318 // FIXME: We need to compute the collapsed before / after borders in the same
1319 // fashion.
1320 border_start_ = CalcBorderStart();
1321 border_end_ = CalcBorderEnd();
1322 }
1323
1324 LayoutUnit LayoutTable::BorderBefore() const { 1178 LayoutUnit LayoutTable::BorderBefore() const {
1325 if (ShouldCollapseBorders()) { 1179 if (ShouldCollapseBorders()) {
1326 RecalcSectionsIfNeeded(); 1180 UpdateCollapsedOuterBorders();
1327 return LayoutUnit(OuterBorderBefore()); 1181 return LayoutUnit(collapsed_outer_border_before_);
1328 } 1182 }
1329 return LayoutBlock::BorderBefore(); 1183 return LayoutBlock::BorderBefore();
1330 } 1184 }
1331 1185
1332 LayoutUnit LayoutTable::BorderAfter() const { 1186 LayoutUnit LayoutTable::BorderAfter() const {
1333 if (ShouldCollapseBorders()) { 1187 if (ShouldCollapseBorders()) {
1334 RecalcSectionsIfNeeded(); 1188 UpdateCollapsedOuterBorders();
1335 return LayoutUnit(OuterBorderAfter()); 1189 return LayoutUnit(collapsed_outer_border_after_);
1336 } 1190 }
1337 return LayoutBlock::BorderAfter(); 1191 return LayoutBlock::BorderAfter();
1338 } 1192 }
1339 1193
1340 int LayoutTable::OuterBorderBefore() const { 1194 LayoutUnit LayoutTable::BorderStart() const {
1341 if (!ShouldCollapseBorders()) 1195 if (ShouldCollapseBorders()) {
1342 return 0; 1196 UpdateCollapsedOuterBorders();
1343 int border_width = 0; 1197 return LayoutUnit(collapsed_outer_border_start_);
1344 if (LayoutTableSection* top_section = this->TopSection()) {
1345 border_width = top_section->OuterBorderBefore();
1346 if (border_width < 0)
1347 return 0; // Overridden by hidden
1348 } 1198 }
1349 const BorderValue& tb = Style()->BorderBefore(); 1199 return LayoutBlock::BorderStart();
1350 if (tb.Style() == kBorderStyleHidden)
1351 return 0;
1352 if (tb.Style() > kBorderStyleHidden)
1353 border_width = std::max<int>(border_width, tb.Width() / 2);
1354 return border_width;
1355 } 1200 }
1356 1201
1357 int LayoutTable::OuterBorderAfter() const { 1202 LayoutUnit LayoutTable::BorderEnd() const {
1358 if (!ShouldCollapseBorders()) 1203 if (ShouldCollapseBorders()) {
1359 return 0; 1204 UpdateCollapsedOuterBorders();
1360 int border_width = 0; 1205 return LayoutUnit(collapsed_outer_border_end_);
1361
1362 if (LayoutTableSection* section = BottomSection()) {
1363 border_width = section->OuterBorderAfter();
1364 if (border_width < 0)
1365 return 0; // Overridden by hidden
1366 } 1206 }
1367 const BorderValue& tb = Style()->BorderAfter(); 1207 return LayoutBlock::BorderEnd();
1368 if (tb.Style() == kBorderStyleHidden)
1369 return 0;
1370 if (tb.Style() > kBorderStyleHidden)
1371 border_width = std::max<int>(border_width, (tb.Width() + 1) / 2);
1372 return border_width;
1373 }
1374
1375 int LayoutTable::OuterBorderStart() const {
1376 if (!ShouldCollapseBorders())
1377 return 0;
1378
1379 int border_width = 0;
1380
1381 const BorderValue& tb = Style()->BorderStart();
1382 if (tb.Style() == kBorderStyleHidden)
1383 return 0;
1384 if (tb.Style() > kBorderStyleHidden)
1385 border_width =
1386 (tb.Width() + (Style()->IsLeftToRightDirection() ? 0 : 1)) / 2;
1387
1388 bool all_hidden = true;
1389 for (LayoutTableSection* section = TopSection(); section;
1390 section = SectionBelow(section)) {
1391 int sw = section->OuterBorderStart();
1392 if (sw < 0)
1393 continue;
1394 all_hidden = false;
1395 border_width = std::max(border_width, sw);
1396 }
1397 if (all_hidden)
1398 return 0;
1399
1400 return border_width;
1401 }
1402
1403 int LayoutTable::OuterBorderEnd() const {
1404 if (!ShouldCollapseBorders())
1405 return 0;
1406
1407 int border_width = 0;
1408
1409 const BorderValue& tb = Style()->BorderEnd();
1410 if (tb.Style() == kBorderStyleHidden)
1411 return 0;
1412 if (tb.Style() > kBorderStyleHidden)
1413 border_width =
1414 (tb.Width() + (Style()->IsLeftToRightDirection() ? 1 : 0)) / 2;
1415
1416 bool all_hidden = true;
1417 for (LayoutTableSection* section = TopSection(); section;
1418 section = SectionBelow(section)) {
1419 int sw = section->OuterBorderEnd();
1420 if (sw < 0)
1421 continue;
1422 all_hidden = false;
1423 border_width = std::max(border_width, sw);
1424 }
1425 if (all_hidden)
1426 return 0;
1427
1428 return border_width;
1429 } 1208 }
1430 1209
1431 LayoutTableSection* LayoutTable::SectionAbove( 1210 LayoutTableSection* LayoutTable::SectionAbove(
1432 const LayoutTableSection* section, 1211 const LayoutTableSection* section,
1433 SkipEmptySectionsValue skip_empty_sections) const { 1212 SkipEmptySectionsValue skip_empty_sections) const {
1434 RecalcSectionsIfNeeded(); 1213 RecalcSectionsIfNeeded();
1435 1214
1436 if (section == head_) 1215 if (section == head_)
1437 return 0; 1216 return 0;
1438 1217
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 return LayoutBlock::PaddingLeft(); 1529 return LayoutBlock::PaddingLeft();
1751 } 1530 }
1752 1531
1753 LayoutUnit LayoutTable::PaddingRight() const { 1532 LayoutUnit LayoutTable::PaddingRight() const {
1754 if (ShouldCollapseBorders()) 1533 if (ShouldCollapseBorders())
1755 return LayoutUnit(); 1534 return LayoutUnit();
1756 1535
1757 return LayoutBlock::PaddingRight(); 1536 return LayoutBlock::PaddingRight();
1758 } 1537 }
1759 1538
1539 unsigned LayoutTable::ComputeCollapsedOuterBorderBefore() const {
1540 DCHECK(ShouldCollapseBorders());
1541
1542 const auto* section = TopNonEmptySection();
1543 if (!section)
1544 return 0;
1545
1546 unsigned n_cols = section->NumEffectiveColumns(0);
1547 unsigned result = 0;
1548 for (unsigned col = 0; col < n_cols; ++col) {
1549 if (const auto* cell = section->PrimaryCellAt(0, col))
1550 result = std::max(result, cell->CollapsedOuterBorderBefore());
1551 }
1552 return result;
1553 }
1554
1555 unsigned LayoutTable::ComputeCollapsedOuterBorderAfter() const {
1556 DCHECK(ShouldCollapseBorders());
1557
1558 const auto* section = BottomNonEmptySection();
1559 if (!section)
1560 return 0;
1561
1562 unsigned row = section->NumRows() - 1;
1563 unsigned n_cols = section->NumEffectiveColumns(row);
1564 unsigned result = 0;
1565 for (unsigned col = 0; col < n_cols; ++col) {
1566 if (const auto* cell = section->PrimaryCellAt(row, col))
1567 result = std::max(result, cell->CollapsedOuterBorderAfter());
1568 }
1569 return result;
1570 }
1571
1572 unsigned LayoutTable::ComputeCollapsedOuterBorderStart() const {
1573 DCHECK(ShouldCollapseBorders());
1574
1575 unsigned result = 0;
1576 for (const auto* section = TopNonEmptySection(); section;
1577 section = SectionBelow(section, kSkipEmptySections)) {
1578 for (unsigned row = 0; row < section->NumRows(); ++row) {
1579 if (const auto* cell = section->PrimaryCellAt(row, 0))
1580 result = std::max(result, cell->CollapsedOuterBorderStart());
1581 }
1582 }
1583 return result;
1584 }
1585
1586 unsigned LayoutTable::ComputeCollapsedOuterBorderEnd() const {
1587 DCHECK(ShouldCollapseBorders());
1588
1589 unsigned n_cols = NumEffectiveColumns();
1590 if (!n_cols)
1591 return 0;
1592
1593 unsigned result = 0;
1594 for (const auto* section = TopNonEmptySection(); section;
1595 section = SectionBelow(section, kSkipEmptySections)) {
1596 for (unsigned row = 0; row < section->NumRows(); ++row) {
1597 if (const auto* cell = section->PrimaryCellAt(row, n_cols - 1))
1598 result = std::max(result, cell->CollapsedOuterBorderEnd());
1599 }
1600 }
1601 return result;
1602 }
1603
1604 void LayoutTable::UpdateCollapsedOuterBorders() const {
1605 if (collapsed_outer_borders_valid_)
1606 return;
1607
1608 collapsed_outer_borders_valid_ = true;
1609 if (ShouldCollapseBorders()) {
1610 collapsed_outer_border_before_ = ComputeCollapsedOuterBorderBefore();
1611 collapsed_outer_border_after_ = ComputeCollapsedOuterBorderAfter();
1612 collapsed_outer_border_start_ = ComputeCollapsedOuterBorderStart();
1613 collapsed_outer_border_end_ = ComputeCollapsedOuterBorderEnd();
1614 }
1615 }
1616
1760 } // namespace blink 1617 } // 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