layout/tables/celldata.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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__
     8 #include "nsISupports.h"
     9 #include "nsCoord.h"
    10 #include "mozilla/gfx/Types.h"
    11 #include <stdint.h>
    13 class nsTableCellFrame;
    14 class nsCellMap;
    15 class BCCellData;
    18 #define MAX_ROWSPAN 65534 // the cellmap can not handle more.
    19 #define MAX_COLSPAN 1000 // limit as IE and opera do.  If this ever changes,
    20                          // change COL_SPAN_OFFSET/COL_SPAN_SHIFT accordingly.
    22 /**
    23   * Data stored by nsCellMap to rationalize rowspan and colspan cells.
    24   */
    25 class CellData
    26 {
    27 public:
    28   /** Initialize the mOrigCell pointer
    29     * @param aOrigCell  the table cell frame which will be stored in mOrigCell.
    30     */
    31   void   Init(nsTableCellFrame* aCellFrame);
    33   /** does a cell originate from here
    34     * @return    is true if a cell corresponds to this cellmap entry
    35     */
    36   bool IsOrig() const;
    38   /** is the celldata valid
    39     * @return    is true if no cell originates and the cell is not spanned by
    40     *            a row- or colspan. mBits are 0 in this case and mOrigCell is
    41     *            nullptr
    42     */
    43   bool IsDead() const;
    45   /** is the entry spanned by row- or a colspan
    46     * @return    is true if the entry is spanned by a row- or colspan
    47     */
    48   bool IsSpan() const;
    50   /** is the entry spanned by rowspan
    51     * @return    is true if the entry is spanned by a rowspan
    52     */
    53   bool IsRowSpan() const;
    55   /** is the entry spanned by a zero rowspan
    56     * zero rowspans span all cells starting from the originating cell down to
    57     * the end of the rowgroup or a cell originating in the same column
    58     * @return    is true if the entry is spanned by a zero rowspan
    59     */
    60   bool IsZeroRowSpan() const;
    62   /** mark the current entry as spanned by a zero rowspan
    63     * @param aIsZero    if true mark the entry as covered by a zero rowspan
    64     */
    65   void SetZeroRowSpan(bool aIsZero);
    67   /** get the distance from the current entry to the corresponding origin of the rowspan
    68     * @return    containing the distance in the column to the originating cell
    69     */
    70   uint32_t GetRowSpanOffset() const;
    72   /** set the distance from the current entry to the corresponding origin of the rowspan
    73     * @param    the distance in the column to the originating cell
    74     */
    75   void SetRowSpanOffset(uint32_t aSpan);
    77   /** is the entry spanned by colspan
    78     * @return    is true if the entry is spanned by a colspan
    79     */
    80   bool IsColSpan() const;
    82   /** is the entry spanned by a zero colspan
    83     * zero colspans span all cells starting from the originating cell towards
    84     * the end of the colgroup or a cell originating in the same row
    85     * or a rowspanned entry
    86     * @return    is true if the entry is spanned by a zero colspan
    87     */
    88   bool IsZeroColSpan() const;
    90   /** mark the current entry as spanned by a zero colspan
    91     * @param aIsZero    if true mark the entry as covered by a zero colspan
    92     */
    93   void SetZeroColSpan(bool aIsZero);
    95   /** get the distance from the current entry to the corresponding origin of the colspan
    96     * @return    containing the distance in the row to the originating cell
    97     */
    98   uint32_t GetColSpanOffset() const;
   100   /** set the distance from the current entry to the corresponding origin of the colspan
   101     * @param    the distance in the column to the originating cell
   102     */
   103   void SetColSpanOffset(uint32_t aSpan);
   105   /** is the entry spanned by a row- and a colspan
   106     * @return    is true if the entry is spanned by a row- and a colspan
   107     */
   108   bool IsOverlap() const;
   110   /** mark the current entry as spanned by a row- and a colspan
   111     * @param aOverlap    if true mark the entry as covered by a row- and a colspan
   112     */
   113   void SetOverlap(bool aOverlap);
   115   /** get the table cell frame for this entry
   116     * @return    a pointer to the cellframe, this will be nullptr when the entry
   117     *            is only a spanned entry
   118     */
   119   nsTableCellFrame* GetCellFrame() const;
   121 private:
   122   friend class nsCellMap;
   123   friend class BCCellData;
   125   /** constructor.
   126     * @param aOrigCell  the table cell frame which will be stored in mOrigCell.
   127     */
   128   CellData(nsTableCellFrame* aOrigCell);  // implemented in nsCellMap.cpp
   130   /** destructor */
   131   ~CellData(); // implemented in nsCellMap.cpp
   133 protected:
   135   // this union relies on the assumption that an object (not primitive type) does
   136   // not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in effect
   137   // and the data does not represent a span. If mSpan is 1, then mBits is in
   138   // effect and the data represents a span.
   139   // mBits must match the size of mOrigCell on both 32- and 64-bit platforms.
   140   union {
   141     nsTableCellFrame* mOrigCell;
   142     uintptr_t         mBits;
   143   };
   144 };
   146 // Border Collapsing Cell Data
   147 enum BCBorderOwner
   148 {
   149   eTableOwner        =  0,
   150   eColGroupOwner     =  1,
   151   eAjaColGroupOwner  =  2, // col group to the left
   152   eColOwner          =  3,
   153   eAjaColOwner       =  4, // col to the left
   154   eRowGroupOwner     =  5,
   155   eAjaRowGroupOwner  =  6, // row group above
   156   eRowOwner          =  7,
   157   eAjaRowOwner       =  8, // row above
   158   eCellOwner         =  9,
   159   eAjaCellOwner      = 10  // cell to the top or to the left
   160 };
   162 typedef uint16_t BCPixelSize;
   164 // These are the max sizes that are stored. If they are exceeded, then the max is stored and
   165 // the actual value is computed when needed.
   166 #define MAX_BORDER_WIDTH nscoord((1u << (sizeof(BCPixelSize) * 8)) - 1)
   168 static inline nscoord
   169 BC_BORDER_TOP_HALF_COORD(int32_t p2t, uint16_t px)    { return (px - px / 2) * p2t; }
   170 static inline nscoord
   171 BC_BORDER_RIGHT_HALF_COORD(int32_t p2t, uint16_t px)  { return (     px / 2) * p2t; }
   172 static inline nscoord
   173 BC_BORDER_BOTTOM_HALF_COORD(int32_t p2t, uint16_t px) { return (     px / 2) * p2t; }
   174 static inline nscoord
   175 BC_BORDER_LEFT_HALF_COORD(int32_t p2t, uint16_t px)   { return (px - px / 2) * p2t; }
   177 #define BC_BORDER_TOP_HALF(px)    ((px) - (px) / 2)
   178 #define BC_BORDER_RIGHT_HALF(px)  ((px) / 2)
   179 #define BC_BORDER_BOTTOM_HALF(px) ((px) / 2)
   180 #define BC_BORDER_LEFT_HALF(px)   ((px) - (px) / 2)
   182 // BCData stores the top and left border info and the corner connecting the two.
   183 class BCData
   184 {
   185 public:
   186   BCData();
   188   ~BCData();
   190   nscoord GetLeftEdge(BCBorderOwner& aOwner,
   191                       bool&        aStart) const;
   193   void SetLeftEdge(BCBorderOwner aOwner,
   194                    nscoord       aSize,
   195                    bool          aStart);
   197   nscoord GetTopEdge(BCBorderOwner& aOwner,
   198                      bool&        aStart) const;
   200   void SetTopEdge(BCBorderOwner aOwner,
   201                   nscoord       aSize,
   202                   bool          aStart);
   204   BCPixelSize GetCorner(mozilla::css::Side&       aCornerOwner,
   205                         bool&  aBevel) const;
   207   void SetCorner(BCPixelSize aSubSize,
   208                  mozilla::css::Side aOwner,
   209                  bool    aBevel);
   211   bool IsLeftStart() const;
   213   void SetLeftStart(bool aValue);
   215   bool IsTopStart() const;
   217   void SetTopStart(bool aValue);
   220 protected:
   221   BCPixelSize mLeftSize;      // size in pixels of left border
   222   BCPixelSize mTopSize;       // size in pixels of top border
   223   BCPixelSize mCornerSubSize; // size of the largest border not in the
   224                               //   dominant plane (for example, if corner is
   225                               //   owned by the segment to its top or bottom,
   226                               //   then the size is the max of the border
   227                               //   sizes of the segments to its left or right.
   228   unsigned mLeftOwner:     4; // owner of left border
   229   unsigned mTopOwner:      4; // owner of top border
   230   unsigned mLeftStart:     1; // set if this is the start of a vertical border segment
   231   unsigned mTopStart:      1; // set if this is the start of a horizontal border segment
   232   unsigned mCornerSide:    2; // mozilla::css::Side of the owner of the upper left corner relative to the corner
   233   unsigned mCornerBevel:   1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
   234 };
   236 // BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
   237 // effect. BCData for a row and col entry contains the left and top borders of cell at that row and
   238 // col and the corner connecting the two. The right borders of the cells in the last col and the bottom
   239 // borders of the last row are stored in separate BCData entries in the cell map.
   240 class BCCellData : public CellData
   241 {
   242 public:
   243   BCCellData(nsTableCellFrame* aOrigCell);
   244   ~BCCellData();
   246   BCData mData;
   247 };
   250 // The layout of a celldata is as follows.  The top 10 bits are the colspan
   251 // offset (which is enough to represent our allowed values 1-1000 for colspan).
   252 // Then there are three bits of flags.  Then 16 bits of rowspan offset (which
   253 // lets us represent numbers up to 65535.  Then another 3 bits of flags.
   255 // num bits to shift right to get right aligned col span
   256 #define COL_SPAN_SHIFT   22
   257 // num bits to shift right to get right aligned row span
   258 #define ROW_SPAN_SHIFT   3
   260 // the col offset to the data containing the original cell.
   261 #define COL_SPAN_OFFSET  (0x3FF << COL_SPAN_SHIFT)
   262 // the row offset to the data containing the original cell
   263 #define ROW_SPAN_OFFSET  (0xFFFF << ROW_SPAN_SHIFT)
   265 // And the flags
   266 #define SPAN             0x00000001 // there a row or col span
   267 #define ROW_SPAN         0x00000002 // there is a row span
   268 #define ROW_SPAN_0       0x00000004 // the row span is 0
   269 #define COL_SPAN         (1 << (COL_SPAN_SHIFT - 3)) // there is a col span
   270 #define COL_SPAN_0       (1 << (COL_SPAN_SHIFT - 2)) // the col span is 0
   271 #define OVERLAP          (1 << (COL_SPAN_SHIFT - 1)) // there is a row span and
   272                                                      // col span but not by
   273                                                      // same cell
   275 inline nsTableCellFrame* CellData::GetCellFrame() const
   276 {
   277   if (SPAN != (SPAN & mBits)) {
   278     return mOrigCell;
   279   }
   280   return nullptr;
   281 }
   283 inline void CellData::Init(nsTableCellFrame* aCellFrame)
   284 {
   285   mOrigCell = aCellFrame;
   286 }
   288 inline bool CellData::IsOrig() const
   289 {
   290   return ((nullptr != mOrigCell) && (SPAN != (SPAN & mBits)));
   291 }
   293 inline bool CellData::IsDead() const
   294 {
   295   return (0 == mBits);
   296 }
   298 inline bool CellData::IsSpan() const
   299 {
   300   return (SPAN == (SPAN & mBits));
   301 }
   303 inline bool CellData::IsRowSpan() const
   304 {
   305   return (SPAN     == (SPAN & mBits)) &&
   306          (ROW_SPAN == (ROW_SPAN & mBits));
   307 }
   309 inline bool CellData::IsZeroRowSpan() const
   310 {
   311   return (SPAN       == (SPAN & mBits))     &&
   312          (ROW_SPAN   == (ROW_SPAN & mBits)) &&
   313          (ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
   314 }
   316 inline void CellData::SetZeroRowSpan(bool aIsZeroSpan)
   317 {
   318   if (SPAN == (SPAN & mBits)) {
   319     if (aIsZeroSpan) {
   320       mBits |= ROW_SPAN_0;
   321     }
   322     else {
   323       mBits &= ~ROW_SPAN_0;
   324     }
   325   }
   326 }
   328 inline uint32_t CellData::GetRowSpanOffset() const
   329 {
   330   if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
   331     return (uint32_t)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
   332   }
   333   return 0;
   334 }
   336 inline void CellData::SetRowSpanOffset(uint32_t aSpan)
   337 {
   338   mBits &= ~ROW_SPAN_OFFSET;
   339   mBits |= (aSpan << ROW_SPAN_SHIFT);
   340   mBits |= SPAN;
   341   mBits |= ROW_SPAN;
   342 }
   344 inline bool CellData::IsColSpan() const
   345 {
   346   return (SPAN     == (SPAN & mBits)) &&
   347          (COL_SPAN == (COL_SPAN & mBits));
   348 }
   350 inline bool CellData::IsZeroColSpan() const
   351 {
   352   return (SPAN       == (SPAN & mBits))     &&
   353          (COL_SPAN   == (COL_SPAN & mBits)) &&
   354          (COL_SPAN_0 == (COL_SPAN_0 & mBits));
   355 }
   357 inline void CellData::SetZeroColSpan(bool aIsZeroSpan)
   358 {
   359   if (SPAN == (SPAN & mBits)) {
   360     if (aIsZeroSpan) {
   361       mBits |= COL_SPAN_0;
   362     }
   363     else {
   364       mBits &= ~COL_SPAN_0;
   365     }
   366   }
   367 }
   369 inline uint32_t CellData::GetColSpanOffset() const
   370 {
   371   if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
   372     return (uint32_t)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
   373   }
   374   return 0;
   375 }
   377 inline void CellData::SetColSpanOffset(uint32_t aSpan)
   378 {
   379   mBits &= ~COL_SPAN_OFFSET;
   380   mBits |= (aSpan << COL_SPAN_SHIFT);
   382   mBits |= SPAN;
   383   mBits |= COL_SPAN;
   384 }
   386 inline bool CellData::IsOverlap() const
   387 {
   388   return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
   389 }
   391 inline void CellData::SetOverlap(bool aOverlap)
   392 {
   393   if (SPAN == (SPAN & mBits)) {
   394     if (aOverlap) {
   395       mBits |= OVERLAP;
   396     }
   397     else {
   398       mBits &= ~OVERLAP;
   399     }
   400   }
   401 }
   403 inline BCData::BCData()
   404 {
   405   mLeftOwner = mTopOwner = eCellOwner;
   406   mLeftStart = mTopStart = 1;
   407   mLeftSize = mCornerSubSize = mTopSize = 0;
   408   mCornerSide = NS_SIDE_TOP;
   409   mCornerBevel = false;
   410 }
   412 inline BCData::~BCData()
   413 {
   414 }
   416 inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
   417                                    bool&        aStart) const
   418 {
   419   aOwner = (BCBorderOwner)mLeftOwner;
   420   aStart = (bool)mLeftStart;
   422   return (nscoord)mLeftSize;
   423 }
   425 inline void BCData::SetLeftEdge(BCBorderOwner  aOwner,
   426                                 nscoord        aSize,
   427                                 bool           aStart)
   428 {
   429   mLeftOwner = aOwner;
   430   mLeftSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
   431   mLeftStart = aStart;
   432 }
   434 inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
   435                                   bool&        aStart) const
   436 {
   437   aOwner = (BCBorderOwner)mTopOwner;
   438   aStart = (bool)mTopStart;
   440   return (nscoord)mTopSize;
   441 }
   443 inline void BCData::SetTopEdge(BCBorderOwner  aOwner,
   444                                nscoord        aSize,
   445                                bool           aStart)
   446 {
   447   mTopOwner = aOwner;
   448   mTopSize  = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
   449   mTopStart = aStart;
   450 }
   452 inline BCPixelSize BCData::GetCorner(mozilla::css::Side& aOwnerSide,
   453                                      bool&       aBevel) const
   454 {
   455   aOwnerSide = mozilla::css::Side(mCornerSide);
   456   aBevel     = (bool)mCornerBevel;
   457   return mCornerSubSize;
   458 }
   460 inline void BCData::SetCorner(BCPixelSize aSubSize,
   461                               mozilla::css::Side aOwnerSide,
   462                               bool    aBevel)
   463 {
   464   mCornerSubSize = aSubSize;
   465   mCornerSide    = aOwnerSide;
   466   mCornerBevel   = aBevel;
   467 }
   469 inline bool BCData::IsLeftStart() const
   470 {
   471   return (bool)mLeftStart;
   472 }
   474 inline void BCData::SetLeftStart(bool aValue)
   475 {
   476   mLeftStart = aValue;
   477 }
   479 inline bool BCData::IsTopStart() const
   480 {
   481   return (bool)mTopStart;
   482 }
   484 inline void BCData::SetTopStart(bool aValue)
   485 {
   486   mTopStart = aValue;
   487 }
   489 #endif

mercurial