зеркало из https://github.com/mozilla/gecko-dev.git
400 строки
11 KiB
C++
400 строки
11 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.1 (the "License"); you may not use this file except in
|
|
* compliance with the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is
|
|
* Netscape Communications Corporation.
|
|
* Portions created by the Initial Developer are Copyright (C) 1998
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the NPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the NPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
#ifndef CellData_h__
|
|
#define CellData_h__
|
|
|
|
#include "nsISupports.h"
|
|
#include "nsCoord.h"
|
|
|
|
class nsTableCellFrame;
|
|
|
|
/**
|
|
* Data stored by nsCellMap to rationalize rowspan and colspan cells.
|
|
*/
|
|
class CellData
|
|
{
|
|
public:
|
|
CellData(nsTableCellFrame* aOrigCell);
|
|
|
|
~CellData();
|
|
|
|
void Init(nsTableCellFrame* aCellFrame);
|
|
PRBool IsOrig() const;
|
|
PRBool IsDead() const;
|
|
PRBool IsSpan() const;
|
|
|
|
PRBool IsRowSpan() const;
|
|
PRBool IsZeroRowSpan() const;
|
|
void SetZeroRowSpan(PRBool aIsZero);
|
|
PRUint32 GetRowSpanOffset() const;
|
|
void SetRowSpanOffset(PRUint32 aSpan);
|
|
|
|
PRBool IsColSpan() const;
|
|
PRBool IsZeroColSpan() const;
|
|
void SetZeroColSpan(PRBool aIsZero);
|
|
PRUint32 GetColSpanOffset() const;
|
|
void SetColSpanOffset(PRUint32 aSpan);
|
|
|
|
PRBool IsOverlap() const;
|
|
void SetOverlap(PRBool aOverlap);
|
|
|
|
nsTableCellFrame* GetCellFrame() const;
|
|
|
|
protected:
|
|
|
|
// this union relies on the assumption that an object (not primitive type) does
|
|
// not start on an odd bit boundary. If mSpan is 0 then mOrigCell is in effect
|
|
// and the data does not represent a span. If mSpan is 1, then mBits is in
|
|
// effect and the data represents a span.
|
|
union {
|
|
nsTableCellFrame* mOrigCell;
|
|
long mBits;
|
|
};
|
|
};
|
|
|
|
// Border Collapsing Cell Data
|
|
enum BCBorderOwner
|
|
{
|
|
eTableOwner = 0,
|
|
eColGroupOwner = 1,
|
|
eAjaColGroupOwner = 2, // col group to the left
|
|
eColOwner = 3,
|
|
eAjaColOwner = 4, // col to the left
|
|
eRowGroupOwner = 5,
|
|
eAjaRowGroupOwner = 6, // row group above
|
|
eRowOwner = 7,
|
|
eAjaRowOwner = 8, // row above
|
|
eCellOwner = 9,
|
|
eAjaCellOwner = 10 // cell to the top or to the left
|
|
};
|
|
|
|
// These are the max sizes that are stored. If they are exceeded, then the max is stored and
|
|
// the actual value is computed when needed.
|
|
#define MAX_BORDER_WIDTH 64
|
|
#define MAX_CORNER_SUB_WIDTH 128
|
|
|
|
// BCData stores the top and left border info and the corner connecting the two.
|
|
class BCData
|
|
{
|
|
public:
|
|
BCData();
|
|
|
|
~BCData();
|
|
|
|
nscoord GetLeftEdge(BCBorderOwner& aOwner,
|
|
PRBool& aStart) const;
|
|
|
|
void SetLeftEdge(BCBorderOwner aOwner,
|
|
nscoord aSize,
|
|
PRBool aStart);
|
|
|
|
nscoord GetTopEdge(BCBorderOwner& aOwner,
|
|
PRBool& aStart) const;
|
|
|
|
void SetTopEdge(BCBorderOwner aOwner,
|
|
nscoord aSize,
|
|
PRBool aStart);
|
|
|
|
PRUint8 GetCorner(PRUint8& aCornerOwner,
|
|
PRPackedBool& aBevel) const;
|
|
|
|
void SetCorner(PRUint8 aOwner,
|
|
PRUint8 aSubSize,
|
|
PRBool aBevel);
|
|
|
|
PRBool IsLeftStart() const;
|
|
|
|
void SetLeftStart(PRBool aValue);
|
|
|
|
PRBool IsTopStart() const;
|
|
|
|
void SetTopStart(PRBool aValue);
|
|
|
|
|
|
protected:
|
|
unsigned mLeftOwner: 4; // owner of left border
|
|
unsigned mLeftSize: 6; // size in pixels of left border
|
|
unsigned mLeftStart: 1; // set if this is the start of a vertical border segment
|
|
unsigned mCornerSide: 2; // side of the owner of the upper left corner relative to the corner
|
|
unsigned mCornerSubSize: 7; // size of the largest border not in the dominate plane (for example, if
|
|
// corner is owned by the segment to its top or bottom, then the size is the
|
|
// max of the border sizes of the segments to its left or right.
|
|
unsigned mCornerBevel: 1; // is the corner beveled (only two segments, perpendicular, not dashed or dotted).
|
|
unsigned mTopOwner: 4; // owner of top border
|
|
unsigned mTopSize: 6; // size in pixels of top border
|
|
unsigned mTopStart: 1; // set if this is the start of a horizontal border segment
|
|
};
|
|
|
|
// BCCellData entries replace CellData entries in the cell map if the border collapsing model is in
|
|
// effect. BCData for a row and col entry contains the left and top borders of cell at that row and
|
|
// col and the corner connecting the two. The right borders of the cells in the last col and the bottom
|
|
// borders of the last row are stored in separate BCData entries in the cell map.
|
|
class BCCellData : public CellData
|
|
{
|
|
public:
|
|
BCCellData(nsTableCellFrame* aOrigCell);
|
|
~BCCellData();
|
|
|
|
BCData mData;
|
|
};
|
|
|
|
|
|
#define SPAN 0x00000001 // there a row or col span
|
|
#define ROW_SPAN 0x00000002 // there is a row span
|
|
#define ROW_SPAN_0 0x00000004 // the row span is 0
|
|
#define ROW_SPAN_OFFSET 0x0000FFF8 // the row offset to the data containing the original cell
|
|
#define COL_SPAN 0x00010000 // there is a col span
|
|
#define COL_SPAN_0 0x00020000 // the col span is 0
|
|
#define OVERLAP 0x00040000 // there is a row span and col span but no by same cell
|
|
#define COL_SPAN_OFFSET 0xFFF80000 // the col offset to the data containing the original cell
|
|
#define ROW_SPAN_SHIFT 3 // num bits to shift to get right justified col span
|
|
#define COL_SPAN_SHIFT 19 // num bits to shift to get right justified col span
|
|
|
|
inline nsTableCellFrame* CellData::GetCellFrame() const
|
|
{
|
|
if (SPAN != (SPAN & mBits)) {
|
|
return mOrigCell;
|
|
}
|
|
return nsnull;
|
|
}
|
|
|
|
inline void CellData::Init(nsTableCellFrame* aCellFrame)
|
|
{
|
|
mOrigCell = aCellFrame;
|
|
}
|
|
|
|
inline PRBool CellData::IsOrig() const
|
|
{
|
|
return ((nsnull != mOrigCell) && (SPAN != (SPAN & mBits)));
|
|
}
|
|
|
|
inline PRBool CellData::IsDead() const
|
|
{
|
|
return (0 == mBits);
|
|
}
|
|
|
|
inline PRBool CellData::IsSpan() const
|
|
{
|
|
return (SPAN == (SPAN & mBits));
|
|
}
|
|
|
|
inline PRBool CellData::IsRowSpan() const
|
|
{
|
|
return (SPAN == (SPAN & mBits)) &&
|
|
(ROW_SPAN == (ROW_SPAN & mBits));
|
|
}
|
|
|
|
inline PRBool CellData::IsZeroRowSpan() const
|
|
{
|
|
return (SPAN == (SPAN & mBits)) &&
|
|
(ROW_SPAN == (ROW_SPAN & mBits)) &&
|
|
(ROW_SPAN_0 == (ROW_SPAN_0 & mBits));
|
|
}
|
|
|
|
inline void CellData::SetZeroRowSpan(PRBool aIsZeroSpan)
|
|
{
|
|
if (SPAN == (SPAN & mBits)) {
|
|
if (aIsZeroSpan) {
|
|
mBits |= ROW_SPAN_0;
|
|
}
|
|
else {
|
|
mBits &= ~ROW_SPAN_0;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline PRUint32 CellData::GetRowSpanOffset() const
|
|
{
|
|
if ((SPAN == (SPAN & mBits)) && ((ROW_SPAN == (ROW_SPAN & mBits)))) {
|
|
return (PRUint32)((mBits & ROW_SPAN_OFFSET) >> ROW_SPAN_SHIFT);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline void CellData::SetRowSpanOffset(PRUint32 aSpan)
|
|
{
|
|
mBits &= ~ROW_SPAN_OFFSET;
|
|
mBits |= (aSpan << ROW_SPAN_SHIFT);
|
|
mBits |= SPAN;
|
|
mBits |= ROW_SPAN;
|
|
}
|
|
|
|
inline PRBool CellData::IsColSpan() const
|
|
{
|
|
return (SPAN == (SPAN & mBits)) &&
|
|
(COL_SPAN == (COL_SPAN & mBits));
|
|
}
|
|
|
|
inline PRBool CellData::IsZeroColSpan() const
|
|
{
|
|
return (SPAN == (SPAN & mBits)) &&
|
|
(COL_SPAN == (COL_SPAN & mBits)) &&
|
|
(COL_SPAN_0 == (COL_SPAN_0 & mBits));
|
|
}
|
|
|
|
inline void CellData::SetZeroColSpan(PRBool aIsZeroSpan)
|
|
{
|
|
if (SPAN == (SPAN & mBits)) {
|
|
if (aIsZeroSpan) {
|
|
mBits |= COL_SPAN_0;
|
|
}
|
|
else {
|
|
mBits &= ~COL_SPAN_0;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline PRUint32 CellData::GetColSpanOffset() const
|
|
{
|
|
if ((SPAN == (SPAN & mBits)) && ((COL_SPAN == (COL_SPAN & mBits)))) {
|
|
return (PRUint32)((mBits & COL_SPAN_OFFSET) >> COL_SPAN_SHIFT);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
inline void CellData::SetColSpanOffset(PRUint32 aSpan)
|
|
{
|
|
mBits &= ~COL_SPAN_OFFSET;
|
|
mBits |= (aSpan << COL_SPAN_SHIFT);
|
|
|
|
mBits |= SPAN;
|
|
mBits |= COL_SPAN;
|
|
}
|
|
|
|
inline PRBool CellData::IsOverlap() const
|
|
{
|
|
return (SPAN == (SPAN & mBits)) && (OVERLAP == (OVERLAP & mBits));
|
|
}
|
|
|
|
inline void CellData::SetOverlap(PRBool aOverlap)
|
|
{
|
|
if (SPAN == (SPAN & mBits)) {
|
|
if (aOverlap) {
|
|
mBits |= OVERLAP;
|
|
}
|
|
else {
|
|
mBits &= ~OVERLAP;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline BCData::BCData()
|
|
{
|
|
mLeftOwner = mTopOwner = eCellOwner;
|
|
mLeftStart = mTopStart = 1;
|
|
mLeftSize = mCornerSide = mCornerSubSize = mTopSize = 0;
|
|
}
|
|
|
|
inline BCData::~BCData()
|
|
{
|
|
}
|
|
|
|
inline nscoord BCData::GetLeftEdge(BCBorderOwner& aOwner,
|
|
PRBool& aStart) const
|
|
{
|
|
aOwner = (BCBorderOwner)mLeftOwner;
|
|
aStart = (PRBool)mLeftStart;
|
|
|
|
return (nscoord)mLeftSize;
|
|
}
|
|
|
|
inline void BCData::SetLeftEdge(BCBorderOwner aOwner,
|
|
nscoord aSize,
|
|
PRBool aStart)
|
|
{
|
|
mLeftOwner = aOwner;
|
|
mLeftSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
|
mLeftStart = aStart;
|
|
}
|
|
|
|
inline nscoord BCData::GetTopEdge(BCBorderOwner& aOwner,
|
|
PRBool& aStart) const
|
|
{
|
|
aOwner = (BCBorderOwner)mTopOwner;
|
|
aStart = (PRBool)mTopStart;
|
|
|
|
return (nscoord)mTopSize;
|
|
}
|
|
|
|
inline void BCData::SetTopEdge(BCBorderOwner aOwner,
|
|
nscoord aSize,
|
|
PRBool aStart)
|
|
{
|
|
mTopOwner = aOwner;
|
|
mTopSize = (aSize > MAX_BORDER_WIDTH) ? MAX_BORDER_WIDTH : aSize;
|
|
mTopStart = aStart;
|
|
}
|
|
|
|
inline PRUint8 BCData::GetCorner(PRUint8& aOwnerSide,
|
|
PRPackedBool& aBevel) const
|
|
{
|
|
aOwnerSide = mCornerSide;
|
|
aBevel = (PRBool)mCornerBevel;
|
|
return (PRUint8)mCornerSubSize;
|
|
}
|
|
|
|
inline void BCData::SetCorner(PRUint8 aSubSize,
|
|
PRUint8 aOwnerSide,
|
|
PRBool aBevel)
|
|
{
|
|
mCornerSubSize = (aSubSize > MAX_CORNER_SUB_WIDTH) ? MAX_CORNER_SUB_WIDTH : aSubSize;
|
|
mCornerSide = aOwnerSide;
|
|
mCornerBevel = aBevel;
|
|
}
|
|
|
|
inline PRBool BCData::IsLeftStart() const
|
|
{
|
|
return (PRBool)mLeftStart;
|
|
}
|
|
|
|
inline void BCData::SetLeftStart(PRBool aValue)
|
|
{
|
|
mLeftStart = aValue;
|
|
}
|
|
|
|
inline PRBool BCData::IsTopStart() const
|
|
{
|
|
return (PRBool)mTopStart;
|
|
}
|
|
|
|
inline void BCData::SetTopStart(PRBool aValue)
|
|
{
|
|
mTopStart = aValue;
|
|
}
|
|
|
|
#endif
|