nsTableColFrame.h (9811B)
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 #ifndef nsTableColFrame_h__ 6 #define nsTableColFrame_h__ 7 8 #include "celldata.h" 9 #include "mozilla/WritingModes.h" 10 #include "nsContainerFrame.h" 11 #include "nsTArray.h" 12 #include "nsTableColGroupFrame.h" 13 #include "nscore.h" 14 15 namespace mozilla { 16 class PresShell; 17 } // namespace mozilla 18 19 class nsTableColFrame final : public nsSplittableFrame { 20 public: 21 NS_DECL_FRAMEARENA_HELPERS(nsTableColFrame) 22 23 enum { 24 eWIDTH_SOURCE_NONE = 0, // no cell has contributed to the width style 25 eWIDTH_SOURCE_CELL = 1, // a cell specified a width 26 eWIDTH_SOURCE_CELL_WITH_SPAN = 2 // a cell implicitly specified a width via 27 // colspan 28 }; 29 30 nsTableColType GetColType() const; 31 void SetColType(nsTableColType aType); 32 33 /** 34 * instantiate a new instance of nsTableRowFrame. 35 * 36 * @param aPresShell the pres shell for this frame 37 * 38 * @return the frame that was created 39 */ 40 friend nsTableColFrame* NS_NewTableColFrame(mozilla::PresShell* aPresShell, 41 ComputedStyle* aContext); 42 43 // nsIFrame overrides 44 void Init(nsIContent* aContent, nsContainerFrame* aParent, 45 nsIFrame* aPrevInFlow) override { 46 nsSplittableFrame::Init(aContent, aParent, aPrevInFlow); 47 if (!aPrevInFlow) { 48 mWritingMode = GetTableFrame()->GetWritingMode(); 49 } 50 } 51 52 /** @see nsIFrame::DidSetComputedStyle */ 53 void DidSetComputedStyle(ComputedStyle* aOldComputedStyle) override; 54 55 void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, 56 const ReflowInput& aReflowInput, 57 nsReflowStatus& aStatus) override; 58 59 void BuildDisplayList(nsDisplayListBuilder* aBuilder, 60 const nsDisplayListSet& aLists) override; 61 62 #ifdef DEBUG_FRAME_DUMP 63 nsresult GetFrameName(nsAString& aResult) const override; 64 #endif 65 66 nsTableColGroupFrame* GetTableColGroupFrame() const { 67 nsIFrame* parent = GetParent(); 68 MOZ_ASSERT(parent && parent->IsTableColGroupFrame()); 69 return static_cast<nsTableColGroupFrame*>(parent); 70 } 71 72 nsTableFrame* GetTableFrame() const { 73 return GetTableColGroupFrame()->GetTableFrame(); 74 } 75 76 int32_t GetColIndex() const; 77 78 void SetColIndex(int32_t aColIndex); 79 80 nsTableColFrame* GetNextCol() const; 81 82 /** return the number of the columns the col represents. always >= 1 */ 83 int32_t GetSpan(); 84 85 /** convenience method, calls into cellmap */ 86 int32_t Count() const; 87 88 nscoord GetIStartBorderWidth() const { return mIStartBorderWidth; } 89 nscoord GetIEndBorderWidth() const { return mIEndBorderWidth; } 90 void SetIStartBorderWidth(nscoord aWidth) { mIStartBorderWidth = aWidth; } 91 void SetIEndBorderWidth(nscoord aWidth) { mIEndBorderWidth = aWidth; } 92 93 #ifdef DEBUG 94 void Dump(int32_t aIndent); 95 #endif 96 97 /** 98 * Restore the default values of the intrinsic widths, so that we can 99 * re-accumulate intrinsic widths from the cells in the column. 100 */ 101 void ResetIntrinsics() { 102 mMinCoord = 0; 103 mPrefCoord = 0; 104 mPrefPercent = 0.0f; 105 mHasSpecifiedCoord = false; 106 } 107 108 /** 109 * Restore the default value of the preferred percentage width (the 110 * only intrinsic width used by FixedTableLayoutStrategy. 111 */ 112 void ResetPrefPercent() { mPrefPercent = 0.0f; } 113 114 /** 115 * Restore the default values of the temporary buffer for 116 * spanning-cell intrinsic widths (as we process spanning cells). 117 */ 118 void ResetSpanIntrinsics() { 119 mSpanMinCoord = 0; 120 mSpanPrefCoord = 0; 121 mSpanPrefPercent = 0.0f; 122 } 123 124 /** 125 * Add the widths for a cell or column element, or the contribution of 126 * the widths from a column-spanning cell: 127 * @param aMinCoord The minimum intrinsic width 128 * @param aPrefCoord The preferred intrinsic width or, if there is a 129 * specified non-percentage width, max(specified width, minimum intrinsic 130 * width). 131 * @param aHasSpecifiedCoord Whether there is a specified 132 * non-percentage width. 133 * 134 * Note that the implementation of this functions is a bit tricky 135 * since mPrefCoord means different things depending on 136 * whether mHasSpecifiedCoord is true (and likewise for aPrefCoord and 137 * aHasSpecifiedCoord). If mHasSpecifiedCoord is false, then 138 * all widths added had aHasSpecifiedCoord false and mPrefCoord is the 139 * largest of the pref widths. But if mHasSpecifiedCoord is true, 140 * then mPrefCoord is the largest of (1) the pref widths for cells 141 * with aHasSpecifiedCoord true and (2) the min widths for cells with 142 * aHasSpecifiedCoord false. 143 */ 144 void AddCoords(nscoord aMinCoord, nscoord aPrefCoord, 145 bool aHasSpecifiedCoord) { 146 NS_ASSERTION(aMinCoord <= aPrefCoord, "intrinsic widths out of order"); 147 148 if (aHasSpecifiedCoord && !mHasSpecifiedCoord) { 149 mPrefCoord = mMinCoord; 150 mHasSpecifiedCoord = true; 151 } 152 if (!aHasSpecifiedCoord && mHasSpecifiedCoord) { 153 aPrefCoord = aMinCoord; // NOTE: modifying argument 154 } 155 156 if (aMinCoord > mMinCoord) { 157 mMinCoord = aMinCoord; 158 } 159 if (aPrefCoord > mPrefCoord) { 160 mPrefCoord = aPrefCoord; 161 } 162 163 NS_ASSERTION(mMinCoord <= mPrefCoord, "min larger than pref"); 164 } 165 166 /** 167 * Add a percentage width specified on a cell or column element or the 168 * contribution to this column of a percentage width specified on a 169 * column-spanning cell. 170 */ 171 void AddPrefPercent(float aPrefPercent) { 172 if (aPrefPercent > mPrefPercent) { 173 mPrefPercent = aPrefPercent; 174 } 175 } 176 177 /** 178 * Get the largest minimum intrinsic width for this column. 179 */ 180 nscoord GetMinCoord() const { return mMinCoord; } 181 /** 182 * Get the largest preferred width for this column, or, if there were 183 * any specified non-percentage widths (see GetHasSpecifiedCoord), the 184 * largest minimum intrinsic width or specified width. 185 */ 186 nscoord GetPrefCoord() const { return mPrefCoord; } 187 /** 188 * Get whether there were any specified widths contributing to this 189 * column. 190 */ 191 bool GetHasSpecifiedCoord() const { return mHasSpecifiedCoord; } 192 193 /** 194 * Get the largest specified percentage width contributing to this 195 * column (returns 0 if there were none). 196 */ 197 float GetPrefPercent() const { return mPrefPercent; } 198 199 /** 200 * Like AddCoords, but into a temporary buffer used for groups of 201 * column-spanning cells. 202 */ 203 void AddSpanCoords(nscoord aSpanMinCoord, nscoord aSpanPrefCoord, 204 bool aSpanHasSpecifiedCoord) { 205 NS_ASSERTION(aSpanMinCoord <= aSpanPrefCoord, 206 "intrinsic widths out of order"); 207 208 if (!aSpanHasSpecifiedCoord && mHasSpecifiedCoord) { 209 aSpanPrefCoord = aSpanMinCoord; // NOTE: modifying argument 210 } 211 212 if (aSpanMinCoord > mSpanMinCoord) { 213 mSpanMinCoord = aSpanMinCoord; 214 } 215 if (aSpanPrefCoord > mSpanPrefCoord) { 216 mSpanPrefCoord = aSpanPrefCoord; 217 } 218 219 NS_ASSERTION(mSpanMinCoord <= mSpanPrefCoord, "min larger than pref"); 220 } 221 222 /* 223 * Accumulate percentage widths on column spanning cells into 224 * temporary variables. 225 */ 226 void AddSpanPrefPercent(float aSpanPrefPercent) { 227 if (aSpanPrefPercent > mSpanPrefPercent) { 228 mSpanPrefPercent = aSpanPrefPercent; 229 } 230 } 231 232 /* 233 * Accumulate the temporary variables for column spanning cells into 234 * the primary variables. 235 */ 236 void AccumulateSpanIntrinsics() { 237 AddCoords(mSpanMinCoord, mSpanPrefCoord, mHasSpecifiedCoord); 238 AddPrefPercent(mSpanPrefPercent); 239 } 240 241 // Used to adjust a column's pref percent so that the table's total 242 // never exceeeds 100% (by only allowing percentages to be used, 243 // starting at the first column, until they reach 100%). 244 void AdjustPrefPercent(float* aTableTotalPercent) { 245 float allowed = 1.0f - *aTableTotalPercent; 246 if (mPrefPercent > allowed) { 247 mPrefPercent = allowed; 248 } 249 *aTableTotalPercent += mPrefPercent; 250 } 251 252 // The final width of the column. 253 void ResetFinalISize() { 254 mFinalISize = nscoord_MIN; // so we detect that it changed 255 } 256 void SetFinalISize(nscoord aFinalISize) { mFinalISize = aFinalISize; } 257 nscoord GetFinalISize() { return mFinalISize; } 258 259 void InvalidateFrame(uint32_t aDisplayItemKey = 0, 260 bool aRebuildDisplayItems = true) override; 261 void InvalidateFrameWithRect(const nsRect& aRect, 262 uint32_t aDisplayItemKey = 0, 263 bool aRebuildDisplayItems = true) override; 264 void InvalidateFrameForRemoval() override { InvalidateFrameSubtree(); } 265 266 protected: 267 explicit nsTableColFrame(ComputedStyle* aStyle, nsPresContext* aPresContext); 268 ~nsTableColFrame(); 269 270 nscoord mMinCoord; 271 nscoord mPrefCoord; 272 nscoord mSpanMinCoord; // XXX... 273 nscoord mSpanPrefCoord; // XXX... 274 float mPrefPercent; 275 float mSpanPrefPercent; // XXX... 276 // ...XXX the four members marked above could be allocated as part of 277 // a separate array allocated only during 278 // BasicTableLayoutStrategy::ComputeColumnIntrinsicISizes (and only 279 // when colspans were present). 280 nscoord mFinalISize; 281 282 // the index of the column with respect to the whole table (starting at 0) 283 // it should never be smaller then the start column index of the parent 284 // colgroup 285 uint32_t mColIndex; 286 287 // border widths of the inner half of the border only 288 nscoord mIStartBorderWidth; 289 nscoord mIEndBorderWidth; 290 291 bool mHasSpecifiedCoord; 292 }; 293 294 inline int32_t nsTableColFrame::GetColIndex() const { return mColIndex; } 295 296 inline void nsTableColFrame::SetColIndex(int32_t aColIndex) { 297 mColIndex = aColIndex; 298 } 299 300 #endif