Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/tables/celldata.h
Line
Count
Source (jump to first uncovered line)
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__
7
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>
14
15
class nsTableCellFrame;
16
class nsCellMap;
17
class BCCellData;
18
19
20
/**
21
  * Data stored by nsCellMap to rationalize rowspan and colspan cells.
22
  */
23
class CellData
24
{
25
public:
26
  /** Initialize the mOrigCell pointer
27
    * @param aOrigCell  the table cell frame which will be stored in mOrigCell.
28
    */
29
  void   Init(nsTableCellFrame* aCellFrame);
30
31
  /** does a cell originate from here
32
    * @return    is true if a cell corresponds to this cellmap entry
33
    */
34
  bool IsOrig() const;
35
36
  /** is the celldata valid
37
    * @return    is true if no cell originates and the cell is not spanned by
38
    *            a row- or colspan. mBits are 0 in this case and mOrigCell is
39
    *            nullptr
40
    */
41
  bool IsDead() const;
42
43
  /** is the entry spanned by row- or a colspan
44
    * @return    is true if the entry is spanned by a row- or colspan
45
    */
46
  bool IsSpan() const;
47
48
  /** is the entry spanned by rowspan
49
    * @return    is true if the entry is spanned by a rowspan
50
    */
51
  bool IsRowSpan() const;
52
53
  /** is the entry spanned by a zero rowspan
54
    * zero rowspans span all cells starting from the originating cell down to
55
    * the end of the rowgroup or a cell originating in the same column
56
    * @return    is true if the entry is spanned by a zero rowspan
57
    */
58
  bool IsZeroRowSpan() const;
59
60
  /** mark the current entry as spanned by a zero rowspan
61
    * @param aIsZero    if true mark the entry as covered by a zero rowspan
62
    */
63
  void SetZeroRowSpan(bool aIsZero);
64
65
  /** get the distance from the current entry to the corresponding origin of the rowspan
66
    * @return    containing the distance in the column to the originating cell
67
    */
68
  uint32_t GetRowSpanOffset() const;
69
70
  /** set the distance from the current entry to the corresponding origin of the rowspan
71
    * @param    the distance in the column to the originating cell
72
    */
73
  void SetRowSpanOffset(uint32_t aSpan);
74
75
  /** is the entry spanned by colspan
76
    * @return    is true if the entry is spanned by a colspan
77
    */
78
  bool IsColSpan() const;
79
80
  /** get the distance from the current entry to the corresponding origin of the colspan
81
    * @return    containing the distance in the row to the originating cell
82
    */
83
  uint32_t GetColSpanOffset() const;
84
85
  /** set the distance from the current entry to the corresponding origin of the colspan
86
    * @param    the distance in the column to the originating cell
87
    */
88
  void SetColSpanOffset(uint32_t aSpan);
89
90
  /** is the entry spanned by a row- and a colspan
91
    * @return    is true if the entry is spanned by a row- and a colspan
92
    */
93
  bool IsOverlap() const;
94
95
  /** mark the current entry as spanned by a row- and a colspan
96
    * @param aOverlap    if true mark the entry as covered by a row- and a colspan
97
    */
98
  void SetOverlap(bool aOverlap);
99
100
  /** get the table cell frame for this entry
101
    * @return    a pointer to the cellframe, this will be nullptr when the entry
102
    *            is only a spanned entry
103
    */
104
  nsTableCellFrame* GetCellFrame() const;
105
106
private:
107
  friend class nsCellMap;
108
  friend class BCCellData;
109
110
  /** constructor.
111
    * @param aOrigCell  the table cell frame which will be stored in mOrigCell.
112
    */
113
  explicit CellData(nsTableCellFrame* aOrigCell);  // implemented in nsCellMap.cpp
114
115
  /** destructor */
116
  ~CellData(); // implemented in nsCellMap.cpp
117
118
protected:
119
120
  // this union relies on the assumption that an object (not primitive type) does
121
  // not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in effect
122
  // and the data does not represent a span. If mSpan is 1, then mBits is in
123
  // effect and the data represents a span.
124
  // mBits must match the size of mOrigCell on both 32- and 64-bit platforms.
125
  union {
126
    nsTableCellFrame* mOrigCell;
127
    uintptr_t         mBits;
128
  };
129
};
130
131
// Border Collapsing Cell Data
132
enum BCBorderOwner
133
{
134
  eTableOwner        =  0,
135
  eColGroupOwner     =  1,
136
  eAjaColGroupOwner  =  2, // col group to the left
137
  eColOwner          =  3,
138
  eAjaColOwner       =  4, // col to the left
139
  eRowGroupOwner     =  5,
140
  eAjaRowGroupOwner  =  6, // row group above
141
  eRowOwner          =  7,
142
  eAjaRowOwner       =  8, // row above
143
  eCellOwner         =  9,
144
  eAjaCellOwner      = 10  // cell to the top or to the left
145
};
146
147
// BCPixelSize is in device pixels.
148
typedef uint16_t BCPixelSize;
149
150
// These are the max sizes that are stored. If they are exceeded, then the max is stored and
151
// the actual value is computed when needed.
152
0
#define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1)
153
154
// The half of border on inline/block-axis start side
155
static inline BCPixelSize
156
0
BC_BORDER_START_HALF(BCPixelSize px) { return px - px / 2; }
Unexecuted instantiation: Unified_cpp_dom_html3.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_editor_libeditor1.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic0.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic1.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic2.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_tables0.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_mathml1.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_painting0.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_build0.cpp:BC_BORDER_START_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_accessible_html0.cpp:BC_BORDER_START_HALF(unsigned short)
157
// The half of border on inline/block-axis end side
158
static inline BCPixelSize
159
0
BC_BORDER_END_HALF(BCPixelSize px) { return px / 2; }
Unexecuted instantiation: Unified_cpp_dom_html3.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_editor_libeditor1.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic0.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic1.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic2.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_tables0.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_mathml1.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_painting0.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_layout_build0.cpp:BC_BORDER_END_HALF(unsigned short)
Unexecuted instantiation: Unified_cpp_accessible_html0.cpp:BC_BORDER_END_HALF(unsigned short)
160
161
static inline nscoord
162
BC_BORDER_START_HALF_COORD(int32_t d2a, BCPixelSize px)
163
0
  { return BC_BORDER_START_HALF(px) * d2a; }
Unexecuted instantiation: Unified_cpp_dom_html3.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_editor_libeditor1.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic0.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic1.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic2.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_tables0.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_mathml1.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_painting0.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_build0.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_accessible_html0.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short)
164
static inline nscoord
165
BC_BORDER_END_HALF_COORD(int32_t d2a, BCPixelSize px)
166
0
  { return BC_BORDER_END_HALF(px) * d2a; }
Unexecuted instantiation: Unified_cpp_dom_html3.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_editor_libeditor1.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_base1.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic0.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic1.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_generic2.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_tables0.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_mathml1.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_painting0.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_layout_build0.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
Unexecuted instantiation: Unified_cpp_accessible_html0.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short)
167
168
// BCData stores the bstart and istart border info and the corner connecting the two.
169
class BCData
170
{
171
public:
172
  BCData();
173
174
  ~BCData();
175
176
  nscoord GetIStartEdge(BCBorderOwner& aOwner,
177
                        bool&          aStart) const;
178
179
  void SetIStartEdge(BCBorderOwner aOwner,
180
                     nscoord       aSize,
181
                     bool          aStart);
182
183
  nscoord GetBStartEdge(BCBorderOwner& aOwner,
184
                        bool&          aStart) const;
185
186
  void SetBStartEdge(BCBorderOwner aOwner,
187
                     nscoord       aSize,
188
                     bool          aStart);
189
190
  BCPixelSize GetCorner(mozilla::LogicalSide& aCornerOwner,
191
                        bool&                 aBevel) const;
192
193
  void SetCorner(BCPixelSize          aSubSize,
194
                 mozilla::LogicalSide aOwner,
195
                 bool                 aBevel);
196
197
  inline bool IsIStartStart() const
198
0
  {
199
0
    return (bool)mIStartStart;
200
0
  }
201
202
  inline void SetIStartStart(bool aValue)
203
0
  {
204
0
    mIStartStart = aValue;
205
0
  }
206
207
  inline bool IsBStartStart() const
208
0
  {
209
0
    return (bool)mBStartStart;
210
0
  }
211
212
  inline void SetBStartStart(bool aValue)
213
0
  {
214
0
    mBStartStart = aValue;
215
0
  }
216
217
protected:
218
  BCPixelSize mIStartSize;    // size in pixels of iStart border
219
  BCPixelSize mBStartSize;    // size in pixels of bStart border
220
  BCPixelSize mCornerSubSize; // size of the largest border not in the
221
                              //   dominant plane (for example, if corner is
222
                              //   owned by the segment to its bStart or bEnd,
223
                              //   then the size is the max of the border
224
                              //   sizes of the segments to its iStart or iEnd.
225
  unsigned mIStartOwner:   4; // owner of iStart border
226
  unsigned mBStartOwner:   4; // owner of bStart border
227
  unsigned mIStartStart:   1; // set if this is the start of a block-dir border segment
228
  unsigned mBStartStart:   1; // set if this is the start of an inline-dir border segment
229
  unsigned mCornerSide:    2; // LogicalSide of the owner of the bStart-iStart corner relative to the corner
230
  unsigned mCornerBevel:   1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
231
};
232
233
// BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
234
// effect. BCData for a row and col entry contains the left and top borders of cell at that row and
235
// col and the corner connecting the two. The right borders of the cells in the last col and the bottom
236
// borders of the last row are stored in separate BCData entries in the cell map.
237
class BCCellData : public CellData
238
{
239
public:
240
  explicit BCCellData(nsTableCellFrame* aOrigCell);
241
  ~BCCellData();
242
243
  BCData mData;
244
};
245
246
247
// The layout of a celldata is as follows.  The top 10 bits are the colspan
248
// offset (which is enough to represent our allowed values 1-1000 for colspan).
249
// Then there are two bits of flags.
250
// XXXmats Then one unused bit that we should decide how to use in bug 862624.
251
// Then 16 bits of rowspan offset (which
252
// lets us represent numbers up to 65535.  Then another 3 bits of flags.
253
254
// num bits to shift right to get right aligned col span
255
0
#define COL_SPAN_SHIFT   22
256
// num bits to shift right to get right aligned row span
257
0
#define ROW_SPAN_SHIFT   3
258
259
// the col offset to the data containing the original cell.
260
0
#define COL_SPAN_OFFSET  (0x3FF << COL_SPAN_SHIFT)
261
// the row offset to the data containing the original cell
262
0
#define ROW_SPAN_OFFSET  (0xFFFF << ROW_SPAN_SHIFT)
263
264
// And the flags
265
0
#define SPAN             0x00000001 // there a row or col span
266
0
#define ROW_SPAN         0x00000002 // there is a row span
267
0
#define ROW_SPAN_0       0x00000004 // the row span is 0
268
0
#define COL_SPAN         (1 << (COL_SPAN_SHIFT - 2)) // there is a col span
269
0
#define OVERLAP          (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
270
                                                     // col span but not by
271
                                                     // same cell
272
273
inline nsTableCellFrame* CellData::GetCellFrame() const
274
0
{
275
0
  if (SPAN != (SPAN & mBits)) {
276
0
    return mOrigCell;
277
0
  }
278
0
  return nullptr;
279
0
}
280
281
inline void CellData::Init(nsTableCellFrame* aCellFrame)
282
0
{
283
0
  mOrigCell = aCellFrame;
284
0
}
285
286
inline bool CellData::IsOrig() const
287
0
{
288
0
  return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits)));
289
0
}
290
291
inline bool CellData::IsDead() const
292
0
{
293
0
  return (0 == mBits);
294
0
}
295
296
inline bool CellData::IsSpan() const
297
0
{
298
0
  return (SPAN == (SPAN & mBits));
299
0
}
300
301
inline bool CellData::IsRowSpan() const
302
0
{
303
0
  return (SPAN     == (SPAN & mBits)) &&
304
0
         (ROW_SPAN == (ROW_SPAN & mBits));
305
0
}
306
307
inline bool CellData::IsZeroRowSpan() const
308
0
{
309
0
  return (SPAN       == (SPAN & mBits))     &&
310
0
         (ROW_SPAN   == (ROW_SPAN & mBits)) &&
311
0
         (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
312
0
}
313
314
inline void CellData::SetZeroRowSpan(bool aIsZeroSpan)
315
0
{
316
0
  if (SPAN == (SPAN & mBits)) {
317
0
    if (aIsZeroSpan) {
318
0
      mBits |= ROW_SPAN_0;
319
0
    }
320
0
    else {
321
0
      mBits &= ~ROW_SPAN_0;
322
0
    }
323
0
  }
324
0
}
325
326
inline uint32_t CellData::GetRowSpanOffset() const
327
0
{
328
0
  if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
329
0
    return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
330
0
  }
331
0
  return 0;
332
0
}
333
334
inline void CellData::SetRowSpanOffset(uint32_t aSpan)
335
0
{
336
0
  mBits &= ~ROW_SPAN_OFFSET;
337
0
  mBits |= (aSpan << ROW_SPAN_SHIFT);
338
0
  mBits |= SPAN;
339
0
  mBits |= ROW_SPAN;
340
0
}
341
342
inline bool CellData::IsColSpan() const
343
0
{
344
0
  return (SPAN     == (SPAN & mBits)) &&
345
0
         (COL_SPAN == (COL_SPAN & mBits));
346
0
}
347
348
inline uint32_t CellData::GetColSpanOffset() const
349
0
{
350
0
  if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
351
0
    return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
352
0
  }
353
0
  return 0;
354
0
}
355
356
inline void CellData::SetColSpanOffset(uint32_t aSpan)
357
0
{
358
0
  mBits &= ~COL_SPAN_OFFSET;
359
0
  mBits |= (aSpan << COL_SPAN_SHIFT);
360
0
361
0
  mBits |= SPAN;
362
0
  mBits |= COL_SPAN;
363
0
}
364
365
inline bool CellData::IsOverlap() const
366
0
{
367
0
  return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
368
0
}
369
370
inline void CellData::SetOverlap(bool aOverlap)
371
0
{
372
0
  if (SPAN == (SPAN & mBits)) {
373
0
    if (aOverlap) {
374
0
      mBits |= OVERLAP;
375
0
    }
376
0
    else {
377
0
      mBits &= ~OVERLAP;
378
0
    }
379
0
  }
380
0
}
381
382
inline BCData::BCData()
383
0
{
384
0
  mIStartOwner = mBStartOwner = eCellOwner;
385
0
  SetBStartStart(true);
386
0
  SetIStartStart(true);
387
0
  mIStartSize = mCornerSubSize = mBStartSize = 0;
388
0
  mCornerSide = mozilla::eLogicalSideBStart;
389
0
  mCornerBevel = false;
390
0
}
391
392
inline BCData::~BCData()
393
0
{
394
0
}
395
396
inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner,
397
                                     bool&          aStart) const
398
0
{
399
0
  aOwner = (BCBorderOwner)mIStartOwner;
400
0
  aStart = IsIStartStart();
401
0
402
0
  return (nscoord)mIStartSize;
403
0
}
404
405
inline void BCData::SetIStartEdge(BCBorderOwner  aOwner,
406
                                  nscoord        aSize,
407
                                  bool           aStart)
408
0
{
409
0
  mIStartOwner = aOwner;
410
0
  mIStartSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
411
0
  SetIStartStart(aStart);
412
0
}
413
414
inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner,
415
                                     bool&          aStart) const
416
0
{
417
0
  aOwner = (BCBorderOwner)mBStartOwner;
418
0
  aStart = IsBStartStart();
419
0
420
0
  return (nscoord)mBStartSize;
421
0
}
422
423
inline void BCData::SetBStartEdge(BCBorderOwner  aOwner,
424
                                  nscoord        aSize,
425
                                  bool           aStart)
426
0
{
427
0
  mBStartOwner = aOwner;
428
0
  mBStartSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
429
0
  SetBStartStart(aStart);
430
0
}
431
432
inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide,
433
                                     bool&                 aBevel) const
434
0
{
435
0
  aOwnerSide = mozilla::LogicalSide(mCornerSide);
436
0
  aBevel     = (bool)mCornerBevel;
437
0
  return mCornerSubSize;
438
0
}
439
440
inline void BCData::SetCorner(BCPixelSize          aSubSize,
441
                              mozilla::LogicalSide aOwnerSide,
442
                              bool                 aBevel)
443
0
{
444
0
  mCornerSubSize = aSubSize;
445
0
  mCornerSide    = aOwnerSide;
446
0
  mCornerBevel   = aBevel;
447
0
}
448
449
#endif