nsTableColFrame.cpp (6625B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 #include "nsTableColFrame.h" 6 7 #include "mozilla/ComputedStyle.h" 8 #include "mozilla/PresShell.h" 9 #include "mozilla/StaticPrefs_layout.h" 10 #include "nsCOMPtr.h" 11 #include "nsCSSRendering.h" 12 #include "nsContainerFrame.h" 13 #include "nsGkAtoms.h" 14 #include "nsIContent.h" 15 #include "nsPresContext.h" 16 #include "nsStyleConsts.h" 17 #include "nsTableFrame.h" 18 19 using namespace mozilla; 20 21 #define COL_TYPE_BITS \ 22 (NS_FRAME_STATE_BIT(28) | NS_FRAME_STATE_BIT(29) | NS_FRAME_STATE_BIT(30) | \ 23 NS_FRAME_STATE_BIT(31)) 24 #define COL_TYPE_OFFSET 28 25 26 using namespace mozilla; 27 28 nsTableColFrame::nsTableColFrame(ComputedStyle* aStyle, 29 nsPresContext* aPresContext) 30 : nsSplittableFrame(aStyle, aPresContext, kClassID), 31 mMinCoord(0), 32 mPrefCoord(0), 33 mSpanMinCoord(0), 34 mSpanPrefCoord(0), 35 mPrefPercent(0.0f), 36 mSpanPrefPercent(0.0f), 37 mFinalISize(0), 38 mColIndex(0), 39 mIStartBorderWidth(0), 40 mIEndBorderWidth(0), 41 mHasSpecifiedCoord(false) { 42 SetColType(eColContent); 43 ResetIntrinsics(); 44 ResetSpanIntrinsics(); 45 ResetFinalISize(); 46 } 47 48 nsTableColFrame::~nsTableColFrame() = default; 49 50 nsTableColType nsTableColFrame::GetColType() const { 51 return (nsTableColType)((GetStateBits() & COL_TYPE_BITS) >> COL_TYPE_OFFSET); 52 } 53 54 void nsTableColFrame::SetColType(nsTableColType aType) { 55 NS_ASSERTION(aType != eColAnonymousCol || 56 (GetPrevContinuation() && 57 GetPrevContinuation()->GetNextContinuation() == this && 58 GetPrevContinuation()->GetNextSibling() == this), 59 "spanned content cols must be continuations"); 60 uint32_t type = aType - eColContent; 61 RemoveStateBits(COL_TYPE_BITS); 62 AddStateBits(nsFrameState(type << COL_TYPE_OFFSET)); 63 } 64 65 /* virtual */ 66 void nsTableColFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) { 67 nsSplittableFrame::DidSetComputedStyle(aOldComputedStyle); 68 69 if (!aOldComputedStyle) { // avoid this on init 70 return; 71 } 72 73 nsTableFrame* tableFrame = GetTableFrame(); 74 if (tableFrame->IsBorderCollapse() && 75 tableFrame->BCRecalcNeeded(aOldComputedStyle, Style())) { 76 TableArea damageArea(GetColIndex(), 0, 1, tableFrame->GetRowCount()); 77 tableFrame->AddBCDamageArea(damageArea); 78 } 79 } 80 81 void nsTableColFrame::Reflow(nsPresContext* aPresContext, 82 ReflowOutput& aDesiredSize, 83 const ReflowInput& aReflowInput, 84 nsReflowStatus& aStatus) { 85 MarkInReflow(); 86 DO_GLOBAL_REFLOW_COUNT("nsTableColFrame"); 87 MOZ_ASSERT(aStatus.IsEmpty(), "Caller should pass a fresh reflow status!"); 88 aDesiredSize.ClearSize(); 89 const nsStyleVisibility* colVis = StyleVisibility(); 90 bool collapseCol = StyleVisibility::Collapse == colVis->mVisible; 91 if (collapseCol) { 92 GetTableFrame()->SetNeedToCollapse(true); 93 } 94 } 95 96 void nsTableColFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, 97 const nsDisplayListSet& aLists) { 98 // Per https://drafts.csswg.org/css-tables-3/#global-style-overrides: 99 // "All css properties of table-column and table-column-group boxes are 100 // ignored, except when explicitly specified by this specification." 101 // CSS outlines and box-shadows fall into this category, so we skip them 102 // on these boxes. 103 MOZ_ASSERT_UNREACHABLE("Cols don't paint themselves"); 104 } 105 106 int32_t nsTableColFrame::GetSpan() { return StyleTable()->mXSpan; } 107 108 #ifdef DEBUG 109 void nsTableColFrame::Dump(int32_t aIndent) { 110 char* indent = new char[aIndent + 1]; 111 if (!indent) return; 112 for (int32_t i = 0; i < aIndent + 1; i++) { 113 indent[i] = ' '; 114 } 115 indent[aIndent] = 0; 116 117 printf("%s**START COL DUMP**\n%s colIndex=%d coltype=", indent, indent, 118 mColIndex); 119 nsTableColType colType = GetColType(); 120 switch (colType) { 121 case eColContent: 122 printf(" content "); 123 break; 124 case eColAnonymousCol: 125 printf(" anonymous-column "); 126 break; 127 case eColAnonymousColGroup: 128 printf(" anonymous-colgroup "); 129 break; 130 case eColAnonymousCell: 131 printf(" anonymous-cell "); 132 break; 133 } 134 printf("\nm:%d c:%d(%c) p:%f sm:%d sc:%d sp:%f f:%d", int32_t(mMinCoord), 135 int32_t(mPrefCoord), mHasSpecifiedCoord ? 's' : 'u', mPrefPercent, 136 int32_t(mSpanMinCoord), int32_t(mSpanPrefCoord), mSpanPrefPercent, 137 int32_t(GetFinalISize())); 138 printf("\n%s**END COL DUMP** ", indent); 139 delete[] indent; 140 } 141 #endif 142 /* ----- global methods ----- */ 143 144 nsTableColFrame* NS_NewTableColFrame(PresShell* aPresShell, 145 ComputedStyle* aStyle) { 146 return new (aPresShell) nsTableColFrame(aStyle, aPresShell->GetPresContext()); 147 } 148 149 NS_IMPL_FRAMEARENA_HELPERS(nsTableColFrame) 150 151 nsTableColFrame* nsTableColFrame::GetNextCol() const { 152 nsIFrame* childFrame = GetNextSibling(); 153 while (childFrame) { 154 if (childFrame->IsTableColFrame()) { 155 return (nsTableColFrame*)childFrame; 156 } 157 childFrame = childFrame->GetNextSibling(); 158 } 159 return nullptr; 160 } 161 162 #ifdef DEBUG_FRAME_DUMP 163 nsresult nsTableColFrame::GetFrameName(nsAString& aResult) const { 164 return MakeFrameName(u"TableCol"_ns, aResult); 165 } 166 #endif 167 168 void nsTableColFrame::InvalidateFrame(uint32_t aDisplayItemKey, 169 bool aRebuildDisplayItems) { 170 nsIFrame::InvalidateFrame(aDisplayItemKey, aRebuildDisplayItems); 171 if (GetTableFrame()->IsBorderCollapse()) { 172 const bool rebuild = StaticPrefs::layout_display_list_retain_sc(); 173 GetParent()->InvalidateFrameWithRect(InkOverflowRect() + GetPosition(), 174 aDisplayItemKey, rebuild); 175 } 176 } 177 178 void nsTableColFrame::InvalidateFrameWithRect(const nsRect& aRect, 179 uint32_t aDisplayItemKey, 180 bool aRebuildDisplayItems) { 181 nsIFrame::InvalidateFrameWithRect(aRect, aDisplayItemKey, 182 aRebuildDisplayItems); 183 184 // If we have filters applied that would affects our bounds, then 185 // we get an inactive layer created and this is computed 186 // within FrameLayerBuilder 187 GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey, 188 aRebuildDisplayItems); 189 }