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

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

Issue 2846563002: Optimize collapsed border calculation (step 1) (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 Apple Inc. 7 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc.
8 * All rights reserved. 8 * All rights reserved.
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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 52
53 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell), 53 static_assert(sizeof(LayoutTableCell) == sizeof(SameSizeAsLayoutTableCell),
54 "LayoutTableCell should stay small"); 54 "LayoutTableCell should stay small");
55 static_assert(sizeof(CollapsedBorderValue) == 8, 55 static_assert(sizeof(CollapsedBorderValue) == 8,
56 "CollapsedBorderValue should stay small"); 56 "CollapsedBorderValue should stay small");
57 57
58 LayoutTableCell::LayoutTableCell(Element* element) 58 LayoutTableCell::LayoutTableCell(Element* element)
59 : LayoutBlockFlow(element), 59 : LayoutBlockFlow(element),
60 absolute_column_index_(kUnsetColumnIndex), 60 absolute_column_index_(kUnsetColumnIndex),
61 cell_width_changed_(false), 61 cell_width_changed_(false),
62 collapsed_border_values_valid_(false),
63 collapsed_borders_visually_changed_(false),
62 intrinsic_padding_before_(0), 64 intrinsic_padding_before_(0),
63 intrinsic_padding_after_(0) { 65 intrinsic_padding_after_(0) {
64 // We only update the flags when notified of DOM changes in 66 // We only update the flags when notified of DOM changes in
65 // colSpanOrRowSpanChanged() so we need to set their initial values here in 67 // colSpanOrRowSpanChanged() so we need to set their initial values here in
66 // case something asks for colSpan()/rowSpan() before then. 68 // case something asks for colSpan()/rowSpan() before then.
67 UpdateColAndRowSpanFlags(); 69 UpdateColAndRowSpanFlags();
68 } 70 }
69 71
70 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues( 72 LayoutTableCell::CollapsedBorderValues::CollapsedBorderValues(
71 const LayoutTableCell& layout_table_cell, 73 const LayoutTableCell& layout_table_cell,
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 return HasSameDirectionAs(Table()) ? IsInStartColumn() : IsInEndColumn(); 591 return HasSameDirectionAs(Table()) ? IsInStartColumn() : IsInEndColumn();
590 } 592 }
591 593
592 bool LayoutTableCell::HasEndBorderAdjoiningTable() const { 594 bool LayoutTableCell::HasEndBorderAdjoiningTable() const {
593 // The table direction determines the row direction. In mixed directionality, 595 // The table direction determines the row direction. In mixed directionality,
594 // we cannot guarantee that we have a common border with the table (think a 596 // we cannot guarantee that we have a common border with the table (think a
595 // ltr table with ltr end cell). 597 // ltr table with ltr end cell).
596 return HasSameDirectionAs(Table()) ? IsInEndColumn() : IsInStartColumn(); 598 return HasSameDirectionAs(Table()) ? IsInEndColumn() : IsInStartColumn();
597 } 599 }
598 600
599 CollapsedBorderValue LayoutTableCell::ComputeCollapsedStartBorder( 601 CollapsedBorderValue LayoutTableCell::ComputeCollapsedStartBorder() const {
600 IncludeBorderColorOrNot include_color) const {
601 LayoutTable* table = this->Table(); 602 LayoutTable* table = this->Table();
603 LayoutTableCell* cell_before = table->CellBefore(this);
604 // We can use the border shared with cellBefore if it is valid.
wkorman 2017/04/27 20:11:15 cellBefore -> |cell_before|
Xianzhu 2017/04/28 20:31:44 Done.
605 if (cell_before && cell_before->collapsed_border_values_valid_ &&
606 cell_before->RowIndex() == RowIndex()) {
607 return cell_before->GetCollapsedBorderValues()
608 ? cell_before->GetCollapsedBorderValues()->EndBorder()
609 : CollapsedBorderValue();
610 }
602 611
603 // For the start border, we need to check, in order of precedence: 612 // For the start border, we need to check, in order of precedence:
604 // (1) Our start border. 613 // (1) Our start border.
605 int start_color_property = include_color 614 int start_color_property = CSSProperty::ResolveDirectionAwareProperty(
606 ? CSSProperty::ResolveDirectionAwareProperty( 615 CSSPropertyWebkitBorderStartColor, StyleForCellFlow().Direction(),
607 CSSPropertyWebkitBorderStartColor, 616 StyleForCellFlow().GetWritingMode());
608 StyleForCellFlow().Direction(), 617 int end_color_property = CSSProperty::ResolveDirectionAwareProperty(
609 StyleForCellFlow().GetWritingMode()) 618 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(),
610 : 0; 619 StyleForCellFlow().GetWritingMode());
611 int end_color_property = 620 CollapsedBorderValue result(Style()->BorderStart(),
612 include_color 621 ResolveColor(start_color_property),
613 ? CSSProperty::ResolveDirectionAwareProperty( 622 kBorderPrecedenceCell);
614 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(),
615 StyleForCellFlow().GetWritingMode())
616 : 0;
617 CollapsedBorderValue result(
618 Style()->BorderStart(),
619 include_color ? ResolveColor(start_color_property) : Color(),
620 kBorderPrecedenceCell);
621 623
622 // (2) The end border of the preceding cell. 624 // (2) The end border of the preceding cell.
623 LayoutTableCell* cell_before = table->CellBefore(this);
624 if (cell_before) { 625 if (cell_before) {
625 CollapsedBorderValue cell_before_adjoining_border = CollapsedBorderValue( 626 CollapsedBorderValue cell_before_adjoining_border = CollapsedBorderValue(
626 cell_before->BorderAdjoiningCellAfter(this), 627 cell_before->BorderAdjoiningCellAfter(this),
627 include_color ? cell_before->ResolveColor(end_color_property) : Color(), 628 cell_before->ResolveColor(end_color_property), kBorderPrecedenceCell);
628 kBorderPrecedenceCell);
629 // |result| should be the 2nd argument as |cellBefore| should win in case of 629 // |result| should be the 2nd argument as |cellBefore| should win in case of
630 // equality per CSS 2.1 (Border conflict resolution, point 4). 630 // equality per CSS 2.1 (Border conflict resolution, point 4).
631 result = ChooseBorder(cell_before_adjoining_border, result); 631 result = ChooseBorder(cell_before_adjoining_border, result);
632 if (!result.Exists()) 632 if (!result.Exists())
633 return result; 633 return result;
634 } 634 }
635 635
636 bool start_border_adjoins_table = HasStartBorderAdjoiningTable(); 636 bool start_border_adjoins_table = HasStartBorderAdjoiningTable();
637 if (start_border_adjoins_table) { 637 if (start_border_adjoins_table) {
638 // (3) Our row's start border. 638 // (3) Our row's start border.
639 result = ChooseBorder( 639 result = ChooseBorder(
640 result, CollapsedBorderValue( 640 result,
641 Row()->BorderAdjoiningStartCell(this), 641 CollapsedBorderValue(Row()->BorderAdjoiningStartCell(this),
642 include_color ? Parent()->ResolveColor(start_color_property) 642 Parent()->ResolveColor(start_color_property),
643 : Color(), 643 kBorderPrecedenceRow));
644 kBorderPrecedenceRow));
645 if (!result.Exists()) 644 if (!result.Exists())
646 return result; 645 return result;
647 646
648 // (4) Our row group's start border. 647 // (4) Our row group's start border.
649 result = ChooseBorder( 648 result = ChooseBorder(
650 result, CollapsedBorderValue(Section()->BorderAdjoiningStartCell(this), 649 result,
651 include_color ? Section()->ResolveColor( 650 CollapsedBorderValue(Section()->BorderAdjoiningStartCell(this),
652 start_color_property) 651 Section()->ResolveColor(start_color_property),
653 : Color(), 652 kBorderPrecedenceRowGroup));
654 kBorderPrecedenceRowGroup));
655 if (!result.Exists()) 653 if (!result.Exists())
656 return result; 654 return result;
657 } 655 }
658 656
659 // (5) Our column and column group's start borders. 657 // (5) Our column and column group's start borders.
660 LayoutTable::ColAndColGroup col_and_col_group = 658 LayoutTable::ColAndColGroup col_and_col_group =
661 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()); 659 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex());
662 if (col_and_col_group.colgroup && 660 if (col_and_col_group.colgroup &&
663 col_and_col_group.adjoins_start_border_of_col_group) { 661 col_and_col_group.adjoins_start_border_of_col_group) {
664 // Only apply the colgroup's border if this cell touches the colgroup edge. 662 // Only apply the colgroup's border if this cell touches the colgroup edge.
665 result = ChooseBorder( 663 result = ChooseBorder(
666 result, 664 result,
667 CollapsedBorderValue( 665 CollapsedBorderValue(
668 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), 666 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this),
669 include_color 667 col_and_col_group.colgroup->ResolveColor(start_color_property),
670 ? col_and_col_group.colgroup->ResolveColor(start_color_property)
671 : Color(),
672 kBorderPrecedenceColumnGroup)); 668 kBorderPrecedenceColumnGroup));
673 if (!result.Exists()) 669 if (!result.Exists())
674 return result; 670 return result;
675 } 671 }
676 if (col_and_col_group.col) { 672 if (col_and_col_group.col) {
677 // Always apply the col's border irrespective of whether this cell touches 673 // Always apply the col's border irrespective of whether this cell touches
678 // it. This is per HTML5: "For the purposes of the CSS table model, the col 674 // it. This is per HTML5: "For the purposes of the CSS table model, the col
679 // element is expected to be treated as if it "was present as many times as 675 // element is expected to be treated as if it "was present as many times as
680 // its span attribute specifies". 676 // its span attribute specifies".
681 result = ChooseBorder( 677 result = ChooseBorder(
682 result, CollapsedBorderValue( 678 result, CollapsedBorderValue(
683 col_and_col_group.col->BorderAdjoiningCellStartBorder(this), 679 col_and_col_group.col->BorderAdjoiningCellStartBorder(this),
684 include_color ? col_and_col_group.col->ResolveColor( 680 col_and_col_group.col->ResolveColor(start_color_property),
685 start_color_property)
686 : Color(),
687 kBorderPrecedenceColumn)); 681 kBorderPrecedenceColumn));
688 if (!result.Exists()) 682 if (!result.Exists())
689 return result; 683 return result;
690 } 684 }
691 685
692 // (6) The end border of the preceding column. 686 // (6) The end border of the preceding column.
693 if (cell_before) { 687 if (cell_before) {
694 LayoutTable::ColAndColGroup col_and_col_group = 688 LayoutTable::ColAndColGroup col_and_col_group =
695 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() - 1); 689 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() - 1);
696 // Only apply the colgroup's border if this cell touches the colgroup edge. 690 // Only apply the colgroup's border if this cell touches the colgroup edge.
697 if (col_and_col_group.colgroup && 691 if (col_and_col_group.colgroup &&
698 col_and_col_group.adjoins_end_border_of_col_group) { 692 col_and_col_group.adjoins_end_border_of_col_group) {
699 result = ChooseBorder( 693 result = ChooseBorder(
700 CollapsedBorderValue( 694 CollapsedBorderValue(
701 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), 695 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this),
702 include_color 696 col_and_col_group.colgroup->ResolveColor(end_color_property),
703 ? col_and_col_group.colgroup->ResolveColor(end_color_property)
704 : Color(),
705 kBorderPrecedenceColumnGroup), 697 kBorderPrecedenceColumnGroup),
706 result); 698 result);
707 if (!result.Exists()) 699 if (!result.Exists())
708 return result; 700 return result;
709 } 701 }
710 // Always apply the col's border irrespective of whether this cell touches 702 // Always apply the col's border irrespective of whether this cell touches
711 // it. This is per HTML5: "For the purposes of the CSS table model, the col 703 // it. This is per HTML5: "For the purposes of the CSS table model, the col
712 // element is expected to be treated as if it "was present as many times as 704 // element is expected to be treated as if it "was present as many times as
713 // its span attribute specifies". 705 // its span attribute specifies".
714 if (col_and_col_group.col) { 706 if (col_and_col_group.col) {
715 result = ChooseBorder( 707 result = ChooseBorder(
716 CollapsedBorderValue( 708 CollapsedBorderValue(
717 col_and_col_group.col->BorderAdjoiningCellAfter(this), 709 col_and_col_group.col->BorderAdjoiningCellAfter(this),
718 include_color 710 col_and_col_group.col->ResolveColor(end_color_property),
719 ? col_and_col_group.col->ResolveColor(end_color_property)
720 : Color(),
721 kBorderPrecedenceColumn), 711 kBorderPrecedenceColumn),
722 result); 712 result);
723 if (!result.Exists()) 713 if (!result.Exists())
724 return result; 714 return result;
725 } 715 }
726 } 716 }
727 717
728 if (start_border_adjoins_table) { 718 if (start_border_adjoins_table) {
729 // (7) The table's start border. 719 // (7) The table's start border.
730 result = ChooseBorder( 720 result = ChooseBorder(
731 result, 721 result, CollapsedBorderValue(table->TableStartBorderAdjoiningCell(this),
732 CollapsedBorderValue( 722 table->ResolveColor(start_color_property),
733 table->TableStartBorderAdjoiningCell(this), 723 kBorderPrecedenceTable));
734 include_color ? table->ResolveColor(start_color_property) : Color(),
735 kBorderPrecedenceTable));
736 if (!result.Exists()) 724 if (!result.Exists())
737 return result; 725 return result;
738 } 726 }
739 727
740 return result; 728 return result;
741 } 729 }
742 730
743 CollapsedBorderValue LayoutTableCell::ComputeCollapsedEndBorder( 731 CollapsedBorderValue LayoutTableCell::ComputeCollapsedEndBorder() const {
744 IncludeBorderColorOrNot include_color) const {
745 LayoutTable* table = this->Table(); 732 LayoutTable* table = this->Table();
746 // Note: We have to use the effective column information instead of whether we 733 // Note: We have to use the effective column information instead of whether we
747 // have a cell after as a table doesn't have to be regular (any row can have 734 // have a cell after as a table doesn't have to be regular (any row can have
748 // less cells than the total cell count). 735 // less cells than the total cell count).
749 bool is_end_column = table->AbsoluteColumnToEffectiveColumn( 736 bool is_end_column = IsInEndColumn();
750 AbsoluteColumnIndex() + ColSpan() - 1) == 737 LayoutTableCell* cell_after =
751 table->NumEffectiveColumns() - 1; 738 is_end_column ? nullptr : table->CellAfter(this);
739 // We can use the border shared with cellAfter if it is valid.
740 if (cell_after && cell_after->collapsed_border_values_valid_ &&
741 cell_after->RowIndex() == RowIndex()) {
742 return cell_after->GetCollapsedBorderValues()
743 ? cell_after->GetCollapsedBorderValues()->StartBorder()
744 : CollapsedBorderValue();
745 }
752 746
753 // For end border, we need to check, in order of precedence: 747 // For end border, we need to check, in order of precedence:
754 // (1) Our end border. 748 // (1) Our end border.
755 int start_color_property = include_color 749 int start_color_property = CSSProperty::ResolveDirectionAwareProperty(
wkorman 2017/04/27 20:11:15 We do similar to these 3 lines about 8 times in th
Xianzhu 2017/04/28 20:31:44 Done.
756 ? CSSProperty::ResolveDirectionAwareProperty( 750 CSSPropertyWebkitBorderStartColor, StyleForCellFlow().Direction(),
757 CSSPropertyWebkitBorderStartColor, 751 StyleForCellFlow().GetWritingMode());
758 StyleForCellFlow().Direction(), 752 int end_color_property = CSSProperty::ResolveDirectionAwareProperty(
759 StyleForCellFlow().GetWritingMode()) 753 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(),
760 : 0; 754 StyleForCellFlow().GetWritingMode());
761 int end_color_property =
762 include_color
763 ? CSSProperty::ResolveDirectionAwareProperty(
764 CSSPropertyWebkitBorderEndColor, StyleForCellFlow().Direction(),
765 StyleForCellFlow().GetWritingMode())
766 : 0;
767 CollapsedBorderValue result = CollapsedBorderValue( 755 CollapsedBorderValue result = CollapsedBorderValue(
768 Style()->BorderEnd(), 756 Style()->BorderEnd(), ResolveColor(end_color_property),
769 include_color ? ResolveColor(end_color_property) : Color(),
770 kBorderPrecedenceCell); 757 kBorderPrecedenceCell);
771 758
772 // (2) The start border of the following cell. 759 // (2) The start border of the following cell.
773 if (!is_end_column) { 760 if (cell_after) {
774 if (LayoutTableCell* cell_after = table->CellAfter(this)) { 761 CollapsedBorderValue cell_after_adjoining_border = CollapsedBorderValue(
775 CollapsedBorderValue cell_after_adjoining_border = CollapsedBorderValue( 762 cell_after->BorderAdjoiningCellBefore(this),
776 cell_after->BorderAdjoiningCellBefore(this), 763 cell_after->ResolveColor(start_color_property), kBorderPrecedenceCell);
777 include_color ? cell_after->ResolveColor(start_color_property) 764 result = ChooseBorder(result, cell_after_adjoining_border);
778 : Color(), 765 if (!result.Exists())
779 kBorderPrecedenceCell); 766 return result;
780 result = ChooseBorder(result, cell_after_adjoining_border);
781 if (!result.Exists())
782 return result;
783 }
784 } 767 }
785 768
786 bool end_border_adjoins_table = HasEndBorderAdjoiningTable(); 769 bool end_border_adjoins_table = HasEndBorderAdjoiningTable();
787 if (end_border_adjoins_table) { 770 if (end_border_adjoins_table) {
788 // (3) Our row's end border. 771 // (3) Our row's end border.
789 result = ChooseBorder( 772 result = ChooseBorder(
790 result, CollapsedBorderValue( 773 result, CollapsedBorderValue(Row()->BorderAdjoiningEndCell(this),
791 Row()->BorderAdjoiningEndCell(this), 774 Parent()->ResolveColor(end_color_property),
792 include_color ? Parent()->ResolveColor(end_color_property) 775 kBorderPrecedenceRow));
793 : Color(),
794 kBorderPrecedenceRow));
795 if (!result.Exists()) 776 if (!result.Exists())
796 return result; 777 return result;
797 778
798 // (4) Our row group's end border. 779 // (4) Our row group's end border.
799 result = ChooseBorder( 780 result = ChooseBorder(
800 result, CollapsedBorderValue( 781 result,
801 Section()->BorderAdjoiningEndCell(this), 782 CollapsedBorderValue(Section()->BorderAdjoiningEndCell(this),
802 include_color ? Section()->ResolveColor(end_color_property) 783 Section()->ResolveColor(end_color_property),
803 : Color(), 784 kBorderPrecedenceRowGroup));
804 kBorderPrecedenceRowGroup));
805 if (!result.Exists()) 785 if (!result.Exists())
806 return result; 786 return result;
807 } 787 }
808 788
809 // (5) Our column and column group's end borders. 789 // (5) Our column and column group's end borders.
810 LayoutTable::ColAndColGroup col_and_col_group = 790 LayoutTable::ColAndColGroup col_and_col_group =
811 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan() - 1); 791 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan() - 1);
812 if (col_and_col_group.colgroup && 792 if (col_and_col_group.colgroup &&
813 col_and_col_group.adjoins_end_border_of_col_group) { 793 col_and_col_group.adjoins_end_border_of_col_group) {
814 // Only apply the colgroup's border if this cell touches the colgroup edge. 794 // Only apply the colgroup's border if this cell touches the colgroup edge.
815 result = ChooseBorder( 795 result = ChooseBorder(
816 result, 796 result,
817 CollapsedBorderValue( 797 CollapsedBorderValue(
818 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this), 798 col_and_col_group.colgroup->BorderAdjoiningCellEndBorder(this),
819 include_color 799 col_and_col_group.colgroup->ResolveColor(end_color_property),
820 ? col_and_col_group.colgroup->ResolveColor(end_color_property)
821 : Color(),
822 kBorderPrecedenceColumnGroup)); 800 kBorderPrecedenceColumnGroup));
823 if (!result.Exists()) 801 if (!result.Exists())
824 return result; 802 return result;
825 } 803 }
826 if (col_and_col_group.col) { 804 if (col_and_col_group.col) {
827 // Always apply the col's border irrespective of whether this cell touches 805 // Always apply the col's border irrespective of whether this cell touches
828 // it. This is per HTML5: "For the purposes of the CSS table model, the col 806 // it. This is per HTML5: "For the purposes of the CSS table model, the col
829 // element is expected to be treated as if it "was present as many times as 807 // element is expected to be treated as if it "was present as many times as
830 // its span attribute specifies". 808 // its span attribute specifies".
831 result = ChooseBorder( 809 result = ChooseBorder(
832 result, CollapsedBorderValue( 810 result, CollapsedBorderValue(
833 col_and_col_group.col->BorderAdjoiningCellEndBorder(this), 811 col_and_col_group.col->BorderAdjoiningCellEndBorder(this),
834 include_color ? col_and_col_group.col->ResolveColor( 812 col_and_col_group.col->ResolveColor(end_color_property),
835 end_color_property)
836 : Color(),
837 kBorderPrecedenceColumn)); 813 kBorderPrecedenceColumn));
838 if (!result.Exists()) 814 if (!result.Exists())
839 return result; 815 return result;
840 } 816 }
841 817
842 // (6) The start border of the next column. 818 // (6) The start border of the next column.
843 if (!is_end_column) { 819 if (!is_end_column) {
844 LayoutTable::ColAndColGroup col_and_col_group = 820 LayoutTable::ColAndColGroup col_and_col_group =
845 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan()); 821 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex() + ColSpan());
846 if (col_and_col_group.colgroup && 822 if (col_and_col_group.colgroup &&
847 col_and_col_group.adjoins_start_border_of_col_group) { 823 col_and_col_group.adjoins_start_border_of_col_group) {
848 // Only apply the colgroup's border if this cell touches the colgroup 824 // Only apply the colgroup's border if this cell touches the colgroup
849 // edge. 825 // edge.
850 result = ChooseBorder( 826 result = ChooseBorder(
851 result, 827 result,
852 CollapsedBorderValue( 828 CollapsedBorderValue(
853 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this), 829 col_and_col_group.colgroup->BorderAdjoiningCellStartBorder(this),
854 include_color ? col_and_col_group.colgroup->ResolveColor( 830 col_and_col_group.colgroup->ResolveColor(start_color_property),
855 start_color_property)
856 : Color(),
857 kBorderPrecedenceColumnGroup)); 831 kBorderPrecedenceColumnGroup));
858 if (!result.Exists()) 832 if (!result.Exists())
859 return result; 833 return result;
860 } 834 }
861 if (col_and_col_group.col) { 835 if (col_and_col_group.col) {
862 // Always apply the col's border irrespective of whether this cell touches 836 // Always apply the col's border irrespective of whether this cell touches
863 // it. This is per HTML5: "For the purposes of the CSS table model, the 837 // it. This is per HTML5: "For the purposes of the CSS table model, the
864 // col element is expected to be treated as if it "was present as many 838 // col element is expected to be treated as if it "was present as many
865 // times as its span attribute specifies". 839 // times as its span attribute specifies".
866 result = ChooseBorder( 840 result = ChooseBorder(
867 result, CollapsedBorderValue( 841 result, CollapsedBorderValue(
868 col_and_col_group.col->BorderAdjoiningCellBefore(this), 842 col_and_col_group.col->BorderAdjoiningCellBefore(this),
869 include_color ? col_and_col_group.col->ResolveColor( 843 col_and_col_group.col->ResolveColor(start_color_property),
870 start_color_property)
871 : Color(),
872 kBorderPrecedenceColumn)); 844 kBorderPrecedenceColumn));
873 if (!result.Exists()) 845 if (!result.Exists())
874 return result; 846 return result;
875 } 847 }
876 } 848 }
877 849
878 if (end_border_adjoins_table) { 850 if (end_border_adjoins_table) {
879 // (7) The table's end border. 851 // (7) The table's end border.
880 result = ChooseBorder( 852 result = ChooseBorder(
881 result, 853 result, CollapsedBorderValue(table->TableEndBorderAdjoiningCell(this),
882 CollapsedBorderValue( 854 table->ResolveColor(end_color_property),
883 table->TableEndBorderAdjoiningCell(this), 855 kBorderPrecedenceTable));
884 include_color ? table->ResolveColor(end_color_property) : Color(),
885 kBorderPrecedenceTable));
886 if (!result.Exists()) 856 if (!result.Exists())
887 return result; 857 return result;
888 } 858 }
889 859
890 return result; 860 return result;
891 } 861 }
892 862
893 CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder( 863 CollapsedBorderValue LayoutTableCell::ComputeCollapsedBeforeBorder() const {
894 IncludeBorderColorOrNot include_color) const {
895 LayoutTable* table = this->Table(); 864 LayoutTable* table = this->Table();
865 LayoutTableCell* prev_cell = table->CellAbove(this);
866 // We can use the border shared with prevCell if it is valid.
wkorman 2017/04/27 20:11:15 prevCell -> |prev_cell|
Xianzhu 2017/04/28 20:31:44 Done.
867 if (prev_cell && prev_cell->collapsed_border_values_valid_ &&
868 prev_cell->AbsoluteColumnIndex() == AbsoluteColumnIndex()) {
869 return prev_cell->GetCollapsedBorderValues()
870 ? prev_cell->GetCollapsedBorderValues()->AfterBorder()
871 : CollapsedBorderValue();
872 }
896 873
897 // For before border, we need to check, in order of precedence: 874 // For before border, we need to check, in order of precedence:
898 // (1) Our before border. 875 // (1) Our before border.
899 int before_color_property = include_color 876 int before_color_property = CSSProperty::ResolveDirectionAwareProperty(
900 ? CSSProperty::ResolveDirectionAwareProperty( 877 CSSPropertyWebkitBorderBeforeColor, StyleForCellFlow().Direction(),
901 CSSPropertyWebkitBorderBeforeColor, 878 StyleForCellFlow().GetWritingMode());
902 StyleForCellFlow().Direction(), 879 int after_color_property = CSSProperty::ResolveDirectionAwareProperty(
903 StyleForCellFlow().GetWritingMode()) 880 CSSPropertyWebkitBorderAfterColor, StyleForCellFlow().Direction(),
904 : 0; 881 StyleForCellFlow().GetWritingMode());
905 int after_color_property = include_color
906 ? CSSProperty::ResolveDirectionAwareProperty(
907 CSSPropertyWebkitBorderAfterColor,
908 StyleForCellFlow().Direction(),
909 StyleForCellFlow().GetWritingMode())
910 : 0;
911 CollapsedBorderValue result = CollapsedBorderValue( 882 CollapsedBorderValue result = CollapsedBorderValue(
912 Style()->BorderBefore(), 883 Style()->BorderBefore(), ResolveColor(before_color_property),
913 include_color ? ResolveColor(before_color_property) : Color(),
914 kBorderPrecedenceCell); 884 kBorderPrecedenceCell);
915 885
916 LayoutTableCell* prev_cell = table->CellAbove(this);
917 if (prev_cell) { 886 if (prev_cell) {
918 // (2) A before cell's after border. 887 // (2) A before cell's after border.
919 result = ChooseBorder( 888 result = ChooseBorder(
920 CollapsedBorderValue(prev_cell->Style()->BorderAfter(), 889 CollapsedBorderValue(prev_cell->Style()->BorderAfter(),
921 include_color 890 prev_cell->ResolveColor(after_color_property),
922 ? prev_cell->ResolveColor(after_color_property)
923 : Color(),
924 kBorderPrecedenceCell), 891 kBorderPrecedenceCell),
925 result); 892 result);
926 if (!result.Exists()) 893 if (!result.Exists())
927 return result; 894 return result;
928 } 895 }
929 896
930 // (3) Our row's before border. 897 // (3) Our row's before border.
931 result = ChooseBorder( 898 result = ChooseBorder(
932 result, CollapsedBorderValue( 899 result,
933 Parent()->Style()->BorderBefore(), 900 CollapsedBorderValue(Parent()->Style()->BorderBefore(),
934 include_color ? Parent()->ResolveColor(before_color_property) 901 Parent()->ResolveColor(before_color_property),
935 : Color(), 902 kBorderPrecedenceRow));
936 kBorderPrecedenceRow));
937 if (!result.Exists()) 903 if (!result.Exists())
938 return result; 904 return result;
939 905
940 // (4) The previous row's after border. 906 // (4) The previous row's after border.
941 if (prev_cell) { 907 if (prev_cell) {
942 LayoutObject* prev_row = nullptr; 908 LayoutObject* prev_row = nullptr;
943 if (prev_cell->Section() == Section()) 909 if (prev_cell->Section() == Section())
944 prev_row = Parent()->PreviousSibling(); 910 prev_row = Parent()->PreviousSibling();
945 else 911 else
946 prev_row = prev_cell->Section()->LastRow(); 912 prev_row = prev_cell->Section()->LastRow();
947 913
948 if (prev_row) { 914 if (prev_row) {
949 result = ChooseBorder( 915 result = ChooseBorder(
950 CollapsedBorderValue( 916 CollapsedBorderValue(prev_row->Style()->BorderAfter(),
951 prev_row->Style()->BorderAfter(), 917 prev_row->ResolveColor(after_color_property),
952 include_color ? prev_row->ResolveColor(after_color_property) 918 kBorderPrecedenceRow),
953 : Color(),
954 kBorderPrecedenceRow),
955 result); 919 result);
956 if (!result.Exists()) 920 if (!result.Exists())
957 return result; 921 return result;
958 } 922 }
959 } 923 }
960 924
961 // Now check row groups. 925 // Now check row groups.
962 LayoutTableSection* curr_section = Section(); 926 LayoutTableSection* curr_section = Section();
963 if (!RowIndex()) { 927 if (!RowIndex()) {
964 // (5) Our row group's before border. 928 // (5) Our row group's before border.
965 result = ChooseBorder( 929 result = ChooseBorder(
966 result, CollapsedBorderValue(curr_section->Style()->BorderBefore(), 930 result,
967 include_color ? curr_section->ResolveColor( 931 CollapsedBorderValue(curr_section->Style()->BorderBefore(),
968 before_color_property) 932 curr_section->ResolveColor(before_color_property),
969 : Color(), 933 kBorderPrecedenceRowGroup));
970 kBorderPrecedenceRowGroup));
971 if (!result.Exists()) 934 if (!result.Exists())
972 return result; 935 return result;
973 936
974 // (6) Previous row group's after border. 937 // (6) Previous row group's after border.
975 curr_section = table->SectionAbove(curr_section, kSkipEmptySections); 938 curr_section = table->SectionAbove(curr_section, kSkipEmptySections);
976 if (curr_section) { 939 if (curr_section) {
977 result = ChooseBorder( 940 result = ChooseBorder(
978 CollapsedBorderValue( 941 CollapsedBorderValue(curr_section->Style()->BorderAfter(),
979 curr_section->Style()->BorderAfter(), 942 curr_section->ResolveColor(after_color_property),
980 include_color ? curr_section->ResolveColor(after_color_property) 943 kBorderPrecedenceRowGroup),
981 : Color(),
982 kBorderPrecedenceRowGroup),
983 result); 944 result);
984 if (!result.Exists()) 945 if (!result.Exists())
985 return result; 946 return result;
986 } 947 }
987 } 948 }
988 949
989 if (!curr_section) { 950 if (!curr_section) {
990 // (8) Our column and column group's before borders. 951 // (8) Our column and column group's before borders.
991 LayoutTableCol* col_elt = 952 LayoutTableCol* col_elt =
992 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) 953 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex())
993 .InnermostColOrColGroup(); 954 .InnermostColOrColGroup();
994 if (col_elt) { 955 if (col_elt) {
995 result = ChooseBorder( 956 result = ChooseBorder(
996 result, 957 result,
997 CollapsedBorderValue( 958 CollapsedBorderValue(col_elt->Style()->BorderBefore(),
998 col_elt->Style()->BorderBefore(), 959 col_elt->ResolveColor(before_color_property),
999 include_color ? col_elt->ResolveColor(before_color_property) 960 kBorderPrecedenceColumn));
1000 : Color(),
1001 kBorderPrecedenceColumn));
1002 if (!result.Exists()) 961 if (!result.Exists())
1003 return result; 962 return result;
1004 if (LayoutTableCol* enclosing_column_group = 963 if (LayoutTableCol* enclosing_column_group =
1005 col_elt->EnclosingColumnGroup()) { 964 col_elt->EnclosingColumnGroup()) {
1006 result = ChooseBorder( 965 result = ChooseBorder(
1007 result, CollapsedBorderValue( 966 result,
1008 enclosing_column_group->Style()->BorderBefore(), 967 CollapsedBorderValue(
1009 include_color ? enclosing_column_group->ResolveColor( 968 enclosing_column_group->Style()->BorderBefore(),
1010 before_color_property) 969 enclosing_column_group->ResolveColor(before_color_property),
1011 : Color(), 970 kBorderPrecedenceColumnGroup));
1012 kBorderPrecedenceColumnGroup));
1013 if (!result.Exists()) 971 if (!result.Exists())
1014 return result; 972 return result;
1015 } 973 }
1016 } 974 }
1017 975
1018 // (9) The table's before border. 976 // (9) The table's before border.
1019 result = ChooseBorder( 977 result = ChooseBorder(
1020 result, CollapsedBorderValue( 978 result, CollapsedBorderValue(table->Style()->BorderBefore(),
1021 table->Style()->BorderBefore(), 979 table->ResolveColor(before_color_property),
1022 include_color ? table->ResolveColor(before_color_property) 980 kBorderPrecedenceTable));
1023 : Color(),
1024 kBorderPrecedenceTable));
1025 if (!result.Exists()) 981 if (!result.Exists())
1026 return result; 982 return result;
1027 } 983 }
1028 984
1029 return result; 985 return result;
1030 } 986 }
1031 987
1032 CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder( 988 CollapsedBorderValue LayoutTableCell::ComputeCollapsedAfterBorder() const {
1033 IncludeBorderColorOrNot include_color) const {
1034 LayoutTable* table = this->Table(); 989 LayoutTable* table = this->Table();
990 LayoutTableCell* next_cell = table->CellBelow(this);
991 // We can use the border shared with nextCell if it is valid.
992 if (next_cell && next_cell->collapsed_border_values_valid_ &&
993 next_cell->AbsoluteColumnIndex() == AbsoluteColumnIndex()) {
994 return next_cell->GetCollapsedBorderValues()
995 ? next_cell->GetCollapsedBorderValues()->BeforeBorder()
996 : CollapsedBorderValue();
997 }
1035 998
1036 // For after border, we need to check, in order of precedence: 999 // For after border, we need to check, in order of precedence:
1037 // (1) Our after border. 1000 // (1) Our after border.
1038 int before_color_property = include_color 1001 int before_color_property = CSSProperty::ResolveDirectionAwareProperty(
1039 ? CSSProperty::ResolveDirectionAwareProperty( 1002 CSSPropertyWebkitBorderBeforeColor, StyleForCellFlow().Direction(),
1040 CSSPropertyWebkitBorderBeforeColor, 1003 StyleForCellFlow().GetWritingMode());
1041 StyleForCellFlow().Direction(), 1004 int after_color_property = CSSProperty::ResolveDirectionAwareProperty(
1042 StyleForCellFlow().GetWritingMode()) 1005 CSSPropertyWebkitBorderAfterColor, StyleForCellFlow().Direction(),
1043 : 0; 1006 StyleForCellFlow().GetWritingMode());
1044 int after_color_property = include_color
1045 ? CSSProperty::ResolveDirectionAwareProperty(
1046 CSSPropertyWebkitBorderAfterColor,
1047 StyleForCellFlow().Direction(),
1048 StyleForCellFlow().GetWritingMode())
1049 : 0;
1050 CollapsedBorderValue result = CollapsedBorderValue( 1007 CollapsedBorderValue result = CollapsedBorderValue(
1051 Style()->BorderAfter(), 1008 Style()->BorderAfter(), ResolveColor(after_color_property),
1052 include_color ? ResolveColor(after_color_property) : Color(),
1053 kBorderPrecedenceCell); 1009 kBorderPrecedenceCell);
1054 1010
1055 LayoutTableCell* next_cell = table->CellBelow(this);
1056 if (next_cell) { 1011 if (next_cell) {
1057 // (2) An after cell's before border. 1012 // (2) An after cell's before border.
1058 result = ChooseBorder( 1013 result = ChooseBorder(
1059 result, CollapsedBorderValue(next_cell->Style()->BorderBefore(), 1014 result,
1060 include_color ? next_cell->ResolveColor( 1015 CollapsedBorderValue(next_cell->Style()->BorderBefore(),
1061 before_color_property) 1016 next_cell->ResolveColor(before_color_property),
1062 : Color(), 1017 kBorderPrecedenceCell));
1063 kBorderPrecedenceCell));
1064 if (!result.Exists()) 1018 if (!result.Exists())
1065 return result; 1019 return result;
1066 } 1020 }
1067 1021
1068 // (3) Our row's after border. (FIXME: Deal with rowspan!) 1022 // (3) Our row's after border. (FIXME: Deal with rowspan!)
1069 result = ChooseBorder( 1023 result = ChooseBorder(
1070 result, CollapsedBorderValue( 1024 result, CollapsedBorderValue(Parent()->Style()->BorderAfter(),
1071 Parent()->Style()->BorderAfter(), 1025 Parent()->ResolveColor(after_color_property),
1072 include_color ? Parent()->ResolveColor(after_color_property) 1026 kBorderPrecedenceRow));
1073 : Color(),
1074 kBorderPrecedenceRow));
1075 if (!result.Exists()) 1027 if (!result.Exists())
1076 return result; 1028 return result;
1077 1029
1078 // (4) The next row's before border. 1030 // (4) The next row's before border.
1079 if (next_cell) { 1031 if (next_cell) {
1080 result = ChooseBorder( 1032 result = ChooseBorder(
1081 result, 1033 result, CollapsedBorderValue(
1082 CollapsedBorderValue(next_cell->Parent()->Style()->BorderBefore(), 1034 next_cell->Parent()->Style()->BorderBefore(),
1083 include_color ? next_cell->Parent()->ResolveColor( 1035 next_cell->Parent()->ResolveColor(before_color_property),
1084 before_color_property) 1036 kBorderPrecedenceRow));
1085 : Color(),
1086 kBorderPrecedenceRow));
1087 if (!result.Exists()) 1037 if (!result.Exists())
1088 return result; 1038 return result;
1089 } 1039 }
1090 1040
1091 // Now check row groups. 1041 // Now check row groups.
1092 LayoutTableSection* curr_section = Section(); 1042 LayoutTableSection* curr_section = Section();
1093 if (RowIndex() + RowSpan() >= curr_section->NumRows()) { 1043 if (RowIndex() + RowSpan() >= curr_section->NumRows()) {
1094 // (5) Our row group's after border. 1044 // (5) Our row group's after border.
1095 result = ChooseBorder( 1045 result = ChooseBorder(
1096 result, CollapsedBorderValue(curr_section->Style()->BorderAfter(), 1046 result,
1097 include_color ? curr_section->ResolveColor( 1047 CollapsedBorderValue(curr_section->Style()->BorderAfter(),
1098 after_color_property) 1048 curr_section->ResolveColor(after_color_property),
1099 : Color(), 1049 kBorderPrecedenceRowGroup));
1100 kBorderPrecedenceRowGroup));
1101 if (!result.Exists()) 1050 if (!result.Exists())
1102 return result; 1051 return result;
1103 1052
1104 // (6) Following row group's before border. 1053 // (6) Following row group's before border.
1105 curr_section = table->SectionBelow(curr_section, kSkipEmptySections); 1054 curr_section = table->SectionBelow(curr_section, kSkipEmptySections);
1106 if (curr_section) { 1055 if (curr_section) {
1107 result = ChooseBorder( 1056 result = ChooseBorder(
1108 result, 1057 result, CollapsedBorderValue(
1109 CollapsedBorderValue( 1058 curr_section->Style()->BorderBefore(),
1110 curr_section->Style()->BorderBefore(), 1059 curr_section->ResolveColor(before_color_property),
1111 include_color ? curr_section->ResolveColor(before_color_property) 1060 kBorderPrecedenceRowGroup));
1112 : Color(),
1113 kBorderPrecedenceRowGroup));
1114 if (!result.Exists()) 1061 if (!result.Exists())
1115 return result; 1062 return result;
1116 } 1063 }
1117 } 1064 }
1118 1065
1119 if (!curr_section) { 1066 if (!curr_section) {
1120 // (8) Our column and column group's after borders. 1067 // (8) Our column and column group's after borders.
1121 LayoutTableCol* col_elt = 1068 LayoutTableCol* col_elt =
1122 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex()) 1069 table->ColElementAtAbsoluteColumn(AbsoluteColumnIndex())
1123 .InnermostColOrColGroup(); 1070 .InnermostColOrColGroup();
1124 if (col_elt) { 1071 if (col_elt) {
1125 result = ChooseBorder( 1072 result = ChooseBorder(
1126 result, CollapsedBorderValue(col_elt->Style()->BorderAfter(), 1073 result,
1127 include_color ? col_elt->ResolveColor( 1074 CollapsedBorderValue(col_elt->Style()->BorderAfter(),
1128 after_color_property) 1075 col_elt->ResolveColor(after_color_property),
1129 : Color(), 1076 kBorderPrecedenceColumn));
1130 kBorderPrecedenceColumn));
1131 if (!result.Exists()) 1077 if (!result.Exists())
1132 return result; 1078 return result;
1133 if (LayoutTableCol* enclosing_column_group = 1079 if (LayoutTableCol* enclosing_column_group =
1134 col_elt->EnclosingColumnGroup()) { 1080 col_elt->EnclosingColumnGroup()) {
1135 result = ChooseBorder( 1081 result = ChooseBorder(
1136 result, CollapsedBorderValue( 1082 result,
1137 enclosing_column_group->Style()->BorderAfter(), 1083 CollapsedBorderValue(
1138 include_color ? enclosing_column_group->ResolveColor( 1084 enclosing_column_group->Style()->BorderAfter(),
wkorman 2017/04/27 20:11:15 Perhaps worth mentioning this color change in CL d
Xianzhu 2017/04/28 20:31:45 Done.
1139 after_color_property) 1085 enclosing_column_group->ResolveColor(after_color_property),
1140 : Color(), 1086 kBorderPrecedenceColumnGroup));
1141 kBorderPrecedenceColumnGroup));
1142 if (!result.Exists()) 1087 if (!result.Exists())
1143 return result; 1088 return result;
1144 } 1089 }
1145 } 1090 }
1146 1091
1147 // (9) The table's after border. 1092 // (9) The table's after border.
1148 result = ChooseBorder( 1093 result = ChooseBorder(
1149 result, 1094 result, CollapsedBorderValue(table->Style()->BorderAfter(),
1150 CollapsedBorderValue( 1095 table->ResolveColor(after_color_property),
1151 table->Style()->BorderAfter(), 1096 kBorderPrecedenceTable));
1152 include_color ? table->ResolveColor(after_color_property) : Color(),
1153 kBorderPrecedenceTable));
1154 if (!result.Exists()) 1097 if (!result.Exists())
1155 return result; 1098 return result;
1156 } 1099 }
1157 1100
1158 return result; 1101 return result;
1159 } 1102 }
1160 1103
1161 LayoutUnit LayoutTableCell::BorderLeft() const { 1104 LayoutUnit LayoutTableCell::BorderLeft() const {
1162 return Table()->CollapseBorders() ? CollapsedBorderHalfLeft(false) 1105 return Table()->CollapseBorders() ? CollapsedBorderHalfLeft(false)
1163 : LayoutBlockFlow::BorderLeft(); 1106 : LayoutBlockFlow::BorderLeft();
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1243 return style_for_cell_flow.IsFlippedBlocksWritingMode() 1186 return style_for_cell_flow.IsFlippedBlocksWritingMode()
1244 ? CollapsedBorderHalfBefore(outer) 1187 ? CollapsedBorderHalfBefore(outer)
1245 : CollapsedBorderHalfAfter(outer); 1188 : CollapsedBorderHalfAfter(outer);
1246 } 1189 }
1247 return style_for_cell_flow.IsLeftToRightDirection() 1190 return style_for_cell_flow.IsLeftToRightDirection()
1248 ? CollapsedBorderHalfEnd(outer) 1191 ? CollapsedBorderHalfEnd(outer)
1249 : CollapsedBorderHalfStart(outer); 1192 : CollapsedBorderHalfStart(outer);
1250 } 1193 }
1251 1194
1252 LayoutUnit LayoutTableCell::CollapsedBorderHalfStart(bool outer) const { 1195 LayoutUnit LayoutTableCell::CollapsedBorderHalfStart(bool outer) const {
1253 CollapsedBorderValue border = 1196 RecalcCollapsedBorderValuesIfNeeded();
1254 ComputeCollapsedStartBorder(kDoNotIncludeBorderColor); 1197 const auto* collapsed_border_values = this->GetCollapsedBorderValues();
1198 if (!collapsed_border_values)
1199 return LayoutUnit();
1200
1201 const auto& border = collapsed_border_values->StartBorder();
1255 if (border.Exists()) { 1202 if (border.Exists()) {
1256 return LayoutUnit( 1203 return LayoutUnit(
1257 (border.Width() + 1204 (border.Width() +
1258 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 1 : 0)) / 1205 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 1 : 0)) /
1259 2); // Give the extra pixel to top and left. 1206 2); // Give the extra pixel to top and left.
1260 } 1207 }
1261 return LayoutUnit(); 1208 return LayoutUnit();
1262 } 1209 }
1263 1210
1264 LayoutUnit LayoutTableCell::CollapsedBorderHalfEnd(bool outer) const { 1211 LayoutUnit LayoutTableCell::CollapsedBorderHalfEnd(bool outer) const {
1265 CollapsedBorderValue border = 1212 RecalcCollapsedBorderValuesIfNeeded();
1266 ComputeCollapsedEndBorder(kDoNotIncludeBorderColor); 1213 const auto* collapsed_border_values = this->GetCollapsedBorderValues();
1214 if (!collapsed_border_values)
1215 return LayoutUnit();
1216
1217 const auto& border = collapsed_border_values->EndBorder();
1267 if (border.Exists()) { 1218 if (border.Exists()) {
1268 return LayoutUnit( 1219 return LayoutUnit(
1269 (border.Width() + 1220 (border.Width() +
1270 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 0 : 1)) / 1221 ((StyleForCellFlow().IsLeftToRightDirection() ^ outer) ? 0 : 1)) /
1271 2); 1222 2);
1272 } 1223 }
1273 return LayoutUnit(); 1224 return LayoutUnit();
1274 } 1225 }
1275 1226
1276 LayoutUnit LayoutTableCell::CollapsedBorderHalfBefore(bool outer) const { 1227 LayoutUnit LayoutTableCell::CollapsedBorderHalfBefore(bool outer) const {
1277 CollapsedBorderValue border = 1228 RecalcCollapsedBorderValuesIfNeeded();
1278 ComputeCollapsedBeforeBorder(kDoNotIncludeBorderColor); 1229 const auto* collapsed_border_values = this->GetCollapsedBorderValues();
1230 if (!collapsed_border_values)
1231 return LayoutUnit();
1232
1233 const auto& border = collapsed_border_values->BeforeBorder();
1279 if (border.Exists()) { 1234 if (border.Exists()) {
1280 return LayoutUnit( 1235 return LayoutUnit(
1281 (border.Width() + 1236 (border.Width() +
1282 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 0 : 1)) / 1237 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 0 : 1)) /
1283 2); // Give the extra pixel to top and left. 1238 2); // Give the extra pixel to top and left.
1284 } 1239 }
1285 return LayoutUnit(); 1240 return LayoutUnit();
1286 } 1241 }
1287 1242
1288 LayoutUnit LayoutTableCell::CollapsedBorderHalfAfter(bool outer) const { 1243 LayoutUnit LayoutTableCell::CollapsedBorderHalfAfter(bool outer) const {
1289 CollapsedBorderValue border = 1244 RecalcCollapsedBorderValuesIfNeeded();
1290 ComputeCollapsedAfterBorder(kDoNotIncludeBorderColor); 1245 const auto* collapsed_border_values = this->GetCollapsedBorderValues();
1246 if (!collapsed_border_values)
1247 return LayoutUnit();
1248
1249 const auto& border = collapsed_border_values->AfterBorder();
1291 if (border.Exists()) { 1250 if (border.Exists()) {
1292 return LayoutUnit( 1251 return LayoutUnit(
1293 (border.Width() + 1252 (border.Width() +
1294 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 1 : 0)) / 1253 ((StyleForCellFlow().IsFlippedBlocksWritingMode() ^ outer) ? 1 : 0)) /
1295 2); 1254 2);
1296 } 1255 }
1297 return LayoutUnit(); 1256 return LayoutUnit();
1298 } 1257 }
1299 1258
1300 void LayoutTableCell::Paint(const PaintInfo& paint_info, 1259 void LayoutTableCell::Paint(const PaintInfo& paint_info,
1301 const LayoutPoint& paint_offset) const { 1260 const LayoutPoint& paint_offset) const {
1302 TableCellPainter(*this).Paint(paint_info, paint_offset); 1261 TableCellPainter(*this).Paint(paint_info, paint_offset);
1303 } 1262 }
1304 1263
1264 void LayoutTableCell::RecalcCollapsedBorderValuesIfNeeded() const {
wkorman 2017/04/27 20:11:15 Same as previous -- believe prefer without ...IfNe
Xianzhu 2017/04/28 20:31:44 Renamed to UpdateCollapsedBorderValues(). Simply r
1265 Table()->InvalidateCollapsedBordersForAllCellsIfNeeded();
1266 if (collapsed_border_values_valid_)
1267 return;
1268
1269 collapsed_border_values_valid_ = true;
1270
1271 if (!Table()->CollapseBorders()) {
1272 if (collapsed_border_values_) {
1273 collapsed_borders_visually_changed_ = true;
1274 collapsed_border_values_ = nullptr;
1275 }
1276 return;
1277 }
1278
1279 CollapsedBorderValues new_values(
1280 *this, ComputeCollapsedStartBorder(), ComputeCollapsedEndBorder(),
1281 ComputeCollapsedBeforeBorder(), ComputeCollapsedAfterBorder());
1282
1283 // We need to save collapsed border if has a non-zero width even if it's
1284 // invisible because the width affects table layout.
1285 if (!new_values.StartBorder().Width() && !new_values.EndBorder().Width() &&
1286 !new_values.BeforeBorder().Width() && !new_values.AfterBorder().Width()) {
1287 if (collapsed_border_values_) {
1288 collapsed_borders_visually_changed_ = true;
1289 collapsed_border_values_ = nullptr;
1290 }
1291 return;
1292 }
1293
1294 if (!collapsed_border_values_) {
1295 collapsed_borders_visually_changed_ = true;
1296 collapsed_border_values_ = WTF::WrapUnique(new CollapsedBorderValues(
1297 *this, new_values.StartBorder(), new_values.EndBorder(),
1298 new_values.BeforeBorder(), new_values.AfterBorder()));
1299 return;
1300 }
1301
1302 // We check VisuallyEquals so that the table cell is invalidated only if a
1303 // changed collapsed border is visible in the first place.
1304 if (!collapsed_border_values_->StartBorder().VisuallyEquals(
1305 new_values.StartBorder()) ||
1306 !collapsed_border_values_->EndBorder().VisuallyEquals(
1307 new_values.EndBorder()) ||
1308 !collapsed_border_values_->BeforeBorder().VisuallyEquals(
1309 new_values.BeforeBorder()) ||
1310 !collapsed_border_values_->AfterBorder().VisuallyEquals(
1311 new_values.AfterBorder())) {
1312 collapsed_border_values_->SetCollapsedBorderValues(new_values);
1313 collapsed_borders_visually_changed_ = true;
1314 }
1315 }
1316
1305 static void AddBorderStyle(LayoutTable::CollapsedBorderValues& border_values, 1317 static void AddBorderStyle(LayoutTable::CollapsedBorderValues& border_values,
1306 CollapsedBorderValue border_value) { 1318 CollapsedBorderValue border_value) {
1307 if (!border_value.IsVisible()) 1319 if (!border_value.IsVisible())
1308 return; 1320 return;
1309 size_t count = border_values.size(); 1321 size_t count = border_values.size();
1310 for (size_t i = 0; i < count; ++i) { 1322 for (size_t i = 0; i < count; ++i) {
1311 if (border_values[i].IsSameIgnoringColor(border_value)) 1323 if (border_values[i].IsSameIgnoringColor(border_value))
1312 return; 1324 return;
1313 } 1325 }
1314 border_values.push_back(border_value); 1326 border_values.push_back(border_value);
1315 } 1327 }
1316 1328
1317 void LayoutTableCell::CollectCollapsedBorderValues( 1329 void LayoutTableCell::CollectCollapsedBorderValues(
1318 LayoutTable::CollapsedBorderValues& border_values) { 1330 LayoutTable::CollapsedBorderValues& border_values) {
1319 CollapsedBorderValues new_values( 1331 RecalcCollapsedBorderValuesIfNeeded();
1320 *this, ComputeCollapsedStartBorder(), ComputeCollapsedEndBorder(),
1321 ComputeCollapsedBeforeBorder(), ComputeCollapsedAfterBorder());
1322
1323 bool changed = false;
1324 if (!new_values.StartBorder().IsVisible() &&
1325 !new_values.EndBorder().IsVisible() &&
1326 !new_values.BeforeBorder().IsVisible() &&
1327 !new_values.AfterBorder().IsVisible()) {
1328 changed = !!collapsed_border_values_;
1329 collapsed_border_values_ = nullptr;
1330 } else if (!collapsed_border_values_) {
1331 changed = true;
1332 collapsed_border_values_ = WTF::WrapUnique(new CollapsedBorderValues(
1333 *this, new_values.StartBorder(), new_values.EndBorder(),
1334 new_values.BeforeBorder(), new_values.AfterBorder()));
1335 } else {
1336 // We check visuallyEquals so that the table cell is invalidated only if a
1337 // changed collapsed border is visible in the first place.
1338 changed = !collapsed_border_values_->StartBorder().VisuallyEquals(
1339 new_values.StartBorder()) ||
1340 !collapsed_border_values_->EndBorder().VisuallyEquals(
1341 new_values.EndBorder()) ||
1342 !collapsed_border_values_->BeforeBorder().VisuallyEquals(
1343 new_values.BeforeBorder()) ||
1344 !collapsed_border_values_->AfterBorder().VisuallyEquals(
1345 new_values.AfterBorder());
1346 if (changed)
1347 collapsed_border_values_->SetCollapsedBorderValues(new_values);
1348 }
1349 1332
1350 // If collapsed borders changed, invalidate the cell's display item client on 1333 // If collapsed borders changed, invalidate the cell's display item client on
1351 // the table's backing. 1334 // the table's backing.
1352 // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders 1335 // TODO(crbug.com/451090#c5): Need a way to invalidate/repaint the borders
1353 // only. 1336 // only.
1354 if (changed) { 1337 if (collapsed_borders_visually_changed_) {
1355 ObjectPaintInvalidator(*Table()) 1338 ObjectPaintInvalidator(*Table())
1356 .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient( 1339 .SlowSetPaintingLayerNeedsRepaintAndInvalidateDisplayItemClient(
1357 *this, kPaintInvalidationStyleChange); 1340 *this, kPaintInvalidationStyleChange);
1341 collapsed_borders_visually_changed_ = false;
1358 } 1342 }
1359 1343
1360 AddBorderStyle(border_values, new_values.StartBorder()); 1344 if (!collapsed_border_values_)
1361 AddBorderStyle(border_values, new_values.EndBorder()); 1345 return;
1362 AddBorderStyle(border_values, new_values.BeforeBorder()); 1346
1363 AddBorderStyle(border_values, new_values.AfterBorder()); 1347 AddBorderStyle(border_values, collapsed_border_values_->StartBorder());
1348 AddBorderStyle(border_values, collapsed_border_values_->EndBorder());
1349 AddBorderStyle(border_values, collapsed_border_values_->BeforeBorder());
1350 AddBorderStyle(border_values, collapsed_border_values_->AfterBorder());
1364 } 1351 }
1365 1352
1366 void LayoutTableCell::SortCollapsedBorderValues( 1353 void LayoutTableCell::SortCollapsedBorderValues(
1367 LayoutTable::CollapsedBorderValues& border_values) { 1354 LayoutTable::CollapsedBorderValues& border_values) {
1368 std::sort(border_values.begin(), border_values.end(), CompareBorders); 1355 std::sort(border_values.begin(), border_values.end(), CompareBorders);
1369 } 1356 }
1370 1357
1371 void LayoutTableCell::PaintBoxDecorationBackground( 1358 void LayoutTableCell::PaintBoxDecorationBackground(
1372 const PaintInfo& paint_info, 1359 const PaintInfo& paint_info,
1373 const LayoutPoint& paint_offset) const { 1360 const LayoutPoint& paint_offset) const {
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 } 1472 }
1486 1473
1487 bool LayoutTableCell::HasLineIfEmpty() const { 1474 bool LayoutTableCell::HasLineIfEmpty() const {
1488 if (GetNode() && HasEditableStyle(*GetNode())) 1475 if (GetNode() && HasEditableStyle(*GetNode()))
1489 return true; 1476 return true;
1490 1477
1491 return LayoutBlock::HasLineIfEmpty(); 1478 return LayoutBlock::HasLineIfEmpty();
1492 } 1479 }
1493 1480
1494 } // namespace blink 1481 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698