/work/obj-fuzz/dist/include/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 | | #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_base4.cpp:BC_BORDER_START_HALF(unsigned short) Unexecuted instantiation: Unified_cpp_accessible_generic0.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_base4.cpp:BC_BORDER_END_HALF(unsigned short) Unexecuted instantiation: Unified_cpp_accessible_generic0.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_base4.cpp:BC_BORDER_START_HALF_COORD(int, unsigned short) Unexecuted instantiation: Unified_cpp_accessible_generic0.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_base4.cpp:BC_BORDER_END_HALF_COORD(int, unsigned short) Unexecuted instantiation: Unified_cpp_accessible_generic0.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 | | { |
199 | | return (bool)mIStartStart; |
200 | | } |
201 | | |
202 | | inline void SetIStartStart(bool aValue) |
203 | | { |
204 | | mIStartStart = aValue; |
205 | | } |
206 | | |
207 | | inline bool IsBStartStart() const |
208 | | { |
209 | | return (bool)mBStartStart; |
210 | | } |
211 | | |
212 | | inline void SetBStartStart(bool aValue) |
213 | | { |
214 | | mBStartStart = aValue; |
215 | | } |
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 | | #define COL_SPAN_SHIFT 22 |
256 | | // num bits to shift right to get right aligned row span |
257 | | #define ROW_SPAN_SHIFT 3 |
258 | | |
259 | | // the col offset to the data containing the original cell. |
260 | | #define COL_SPAN_OFFSET (0x3FF << COL_SPAN_SHIFT) |
261 | | // the row offset to the data containing the original cell |
262 | | #define ROW_SPAN_OFFSET (0xFFFF << ROW_SPAN_SHIFT) |
263 | | |
264 | | // And the flags |
265 | | #define SPAN 0x00000001 // there a row or col span |
266 | | #define ROW_SPAN 0x00000002 // there is a row span |
267 | | #define ROW_SPAN_0 0x00000004 // the row span is 0 |
268 | | #define COL_SPAN (1 << (COL_SPAN_SHIFT - 2)) // there is a col span |
269 | | #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 | | { |
275 | | if (SPAN != (SPAN & mBits)) { |
276 | | return mOrigCell; |
277 | | } |
278 | | return nullptr; |
279 | | } |
280 | | |
281 | | inline void CellData::Init(nsTableCellFrame* aCellFrame) |
282 | | { |
283 | | mOrigCell = aCellFrame; |
284 | | } |
285 | | |
286 | | inline bool CellData::IsOrig() const |
287 | | { |
288 | | return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits))); |
289 | | } |
290 | | |
291 | | inline bool CellData::IsDead() const |
292 | | { |
293 | | return (0 == mBits); |
294 | | } |
295 | | |
296 | | inline bool CellData::IsSpan() const |
297 | | { |
298 | | return (SPAN == (SPAN & mBits)); |
299 | | } |
300 | | |
301 | | inline bool CellData::IsRowSpan() const |
302 | | { |
303 | | return (SPAN == (SPAN & mBits)) && |
304 | | (ROW_SPAN == (ROW_SPAN & mBits)); |
305 | | } |
306 | | |
307 | | inline bool CellData::IsZeroRowSpan() const |
308 | | { |
309 | | return (SPAN == (SPAN & mBits)) && |
310 | | (ROW_SPAN == (ROW_SPAN & mBits)) && |
311 | | (ROW_SPAN_0 == (ROW_SPAN_0 & mBits)); |
312 | | } |
313 | | |
314 | | inline void CellData::SetZeroRowSpan(bool aIsZeroSpan) |
315 | | { |
316 | | if (SPAN == (SPAN & mBits)) { |
317 | | if (aIsZeroSpan) { |
318 | | mBits |= ROW_SPAN_0; |
319 | | } |
320 | | else { |
321 | | mBits &= ~ROW_SPAN_0; |
322 | | } |
323 | | } |
324 | | } |
325 | | |
326 | | inline uint32_t CellData::GetRowSpanOffset() const |
327 | | { |
328 | | if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) { |
329 | | return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT); |
330 | | } |
331 | | return 0; |
332 | | } |
333 | | |
334 | | inline void CellData::SetRowSpanOffset(uint32_t aSpan) |
335 | | { |
336 | | mBits &= ~ROW_SPAN_OFFSET; |
337 | | mBits |= (aSpan << ROW_SPAN_SHIFT); |
338 | | mBits |= SPAN; |
339 | | mBits |= ROW_SPAN; |
340 | | } |
341 | | |
342 | | inline bool CellData::IsColSpan() const |
343 | | { |
344 | | return (SPAN == (SPAN & mBits)) && |
345 | | (COL_SPAN == (COL_SPAN & mBits)); |
346 | | } |
347 | | |
348 | | inline uint32_t CellData::GetColSpanOffset() const |
349 | | { |
350 | | if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) { |
351 | | return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT); |
352 | | } |
353 | | return 0; |
354 | | } |
355 | | |
356 | | inline void CellData::SetColSpanOffset(uint32_t aSpan) |
357 | | { |
358 | | mBits &= ~COL_SPAN_OFFSET; |
359 | | mBits |= (aSpan << COL_SPAN_SHIFT); |
360 | | |
361 | | mBits |= SPAN; |
362 | | mBits |= COL_SPAN; |
363 | | } |
364 | | |
365 | | inline bool CellData::IsOverlap() const |
366 | | { |
367 | | return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits)); |
368 | | } |
369 | | |
370 | | inline void CellData::SetOverlap(bool aOverlap) |
371 | | { |
372 | | if (SPAN == (SPAN & mBits)) { |
373 | | if (aOverlap) { |
374 | | mBits |= OVERLAP; |
375 | | } |
376 | | else { |
377 | | mBits &= ~OVERLAP; |
378 | | } |
379 | | } |
380 | | } |
381 | | |
382 | | inline BCData::BCData() |
383 | | { |
384 | | mIStartOwner = mBStartOwner = eCellOwner; |
385 | | SetBStartStart(true); |
386 | | SetIStartStart(true); |
387 | | mIStartSize = mCornerSubSize = mBStartSize = 0; |
388 | | mCornerSide = mozilla::eLogicalSideBStart; |
389 | | mCornerBevel = false; |
390 | | } |
391 | | |
392 | | inline BCData::~BCData() |
393 | | { |
394 | | } |
395 | | |
396 | | inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner, |
397 | | bool& aStart) const |
398 | | { |
399 | | aOwner = (BCBorderOwner)mIStartOwner; |
400 | | aStart = IsIStartStart(); |
401 | | |
402 | | return (nscoord)mIStartSize; |
403 | | } |
404 | | |
405 | | inline void BCData::SetIStartEdge(BCBorderOwner aOwner, |
406 | | nscoord aSize, |
407 | | bool aStart) |
408 | | { |
409 | | mIStartOwner = aOwner; |
410 | | mIStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; |
411 | | SetIStartStart(aStart); |
412 | | } |
413 | | |
414 | | inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner, |
415 | | bool& aStart) const |
416 | | { |
417 | | aOwner = (BCBorderOwner)mBStartOwner; |
418 | | aStart = IsBStartStart(); |
419 | | |
420 | | return (nscoord)mBStartSize; |
421 | | } |
422 | | |
423 | | inline void BCData::SetBStartEdge(BCBorderOwner aOwner, |
424 | | nscoord aSize, |
425 | | bool aStart) |
426 | | { |
427 | | mBStartOwner = aOwner; |
428 | | mBStartSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize; |
429 | | SetBStartStart(aStart); |
430 | | } |
431 | | |
432 | | inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide, |
433 | | bool& aBevel) const |
434 | | { |
435 | | aOwnerSide = mozilla::LogicalSide(mCornerSide); |
436 | | aBevel = (bool)mCornerBevel; |
437 | | return mCornerSubSize; |
438 | | } |
439 | | |
440 | | inline void BCData::SetCorner(BCPixelSize aSubSize, |
441 | | mozilla::LogicalSide aOwnerSide, |
442 | | bool aBevel) |
443 | | { |
444 | | mCornerSubSize = aSubSize; |
445 | | mCornerSide = aOwnerSide; |
446 | | mCornerBevel = aBevel; |
447 | | } |
448 | | |
449 | | #endif |