LCOV - code coverage report
Current view: top level - layout/tables - celldata.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 104 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 29 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : typedef uint16_t BCPixelSize;
     148             : 
     149             : // These are the max sizes that are stored. If they are exceeded, then the max is stored and
     150             : // the actual value is computed when needed.
     151             : #define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1)
     152             : 
     153             : // The half of border on inline/block-axis start side
     154             : static inline BCPixelSize
     155           0 : BC_BORDER_START_HALF(BCPixelSize px) { return px - px / 2; }
     156             : // The half of border on inline/block-axis end side
     157             : static inline BCPixelSize
     158           0 : BC_BORDER_END_HALF(BCPixelSize px) { return px / 2; }
     159             : 
     160             : static inline nscoord
     161           0 : BC_BORDER_START_HALF_COORD(int32_t p2t, BCPixelSize px)
     162           0 :   { return BC_BORDER_START_HALF(px) * p2t; }
     163             : static inline nscoord
     164           0 : BC_BORDER_END_HALF_COORD(int32_t p2t, BCPixelSize px)
     165           0 :   { return BC_BORDER_END_HALF(px) * p2t; }
     166             : 
     167             : // BCData stores the bstart and istart border info and the corner connecting the two.
     168             : class BCData
     169             : {
     170             : public:
     171             :   BCData();
     172             : 
     173             :   ~BCData();
     174             : 
     175             :   nscoord GetIStartEdge(BCBorderOwner& aOwner,
     176             :                         bool&          aStart) const;
     177             : 
     178             :   void SetIStartEdge(BCBorderOwner aOwner,
     179             :                      nscoord       aSize,
     180             :                      bool          aStart);
     181             : 
     182             :   nscoord GetBStartEdge(BCBorderOwner& aOwner,
     183             :                         bool&          aStart) const;
     184             : 
     185             :   void SetBStartEdge(BCBorderOwner aOwner,
     186             :                      nscoord       aSize,
     187             :                      bool          aStart);
     188             : 
     189             :   BCPixelSize GetCorner(mozilla::LogicalSide& aCornerOwner,
     190             :                         bool&                 aBevel) const;
     191             : 
     192             :   void SetCorner(BCPixelSize          aSubSize,
     193             :                  mozilla::LogicalSide aOwner,
     194             :                  bool                 aBevel);
     195             : 
     196             :   bool IsIStartStart() const;
     197             : 
     198             :   void SetIStartStart(bool aValue);
     199             : 
     200             :   bool IsBStartStart() const;
     201             : 
     202             :   void SetBStartStart(bool aValue);
     203             : 
     204             : 
     205             : protected:
     206             :   BCPixelSize mIStartSize;    // size in pixels of iStart border
     207             :   BCPixelSize mBStartSize;    // size in pixels of bStart border
     208             :   BCPixelSize mCornerSubSize; // size of the largest border not in the
     209             :                               //   dominant plane (for example, if corner is
     210             :                               //   owned by the segment to its bStart or bEnd,
     211             :                               //   then the size is the max of the border
     212             :                               //   sizes of the segments to its iStart or iEnd.
     213             :   unsigned mIStartOwner:   4; // owner of iStart border
     214             :   unsigned mBStartOwner:   4; // owner of bStart border
     215             :   unsigned mIStartStart:   1; // set if this is the start of a block-dir border segment
     216             :   unsigned mBStartStart:   1; // set if this is the start of an inline-dir border segment
     217             :   unsigned mCornerSide:    2; // LogicalSide of the owner of the bStart-iStart corner relative to the corner
     218             :   unsigned mCornerBevel:   1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
     219             : };
     220             : 
     221             : // BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
     222             : // effect. BCData for a row and col entry contains the left and top borders of cell at that row and
     223             : // col and the corner connecting the two. The right borders of the cells in the last col and the bottom
     224             : // borders of the last row are stored in separate BCData entries in the cell map.
     225             : class BCCellData : public CellData
     226             : {
     227             : public:
     228             :   explicit BCCellData(nsTableCellFrame* aOrigCell);
     229             :   ~BCCellData();
     230             : 
     231             :   BCData mData;
     232             : };
     233             : 
     234             : 
     235             : // The layout of a celldata is as follows.  The top 10 bits are the colspan
     236             : // offset (which is enough to represent our allowed values 1-1000 for colspan).
     237             : // Then there are two bits of flags.
     238             : // XXXmats Then one unused bit that we should decide how to use in bug 862624.
     239             : // Then 16 bits of rowspan offset (which
     240             : // lets us represent numbers up to 65535.  Then another 3 bits of flags.
     241             : 
     242             : // num bits to shift right to get right aligned col span
     243             : #define COL_SPAN_SHIFT   22
     244             : // num bits to shift right to get right aligned row span
     245             : #define ROW_SPAN_SHIFT   3
     246             : 
     247             : // the col offset to the data containing the original cell.
     248             : #define COL_SPAN_OFFSET  (0x3FF << COL_SPAN_SHIFT)
     249             : // the row offset to the data containing the original cell
     250             : #define ROW_SPAN_OFFSET  (0xFFFF << ROW_SPAN_SHIFT)
     251             : 
     252             : // And the flags
     253             : #define SPAN             0x00000001 // there a row or col span
     254             : #define ROW_SPAN         0x00000002 // there is a row span
     255             : #define ROW_SPAN_0       0x00000004 // the row span is 0
     256             : #define COL_SPAN         (1 << (COL_SPAN_SHIFT - 2)) // there is a col span
     257             : #define OVERLAP          (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
     258             :                                                      // col span but not by
     259             :                                                      // same cell
     260             : 
     261           0 : inline nsTableCellFrame* CellData::GetCellFrame() const
     262             : {
     263           0 :   if (SPAN != (SPAN & mBits)) {
     264           0 :     return mOrigCell;
     265             :   }
     266           0 :   return nullptr;
     267             : }
     268             : 
     269           0 : inline void CellData::Init(nsTableCellFrame* aCellFrame)
     270             : {
     271           0 :   mOrigCell = aCellFrame;
     272           0 : }
     273             : 
     274           0 : inline bool CellData::IsOrig() const
     275             : {
     276           0 :   return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits)));
     277             : }
     278             : 
     279           0 : inline bool CellData::IsDead() const
     280             : {
     281           0 :   return (0 == mBits);
     282             : }
     283             : 
     284           0 : inline bool CellData::IsSpan() const
     285             : {
     286           0 :   return (SPAN == (SPAN & mBits));
     287             : }
     288             : 
     289           0 : inline bool CellData::IsRowSpan() const
     290             : {
     291           0 :   return (SPAN     == (SPAN & mBits)) &&
     292           0 :          (ROW_SPAN == (ROW_SPAN & mBits));
     293             : }
     294             : 
     295           0 : inline bool CellData::IsZeroRowSpan() const
     296             : {
     297           0 :   return (SPAN       == (SPAN & mBits))     &&
     298           0 :          (ROW_SPAN   == (ROW_SPAN & mBits)) &&
     299           0 :          (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
     300             : }
     301             : 
     302           0 : inline void CellData::SetZeroRowSpan(bool aIsZeroSpan)
     303             : {
     304           0 :   if (SPAN == (SPAN & mBits)) {
     305           0 :     if (aIsZeroSpan) {
     306           0 :       mBits |= ROW_SPAN_0;
     307             :     }
     308             :     else {
     309           0 :       mBits &= ~ROW_SPAN_0;
     310             :     }
     311             :   }
     312           0 : }
     313             : 
     314           0 : inline uint32_t CellData::GetRowSpanOffset() const
     315             : {
     316           0 :   if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
     317           0 :     return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
     318             :   }
     319           0 :   return 0;
     320             : }
     321             : 
     322           0 : inline void CellData::SetRowSpanOffset(uint32_t aSpan)
     323             : {
     324           0 :   mBits &= ~ROW_SPAN_OFFSET;
     325           0 :   mBits |= (aSpan << ROW_SPAN_SHIFT);
     326           0 :   mBits |= SPAN;
     327           0 :   mBits |= ROW_SPAN;
     328           0 : }
     329             : 
     330           0 : inline bool CellData::IsColSpan() const
     331             : {
     332           0 :   return (SPAN     == (SPAN & mBits)) &&
     333           0 :          (COL_SPAN == (COL_SPAN & mBits));
     334             : }
     335             : 
     336           0 : inline uint32_t CellData::GetColSpanOffset() const
     337             : {
     338           0 :   if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
     339           0 :     return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
     340             :   }
     341           0 :   return 0;
     342             : }
     343             : 
     344           0 : inline void CellData::SetColSpanOffset(uint32_t aSpan)
     345             : {
     346           0 :   mBits &= ~COL_SPAN_OFFSET;
     347           0 :   mBits |= (aSpan << COL_SPAN_SHIFT);
     348             : 
     349           0 :   mBits |= SPAN;
     350           0 :   mBits |= COL_SPAN;
     351           0 : }
     352             : 
     353           0 : inline bool CellData::IsOverlap() const
     354             : {
     355           0 :   return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
     356             : }
     357             : 
     358           0 : inline void CellData::SetOverlap(bool aOverlap)
     359             : {
     360           0 :   if (SPAN == (SPAN & mBits)) {
     361           0 :     if (aOverlap) {
     362           0 :       mBits |= OVERLAP;
     363             :     }
     364             :     else {
     365           0 :       mBits &= ~OVERLAP;
     366             :     }
     367             :   }
     368           0 : }
     369             : 
     370           0 : inline BCData::BCData()
     371             : {
     372           0 :   mIStartOwner = mBStartOwner = eCellOwner;
     373           0 :   mIStartStart = mBStartStart = 1;
     374           0 :   mIStartSize = mCornerSubSize = mBStartSize = 0;
     375           0 :   mCornerSide = mozilla::eLogicalSideBStart;
     376           0 :   mCornerBevel = false;
     377           0 : }
     378             : 
     379           0 : inline BCData::~BCData()
     380             : {
     381           0 : }
     382             : 
     383           0 : inline nscoord BCData::GetIStartEdge(BCBorderOwner& aOwner,
     384             :                                      bool&          aStart) const
     385             : {
     386           0 :   aOwner = (BCBorderOwner)mIStartOwner;
     387           0 :   aStart = (bool)mIStartStart;
     388             : 
     389           0 :   return (nscoord)mIStartSize;
     390             : }
     391             : 
     392           0 : inline void BCData::SetIStartEdge(BCBorderOwner  aOwner,
     393             :                                   nscoord        aSize,
     394             :                                   bool           aStart)
     395             : {
     396           0 :   mIStartOwner = aOwner;
     397           0 :   mIStartSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
     398           0 :   mIStartStart = aStart;
     399           0 : }
     400             : 
     401           0 : inline nscoord BCData::GetBStartEdge(BCBorderOwner& aOwner,
     402             :                                      bool&          aStart) const
     403             : {
     404           0 :   aOwner = (BCBorderOwner)mBStartOwner;
     405           0 :   aStart = (bool)mBStartStart;
     406             : 
     407           0 :   return (nscoord)mBStartSize;
     408             : }
     409             : 
     410           0 : inline void BCData::SetBStartEdge(BCBorderOwner  aOwner,
     411             :                                   nscoord        aSize,
     412             :                                   bool           aStart)
     413             : {
     414           0 :   mBStartOwner = aOwner;
     415           0 :   mBStartSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
     416           0 :   mBStartStart = aStart;
     417           0 : }
     418             : 
     419           0 : inline BCPixelSize BCData::GetCorner(mozilla::LogicalSide& aOwnerSide,
     420             :                                      bool&                 aBevel) const
     421             : {
     422           0 :   aOwnerSide = mozilla::LogicalSide(mCornerSide);
     423           0 :   aBevel     = (bool)mCornerBevel;
     424           0 :   return mCornerSubSize;
     425             : }
     426             : 
     427           0 : inline void BCData::SetCorner(BCPixelSize          aSubSize,
     428             :                               mozilla::LogicalSide aOwnerSide,
     429             :                               bool                 aBevel)
     430             : {
     431           0 :   mCornerSubSize = aSubSize;
     432           0 :   mCornerSide    = aOwnerSide;
     433           0 :   mCornerBevel   = aBevel;
     434           0 : }
     435             : 
     436             : inline bool BCData::IsIStartStart() const
     437             : {
     438             :   return (bool)mIStartStart;
     439             : }
     440             : 
     441             : inline void BCData::SetIStartStart(bool aValue)
     442             : {
     443             :   mIStartStart = aValue;
     444             : }
     445             : 
     446           0 : inline bool BCData::IsBStartStart() const
     447             : {
     448           0 :   return (bool)mBStartStart;
     449             : }
     450             : 
     451           0 : inline void BCData::SetBStartStart(bool aValue)
     452             : {
     453           0 :   mBStartStart = aValue;
     454           0 : }
     455             : 
     456             : #endif

Generated by: LCOV version 1.13