Bumping manifests a=b2g-bump
[gecko.git] / layout / tables / celldata.h
blob4a225928e28932304f09ea73a1841b9f59d70c87
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 "nsCoord.h"
10 #include "mozilla/gfx/Types.h"
11 #include <stdint.h>
13 class nsTableCellFrame;
14 class nsCellMap;
15 class BCCellData;
18 #define MAX_ROWSPAN 65534 // the cellmap can not handle more.
19 #define MAX_COLSPAN 1000 // limit as IE and opera do. If this ever changes,
20 // change COL_SPAN_OFFSET/COL_SPAN_SHIFT accordingly.
22 /**
23 * Data stored by nsCellMap to rationalize rowspan and colspan cells.
25 class CellData
27 public:
28 /** Initialize the mOrigCell pointer
29 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
31 void Init(nsTableCellFrame* aCellFrame);
33 /** does a cell originate from here
34 * @return is true if a cell corresponds to this cellmap entry
36 bool IsOrig() const;
38 /** is the celldata valid
39 * @return is true if no cell originates and the cell is not spanned by
40 * a row- or colspan. mBits are 0 in this case and mOrigCell is
41 * nullptr
43 bool IsDead() const;
45 /** is the entry spanned by row- or a colspan
46 * @return is true if the entry is spanned by a row- or colspan
48 bool IsSpan() const;
50 /** is the entry spanned by rowspan
51 * @return is true if the entry is spanned by a rowspan
53 bool IsRowSpan() const;
55 /** is the entry spanned by a zero rowspan
56 * zero rowspans span all cells starting from the originating cell down to
57 * the end of the rowgroup or a cell originating in the same column
58 * @return is true if the entry is spanned by a zero rowspan
60 bool IsZeroRowSpan() const;
62 /** mark the current entry as spanned by a zero rowspan
63 * @param aIsZero if true mark the entry as covered by a zero rowspan
65 void SetZeroRowSpan(bool aIsZero);
67 /** get the distance from the current entry to the corresponding origin of the rowspan
68 * @return containing the distance in the column to the originating cell
70 uint32_t GetRowSpanOffset() const;
72 /** set the distance from the current entry to the corresponding origin of the rowspan
73 * @param the distance in the column to the originating cell
75 void SetRowSpanOffset(uint32_t aSpan);
77 /** is the entry spanned by colspan
78 * @return is true if the entry is spanned by a colspan
80 bool IsColSpan() const;
82 /** is the entry spanned by a zero colspan
83 * zero colspans span all cells starting from the originating cell towards
84 * the end of the colgroup or a cell originating in the same row
85 * or a rowspanned entry
86 * @return is true if the entry is spanned by a zero colspan
88 bool IsZeroColSpan() const;
90 /** mark the current entry as spanned by a zero colspan
91 * @param aIsZero if true mark the entry as covered by a zero colspan
93 void SetZeroColSpan(bool aIsZero);
95 /** get the distance from the current entry to the corresponding origin of the colspan
96 * @return containing the distance in the row to the originating cell
98 uint32_t GetColSpanOffset() const;
100 /** set the distance from the current entry to the corresponding origin of the colspan
101 * @param the distance in the column to the originating cell
103 void SetColSpanOffset(uint32_t aSpan);
105 /** is the entry spanned by a row- and a colspan
106 * @return is true if the entry is spanned by a row- and a colspan
108 bool IsOverlap() const;
110 /** mark the current entry as spanned by a row- and a colspan
111 * @param aOverlap if true mark the entry as covered by a row- and a colspan
113 void SetOverlap(bool aOverlap);
115 /** get the table cell frame for this entry
116 * @return a pointer to the cellframe, this will be nullptr when the entry
117 * is only a spanned entry
119 nsTableCellFrame* GetCellFrame() const;
121 private:
122 friend class nsCellMap;
123 friend class BCCellData;
125 /** constructor.
126 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
128 explicit CellData(nsTableCellFrame* aOrigCell); // implemented in nsCellMap.cpp
130 /** destructor */
131 ~CellData(); // implemented in nsCellMap.cpp
133 protected:
135 // this union relies on the assumption that an object (not primitive type) does
136 // not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in effect
137 // and the data does not represent a span. If mSpan is 1, then mBits is in
138 // effect and the data represents a span.
139 // mBits must match the size of mOrigCell on both 32- and 64-bit platforms.
140 union {
141 nsTableCellFrame* mOrigCell;
142 uintptr_t mBits;
146 // Border Collapsing Cell Data
147 enum BCBorderOwner
149 eTableOwner = 0,
150 eColGroupOwner = 1,
151 eAjaColGroupOwner = 2, // col group to the left
152 eColOwner = 3,
153 eAjaColOwner = 4, // col to the left
154 eRowGroupOwner = 5,
155 eAjaRowGroupOwner = 6, // row group above
156 eRowOwner = 7,
157 eAjaRowOwner = 8, // row above
158 eCellOwner = 9,
159 eAjaCellOwner = 10 // cell to the top or to the left
162 typedef uint16_t BCPixelSize;
164 // These are the max sizes that are stored. If they are exceeded, then the max is stored and
165 // the actual value is computed when needed.
166 #define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1)
168 static inline nscoord
169 BC_BORDER_TOP_HALF_COORD(int32_t p2t, uint16_t px) { return (px - px / 2) * p2t; }
170 static inline nscoord
171 BC_BORDER_RIGHT_HALF_COORD(int32_t p2t, uint16_t px) { return ( px / 2) * p2t; }
172 static inline nscoord
173 BC_BORDER_BOTTOM_HALF_COORD(int32_t p2t, uint16_t px) { return ( px / 2) * p2t; }
174 static inline nscoord
175 BC_BORDER_LEFT_HALF_COORD(int32_t p2t, uint16_t px) { return (px - px / 2) * p2t; }
177 #define BC_BORDER_TOP_HALF(px) ((px) - (px) / 2)
178 #define BC_BORDER_RIGHT_HALF(px) ((px) / 2)
179 #define BC_BORDER_BOTTOM_HALF(px) ((px) / 2)
180 #define BC_BORDER_LEFT_HALF(px) ((px) - (px) / 2)
182 // BCData stores the top and left border info and the corner connecting the two.
183 class BCData
185 public:
186 BCData();
188 ~BCData();
190 nscoord GetLeftEdge(BCBorderOwner& aOwner,
191 bool& aStart) const;
193 void SetLeftEdge(BCBorderOwner aOwner,
194 nscoord aSize,
195 bool aStart);
197 nscoord GetTopEdge(BCBorderOwner& aOwner,
198 bool& aStart) const;
200 void SetTopEdge(BCBorderOwner aOwner,
201 nscoord aSize,
202 bool aStart);
204 BCPixelSize GetCorner(mozilla::Side& aCornerOwner,
205 bool& aBevel) const;
207 void SetCorner(BCPixelSize aSubSize,
208 mozilla::Side aOwner,
209 bool aBevel);
211 bool IsLeftStart() const;
213 void SetLeftStart(bool aValue);
215 bool IsTopStart() const;
217 void SetTopStart(bool aValue);
220 protected:
221 BCPixelSize mLeftSize; // size in pixels of left border
222 BCPixelSize mTopSize; // size in pixels of top border
223 BCPixelSize mCornerSubSize; // size of the largest border not in the
224 // dominant plane (for example, if corner is
225 // owned by the segment to its top or bottom,
226 // then the size is the max of the border
227 // sizes of the segments to its left or right.
228 unsigned mLeftOwner: 4; // owner of left border
229 unsigned mTopOwner: 4; // owner of top border
230 unsigned mLeftStart: 1; // set if this is the start of a vertical border segment
231 unsigned mTopStart: 1; // set if this is the start of a horizontal border segment
232 unsigned mCornerSide: 2; // mozilla::Side of the owner of the upper left corner relative to the corner
233 unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
236 // BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
237 // effect. BCData for a row and col entry contains the left and top borders of cell at that row and
238 // col and the corner connecting the two. The right borders of the cells in the last col and the bottom
239 // borders of the last row are stored in separate BCData entries in the cell map.
240 class BCCellData : public CellData
242 public:
243 explicit BCCellData(nsTableCellFrame* aOrigCell);
244 ~BCCellData();
246 BCData mData;
250 // The layout of a celldata is as follows. The top 10 bits are the colspan
251 // offset (which is enough to represent our allowed values 1-1000 for colspan).
252 // Then there are three bits of flags. Then 16 bits of rowspan offset (which
253 // lets us represent numbers up to 65535. Then another 3 bits of flags.
255 // num bits to shift right to get right aligned col span
256 #define COL_SPAN_SHIFT 22
257 // num bits to shift right to get right aligned row span
258 #define ROW_SPAN_SHIFT 3
260 // the col offset to the data containing the original cell.
261 #define COL_SPAN_OFFSET (0x3FF << COL_SPAN_SHIFT)
262 // the row offset to the data containing the original cell
263 #define ROW_SPAN_OFFSET (0xFFFF << ROW_SPAN_SHIFT)
265 // And the flags
266 #define SPAN 0x00000001 // there a row or col span
267 #define ROW_SPAN 0x00000002 // there is a row span
268 #define ROW_SPAN_0 0x00000004 // the row span is 0
269 #define COL_SPAN (1 << (COL_SPAN_SHIFT - 3)) // there is a col span
270 #define COL_SPAN_0 (1 << (COL_SPAN_SHIFT - 2)) // the col span is 0
271 #define OVERLAP (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
272 // col span but not by
273 // same cell
275 inline nsTableCellFrame* CellData::GetCellFrame() const
277 if (SPAN != (SPAN & mBits)) {
278 return mOrigCell;
280 return nullptr;
283 inline void CellData::Init(nsTableCellFrame* aCellFrame)
285 mOrigCell = aCellFrame;
288 inline bool CellData::IsOrig() const
290 return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits)));
293 inline bool CellData::IsDead() const
295 return (0 == mBits);
298 inline bool CellData::IsSpan() const
300 return (SPAN == (SPAN & mBits));
303 inline bool CellData::IsRowSpan() const
305 return (SPAN == (SPAN & mBits)) &&
306 (ROW_SPAN == (ROW_SPAN & mBits));
309 inline bool CellData::IsZeroRowSpan() const
311 return (SPAN == (SPAN & mBits)) &&
312 (ROW_SPAN == (ROW_SPAN & mBits)) &&
313 (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
316 inline void CellData::SetZeroRowSpan(bool aIsZeroSpan)
318 if (SPAN == (SPAN & mBits)) {
319 if (aIsZeroSpan) {
320 mBits |= ROW_SPAN_0;
322 else {
323 mBits &= ~ROW_SPAN_0;
328 inline uint32_t CellData::GetRowSpanOffset() const
330 if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
331 return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
333 return 0;
336 inline void CellData::SetRowSpanOffset(uint32_t aSpan)
338 mBits &= ~ROW_SPAN_OFFSET;
339 mBits |= (aSpan << ROW_SPAN_SHIFT);
340 mBits |= SPAN;
341 mBits |= ROW_SPAN;
344 inline bool CellData::IsColSpan() const
346 return (SPAN == (SPAN & mBits)) &&
347 (COL_SPAN == (COL_SPAN & mBits));
350 inline bool CellData::IsZeroColSpan() const
352 return (SPAN == (SPAN & mBits)) &&
353 (COL_SPAN == (COL_SPAN & mBits)) &&
354 (COL_SPAN_0 == (COL_SPAN_0 & mBits));
357 inline void CellData::SetZeroColSpan(bool aIsZeroSpan)
359 if (SPAN == (SPAN & mBits)) {
360 if (aIsZeroSpan) {
361 mBits |= COL_SPAN_0;
363 else {
364 mBits &= ~COL_SPAN_0;
369 inline uint32_t CellData::GetColSpanOffset() const
371 if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
372 return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
374 return 0;
377 inline void CellData::SetColSpanOffset(uint32_t aSpan)
379 mBits &= ~COL_SPAN_OFFSET;
380 mBits |= (aSpan << COL_SPAN_SHIFT);
382 mBits |= SPAN;
383 mBits |= COL_SPAN;
386 inline bool CellData::IsOverlap() const
388 return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
391 inline void CellData::SetOverlap(bool aOverlap)
393 if (SPAN == (SPAN & mBits)) {
394 if (aOverlap) {
395 mBits |= OVERLAP;
397 else {
398 mBits &= ~OVERLAP;
403 inline BCData::BCData()
405 mLeftOwner = mTopOwner = eCellOwner;
406 mLeftStart = mTopStart = 1;
407 mLeftSize = mCornerSubSize = mTopSize = 0;
408 mCornerSide = NS_SIDE_TOP;
409 mCornerBevel = false;
412 inline BCData::~BCData()
416 inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
417 bool& aStart) const
419 aOwner = (BCBorderOwner)mLeftOwner;
420 aStart = (bool)mLeftStart;
422 return (nscoord)mLeftSize;
425 inline void BCData::SetLeftEdge(BCBorderOwner aOwner,
426 nscoord aSize,
427 bool aStart)
429 mLeftOwner = aOwner;
430 mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
431 mLeftStart = aStart;
434 inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
435 bool& aStart) const
437 aOwner = (BCBorderOwner)mTopOwner;
438 aStart = (bool)mTopStart;
440 return (nscoord)mTopSize;
443 inline void BCData::SetTopEdge(BCBorderOwner aOwner,
444 nscoord aSize,
445 bool aStart)
447 mTopOwner = aOwner;
448 mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
449 mTopStart = aStart;
452 inline BCPixelSize BCData::GetCorner(mozilla::Side& aOwnerSide,
453 bool& aBevel) const
455 aOwnerSide = mozilla::Side(mCornerSide);
456 aBevel = (bool)mCornerBevel;
457 return mCornerSubSize;
460 inline void BCData::SetCorner(BCPixelSize aSubSize,
461 mozilla::Side aOwnerSide,
462 bool aBevel)
464 mCornerSubSize = aSubSize;
465 mCornerSide = aOwnerSide;
466 mCornerBevel = aBevel;
469 inline bool BCData::IsLeftStart() const
471 return (bool)mLeftStart;
474 inline void BCData::SetLeftStart(bool aValue)
476 mLeftStart = aValue;
479 inline bool BCData::IsTopStart() const
481 return (bool)mTopStart;
484 inline void BCData::SetTopStart(bool aValue)
486 mTopStart = aValue;
489 #endif