tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

celldata.h (12759B)


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