Back out bug 459443 for now, until the patch in bug 474389 gets reviewed
[mozilla-central.git] / layout / tables / celldata.h
blob44965e32c70cd7a320df0e6105a6b6df23a4cfc3
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
37 #ifndef CellData_h__
38 #define CellData_h__
40 #include "nsISupports.h"
41 #include "nsCoord.h"
43 class nsTableCellFrame;
44 class nsCellMap;
45 class BCCellData;
48 #define MAX_ROWSPAN 8190 // the cellmap can not handle more
49 #define MAX_COLSPAN 1000 // limit as IE and opera do
51 /**
52 * Data stored by nsCellMap to rationalize rowspan and colspan cells.
54 class CellData
56 public:
57 /** Initialize the mOrigCell pointer
58 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
59 */
60 void Init(nsTableCellFrame* aCellFrame);
62 /** does a cell originate from here
63 * @return is true if a cell corresponds to this cellmap entry
65 PRBool IsOrig() const;
67 /** is the celldata valid
68 * @return is true if no cell originates and the cell is not spanned by
69 * a row- or colspan. mBits are 0 in this case and mOrigCell is
70 * nsnull
72 PRBool IsDead() const;
74 /** is the entry spanned by row- or a colspan
75 * @return is true if the entry is spanned by a row- or colspan
77 PRBool IsSpan() const;
79 /** is the entry spanned by rowspan
80 * @return is true if the entry is spanned by a rowspan
82 PRBool IsRowSpan() const;
84 /** is the entry spanned by a zero rowspan
85 * zero rowspans span all cells starting from the originating cell down to
86 * the end of the rowgroup or a cell originating in the same column
87 * @return is true if the entry is spanned by a zero rowspan
89 PRBool IsZeroRowSpan() const;
91 /** mark the current entry as spanned by a zero rowspan
92 * @param aIsZero if true mark the entry as covered by a zero rowspan
94 void SetZeroRowSpan(PRBool aIsZero);
96 /** get the distance from the current entry to the corresponding origin of the rowspan
97 * @return containing the distance in the column to the originating cell
99 PRUint32 GetRowSpanOffset() const;
101 /** set the distance from the current entry to the corresponding origin of the rowspan
102 * @param the distance in the column to the originating cell
104 void SetRowSpanOffset(PRUint32 aSpan);
106 /** is the entry spanned by colspan
107 * @return is true if the entry is spanned by a colspan
109 PRBool IsColSpan() const;
111 /** is the entry spanned by a zero colspan
112 * zero colspans span all cells starting from the originating cell towards
113 * the end of the colgroup or a cell originating in the same row
114 * or a rowspanned entry
115 * @return is true if the entry is spanned by a zero colspan
117 PRBool IsZeroColSpan() const;
119 /** mark the current entry as spanned by a zero colspan
120 * @param aIsZero if true mark the entry as covered by a zero colspan
122 void SetZeroColSpan(PRBool aIsZero);
124 /** get the distance from the current entry to the corresponding origin of the colspan
125 * @return containing the distance in the row to the originating cell
127 PRUint32 GetColSpanOffset() const;
129 /** set the distance from the current entry to the corresponding origin of the colspan
130 * @param the distance in the column to the originating cell
132 void SetColSpanOffset(PRUint32 aSpan);
134 /** is the entry spanned by a row- and a colspan
135 * @return is true if the entry is spanned by a row- and a colspan
137 PRBool IsOverlap() const;
139 /** mark the current entry as spanned by a row- and a colspan
140 * @param aOverlap if true mark the entry as covered by a row- and a colspan
142 void SetOverlap(PRBool aOverlap);
144 /** get the table cell frame for this entry
145 * @return a pointer to the cellframe, this will be nsnull when the entry
146 * is only a spanned entry
148 nsTableCellFrame* GetCellFrame() const;
150 private:
151 friend class nsCellMap;
152 friend class BCCellData;
154 /** constructor.
155 * @param aOrigCell the table cell frame which will be stored in mOrigCell.
157 CellData(nsTableCellFrame* aOrigCell); // implemented in nsCellMap.cpp
159 /** destructor */
160 ~CellData(); // implemented in nsCellMap.cpp
162 protected:
164 // this union relies on the assumption that an object (not primitive type) does
165 // not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in effect
166 // and the data does not represent a span. If mSpan is 1, then mBits is in
167 // effect and the data represents a span.
168 // mBits must be an unsigned long because it must match the size of
169 // mOrigCell on both 32- and 64-bit platforms.
170 union {
171 nsTableCellFrame* mOrigCell;
172 unsigned long mBits;
176 // Border Collapsing Cell Data
177 enum BCBorderOwner
179 eTableOwner = 0,
180 eColGroupOwner = 1,
181 eAjaColGroupOwner = 2, // col group to the left
182 eColOwner = 3,
183 eAjaColOwner = 4, // col to the left
184 eRowGroupOwner = 5,
185 eAjaRowGroupOwner = 6, // row group above
186 eRowOwner = 7,
187 eAjaRowOwner = 8, // row above
188 eCellOwner = 9,
189 eAjaCellOwner = 10 // cell to the top or to the left
192 typedef PRUint16 BCPixelSize;
194 // These are the max sizes that are stored. If they are exceeded, then the max is stored and
195 // the actual value is computed when needed.
196 #define MAX_BORDER_WIDTH nscoord(PR_BITMASK(sizeof(BCPixelSize) * 8))
198 #define BC_BORDER_TOP_HALF_COORD(p2t,px) NSToCoordRound(float((px) - (px) / 2) * (p2t) )
199 #define BC_BORDER_RIGHT_HALF_COORD(p2t,px) NSToCoordRound(float( (px) / 2) * (p2t) )
200 #define BC_BORDER_BOTTOM_HALF_COORD(p2t,px) NSToCoordRound(float( (px) / 2) * (p2t) )
201 #define BC_BORDER_LEFT_HALF_COORD(p2t,px) NSToCoordRound(float((px) - (px) / 2) * (p2t) )
203 #define BC_BORDER_TOP_HALF(px) ((px) - (px) / 2)
204 #define BC_BORDER_RIGHT_HALF(px) ((px) / 2)
205 #define BC_BORDER_BOTTOM_HALF(px) ((px) / 2)
206 #define BC_BORDER_LEFT_HALF(px) ((px) - (px) / 2)
208 // BCData stores the top and left border info and the corner connecting the two.
209 class BCData
211 public:
212 BCData();
214 ~BCData();
216 nscoord GetLeftEdge(BCBorderOwner& aOwner,
217 PRBool& aStart) const;
219 void SetLeftEdge(BCBorderOwner aOwner,
220 nscoord aSize,
221 PRBool aStart);
223 nscoord GetTopEdge(BCBorderOwner& aOwner,
224 PRBool& aStart) const;
226 void SetTopEdge(BCBorderOwner aOwner,
227 nscoord aSize,
228 PRBool aStart);
230 BCPixelSize GetCorner(PRUint8& aCornerOwner,
231 PRPackedBool& aBevel) const;
233 void SetCorner(BCPixelSize aSubSize,
234 PRUint8 aOwner,
235 PRBool aBevel);
237 PRBool IsLeftStart() const;
239 void SetLeftStart(PRBool aValue);
241 PRBool IsTopStart() const;
243 void SetTopStart(PRBool aValue);
246 protected:
247 BCPixelSize mLeftSize; // size in pixels of left border
248 BCPixelSize mTopSize; // size in pixels of top border
249 BCPixelSize mCornerSubSize; // size of the largest border not in the
250 // dominant plane (for example, if corner is
251 // owned by the segment to its top or bottom,
252 // then the size is the max of the border
253 // sizes of the segments to its left or right.
254 unsigned mLeftOwner: 4; // owner of left border
255 unsigned mTopOwner: 4; // owner of top border
256 unsigned mLeftStart: 1; // set if this is the start of a vertical border segment
257 unsigned mTopStart: 1; // set if this is the start of a horizontal border segment
258 unsigned mCornerSide: 2; // side of the owner of the upper left corner relative to the corner
259 unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
262 // BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
263 // effect. BCData for a row and col entry contains the left and top borders of cell at that row and
264 // col and the corner connecting the two. The right borders of the cells in the last col and the bottom
265 // borders of the last row are stored in separate BCData entries in the cell map.
266 class BCCellData : public CellData
268 public:
269 BCCellData(nsTableCellFrame* aOrigCell);
270 ~BCCellData();
272 BCData mData;
276 #define SPAN 0x00000001 // there a row or col span
277 #define ROW_SPAN 0x00000002 // there is a row span
278 #define ROW_SPAN_0 0x00000004 // the row span is 0
279 #define ROW_SPAN_OFFSET 0x0000FFF8 // the row offset to the data containing the original cell
280 #define COL_SPAN 0x00010000 // there is a col span
281 #define COL_SPAN_0 0x00020000 // the col span is 0
282 #define OVERLAP 0x00040000 // there is a row span and col span but no by same cell
283 #define COL_SPAN_OFFSET 0xFFF80000 // the col offset to the data containing the original cell
284 #define ROW_SPAN_SHIFT 3 // num bits to shift to get right justified row span
285 #define COL_SPAN_SHIFT 19 // num bits to shift to get right justified col span
287 inline nsTableCellFrame* CellData::GetCellFrame() const
289 if (SPAN != (SPAN & mBits)) {
290 return mOrigCell;
292 return nsnull;
295 inline void CellData::Init(nsTableCellFrame* aCellFrame)
297 mOrigCell = aCellFrame;
300 inline PRBool CellData::IsOrig() const
302 return ((nsnull != mOrigCell) && (SPAN != (SPAN & mBits)));
305 inline PRBool CellData::IsDead() const
307 return (0 == mBits);
310 inline PRBool CellData::IsSpan() const
312 return (SPAN == (SPAN & mBits));
315 inline PRBool CellData::IsRowSpan() const
317 return (SPAN == (SPAN & mBits)) &&
318 (ROW_SPAN == (ROW_SPAN & mBits));
321 inline PRBool CellData::IsZeroRowSpan() const
323 return (SPAN == (SPAN & mBits)) &&
324 (ROW_SPAN == (ROW_SPAN & mBits)) &&
325 (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
328 inline void CellData::SetZeroRowSpan(PRBool aIsZeroSpan)
330 if (SPAN == (SPAN & mBits)) {
331 if (aIsZeroSpan) {
332 mBits |= ROW_SPAN_0;
334 else {
335 mBits &= ~ROW_SPAN_0;
340 inline PRUint32 CellData::GetRowSpanOffset() const
342 if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
343 return (PRUint32)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
345 return 0;
348 inline void CellData::SetRowSpanOffset(PRUint32 aSpan)
350 mBits &= ~ROW_SPAN_OFFSET;
351 mBits |= (aSpan << ROW_SPAN_SHIFT);
352 mBits |= SPAN;
353 mBits |= ROW_SPAN;
356 inline PRBool CellData::IsColSpan() const
358 return (SPAN == (SPAN & mBits)) &&
359 (COL_SPAN == (COL_SPAN & mBits));
362 inline PRBool CellData::IsZeroColSpan() const
364 return (SPAN == (SPAN & mBits)) &&
365 (COL_SPAN == (COL_SPAN & mBits)) &&
366 (COL_SPAN_0 == (COL_SPAN_0 & mBits));
369 inline void CellData::SetZeroColSpan(PRBool aIsZeroSpan)
371 if (SPAN == (SPAN & mBits)) {
372 if (aIsZeroSpan) {
373 mBits |= COL_SPAN_0;
375 else {
376 mBits &= ~COL_SPAN_0;
381 inline PRUint32 CellData::GetColSpanOffset() const
383 if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
384 return (PRUint32)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
386 return 0;
389 inline void CellData::SetColSpanOffset(PRUint32 aSpan)
391 mBits &= ~COL_SPAN_OFFSET;
392 mBits |= (aSpan << COL_SPAN_SHIFT);
394 mBits |= SPAN;
395 mBits |= COL_SPAN;
398 inline PRBool CellData::IsOverlap() const
400 return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
403 inline void CellData::SetOverlap(PRBool aOverlap)
405 if (SPAN == (SPAN & mBits)) {
406 if (aOverlap) {
407 mBits |= OVERLAP;
409 else {
410 mBits &= ~OVERLAP;
415 inline BCData::BCData()
417 mLeftOwner = mTopOwner = eCellOwner;
418 mLeftStart = mTopStart = 1;
419 mLeftSize = mCornerSide = mCornerSubSize = mTopSize = 0;
420 mCornerBevel = PR_FALSE;
423 inline BCData::~BCData()
427 inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
428 PRBool& aStart) const
430 aOwner = (BCBorderOwner)mLeftOwner;
431 aStart = (PRBool)mLeftStart;
433 return (nscoord)mLeftSize;
436 inline void BCData::SetLeftEdge(BCBorderOwner aOwner,
437 nscoord aSize,
438 PRBool aStart)
440 mLeftOwner = aOwner;
441 mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
442 mLeftStart = aStart;
445 inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
446 PRBool& aStart) const
448 aOwner = (BCBorderOwner)mTopOwner;
449 aStart = (PRBool)mTopStart;
451 return (nscoord)mTopSize;
454 inline void BCData::SetTopEdge(BCBorderOwner aOwner,
455 nscoord aSize,
456 PRBool aStart)
458 mTopOwner = aOwner;
459 mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
460 mTopStart = aStart;
463 inline BCPixelSize BCData::GetCorner(PRUint8& aOwnerSide,
464 PRPackedBool& aBevel) const
466 aOwnerSide = mCornerSide;
467 aBevel = (PRBool)mCornerBevel;
468 return mCornerSubSize;
471 inline void BCData::SetCorner(BCPixelSize aSubSize,
472 PRUint8 aOwnerSide,
473 PRBool aBevel)
475 mCornerSubSize = aSubSize;
476 mCornerSide = aOwnerSide;
477 mCornerBevel = aBevel;
480 inline PRBool BCData::IsLeftStart() const
482 return (PRBool)mLeftStart;
485 inline void BCData::SetLeftStart(PRBool aValue)
487 mLeftStart = aValue;
490 inline PRBool BCData::IsTopStart() const
492 return (PRBool)mTopStart;
495 inline void BCData::SetTopStart(PRBool aValue)
497 mTopStart = aValue;
500 #endif