Bug 1903805 - Added additional allowed characters to search-config-icons-schema.json...
[gecko.git] / layout / tables / celldata.h
blobc365bdae51570b35bcb897a8b294987cf0b02d17
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 CellData_h__
6 #define CellData_h__
8 #include "nsISupports.h"
9 #include "nsITableCellLayout.h" // for MAX_COLSPAN / MAX_ROWSPAN
10 #include "nsCoord.h"
11 #include "mozilla/gfx/Types.h"
12 #include "mozilla/WritingModes.h"
13 #include <stdint.h>
15 class nsTableCellFrame;
16 class nsCellMap;
17 class BCCellData;
19 /**
20 * Data stored by nsCellMap to rationalize rowspan and colspan cells.
22 class CellData {
23 public:
24 /** Initialize the mOrigCell pointer
25 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
27 void Init(nsTableCellFrame* aCellFrame);
29 /** does a cell originate from here
30 * @return is true if a cell corresponds to this cellmap entry
32 bool IsOrig() const;
34 /** is the celldata valid
35 * @return is true if no cell originates and the cell is not spanned by
36 * a row- or colspan. mBits are 0 in this case and mOrigCell is
37 * nullptr
39 bool IsDead() const;
41 /** is the entry spanned by row- or a colspan
42 * @return is true if the entry is spanned by a row- or colspan
44 bool IsSpan() const;
46 /** is the entry spanned by rowspan
47 * @return is true if the entry is spanned by a rowspan
49 bool IsRowSpan() const;
51 /** is the entry spanned by a zero rowspan
52 * zero rowspans span all cells starting from the originating cell down to
53 * the end of the rowgroup or a cell originating in the same column
54 * @return is true if the entry is spanned by a zero rowspan
56 bool IsZeroRowSpan() const;
58 /** mark the current entry as spanned by a zero rowspan
59 * @param aIsZero if true mark the entry as covered by a zero rowspan
61 void SetZeroRowSpan(bool aIsZero);
63 /** get the distance from the current entry to the corresponding origin of the
64 * rowspan
65 * @return containing the distance in the column to the originating cell
67 uint32_t GetRowSpanOffset() const;
69 /** set the distance from the current entry to the corresponding origin of
70 * the rowspan
71 * @param the distance in the column to the originating cell
73 void SetRowSpanOffset(uint32_t aSpan);
75 /** is the entry spanned by colspan
76 * @return is true if the entry is spanned by a colspan
78 bool IsColSpan() const;
80 /** get the distance from the current entry to the corresponding origin of
81 * the colspan
82 * @return containing the distance in the row to the originating cell
84 uint32_t GetColSpanOffset() const;
86 /** set the distance from the current entry to the corresponding origin of the
87 * colspan
88 * @param the distance in the column to the originating cell
90 void SetColSpanOffset(uint32_t aSpan);
92 /** is the entry spanned by a row- and a colspan
93 * @return is true if the entry is spanned by a row- and a colspan
95 bool IsOverlap() const;
97 /** mark the current entry as spanned by a row- and a colspan
98 * @param aOverlap if true mark the entry as covered by a row- and
99 * a colspan
101 void SetOverlap(bool aOverlap);
103 /** get the table cell frame for this entry
104 * @return a pointer to the cellframe, this will be nullptr when the entry
105 * is only a spanned entry
107 nsTableCellFrame* GetCellFrame() const;
109 private:
110 friend class nsCellMap;
111 friend class BCCellData;
114 * Implemented in nsCellMap.cpp
116 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
118 explicit CellData(nsTableCellFrame* aOrigCell);
120 ~CellData(); // implemented in nsCellMap.cpp
122 protected:
123 // this union relies on the assumption that an object (not primitive type)
124 // does not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in
125 // effect and the data does not represent a span. If mSpan is 1, then mBits is
126 // in effect and the data represents a span. mBits must match the size of
127 // mOrigCell on both 32- and 64-bit platforms.
128 union {
129 nsTableCellFrame* mOrigCell;
130 uintptr_t mBits;
134 // Border Collapsing Cell Data
135 enum BCBorderOwner {
136 eTableOwner = 0,
137 eColGroupOwner = 1,
138 eAjaColGroupOwner = 2, // col group to the left
139 eColOwner = 3,
140 eAjaColOwner = 4, // col to the left
141 eRowGroupOwner = 5,
142 eAjaRowGroupOwner = 6, // row group above
143 eRowOwner = 7,
144 eAjaRowOwner = 8, // row above
145 eCellOwner = 9,
146 eAjaCellOwner = 10 // cell to the top or to the left
149 // These are the max sizes that are stored. If they are exceeded, then the max
150 // is stored and the actual value is computed when needed.
151 #define MAX_BORDER_WIDTH nscoord((1u << (sizeof(uint16_t) * 8)) - 1)
153 // The half of border on inline/block-axis start side
154 static inline nscoord BC_BORDER_START_HALF(nscoord aCoord) {
155 return aCoord - aCoord / 2;
157 // The half of border on inline/block-axis end side
158 static inline nscoord BC_BORDER_END_HALF(nscoord aCoord) { return aCoord / 2; }
160 // BCData stores the bstart and istart border info and the corner connecting the
161 // two.
162 class BCData {
163 public:
164 BCData();
166 ~BCData();
168 nscoord GetIStartEdge(BCBorderOwner& aOwner, bool& aStart) const;
170 void SetIStartEdge(BCBorderOwner aOwner, nscoord aSize, bool aStart);
172 nscoord GetBStartEdge(BCBorderOwner& aOwner, bool& aStart) const;
174 void SetBStartEdge(BCBorderOwner aOwner, nscoord aSize, bool aStart);
176 nscoord GetCorner(mozilla::LogicalSide& aOwnerSide, bool& aBevel) const;
178 void SetCorner(nscoord aSubSize, mozilla::LogicalSide aOwner, bool aBevel);
180 inline bool IsIStartStart() const { return (bool)mIStartStart; }
182 inline void SetIStartStart(bool aValue) { mIStartStart = aValue; }
184 inline bool IsBStartStart() const { return (bool)mBStartStart; }
186 inline void SetBStartStart(bool aValue) { mBStartStart = aValue; }
188 protected:
189 nscoord mIStartSize; // size of iStart border
190 nscoord mBStartSize; // size of bStart border
191 nscoord mCornerSubSize; // size of the largest border not in the
192 // dominant plane (for example, if corner is
193 // owned by the segment to its bStart or bEnd,
194 // then the size is the max of the border
195 // sizes of the segments to its iStart or iEnd.
196 unsigned mIStartOwner : 4; // owner of iStart border
197 unsigned mBStartOwner : 4; // owner of bStart border
198 unsigned mIStartStart : 1; // set if this is the start of a block-dir border
199 // segment
200 unsigned mBStartStart : 1; // set if this is the start of an inline-dir
201 // border segment
202 unsigned mCornerSide : 2; // LogicalSide of the owner of the bStart-iStart
203 // corner relative to the corner
204 unsigned mCornerBevel : 1; // is the corner beveled (only two segments,
205 // perpendicular, not dashed or dotted).
208 // BCCellData entries replace CellData entries in the cell map if the border
209 // collapsing model is in effect. BCData for a row and col entry contains the
210 // left and top borders of cell at that row and col and the corner connecting
211 // the two. The right borders of the cells in the last col and the bottom
212 // borders of the last row are stored in separate BCData entries in the cell
213 // map.
214 class BCCellData : public CellData {
215 public:
216 explicit BCCellData(nsTableCellFrame* aOrigCell);
217 ~BCCellData();
219 BCData mData;
222 // The layout of a celldata is as follows. The top 10 bits are the colspan
223 // offset (which is enough to represent our allowed values 1-1000 for colspan).
224 // Then there are two bits of flags.
225 // XXXmats Then one unused bit that we should decide how to use in bug 862624.
226 // Then 16 bits of rowspan offset (which
227 // lets us represent numbers up to 65535. Then another 3 bits of flags.
229 // num bits to shift right to get right aligned col span
230 #define COL_SPAN_SHIFT 22
231 // num bits to shift right to get right aligned row span
232 #define ROW_SPAN_SHIFT 3
234 // the col offset to the data containing the original cell.
235 #define COL_SPAN_OFFSET (0x3FF << COL_SPAN_SHIFT)
236 // the row offset to the data containing the original cell
237 #define ROW_SPAN_OFFSET (0xFFFF << ROW_SPAN_SHIFT)
239 // And the flags
240 #define SPAN 0x00000001 // there a row or col span
241 #define ROW_SPAN 0x00000002 // there is a row span
242 #define ROW_SPAN_0 0x00000004 // the row span is 0
243 #define COL_SPAN (1 << (COL_SPAN_SHIFT - 2)) // there is a col span
244 #define OVERLAP \
245 (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
246 // col span but not by
247 // same cell
249 inline nsTableCellFrame* CellData::GetCellFrame() const {
250 if (SPAN != (SPAN & mBits)) {
251 return mOrigCell;
253 return nullptr;
256 inline void CellData::Init(nsTableCellFrame* aCellFrame) {
257 mOrigCell = aCellFrame;
260 inline bool CellData::IsOrig() const {
261 return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits)));
264 inline bool CellData::IsDead() const { return (0 == mBits); }
266 inline bool CellData::IsSpan() const { return (SPAN == (SPAN & mBits)); }
268 inline bool CellData::IsRowSpan() const {
269 return (SPAN == (SPAN & mBits)) && (ROW_SPAN == (ROW_SPAN & mBits));
272 inline bool CellData::IsZeroRowSpan() const {
273 return (SPAN == (SPAN & mBits)) && (ROW_SPAN == (ROW_SPAN & mBits)) &&
274 (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
277 inline void CellData::SetZeroRowSpan(bool aIsZeroSpan) {
278 if (SPAN == (SPAN & mBits)) {
279 if (aIsZeroSpan) {
280 mBits |= ROW_SPAN_0;
281 } else {
282 mBits &= ~ROW_SPAN_0;
287 inline uint32_t CellData::GetRowSpanOffset() const {
288 if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
289 return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
291 return 0;
294 inline void CellData::SetRowSpanOffset(uint32_t aSpan) {
295 mBits &= ~ROW_SPAN_OFFSET;
296 mBits |= (aSpan << ROW_SPAN_SHIFT);
297 mBits |= SPAN;
298 mBits |= ROW_SPAN;
301 inline bool CellData::IsColSpan() const {
302 return (SPAN == (SPAN & mBits)) && (COL_SPAN == (COL_SPAN & mBits));
305 inline uint32_t CellData::GetColSpanOffset() const {
306 if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
307 return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
309 return 0;
312 inline void CellData::SetColSpanOffset(uint32_t aSpan) {
313 mBits &= ~COL_SPAN_OFFSET;
314 mBits |= (aSpan << COL_SPAN_SHIFT);
316 mBits |= SPAN;
317 mBits |= COL_SPAN;
320 inline bool CellData::IsOverlap() const {
321 return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
324 inline void CellData::SetOverlap(bool aOverlap) {
325 if (SPAN == (SPAN & mBits)) {
326 if (aOverlap) {
327 mBits |= OVERLAP;
328 } else {
329 mBits &= ~OVERLAP;
334 inline BCData::BCData() {
335 mIStartOwner = mBStartOwner = eCellOwner;
336 SetBStartStart(true);
337 SetIStartStart(true);
338 mIStartSize = mCornerSubSize = mBStartSize = 0;
339 mCornerSide = static_cast<uint8_t>(mozilla::LogicalSide::BStart);
340 mCornerBevel = false;
343 inline BCData::~BCData() = default;
345 inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner,
346 bool& aStart) const {
347 aOwner = (BCBorderOwner)mIStartOwner;
348 aStart = IsIStartStart();
350 return (nscoord)mIStartSize;
353 inline void BCData::SetIStartEdge(BCBorderOwner aOwner, nscoord aSize,
354 bool aStart) {
355 mIStartOwner = aOwner;
356 mIStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
357 SetIStartStart(aStart);
360 inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner,
361 bool& aStart) const {
362 aOwner = (BCBorderOwner)mBStartOwner;
363 aStart = IsBStartStart();
365 return (nscoord)mBStartSize;
368 inline void BCData::SetBStartEdge(BCBorderOwner aOwner, nscoord aSize,
369 bool aStart) {
370 mBStartOwner = aOwner;
371 mBStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
372 SetBStartStart(aStart);
375 inline nscoord BCData::GetCorner(mozilla::LogicalSide& aOwnerSide,
376 bool& aBevel) const {
377 aOwnerSide = mozilla::LogicalSide(mCornerSide);
378 aBevel = (bool)mCornerBevel;
379 return mCornerSubSize;
382 inline void BCData::SetCorner(nscoord aSubSize, mozilla::LogicalSide aOwnerSide,
383 bool aBevel) {
384 mCornerSubSize = aSubSize;
385 mCornerSide = static_cast<uint8_t>(aOwnerSide);
386 mCornerBevel = aBevel;
389 #endif