bugs 19061, 9879 - each top level row group gets its own cell map; CellData reduced to 4 bytes.

This commit is contained in:
karnaze%netscape.com 2000-01-13 05:29:38 +00:00
parent 3df7c0b3ac
commit d41822031d
26 changed files with 3452 additions and 1564 deletions

View File

@ -349,15 +349,15 @@ nsHTMLTableCellElement::StringToAttribute(nsIAtom* aAttribute,
}
}
/* attributes that resolve to integers with a min of 1 */
else if ((aAttribute == nsHTMLAtoms::colspan) ||
(aAttribute == nsHTMLAtoms::rowspan)) {
if (nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer)) {
(aAttribute == nsHTMLAtoms::rowspan)) {
if (nsGenericHTMLElement::ParseValue(aValue, -1, MAX_COLSPAN, aResult, eHTMLUnit_Integer)) {
PRInt32 val = aResult.GetIntValue();
if (val > MAX_COLSPAN) {
if (val < 0) {
nsHTMLUnit unit = aResult.GetUnit();
aResult.SetIntValue(MAX_COLSPAN, unit);
aResult.SetIntValue(1, unit);
}
return NS_CONTENT_ATTR_HAS_VALUE;
}
}

View File

@ -349,15 +349,15 @@ nsHTMLTableCellElement::StringToAttribute(nsIAtom* aAttribute,
}
}
/* attributes that resolve to integers with a min of 1 */
else if ((aAttribute == nsHTMLAtoms::colspan) ||
(aAttribute == nsHTMLAtoms::rowspan)) {
if (nsGenericHTMLElement::ParseValue(aValue, 1, aResult, eHTMLUnit_Integer)) {
(aAttribute == nsHTMLAtoms::rowspan)) {
if (nsGenericHTMLElement::ParseValue(aValue, -1, MAX_COLSPAN, aResult, eHTMLUnit_Integer)) {
PRInt32 val = aResult.GetIntValue();
if (val > MAX_COLSPAN) {
if (val < 0) {
nsHTMLUnit unit = aResult.GetUnit();
aResult.SetIntValue(MAX_COLSPAN, unit);
aResult.SetIntValue(1, unit);
}
return NS_CONTENT_ATTR_HAS_VALUE;
}
}

View File

@ -26,36 +26,176 @@
class nsTableCellFrame;
/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
* if mOrigCell is null then mSpanCell will be the rowspan/colspan source.
* if mSpanCell2 is non-null then it will point to a 2nd cell that overlaps this position
* @see nsCellMap
* @see nsTableFrame::BuildCellMap
* @see nsTableFrame::GrowCellMap
* @see nsTableFrame::BuildCellIntoMap
*
/**
* Data stored by nsCellMap to rationalize rowspan and colspan cells.
*/
class CellData
{
public:
CellData();
#ifndef NS_BUILD_REFCNT_LOGGING
CellData(nsTableCellFrame* aOrigCell, CellData* aRowSpanData, CellData* aColSpanData)
: mOrigCell(aOrigCell), mRowSpanData(aRowSpanData), mColSpanData(aColSpanData)
{
}
#else
CellData(nsTableCellFrame* aOrigCell, CellData* aRowSpanData,
CellData* aColSpanData);
#endif
CellData(nsTableCellFrame* aOrigCell);
~CellData();
nsTableCellFrame* mOrigCell;
CellData* mRowSpanData;
CellData* mColSpanData;
PRBool IsOrig() 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;
PRUint32 mBits;
};
};
#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 0x00010010 // there is a col span
#define COL_SPAN_0 0x00020010 // the col span is 0
#define OVERLAP 0x00040010 // there is a row span and col span but no by same cell
#define COL_SPAN_OFFSET 0xFFF80010 // 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 PRBool CellData::IsOrig() const
{
return (SPAN != (SPAN & 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;
}
else {
mBits &= ~ROW_SPAN;
}
}
}
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;
}
else {
mBits &= ~COL_SPAN;
}
}
}
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;
}
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@
class nsTableColFrame;
class nsTableCellFrame;
class nsIPresContext;
class nsTableRowGroupFrame;
class nsTableFrame;
class nsCellMap;
struct nsColInfo
{
@ -39,6 +42,107 @@ struct nsColInfo
PRInt32 aNumCellsSpan);
};
class nsTableCellMap
{
public:
nsTableCellMap(nsTableFrame& aTableFrame);
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
~nsTableCellMap();
void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
void InsertGroupCellMap(PRInt32 aRowIndex,
nsTableRowGroupFrame& aNewRowGroup);
void InsertGroupCellMap(nsTableRowGroupFrame* aPrevRowGroup,
nsTableRowGroupFrame& aNewRowGroup);
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
PRInt32 aColIndex,
CellData& aData,
PRBool aUseRowIfOverlap) const;
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex);
nsColInfo* GetColInfoAt(PRInt32 aColIndex);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRBool aRebuildIfNecessary);
void InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void RemoveCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void InsertRows(nsTableRowGroupFrame& aRowGroup,
nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
void RemoveRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
PRInt32 GetEffectiveColSpan(PRInt32 aColIndex,
const nsTableCellFrame* aCell);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
/** return the total number of columns in the table represented by this CellMap */
PRInt32 GetColCount() const;
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRBool* aOriginates = nsnull,
PRInt32* aColSpan = nsnull);
void AddColsAtEnd(PRUint32 aNumCols);
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
PRBool RowIsSpannedInto(PRInt32 aRowIndex);
PRBool RowHasSpanningCells(PRInt32 aRowIndex);
PRBool ColIsSpannedInto(PRInt32 aColIndex);
PRBool ColHasSpanningCells(PRInt32 aColIndex);
/** dump a representation of the cell map to stdout for debugging */
#ifdef NS_DEBUG
void Dump() const;
#endif
#ifdef DEBUG
void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
protected:
friend class nsCellMap;
void InsertGroupCellMap(nsCellMap* aPrevMap,
nsCellMap& aNewMap);
nsVoidArray mCols;
nsCellMap* mFirstMap;
};
/** nsCellMap is a support class for nsTablePart.
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
* This makes processing of rowspan and colspan attributes much easier.
@ -59,72 +163,89 @@ public:
* @param aNumRows - initial number of rows
* @param aNumColumns - initial number of columns
*/
nsCellMap(PRInt32 aNumRows,
PRInt32 aNumCols);
nsCellMap(nsTableRowGroupFrame& aRowGroupFrame);
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
~nsCellMap();
nsCellMap* GetNextSibling() const;
void SetNextSibling(nsCellMap* aSibling);
nsTableRowGroupFrame* GetRowGroup() const;
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
PRInt32 aColIndex,
CellData& aData,
PRBool aUseRowSpanIfOverlap) const;
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
void AppendCol();
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,
PRInt32 AppendCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRBool aRebuildIfNecessary);
void InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void InsertCells(nsTableCellMap& aMap,
nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void RemoveCell(nsTableCellFrame* aCellFrame,
void RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void InsertRows(nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
void RemoveCol(PRInt32 aColIndex);
void RemoveRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
void InsertRows(nsTableCellMap& aMap,
nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
PRInt32 GetNextAvailRowIndex();
void RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
PRInt32 GetEffectiveColSpan(nsTableCellFrame* aCell) const;
PRInt32 GetEffectiveColSpan(PRInt32 aColIndex,
const nsTableCellFrame* aCell) const;
PRInt32 GetEffectiveColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
const nsTableCellFrame* aCell);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
/** return the total number of columns in the table represented by this CellMap */
PRInt32 GetColCount() const;
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX) const;
PRInt32 aColX,
PRInt32 aNumColsInTable);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRInt32 aNumColsInTable,
PRBool* aOriginates = nsnull,
PRInt32* aColSpan = nsnull) const;
PRInt32* aColSpan = nsnull);
void AddColsAtEnd(PRUint32 aNumCols);
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
PRBool RowIsSpannedInto(PRInt32 aRowIndex,
PRInt32 aNumColsInTable);
PRBool RowIsSpannedInto(PRInt32 aRowIndex) const;
PRBool RowHasSpanningCells(PRInt32 aRowIndex) const;
PRBool ColIsSpannedInto(PRInt32 aColIndex) const;
PRBool ColHasSpanningCells(PRInt32 aColIndex) const;
PRBool RowHasSpanningCells(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRBool ColIsSpannedInto(PRInt32 aColIndex,
PRInt32 aNumCols);
PRBool ColHasSpanningCells(PRInt32 aColIndex,
PRInt32 aNumCols);
/** dump a representation of the cell map to stdout for debugging */
#ifdef NS_DEBUG
@ -136,115 +257,135 @@ public:
#endif
protected:
/** set the CellMap to (aNumRows x aNumColumns) */
void Grow(PRInt32 aNumMapRows,
PRInt32 aNumCols);
friend class nsTableCellMap;
PRBool Grow(nsTableCellMap& aMap,
PRInt32 aNumRows,
PRInt32 aRowIndex = -1);
void GrowRow(nsVoidArray& aRow,
PRInt32 aNumCols);
/** assign aCellData to the cell at (aRow,aColumn) */
void SetMapCellAt(CellData& aCellData,
PRInt32 aMapRowIndex,
PRInt32 aColIndex);
void SetMapCellAt(nsTableCellMap& aMap,
CellData& aCellData,
PRInt32 aMapRowIndex,
PRInt32 aColIndex,
PRBool aCountZeroSpanAsSpan);
CellData* GetMapCellAt(PRInt32 aMapRowIndex,
PRInt32 aColIndex) const;
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
void ExpandWithRows(nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex);
void ExpandWithRows(nsTableCellMap& aMap,
nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex);
void ExpandWithCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aRowSpan);
void ExpandWithCells(nsTableCellMap& aMap,
nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aRowSpan,
PRBool aRowSpanIsZero);
void ShrinkWithoutRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove);
void ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove);
void ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
void ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex);
void RebuildConsideringRows(PRInt32 aStartRowIndex,
nsVoidArray* aRowsToInsert,
PRInt32 aNumRowsToRemove = 0);
void RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex,
nsVoidArray* aRowsToInsert,
PRInt32 aNumRowsToRemove = 0);
void RebuildConsideringCells(nsVoidArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRBool aInsert);
void RebuildConsideringCells(nsTableCellMap& aMap,
nsVoidArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRBool aInsert);
PRBool CellsSpanOut(nsVoidArray& aNewRows);
PRBool CellsSpanInOrOut(PRInt32 aStartRowIndex,
PRInt32 aEndRowIndex,
PRInt32 aStartColIndex,
PRInt32 aEndColIndex);
PRInt32 aEndColIndex,
PRInt32 aNumColsInTable);
void ExpandForZeroSpan(nsTableCellFrame* aCellFrame,
PRInt32 aNumColsInTable);
PRBool CreateEmptyRow(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRInt32 GetColSpan(nsTableCellFrame& aCellFrameToAdd,
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
PRBool& aIsZeroColSpan);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
PRBool& aIsZeroColSpan);
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 aColIndex,
PRBool& aIsZeroRowSpan);
PRInt32 GetRowSpan(nsTableCellFrame& aCellFrameToAdd,
PRInt32 aRowIndex,
PRBool& aIsZeroRowSpan);
void AdjustForZeroSpan(PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
PRBool IsZeroColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
/** an array containing col array. It can be larger than mRowCount due to
* row spans extending beyond the table */
nsVoidArray mRows;
/** an array of nsColInfo indexed by col and giving the number of
* cells originating and spanning each col. */
nsVoidArray mCols;
/** the number of rows in the table which is <= the number of rows in the cell map
* due to row spans extending beyond the end of the table (dead rows) */
PRInt32 mRowCount;
PRInt32 mNextAvailRowIndex;
// the row group that corresponds to this map
nsTableRowGroupFrame* mRowGroupFrame;
// the next row group cell map
nsCellMap* mNextSibling;
};
/* ----- inline methods ----- */
inline CellData* nsCellMap::GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const
inline PRInt32 nsTableCellMap::GetColCount() const
{
if ((0 > aRowIndex) || (aRowIndex >= mRowCount) ||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
//bug 9024 tickled this
//printf("%s \n", "nsCellMap::GetCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
return nsnull;
}
CellData* result = nsnull;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
if (row)
result = (CellData *)(row->ElementAt(aColIndex));
return result;
}
inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
PRInt32 aColIndex) const
{
if ((0 > aMapRowIndex) || (aMapRowIndex >= mRows.Count()) ||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
//see bug 9024 comments above
//printf("%s \n", "nsCellMap::GetMapCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
return nsnull;
}
CellData* result = nsnull;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex));
if (row)
result = (CellData *)(row->ElementAt(aColIndex));
return result;
}
inline PRInt32 nsCellMap::GetColCount() const
{
return mCols.Count();
}
inline nsCellMap* nsCellMap::GetNextSibling() const
{
return mNextSibling;
}
inline void nsCellMap::SetNextSibling(nsCellMap* aSibling)
{
mNextSibling = aSibling;
}
inline nsTableRowGroupFrame* nsCellMap::GetRowGroup() const
{
return mRowGroupFrame;
}
inline PRInt32 nsCellMap::GetRowCount() const
{
return mRowCount;

View File

@ -236,7 +236,8 @@ void nsTableBorderCollapser::ComputeLeftBorderForEdgeAt(nsIPresContext* aPresCon
// we need to factor in the table's horizontal borders.
// but we can't compute that length here because we don't know how thick top and bottom borders are
// see DidComputeHorizontalCollapsingBorders
if (cellFrame) {
if (nsnull!=cellFrame)
{
border->mInsideNeighbor = cellFrame->mBorderEdges;
cellFrame->SetBorderEdge(NS_SIDE_LEFT, aRowIndex, aColIndex, border, 0); // set the left edge of the cell frame
}
@ -248,7 +249,7 @@ void nsTableBorderCollapser::ComputeRightBorderForEdgeAt(nsIPresContext* aPresCo
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
nsCellMap* cellMap = mTableFrame.GetCellMap();
nsTableCellMap* cellMap = mTableFrame.GetCellMap();
if (!cellMap) {
return;
}
@ -274,22 +275,19 @@ void nsTableBorderCollapser::ComputeRightBorderForEdgeAt(nsIPresContext* aPresCo
for (PRInt32 colIndex = aColIndex + 1; colIndex < colCount; colIndex++) {
CellData* cd = cellMap->GetCellAt(aRowIndex, colIndex);
if (cd) { // there's really a cell at (aRowIndex, colIndex)
if (!cd->mOrigCell) { // the cell at (aRowIndex, colIndex) is the result of a span
if (cd->IsSpan()) { // the cell at (aRowIndex, colIndex) is the result of a span
nsTableCellFrame* cell = nsnull;
if (cd->mRowSpanData)
cell = cd->mRowSpanData->mOrigCell;
else if (cd->mColSpanData)
cell = cd->mColSpanData->mOrigCell;
cell = cellMap->GetCellFrame(aRowIndex, colIndex, *cd, PR_TRUE);
NS_ASSERTION(cell, "bad cell map state, missing real cell");
PRInt32 realRowIndex;
cell->GetRowIndex (realRowIndex);
if (realRowIndex!=aRowIndex) { // the span is caused by a rowspan
rightNeighborFrame = cd->mRowSpanData->mOrigCell;
rightNeighborFrame = cell;
break;
}
}
else {
rightNeighborFrame = cd->mOrigCell;
rightNeighborFrame = cd->GetCellFrame();
break;
}
}
@ -375,7 +373,7 @@ void nsTableBorderCollapser::ComputeTopBorderForEdgeAt(nsIPresContext* aPresCont
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
nsCellMap* cellMap = mTableFrame.GetCellMap();
nsTableCellMap* cellMap = mTableFrame.GetCellMap();
if (!cellMap) {
return;
}
@ -464,7 +462,7 @@ void nsTableBorderCollapser::ComputeBottomBorderForEdgeAt(nsIPresContext* aPresC
PRInt32 aRowIndex,
PRInt32 aColIndex)
{
nsCellMap* cellMap = mTableFrame.GetCellMap();
nsTableCellMap* cellMap = mTableFrame.GetCellMap();
if (!cellMap) {
return;
}
@ -489,23 +487,19 @@ void nsTableBorderCollapser::ComputeBottomBorderForEdgeAt(nsIPresContext* aPresC
for (PRInt32 rowIndex = aRowIndex + 1; rowIndex < rowCount; rowIndex++) {
CellData* cd = cellMap->GetCellAt(rowIndex, aColIndex);
if (cd) { // there's really a cell at (rowIndex, aColIndex)
if (!cd->mOrigCell) {
if (cd->IsSpan()) {
// the cell at (rowIndex, aColIndex) is the result of a span
nsTableCellFrame* cell = nsnull;
if (cd->mRowSpanData) // XXX should we check for a row span
cell = cd->mRowSpanData->mOrigCell;
else if (cd->mColSpanData)
cell = cd->mColSpanData->mOrigCell;
nsTableCellFrame* cell = cellMap->GetCellFrame(rowIndex, aColIndex, *cd, PR_FALSE);
NS_ASSERTION( cell, "bad cell map state, missing real cell");
PRInt32 realColIndex;
cell->GetColIndex (realColIndex);
if (realColIndex!=aColIndex) { // the span is caused by a colspan
bottomNeighborFrame = cd->mColSpanData->mOrigCell;
bottomNeighborFrame = cell;
break;
}
}
else {
bottomNeighborFrame = cd->mOrigCell;
bottomNeighborFrame = cd->GetCellFrame();
break;
}
}

View File

@ -171,7 +171,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
mBorderEdges = new nsBorderEdges;
mBorderEdges->mOutsideEdge=PR_FALSE;
PRInt32 rowspan = GetRowSpan();
PRInt32 rowspan = tableFrame->GetRowSpan(*this);
PRInt32 i;
for (i=0; i<rowspan; i++) {
nsBorderEdge *borderToAdd = new nsBorderEdge();
@ -179,7 +179,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
borderToAdd = new nsBorderEdge();
mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
}
PRInt32 colspan = GetColSpan();
PRInt32 colspan = tableFrame->GetColSpan(*this);
for (i=0; i<colspan; i++) {
nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
@ -728,7 +728,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
}
}
}
PRInt32 colspan = GetColSpan();
PRInt32 colspan = tableFrame->GetColSpan(*this);
if (colspan > 1) {
smallestMinWidth = PR_MAX(smallestMinWidth, colspan * onePixel);
nscoord spacingX = tableFrame->GetCellSpacingX();

View File

@ -168,7 +168,7 @@ nsTableFrame::nsTableFrame()
mColumnWidths = new PRInt32[mColumnWidthsLength];
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
#endif
mCellMap = new nsCellMap(0, 0);
mCellMap = new nsTableCellMap(*this);
}
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
@ -347,6 +347,43 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
return rv;
}
PRInt32
nsTableFrame::GetColSpan(nsTableCellFrame& aCellFrame)
{
PRInt32 colspan = aCellFrame.GetColSpan();
if (0 == colspan) {
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex, colIndex;
aCellFrame.GetRowIndex(rowIndex);
aCellFrame.GetColIndex(colIndex);
colspan = cellMap->GetColSpan(rowIndex, colIndex);
}
else {
colspan = 1;
}
}
return colspan;
}
PRInt32
nsTableFrame::GetRowSpan(nsTableCellFrame& aCellFrame)
{
PRInt32 rowspan = aCellFrame.GetRowSpan();
if (0 == rowspan) {
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex, colIndex;
aCellFrame.GetRowIndex(rowIndex);
aCellFrame.GetColIndex(colIndex);
rowspan = cellMap->GetRowSpan(rowIndex, colIndex);
}
else {
rowspan = 1;
}
}
return rowspan;
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
@ -358,7 +395,7 @@ void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
if (nsLayoutAtoms::tableCellFrame == frameType) {
if ((nsHTMLAtoms::rowspan == aAttribute) ||
(nsHTMLAtoms::colspan == aAttribute)) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// for now just remove the cell from the map and reinsert it
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
@ -396,7 +433,7 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
PRInt32 nsTableFrame::GetRowCount () const
{
PRInt32 rowCount = 0;
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
if (nsnull!=cellMap)
rowCount = cellMap->GetRowCount();
@ -407,7 +444,7 @@ PRInt32 nsTableFrame::GetRowCount () const
PRInt32 nsTableFrame::GetColCount ()
{
PRInt32 colCount = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_ASSERTION(nsnull != cellMap, "GetColCount null cellmap");
if (nsnull != cellMap)
colCount = cellMap->GetColCount();
@ -423,7 +460,7 @@ nsTableColFrame* nsTableFrame::GetColFrame(PRInt32 aColIndex)
// can return nsnull
nsTableCellFrame* nsTableFrame::GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap)
return cellMap->GetCellInfoAt(aRowIndex, aColIndex);
return nsnull;
@ -453,7 +490,7 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return (rowCount - aRowIndex);
return rowSpan;
#else
PRInt32 rowSpan = aCell->GetRowSpan();
PRInt32 rowSpan = GetRowSpan(*aCell);
PRInt32 rowCount = GetRowCount();
PRInt32 startRow;
aCell->GetRowIndex(startRow);
@ -490,7 +527,7 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan(nsTableCellFrame *aCell)
PRInt32 nsTableFrame::GetEffectiveColSpan(PRInt32 aColIndex, const nsTableCellFrame* aCell) const
{
NS_PRECONDITION (nsnull != aCell, "bad cell arg");
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (nsnull != cellMap, "bad call, cellMap not yet allocated.");
return cellMap->GetEffectiveColSpan(aColIndex, aCell);
@ -499,7 +536,7 @@ PRInt32 nsTableFrame::GetEffectiveColSpan(PRInt32 aColIndex, const nsTableCellFr
PRInt32 nsTableFrame::GetEffectiveColSpan(const nsTableCellFrame* aCell) const
{
NS_PRECONDITION (nsnull != aCell, "bad cell arg");
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (nsnull != cellMap, "bad call, cellMap not yet allocated.");
PRInt32 initialColIndex;
@ -509,7 +546,7 @@ PRInt32 nsTableFrame::GetEffectiveColSpan(const nsTableCellFrame* aCell) const
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
{
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
PRInt32 result;
const nsStyleTable *tableStyle=nsnull;
@ -665,7 +702,7 @@ void nsTableFrame::InsertCol(nsIPresContext& aPresContext,
mColFrames.InsertElementAt(&aColFrame, aColIndex);
nsTableColType insertedColType = aColFrame.GetType();
PRInt32 numCacheCols = mColFrames.Count();
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 numMapCols = cellMap->GetColCount();
if (numCacheCols > numMapCols) {
@ -691,7 +728,7 @@ void nsTableFrame::InsertCol(nsIPresContext& aPresContext,
}
}
if (!removedFromCache) {
cellMap->AppendCol();
cellMap->AddColsAtEnd(1);
}
}
}
@ -707,7 +744,7 @@ void nsTableFrame::RemoveCol(nsIPresContext& aPresContext,
mColFrames.RemoveElementAt(aColIndex);
}
if (aRemoveFromCellMap) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// check to see if the cell map can remove the col
if (cellMap->RemoveUnusedCols(1) < 1) {
@ -718,22 +755,10 @@ void nsTableFrame::RemoveCol(nsIPresContext& aPresContext,
}
}
/** return the index of the next row that is not yet assigned */
PRInt32 nsTableFrame::GetNextAvailRowIndex() const
{
PRInt32 result=0;
nsCellMap *cellMap = GetCellMap();
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
if (nsnull!=cellMap) {
result = cellMap->GetNextAvailRowIndex();
}
return result;
}
/** Get the cell map for this table frame. It is not always mCellMap.
* Only the firstInFlow has a legit cell map
*/
nsCellMap * nsTableFrame::GetCellMap() const
nsTableCellMap * nsTableFrame::GetCellMap() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
if (this!=firstInFlow)
@ -917,9 +942,9 @@ PRInt32 nsTableFrame::AppendCell(nsIPresContext& aPresContext,
PRInt32 aRowIndex)
{
PRInt32 colIndex = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
colIndex = cellMap->AppendCell(&aCellFrame, aRowIndex, PR_TRUE);
colIndex = cellMap->AppendCell(aCellFrame, aRowIndex, PR_TRUE);
PRInt32 numColsInMap = GetColCount();
PRInt32 numColsInCache = mColFrames.Count();
PRInt32 numColsToAdd = numColsInMap - numColsInCache;
@ -936,7 +961,7 @@ void nsTableFrame::InsertCells(nsIPresContext& aPresContext,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore);
PRInt32 numColsInMap = GetColCount();
@ -980,7 +1005,7 @@ void nsTableFrame::RemoveCell(nsIPresContext& aPresContext,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveCell(aCellFrame, aRowIndex);
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
@ -994,43 +1019,46 @@ void nsTableFrame::RemoveCell(nsIPresContext& aPresContext,
}
// this cannot extend beyond a single row group
void nsTableFrame::AppendRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames)
void nsTableFrame::AppendRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex = cellMap->GetRowCount();
InsertRows(aPresContext, aRowFrames, rowIndex, PR_TRUE);
InsertRows(aPresContext, aRowGroupFrame, aRowFrames, rowIndex, PR_TRUE);
}
}
PRInt32
nsTableFrame::InsertRow(nsIPresContext& aPresContext,
nsIFrame& aRowFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
nsTableFrame::InsertRow(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsIFrame& aRowFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
{
nsVoidArray rows;
rows.AppendElement(&aRowFrame);
return InsertRows(aPresContext, rows, aRowIndex, aConsiderSpans);
return InsertRows(aPresContext, aRowGroupFrame, rows, aRowIndex, aConsiderSpans);
}
// this cannot extend beyond a single row group
PRInt32
nsTableFrame::InsertRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
nsTableFrame::InsertRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
{
//printf("insertRowsBefore firstRow=%d \n", aRowIndex);
//Dump(PR_TRUE, PR_FALSE, PR_TRUE);
PRInt32 numColsToAdd = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 origNumRows = cellMap->GetRowCount();
PRInt32 numNewRows = aRowFrames.Count();
cellMap->InsertRows(aRowFrames, aRowIndex, aConsiderSpans);
cellMap->InsertRows(aRowGroupFrame, aRowFrames, aRowIndex, aConsiderSpans);
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
PRInt32 numColsInCache = mColFrames.Count();
numColsToAdd = numColsInMap - numColsInCache;
@ -1065,7 +1093,7 @@ void nsTableFrame::RemoveRows(nsIPresContext& aPresContext,
//printf("removeRowsBefore firstRow=%d numRows=%d\n", aFirstRowIndex, aNumRowsToRemove);
//Dump(PR_TRUE, PR_FALSE, PR_TRUE);
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveRows(aFirstRowIndex, aNumRowsToRemove, aConsiderSpans);
// only remove cols that are of type eTypeAnonymous cell (they are at the end)
@ -1085,7 +1113,7 @@ void nsTableFrame::RemoveRows(nsIPresContext& aPresContext,
void nsTableFrame::AppendRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex = cellMap->GetRowCount();
InsertRowGroups(aPresContext, aFirstRowGroupFrame, rowIndex);
@ -1127,11 +1155,12 @@ nsTableFrame::GetRowGroupFrame(nsIFrame* aFrame,
}
// collect the rows ancestors of aFrame
void
PRInt32
nsTableFrame::CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection)
{
if (!aFrame) return;
if (!aFrame) return 0;
PRInt32 numRows = 0;
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aFrame);
if (rgFrame) {
nsIFrame* childFrame = nsnull;
@ -1141,14 +1170,16 @@ nsTableFrame::CollectRows(nsIFrame* aFrame,
childFrame->GetFrameType(&childType);
if (nsLayoutAtoms::tableRowFrame == childType) {
aCollection.AppendElement(childFrame);
numRows++;
}
else {
CollectRows(childFrame, aCollection);
numRows += CollectRows(childFrame, aCollection);
}
NS_IF_RELEASE(childType);
childFrame->GetNextSibling(&childFrame);
}
}
return numRows;
}
void
@ -1156,15 +1187,24 @@ nsTableFrame::InsertRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame,
PRInt32 aRowIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// collect the new row frames in an array
PRInt32 rowIndex = aRowIndex;
nsVoidArray rows;
for (nsIFrame* kidFrame = aFirstRowGroupFrame; kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
CollectRows(kidFrame, rows);
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
if (rgFrame) {
// create and add the cell map for the row group
cellMap->InsertGroupCellMap(rowIndex, *rgFrame);
// collect the new row frames in an array and add them to the table
PRInt32 numRows = CollectRows(kidFrame, rows);
if (numRows > 0) {
InsertRows(aPresContext, *rgFrame, rows, rowIndex, PR_TRUE);
rowIndex += numRows;
rows.Clear();
}
}
}
InsertRows(aPresContext, rows, aRowIndex, PR_TRUE);
}
}
@ -1185,7 +1225,7 @@ void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent)
return;
}
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
if (nsnull!=cellMap)
{
fprintf(out,"Column Layout Data \n");
@ -2040,11 +2080,11 @@ nsTableFrame::CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(aRowX, colX);
if (cellData && !cellData->mOrigCell) { // a cell above is spanning into here
if (cellData && cellData->IsSpan()) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = nsnull;
if (cellData->mRowSpanData)
realCell = cellData->mRowSpanData->mOrigCell;
if (cellData->IsRowSpan())
realCell = mCellMap->GetCellFrame(aRowX, colX, *cellData, PR_TRUE);
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
@ -2133,8 +2173,8 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
nsRect cellRect;
if (cellData) {
cellFrame = cellData->mOrigCell;
if (cellFrame) { // the cell originates at (rowX, colX)
if (cellData->IsOrig()) { // the cell originates at (rowX, colX)
cellFrame = cellData->GetCellFrame();
// reset the collapse offsets since they may have been collapsed previously
cellFrame->SetCollapseOffsetX(aPresContext, 0);
cellFrame->SetCollapseOffsetY(aPresContext, 0);
@ -2150,8 +2190,8 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
cellFrame->SetRect(aPresContext, cellRect);
// if the cell does not originate at (rowX, colX), adjust the real cells width
} else if (collapseGroup || collapseCol) {
if (cellData->mColSpanData) {
cellFrame = cellData->mColSpanData->mOrigCell;
if (cellData->IsColSpan()) {
cellFrame = mCellMap->GetCellFrame(rowX, colX, *cellData, PR_FALSE);
}
if ((cellFrame) && (lastCell != cellFrame)) {
cellFrame->GetRect(cellRect);
@ -2408,42 +2448,39 @@ nsTableFrame::RemoveFrame(nsIPresContext* aPresContext,
}
InvalidateColumnWidths();
} else if (IsRowGroup(display->mDisplay)) {
// remove the rows from the table
nsTableRowGroupFrame* rgFrame = (nsTableRowGroupFrame *) aOldFrame;
PRInt32 firstRowIndex = rgFrame->GetStartRowIndex();
PRInt32 numRows;
rgFrame->GetRowCount(numRows);
RemoveRows(*aPresContext, firstRowIndex, numRows, PR_TRUE);
// remove the row group frame from the sibling chain
mFrames.DestroyFrame(aPresContext, aOldFrame);
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
} else {
// Just remove the frame
mFrames.DestroyFrame(aPresContext, aOldFrame);
return NS_OK;
}
// Because the number of columns may have changed invalidate the column
// cache. Note that this has the side effect of recomputing the column
// widths, so we don't need to call InvalidateColumnWidths()
InvalidateColumnWidths();
// Mark the table as dirty and generate a reflow command targeted at the
// outer table frame
nsIReflowCommand* reflowCmd;
nsresult rv;
mState |= NS_FRAME_IS_DIRTY;
rv = NS_NewHTMLReflowCommand(&reflowCmd, mParent, nsIReflowCommand::ReflowDirty);
if (NS_SUCCEEDED(rv)) {
// Add the reflow command
rv = aPresShell.AppendReflowCommand(reflowCmd);
NS_RELEASE(reflowCmd);
}
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aOldFrame);
if (rgFrame) {
PRInt32 startRowIndex = rgFrame->GetStartRowIndex();
PRInt32 numRows;
rgFrame->GetRowCount(numRows);
// remove the row group from the cell map
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveGroupCellMap(rgFrame);
}
// only remove cols that are of type eTypeAnonymous cell (they are at the end)
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
PRInt32 numColsInCache = mColFrames.Count();
PRInt32 numColsNotRemoved = DestroyAnonymousColFrames(*aPresContext, numColsInCache - numColsInMap);
// if the cell map has fewer cols than the cache, correct it
if (numColsNotRemoved > 0) {
cellMap->AddColsAtEnd(numColsNotRemoved);
}
AdjustRowIndices(startRowIndex, -numRows);
// remove the row group frame from the sibling chain
mFrames.DestroyFrame(aPresContext, aOldFrame);
return rv;
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
} else {
// Just remove the frame
mFrames.DestroyFrame(aPresContext, aOldFrame);
return NS_OK;
}
}
return NS_OK;
}
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext* aPresContext,
@ -3522,7 +3559,7 @@ void nsTableFrame::AdjustColumnsForCOLSAttribute()
{
// XXX this is not right,
#if 0
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_ASSERTION(nsnull!=cellMap, "bad cell map");
// any specified-width column turns off COLS attribute
@ -3886,7 +3923,7 @@ void nsTableFrame::GetTableBorderForRowGroup(nsTableRowGroupFrame* aRowGroupFram
if (mBorderCollapser) {
PRInt32 rowCount;
aRowGroupFrame->GetRowCount(rowCount);
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
//PRInt32 colCount = cellMap->GetColCount();
mBorderCollapser->GetMaxBorder(aRowGroupFrame->GetStartRowIndex(), rowCount - 1,
0, cellMap->GetColCount() - 1, aBorder);
@ -4293,7 +4330,7 @@ void nsTableFrame::Dump(PRBool aDumpRows,
}
}
if (aDumpCellMap) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
#ifdef NS_DEBUG
cellMap->Dump();
#endif
@ -4405,20 +4442,23 @@ nsTableCellFrame* nsTableFrame::GetCellInfoAt(PRInt32 aRowX,
PRBool* aOriginates,
PRInt32* aColSpan)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
return cellMap->GetCellInfoAt(aRowX, aColX, aOriginates, aColSpan);
}
/*------------------ nsITableLayout methods ------------------------------*/
NS_IMETHODIMP
nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
PRBool& aIsSelected)
PRInt32& aStartRowIndex,
PRInt32& aStartColIndex,
PRInt32& aRowSpan,
PRInt32& aColSpan,
PRBool& aIsSelected)
{
nsresult result;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aCell = nsnull;
aStartRowIndex = 0;
@ -4455,8 +4495,8 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = cellFrame->GetRowSpan();
colSpan = cellFrame->GetColSpan();
rowSpan = GetRowSpan(*cellFrame);
colSpan = GetColSpan(*cellFrame);
// Check if this extends into the location we want
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
@ -4479,8 +4519,8 @@ CELL_FOUND:
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = cellFrame->GetRowSpan();
colSpan = cellFrame->GetColSpan();
rowSpan = GetRowSpan(*cellFrame);
colSpan = GetColSpan(*cellFrame);
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
@ -4499,8 +4539,8 @@ CELL_FOUND:
if (NS_FAILED(result)) return result;
result = cellFrame->GetColIndex(aStartColIndex);
if (NS_FAILED(result)) return result;
aRowSpan = cellFrame->GetRowSpan();
aColSpan = cellFrame->GetColSpan();
aRowSpan = GetRowSpan(*cellFrame);
aColSpan = GetColSpan(*cellFrame);
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
@ -4519,7 +4559,7 @@ TEST_IF_SELECTED:
NS_IMETHODIMP nsTableFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aRowCount = 0;
aColCount = 0;
@ -4534,7 +4574,7 @@ NS_IMETHODIMP nsTableFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
return cellMap->GetNumCellsOriginatingInCol(aColIndex);
}
@ -4617,7 +4657,7 @@ void nsTableFrame::DebugReflow(char* aMessage,
PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
{
PRBool result = PR_FALSE;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->RowHasSpanningCells(aRowIndex);
@ -4628,7 +4668,7 @@ PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
PRBool nsTableFrame::RowIsSpannedInto(PRInt32 aRowIndex)
{
PRBool result = PR_FALSE;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->RowIsSpannedInto(aRowIndex);
@ -4639,7 +4679,7 @@ PRBool nsTableFrame::RowIsSpannedInto(PRInt32 aRowIndex)
PRBool nsTableFrame::ColIsSpannedInto(PRInt32 aColIndex)
{
PRBool result = PR_FALSE;
nsCellMap * cellMap = GetCellMap();
nsTableCellMap * cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->ColIsSpannedInto(aColIndex);

View File

@ -32,7 +32,7 @@
#include "nsTableColFrame.h"
#include "nsTableColGroupFrame.h"
class nsCellMap;
class nsTableCellMap;
class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
@ -141,12 +141,12 @@ public:
// calculate the width of aFrame including its border and padding given
// given its reflow state.
static nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
// calculate the height of aFrame including its border and padding given
// its reflow state.
static nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
// of type aChildType.
@ -309,11 +309,6 @@ public:
*/
PRInt32 GetEffectiveCOLSAttribute();
/** return the index of the next row that is not yet assigned.
* If no row is initialized, 0 is returned.
*/
PRInt32 GetNextAvailRowIndex() const;
/** return the column frame associated with aColIndex */
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
@ -357,18 +352,21 @@ public:
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void AppendRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames);
void AppendRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames);
PRInt32 InsertRow(nsIPresContext& aPresContext,
nsIFrame& aFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRow(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsIFrame& aFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRows(nsIPresContext& aPresContext,
nsVoidArray& aFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
virtual void RemoveRows(nsIPresContext& aPresContext,
PRInt32 aFirstRowFrame,
@ -700,7 +698,7 @@ public:
/** Get the cell map for this table frame. It is not always mCellMap.
* Only the firstInFlow has a legit cell map
*/
virtual nsCellMap *GetCellMap() const;
virtual nsTableCellMap* GetCellMap() const;
void AdjustRowIndices(PRInt32 aRowIndex,
PRInt32 aAdjustment);
@ -717,6 +715,15 @@ public:
nsVoidArray& GetColCache();
/**
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
*/
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay);
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
nsIAtom* aFrameTypeIn = nsnull);
protected:
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
@ -735,17 +742,8 @@ protected:
*/
virtual PRInt32 GetSpecifiedColumnCount ();
/**
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
*/
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay);
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
nsIAtom* aFrameTypeIn = nsnull);
void CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection);
PRInt32 CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection);
public: /* ----- Cell Map public methods ----- */
@ -759,6 +757,9 @@ public: /* ----- Cell Map public methods ----- */
*/
virtual PRInt32 GetColCount();
PRInt32 GetRowSpan(nsTableCellFrame& aCellFrame);
PRInt32 GetColSpan(nsTableCellFrame& aCellFrame);
/** return the column frame at colIndex.
* returns nsnull if the col frame has not yet been allocated, or if aColIndex is out of range
*/
@ -838,7 +839,7 @@ protected:
int : 26; // unused
} mBits;
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
nsFrameList mColGroups; // the list of colgroup frames

View File

@ -438,7 +438,7 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
if (PR_TRUE == innerTableNeedsReflow) {
// Compute the width to use for the table. In the case of an auto sizing
// table this represents the maximum available width
nscoord tableWidth = nsTableFrame::CalcBorderBoxWidth(aReflowState.reflowState);
nscoord tableWidth = ((nsTableFrame*)mInnerTableFrame)->CalcBorderBoxWidth(aReflowState.reflowState);
// If the caption max element size is larger, then use it instead.
// XXX: caption align = left|right ignored here!

View File

@ -472,23 +472,6 @@ nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
return tableFrame->GetCellSpacingY();
}
PRInt32 nsTableRowFrame::GetMaxColumns() const
{
int sum = 0;
nsIFrame *cell=mFrames.FirstChild();
while (nsnull!=cell)
{
const nsStyleDisplay *kidDisplay;
cell->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
sum += ((nsTableCellFrame *)cell)->GetColSpan();
}
cell->GetNextSibling(&cell);
}
return sum;
}
/* GetMinRowSpan is needed for deviant cases where every cell in a row has a rowspan > 1.
* It sets mMinRowSpan, which is used in FixMinCellHeight and PlaceChild
*/
@ -1284,6 +1267,24 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
if (oldMaximumWidth != desiredSize.mMaximumWidth) {
aReflowState.tableFrame->InvalidateMaximumWidth();
}
// Now that we know the minimum and preferred widths see if the column
// widths need to be rebalanced
if (aReflowState.tableFrame->ColumnsAreValidFor(*(nsTableCellFrame*)aNextFrame,
oldMinSize.width,
oldMaximumWidth)) {
// The column widths don't need to be rebalanced. Now reflow the cell
// again this time constraining the width back to the column width again
kidReflowState.reason = eReflowReason_Resize;
kidReflowState.availableWidth = cellAvailWidth;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
} else {
// The column widths need to be rebalanced, so don't waste time reflowing
// the cell again. Tell the table to rebalance the column widths
aReflowState.tableFrame->InvalidateColumnWidths();
}
}
// Now that we know the minimum and preferred widths see if the column

View File

@ -166,8 +166,6 @@ public:
nscoord GetChildMaxTopMargin() const;
nscoord GetChildMaxBottomMargin() const;
PRInt32 GetMaxColumns() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;

View File

@ -112,33 +112,6 @@ PRInt32 nsTableRowGroupFrame::GetStartRowIndex()
return result;
}
NS_METHOD nsTableRowGroupFrame::GetMaxColumns(PRInt32 &aMaxColumns)
{
aMaxColumns=0;
// loop through children, remembering the max of the columns in each row
nsIFrame *childFrame = GetFirstFrame();
while (PR_TRUE)
{
if (nsnull==childFrame)
break;
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
PRInt32 colCount = ((nsTableRowFrame *)childFrame)->GetMaxColumns();
aMaxColumns = PR_MAX(aMaxColumns, colCount);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 rgColCount;
((nsTableRowGroupFrame*)childFrame)->GetMaxColumns(rgColCount);
aMaxColumns = PR_MAX(aMaxColumns, rgColCount);
}
GetNextFrame(childFrame, &childFrame);
}
return NS_OK;
}
nsresult
nsTableRowGroupFrame::InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame)
{
@ -1209,7 +1182,7 @@ nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
nsTableFrame* tableFrame = nsnull;
nsTableFrame::GetTableFrame(this, tableFrame);
if (tableFrame) {
tableFrame->AppendRows(*aPresContext, rows);
tableFrame->AppendRows(*aPresContext, *this, rows);
// Because the number of columns may have changed invalidate the column widths
tableFrame->InvalidateColumnWidths();
@ -1257,7 +1230,7 @@ nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
if (tableFrame) {
nsTableRowFrame* prevRow = (nsTableRowFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableRowFrame);
PRInt32 rowIndex = (prevRow) ? prevRow->GetRowIndex() : 0;
tableFrame->InsertRows(*aPresContext, rows, rowIndex, PR_TRUE);
tableFrame->InsertRows(*aPresContext, *this, rows, rowIndex, PR_TRUE);
// Reflow the new frames. They're already marked dirty, so generate a reflow
// command that tells us to reflow our dirty child frames

View File

@ -171,9 +171,6 @@ public:
*/
PRInt32 GetStartRowIndex();
/** get the maximum number of columns taken up by any row in this rowgroup */
NS_METHOD GetMaxColumns(PRInt32 &aMaxColumns);
/**
* Used for header and footer row group frames that are repeated when
* splitting a table frame.

View File

@ -26,36 +26,176 @@
class nsTableCellFrame;
/** Data stored by nsCellMap to rationalize rowspan and colspan cells.
* if mOrigCell is null then mSpanCell will be the rowspan/colspan source.
* if mSpanCell2 is non-null then it will point to a 2nd cell that overlaps this position
* @see nsCellMap
* @see nsTableFrame::BuildCellMap
* @see nsTableFrame::GrowCellMap
* @see nsTableFrame::BuildCellIntoMap
*
/**
* Data stored by nsCellMap to rationalize rowspan and colspan cells.
*/
class CellData
{
public:
CellData();
#ifndef NS_BUILD_REFCNT_LOGGING
CellData(nsTableCellFrame* aOrigCell, CellData* aRowSpanData, CellData* aColSpanData)
: mOrigCell(aOrigCell), mRowSpanData(aRowSpanData), mColSpanData(aColSpanData)
{
}
#else
CellData(nsTableCellFrame* aOrigCell, CellData* aRowSpanData,
CellData* aColSpanData);
#endif
CellData(nsTableCellFrame* aOrigCell);
~CellData();
nsTableCellFrame* mOrigCell;
CellData* mRowSpanData;
CellData* mColSpanData;
PRBool IsOrig() 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;
PRUint32 mBits;
};
};
#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 0x00010010 // there is a col span
#define COL_SPAN_0 0x00020010 // the col span is 0
#define OVERLAP 0x00040010 // there is a row span and col span but no by same cell
#define COL_SPAN_OFFSET 0xFFF80010 // 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 PRBool CellData::IsOrig() const
{
return (SPAN != (SPAN & 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;
}
else {
mBits &= ~ROW_SPAN;
}
}
}
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;
}
else {
mBits &= ~COL_SPAN;
}
}
}
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;
}
}
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,9 @@
class nsTableColFrame;
class nsTableCellFrame;
class nsIPresContext;
class nsTableRowGroupFrame;
class nsTableFrame;
class nsCellMap;
struct nsColInfo
{
@ -39,6 +42,107 @@ struct nsColInfo
PRInt32 aNumCellsSpan);
};
class nsTableCellMap
{
public:
nsTableCellMap(nsTableFrame& aTableFrame);
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
~nsTableCellMap();
void RemoveGroupCellMap(nsTableRowGroupFrame* aRowGroup);
void InsertGroupCellMap(PRInt32 aRowIndex,
nsTableRowGroupFrame& aNewRowGroup);
void InsertGroupCellMap(nsTableRowGroupFrame* aPrevRowGroup,
nsTableRowGroupFrame& aNewRowGroup);
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
PRInt32 aColIndex,
CellData& aData,
PRBool aUseRowIfOverlap) const;
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex);
nsColInfo* GetColInfoAt(PRInt32 aColIndex);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRBool aRebuildIfNecessary);
void InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void RemoveCell(nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void InsertRows(nsTableRowGroupFrame& aRowGroup,
nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
void RemoveRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
PRInt32 GetEffectiveColSpan(PRInt32 aColIndex,
const nsTableCellFrame* aCell);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
/** return the total number of columns in the table represented by this CellMap */
PRInt32 GetColCount() const;
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRBool* aOriginates = nsnull,
PRInt32* aColSpan = nsnull);
void AddColsAtEnd(PRUint32 aNumCols);
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
PRBool RowIsSpannedInto(PRInt32 aRowIndex);
PRBool RowHasSpanningCells(PRInt32 aRowIndex);
PRBool ColIsSpannedInto(PRInt32 aColIndex);
PRBool ColHasSpanningCells(PRInt32 aColIndex);
/** dump a representation of the cell map to stdout for debugging */
#ifdef NS_DEBUG
void Dump() const;
#endif
#ifdef DEBUG
void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
#endif
protected:
friend class nsCellMap;
void InsertGroupCellMap(nsCellMap* aPrevMap,
nsCellMap& aNewMap);
nsVoidArray mCols;
nsCellMap* mFirstMap;
};
/** nsCellMap is a support class for nsTablePart.
* It maintains an Rows x Columns grid onto which the cells of the table are mapped.
* This makes processing of rowspan and colspan attributes much easier.
@ -59,72 +163,89 @@ public:
* @param aNumRows - initial number of rows
* @param aNumColumns - initial number of columns
*/
nsCellMap(PRInt32 aNumRows,
PRInt32 aNumCols);
nsCellMap(nsTableRowGroupFrame& aRowGroupFrame);
/** destructor
* NOT VIRTUAL BECAUSE THIS CLASS SHOULD **NEVER** BE SUBCLASSED
*/
~nsCellMap();
nsCellMap* GetNextSibling() const;
void SetNextSibling(nsCellMap* aSibling);
nsTableRowGroupFrame* GetRowGroup() const;
nsTableCellFrame* GetCellFrame(PRInt32 aRowIndex,
PRInt32 aColIndex,
CellData& aData,
PRBool aUseRowSpanIfOverlap) const;
/** return the CellData for the cell at (aTableRowIndex, aTableColIndex) */
CellData* GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
void AppendCol();
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
/** append the cellFrame at the end of the row at aRowIndex and return the col index
*/
PRInt32 AppendCell(nsTableCellFrame* aCellFrame,
PRInt32 AppendCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRBool aRebuildIfNecessary);
void InsertCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void InsertCells(nsTableCellMap& aMap,
nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore);
void RemoveCell(nsTableCellFrame* aCellFrame,
void RemoveCell(nsTableCellMap& aMap,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void InsertRows(nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
void RemoveCol(PRInt32 aColIndex);
void RemoveRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
void InsertRows(nsTableCellMap& aMap,
nsVoidArray& aRows,
PRInt32 aFirstRowIndex,
PRBool aConsiderSpans);
PRInt32 GetNextAvailRowIndex();
void RemoveRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove,
PRBool aConsiderSpans);
PRInt32 GetEffectiveColSpan(nsTableCellFrame* aCell) const;
PRInt32 GetEffectiveColSpan(PRInt32 aColIndex,
const nsTableCellFrame* aCell) const;
PRInt32 GetEffectiveColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
const nsTableCellFrame* aCell);
PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
/** return the total number of columns in the table represented by this CellMap */
PRInt32 GetColCount() const;
/** return the actual number of rows in the table represented by this CellMap */
PRInt32 GetRowCount() const;
// temporary until nsTableFrame::GetCellData uses GetCellFrameAt
nsTableCellFrame* GetCellFrameOriginatingAt(PRInt32 aRowX,
PRInt32 aColX) const;
PRInt32 aColX,
PRInt32 aNumColsInTable);
nsTableCellFrame* GetCellInfoAt(PRInt32 aRowX,
PRInt32 aColX,
PRInt32 aNumColsInTable,
PRBool* aOriginates = nsnull,
PRInt32* aColSpan = nsnull) const;
PRInt32* aColSpan = nsnull);
void AddColsAtEnd(PRUint32 aNumCols);
PRInt32 RemoveUnusedCols(PRInt32 aMaxNumToRemove);
PRBool RowIsSpannedInto(PRInt32 aRowIndex,
PRInt32 aNumColsInTable);
PRBool RowIsSpannedInto(PRInt32 aRowIndex) const;
PRBool RowHasSpanningCells(PRInt32 aRowIndex) const;
PRBool ColIsSpannedInto(PRInt32 aColIndex) const;
PRBool ColHasSpanningCells(PRInt32 aColIndex) const;
PRBool RowHasSpanningCells(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRBool ColIsSpannedInto(PRInt32 aColIndex,
PRInt32 aNumCols);
PRBool ColHasSpanningCells(PRInt32 aColIndex,
PRInt32 aNumCols);
/** dump a representation of the cell map to stdout for debugging */
#ifdef NS_DEBUG
@ -136,115 +257,135 @@ public:
#endif
protected:
/** set the CellMap to (aNumRows x aNumColumns) */
void Grow(PRInt32 aNumMapRows,
PRInt32 aNumCols);
friend class nsTableCellMap;
PRBool Grow(nsTableCellMap& aMap,
PRInt32 aNumRows,
PRInt32 aRowIndex = -1);
void GrowRow(nsVoidArray& aRow,
PRInt32 aNumCols);
/** assign aCellData to the cell at (aRow,aColumn) */
void SetMapCellAt(CellData& aCellData,
PRInt32 aMapRowIndex,
PRInt32 aColIndex);
void SetMapCellAt(nsTableCellMap& aMap,
CellData& aCellData,
PRInt32 aMapRowIndex,
PRInt32 aColIndex,
PRBool aCountZeroSpanAsSpan);
CellData* GetMapCellAt(PRInt32 aMapRowIndex,
PRInt32 aColIndex) const;
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
PRInt32 GetNumCellsIn(PRInt32 aColIndex) const;
void ExpandWithRows(nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex);
void ExpandWithRows(nsTableCellMap& aMap,
nsVoidArray& aRowFrames,
PRInt32 aStartRowIndex);
void ExpandWithCells(nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aRowSpan);
void ExpandWithCells(nsTableCellMap& aMap,
nsVoidArray& aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aRowSpan,
PRBool aRowSpanIsZero);
void ShrinkWithoutRows(PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove);
void ShrinkWithoutRows(nsTableCellMap& aMap,
PRInt32 aFirstRowIndex,
PRInt32 aNumRowsToRemove);
void ShrinkWithoutCell(nsTableCellFrame& aCellFrame,
void ShrinkWithoutCell(nsTableCellMap& aMap,
nsTableCellFrame& aCellFrame,
PRInt32 aRowIndex,
PRInt32 aColIndex);
void RebuildConsideringRows(PRInt32 aStartRowIndex,
nsVoidArray* aRowsToInsert,
PRInt32 aNumRowsToRemove = 0);
void RebuildConsideringRows(nsTableCellMap& aMap,
PRInt32 aStartRowIndex,
nsVoidArray* aRowsToInsert,
PRInt32 aNumRowsToRemove = 0);
void RebuildConsideringCells(nsVoidArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRBool aInsert);
void RebuildConsideringCells(nsTableCellMap& aMap,
nsVoidArray* aCellFrames,
PRInt32 aRowIndex,
PRInt32 aColIndex,
PRBool aInsert);
PRBool CellsSpanOut(nsVoidArray& aNewRows);
PRBool CellsSpanInOrOut(PRInt32 aStartRowIndex,
PRInt32 aEndRowIndex,
PRInt32 aStartColIndex,
PRInt32 aEndColIndex);
PRInt32 aEndColIndex,
PRInt32 aNumColsInTable);
void ExpandForZeroSpan(nsTableCellFrame* aCellFrame,
PRInt32 aNumColsInTable);
PRBool CreateEmptyRow(PRInt32 aRowIndex,
PRInt32 aNumCols);
PRInt32 GetColSpan(nsTableCellFrame& aCellFrameToAdd,
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
PRBool& aIsZeroColSpan);
PRInt32 GetColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 aColIndex,
PRInt32 aNumColsInTable,
PRBool& aIsZeroColSpan);
PRInt32 GetRowSpan(PRInt32 aRowIndex,
PRInt32 aColIndex);
PRInt32 aColIndex,
PRBool& aIsZeroRowSpan);
PRInt32 GetRowSpan(nsTableCellFrame& aCellFrameToAdd,
PRInt32 aRowIndex,
PRBool& aIsZeroRowSpan);
void AdjustForZeroSpan(PRInt32 aRowIndex,
PRInt32 aColIndex,
PRInt32 aNumColsInTable);
PRBool IsZeroColSpan(PRInt32 aRowIndex,
PRInt32 aColIndex) const;
/** an array containing col array. It can be larger than mRowCount due to
* row spans extending beyond the table */
nsVoidArray mRows;
/** an array of nsColInfo indexed by col and giving the number of
* cells originating and spanning each col. */
nsVoidArray mCols;
/** the number of rows in the table which is <= the number of rows in the cell map
* due to row spans extending beyond the end of the table (dead rows) */
PRInt32 mRowCount;
PRInt32 mNextAvailRowIndex;
// the row group that corresponds to this map
nsTableRowGroupFrame* mRowGroupFrame;
// the next row group cell map
nsCellMap* mNextSibling;
};
/* ----- inline methods ----- */
inline CellData* nsCellMap::GetCellAt(PRInt32 aRowIndex,
PRInt32 aColIndex) const
inline PRInt32 nsTableCellMap::GetColCount() const
{
if ((0 > aRowIndex) || (aRowIndex >= mRowCount) ||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
//bug 9024 tickled this
//printf("%s \n", "nsCellMap::GetCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
return nsnull;
}
CellData* result = nsnull;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aRowIndex));
if (row)
result = (CellData *)(row->ElementAt(aColIndex));
return result;
}
inline CellData* nsCellMap::GetMapCellAt(PRInt32 aMapRowIndex,
PRInt32 aColIndex) const
{
if ((0 > aMapRowIndex) || (aMapRowIndex >= mRows.Count()) ||
(0 > aColIndex) || (aColIndex >= mCols.Count())) {
//see bug 9024 comments above
//printf("%s \n", "nsCellMap::GetMapCellAt called with invalid row or col index"); // XXX look at this when bug 10911 get fixed
return nsnull;
}
CellData* result = nsnull;
nsVoidArray* row = (nsVoidArray *)(mRows.ElementAt(aMapRowIndex));
if (row)
result = (CellData *)(row->ElementAt(aColIndex));
return result;
}
inline PRInt32 nsCellMap::GetColCount() const
{
return mCols.Count();
}
inline nsCellMap* nsCellMap::GetNextSibling() const
{
return mNextSibling;
}
inline void nsCellMap::SetNextSibling(nsCellMap* aSibling)
{
mNextSibling = aSibling;
}
inline nsTableRowGroupFrame* nsCellMap::GetRowGroup() const
{
return mRowGroupFrame;
}
inline PRInt32 nsCellMap::GetRowCount() const
{
return mRowCount;

View File

@ -171,7 +171,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
mBorderEdges = new nsBorderEdges;
mBorderEdges->mOutsideEdge=PR_FALSE;
PRInt32 rowspan = GetRowSpan();
PRInt32 rowspan = tableFrame->GetRowSpan(*this);
PRInt32 i;
for (i=0; i<rowspan; i++) {
nsBorderEdge *borderToAdd = new nsBorderEdge();
@ -179,7 +179,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
borderToAdd = new nsBorderEdge();
mBorderEdges->mEdges[NS_SIDE_RIGHT].AppendElement(borderToAdd);
}
PRInt32 colspan = GetColSpan();
PRInt32 colspan = tableFrame->GetColSpan(*this);
for (i=0; i<colspan; i++) {
nsBorderEdge *borderToAdd = new nsBorderEdge();
mBorderEdges->mEdges[NS_SIDE_TOP].AppendElement(borderToAdd);
@ -728,7 +728,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
}
}
}
PRInt32 colspan = GetColSpan();
PRInt32 colspan = tableFrame->GetColSpan(*this);
if (colspan > 1) {
smallestMinWidth = PR_MAX(smallestMinWidth, colspan * onePixel);
nscoord spacingX = tableFrame->GetCellSpacingX();

View File

@ -168,7 +168,7 @@ nsTableFrame::nsTableFrame()
mColumnWidths = new PRInt32[mColumnWidthsLength];
nsCRT::memset (mColumnWidths, 0, mColumnWidthsLength*sizeof(PRInt32));
#endif
mCellMap = new nsCellMap(0, 0);
mCellMap = new nsTableCellMap(*this);
}
NS_IMPL_ADDREF_INHERITED(nsTableFrame, nsHTMLContainerFrame)
@ -347,6 +347,43 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
return rv;
}
PRInt32
nsTableFrame::GetColSpan(nsTableCellFrame& aCellFrame)
{
PRInt32 colspan = aCellFrame.GetColSpan();
if (0 == colspan) {
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex, colIndex;
aCellFrame.GetRowIndex(rowIndex);
aCellFrame.GetColIndex(colIndex);
colspan = cellMap->GetColSpan(rowIndex, colIndex);
}
else {
colspan = 1;
}
}
return colspan;
}
PRInt32
nsTableFrame::GetRowSpan(nsTableCellFrame& aCellFrame)
{
PRInt32 rowspan = aCellFrame.GetRowSpan();
if (0 == rowspan) {
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex, colIndex;
aCellFrame.GetRowIndex(rowIndex);
aCellFrame.GetColIndex(colIndex);
rowspan = cellMap->GetRowSpan(rowIndex, colIndex);
}
else {
rowspan = 1;
}
}
return rowspan;
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
@ -358,7 +395,7 @@ void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
if (nsLayoutAtoms::tableCellFrame == frameType) {
if ((nsHTMLAtoms::rowspan == aAttribute) ||
(nsHTMLAtoms::colspan == aAttribute)) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// for now just remove the cell from the map and reinsert it
nsTableCellFrame* cellFrame = (nsTableCellFrame*)aFrame;
@ -396,7 +433,7 @@ PRInt32 nsTableFrame::GetSpecifiedColumnCount ()
PRInt32 nsTableFrame::GetRowCount () const
{
PRInt32 rowCount = 0;
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_ASSERTION(nsnull!=cellMap, "GetRowCount null cellmap");
if (nsnull!=cellMap)
rowCount = cellMap->GetRowCount();
@ -407,7 +444,7 @@ PRInt32 nsTableFrame::GetRowCount () const
PRInt32 nsTableFrame::GetColCount ()
{
PRInt32 colCount = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_ASSERTION(nsnull != cellMap, "GetColCount null cellmap");
if (nsnull != cellMap)
colCount = cellMap->GetColCount();
@ -423,7 +460,7 @@ nsTableColFrame* nsTableFrame::GetColFrame(PRInt32 aColIndex)
// can return nsnull
nsTableCellFrame* nsTableFrame::GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap)
return cellMap->GetCellInfoAt(aRowIndex, aColIndex);
return nsnull;
@ -453,7 +490,7 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return (rowCount - aRowIndex);
return rowSpan;
#else
PRInt32 rowSpan = aCell->GetRowSpan();
PRInt32 rowSpan = GetRowSpan(*aCell);
PRInt32 rowCount = GetRowCount();
PRInt32 startRow;
aCell->GetRowIndex(startRow);
@ -490,7 +527,7 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan(nsTableCellFrame *aCell)
PRInt32 nsTableFrame::GetEffectiveColSpan(PRInt32 aColIndex, const nsTableCellFrame* aCell) const
{
NS_PRECONDITION (nsnull != aCell, "bad cell arg");
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (nsnull != cellMap, "bad call, cellMap not yet allocated.");
return cellMap->GetEffectiveColSpan(aColIndex, aCell);
@ -499,7 +536,7 @@ PRInt32 nsTableFrame::GetEffectiveColSpan(PRInt32 aColIndex, const nsTableCellFr
PRInt32 nsTableFrame::GetEffectiveColSpan(const nsTableCellFrame* aCell) const
{
NS_PRECONDITION (nsnull != aCell, "bad cell arg");
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (nsnull != cellMap, "bad call, cellMap not yet allocated.");
PRInt32 initialColIndex;
@ -509,7 +546,7 @@ PRInt32 nsTableFrame::GetEffectiveColSpan(const nsTableCellFrame* aCell) const
PRInt32 nsTableFrame::GetEffectiveCOLSAttribute()
{
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
PRInt32 result;
const nsStyleTable *tableStyle=nsnull;
@ -665,7 +702,7 @@ void nsTableFrame::InsertCol(nsIPresContext& aPresContext,
mColFrames.InsertElementAt(&aColFrame, aColIndex);
nsTableColType insertedColType = aColFrame.GetType();
PRInt32 numCacheCols = mColFrames.Count();
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 numMapCols = cellMap->GetColCount();
if (numCacheCols > numMapCols) {
@ -691,7 +728,7 @@ void nsTableFrame::InsertCol(nsIPresContext& aPresContext,
}
}
if (!removedFromCache) {
cellMap->AppendCol();
cellMap->AddColsAtEnd(1);
}
}
}
@ -707,7 +744,7 @@ void nsTableFrame::RemoveCol(nsIPresContext& aPresContext,
mColFrames.RemoveElementAt(aColIndex);
}
if (aRemoveFromCellMap) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// check to see if the cell map can remove the col
if (cellMap->RemoveUnusedCols(1) < 1) {
@ -718,22 +755,10 @@ void nsTableFrame::RemoveCol(nsIPresContext& aPresContext,
}
}
/** return the index of the next row that is not yet assigned */
PRInt32 nsTableFrame::GetNextAvailRowIndex() const
{
PRInt32 result=0;
nsCellMap *cellMap = GetCellMap();
NS_PRECONDITION (nsnull!=cellMap, "null cellMap.");
if (nsnull!=cellMap) {
result = cellMap->GetNextAvailRowIndex();
}
return result;
}
/** Get the cell map for this table frame. It is not always mCellMap.
* Only the firstInFlow has a legit cell map
*/
nsCellMap * nsTableFrame::GetCellMap() const
nsTableCellMap * nsTableFrame::GetCellMap() const
{
nsTableFrame * firstInFlow = (nsTableFrame *)GetFirstInFlow();
if (this!=firstInFlow)
@ -917,9 +942,9 @@ PRInt32 nsTableFrame::AppendCell(nsIPresContext& aPresContext,
PRInt32 aRowIndex)
{
PRInt32 colIndex = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
colIndex = cellMap->AppendCell(&aCellFrame, aRowIndex, PR_TRUE);
colIndex = cellMap->AppendCell(aCellFrame, aRowIndex, PR_TRUE);
PRInt32 numColsInMap = GetColCount();
PRInt32 numColsInCache = mColFrames.Count();
PRInt32 numColsToAdd = numColsInMap - numColsInCache;
@ -936,7 +961,7 @@ void nsTableFrame::InsertCells(nsIPresContext& aPresContext,
PRInt32 aRowIndex,
PRInt32 aColIndexBefore)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->InsertCells(aCellFrames, aRowIndex, aColIndexBefore);
PRInt32 numColsInMap = GetColCount();
@ -980,7 +1005,7 @@ void nsTableFrame::RemoveCell(nsIPresContext& aPresContext,
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveCell(aCellFrame, aRowIndex);
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
@ -994,43 +1019,46 @@ void nsTableFrame::RemoveCell(nsIPresContext& aPresContext,
}
// this cannot extend beyond a single row group
void nsTableFrame::AppendRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames)
void nsTableFrame::AppendRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex = cellMap->GetRowCount();
InsertRows(aPresContext, aRowFrames, rowIndex, PR_TRUE);
InsertRows(aPresContext, aRowGroupFrame, aRowFrames, rowIndex, PR_TRUE);
}
}
PRInt32
nsTableFrame::InsertRow(nsIPresContext& aPresContext,
nsIFrame& aRowFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
nsTableFrame::InsertRow(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsIFrame& aRowFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
{
nsVoidArray rows;
rows.AppendElement(&aRowFrame);
return InsertRows(aPresContext, rows, aRowIndex, aConsiderSpans);
return InsertRows(aPresContext, aRowGroupFrame, rows, aRowIndex, aConsiderSpans);
}
// this cannot extend beyond a single row group
PRInt32
nsTableFrame::InsertRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
nsTableFrame::InsertRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans)
{
//printf("insertRowsBefore firstRow=%d \n", aRowIndex);
//Dump(PR_TRUE, PR_FALSE, PR_TRUE);
PRInt32 numColsToAdd = 0;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 origNumRows = cellMap->GetRowCount();
PRInt32 numNewRows = aRowFrames.Count();
cellMap->InsertRows(aRowFrames, aRowIndex, aConsiderSpans);
cellMap->InsertRows(aRowGroupFrame, aRowFrames, aRowIndex, aConsiderSpans);
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
PRInt32 numColsInCache = mColFrames.Count();
numColsToAdd = numColsInMap - numColsInCache;
@ -1065,7 +1093,7 @@ void nsTableFrame::RemoveRows(nsIPresContext& aPresContext,
//printf("removeRowsBefore firstRow=%d numRows=%d\n", aFirstRowIndex, aNumRowsToRemove);
//Dump(PR_TRUE, PR_FALSE, PR_TRUE);
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveRows(aFirstRowIndex, aNumRowsToRemove, aConsiderSpans);
// only remove cols that are of type eTypeAnonymous cell (they are at the end)
@ -1085,7 +1113,7 @@ void nsTableFrame::RemoveRows(nsIPresContext& aPresContext,
void nsTableFrame::AppendRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
PRInt32 rowIndex = cellMap->GetRowCount();
InsertRowGroups(aPresContext, aFirstRowGroupFrame, rowIndex);
@ -1127,11 +1155,12 @@ nsTableFrame::GetRowGroupFrame(nsIFrame* aFrame,
}
// collect the rows ancestors of aFrame
void
PRInt32
nsTableFrame::CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection)
{
if (!aFrame) return;
if (!aFrame) return 0;
PRInt32 numRows = 0;
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aFrame);
if (rgFrame) {
nsIFrame* childFrame = nsnull;
@ -1141,14 +1170,16 @@ nsTableFrame::CollectRows(nsIFrame* aFrame,
childFrame->GetFrameType(&childType);
if (nsLayoutAtoms::tableRowFrame == childType) {
aCollection.AppendElement(childFrame);
numRows++;
}
else {
CollectRows(childFrame, aCollection);
numRows += CollectRows(childFrame, aCollection);
}
NS_IF_RELEASE(childType);
childFrame->GetNextSibling(&childFrame);
}
}
return numRows;
}
void
@ -1156,15 +1187,24 @@ nsTableFrame::InsertRowGroups(nsIPresContext& aPresContext,
nsIFrame* aFirstRowGroupFrame,
PRInt32 aRowIndex)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
// collect the new row frames in an array
PRInt32 rowIndex = aRowIndex;
nsVoidArray rows;
for (nsIFrame* kidFrame = aFirstRowGroupFrame; kidFrame; kidFrame->GetNextSibling(&kidFrame)) {
CollectRows(kidFrame, rows);
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(kidFrame);
if (rgFrame) {
// create and add the cell map for the row group
cellMap->InsertGroupCellMap(rowIndex, *rgFrame);
// collect the new row frames in an array and add them to the table
PRInt32 numRows = CollectRows(kidFrame, rows);
if (numRows > 0) {
InsertRows(aPresContext, *rgFrame, rows, rowIndex, PR_TRUE);
rowIndex += numRows;
rows.Clear();
}
}
}
InsertRows(aPresContext, rows, aRowIndex, PR_TRUE);
}
}
@ -1185,7 +1225,7 @@ void nsTableFrame::ListColumnLayoutData(FILE* out, PRInt32 aIndent)
return;
}
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
if (nsnull!=cellMap)
{
fprintf(out,"Column Layout Data \n");
@ -2040,11 +2080,11 @@ nsTableFrame::CollapseRowGroupIfNecessary(nsIPresContext* aPresContext,
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(aRowX, colX);
if (cellData && !cellData->mOrigCell) { // a cell above is spanning into here
if (cellData && cellData->IsSpan()) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = nsnull;
if (cellData->mRowSpanData)
realCell = cellData->mRowSpanData->mOrigCell;
if (cellData->IsRowSpan())
realCell = mCellMap->GetCellFrame(aRowX, colX, *cellData, PR_TRUE);
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
@ -2133,8 +2173,8 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
nsRect cellRect;
if (cellData) {
cellFrame = cellData->mOrigCell;
if (cellFrame) { // the cell originates at (rowX, colX)
if (cellData->IsOrig()) { // the cell originates at (rowX, colX)
cellFrame = cellData->GetCellFrame();
// reset the collapse offsets since they may have been collapsed previously
cellFrame->SetCollapseOffsetX(aPresContext, 0);
cellFrame->SetCollapseOffsetY(aPresContext, 0);
@ -2150,8 +2190,8 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
cellFrame->SetRect(aPresContext, cellRect);
// if the cell does not originate at (rowX, colX), adjust the real cells width
} else if (collapseGroup || collapseCol) {
if (cellData->mColSpanData) {
cellFrame = cellData->mColSpanData->mOrigCell;
if (cellData->IsColSpan()) {
cellFrame = mCellMap->GetCellFrame(rowX, colX, *cellData, PR_FALSE);
}
if ((cellFrame) && (lastCell != cellFrame)) {
cellFrame->GetRect(cellRect);
@ -2408,42 +2448,39 @@ nsTableFrame::RemoveFrame(nsIPresContext* aPresContext,
}
InvalidateColumnWidths();
} else if (IsRowGroup(display->mDisplay)) {
// remove the rows from the table
nsTableRowGroupFrame* rgFrame = (nsTableRowGroupFrame *) aOldFrame;
PRInt32 firstRowIndex = rgFrame->GetStartRowIndex();
PRInt32 numRows;
rgFrame->GetRowCount(numRows);
RemoveRows(*aPresContext, firstRowIndex, numRows, PR_TRUE);
// remove the row group frame from the sibling chain
mFrames.DestroyFrame(aPresContext, aOldFrame);
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
} else {
// Just remove the frame
mFrames.DestroyFrame(aPresContext, aOldFrame);
return NS_OK;
}
// Because the number of columns may have changed invalidate the column
// cache. Note that this has the side effect of recomputing the column
// widths, so we don't need to call InvalidateColumnWidths()
InvalidateColumnWidths();
// Mark the table as dirty and generate a reflow command targeted at the
// outer table frame
nsIReflowCommand* reflowCmd;
nsresult rv;
mState |= NS_FRAME_IS_DIRTY;
rv = NS_NewHTMLReflowCommand(&reflowCmd, mParent, nsIReflowCommand::ReflowDirty);
if (NS_SUCCEEDED(rv)) {
// Add the reflow command
rv = aPresShell.AppendReflowCommand(reflowCmd);
NS_RELEASE(reflowCmd);
}
nsTableRowGroupFrame* rgFrame = GetRowGroupFrame(aOldFrame);
if (rgFrame) {
PRInt32 startRowIndex = rgFrame->GetStartRowIndex();
PRInt32 numRows;
rgFrame->GetRowCount(numRows);
// remove the row group from the cell map
nsTableCellMap* cellMap = GetCellMap();
if (cellMap) {
cellMap->RemoveGroupCellMap(rgFrame);
}
// only remove cols that are of type eTypeAnonymous cell (they are at the end)
PRInt32 numColsInMap = GetColCount(); // cell map's notion of num cols
PRInt32 numColsInCache = mColFrames.Count();
PRInt32 numColsNotRemoved = DestroyAnonymousColFrames(*aPresContext, numColsInCache - numColsInMap);
// if the cell map has fewer cols than the cache, correct it
if (numColsNotRemoved > 0) {
cellMap->AddColsAtEnd(numColsNotRemoved);
}
AdjustRowIndices(startRowIndex, -numRows);
// remove the row group frame from the sibling chain
mFrames.DestroyFrame(aPresContext, aOldFrame);
return rv;
InvalidateColumnWidths();
AddTableDirtyReflowCommand(aPresContext, this);
} else {
// Just remove the frame
mFrames.DestroyFrame(aPresContext, aOldFrame);
return NS_OK;
}
}
return NS_OK;
}
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext* aPresContext,
@ -3522,7 +3559,7 @@ void nsTableFrame::AdjustColumnsForCOLSAttribute()
{
// XXX this is not right,
#if 0
nsCellMap *cellMap = GetCellMap();
nsTableCellMap *cellMap = GetCellMap();
NS_ASSERTION(nsnull!=cellMap, "bad cell map");
// any specified-width column turns off COLS attribute
@ -3886,7 +3923,7 @@ void nsTableFrame::GetTableBorderForRowGroup(nsTableRowGroupFrame* aRowGroupFram
if (mBorderCollapser) {
PRInt32 rowCount;
aRowGroupFrame->GetRowCount(rowCount);
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
//PRInt32 colCount = cellMap->GetColCount();
mBorderCollapser->GetMaxBorder(aRowGroupFrame->GetStartRowIndex(), rowCount - 1,
0, cellMap->GetColCount() - 1, aBorder);
@ -4293,7 +4330,7 @@ void nsTableFrame::Dump(PRBool aDumpRows,
}
}
if (aDumpCellMap) {
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
#ifdef NS_DEBUG
cellMap->Dump();
#endif
@ -4405,20 +4442,23 @@ nsTableCellFrame* nsTableFrame::GetCellInfoAt(PRInt32 aRowX,
PRBool* aOriginates,
PRInt32* aColSpan)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
return cellMap->GetCellInfoAt(aRowX, aColX, aOriginates, aColSpan);
}
/*------------------ nsITableLayout methods ------------------------------*/
NS_IMETHODIMP
nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
nsTableFrame::GetCellDataAt(PRInt32 aRowIndex,
PRInt32 aColIndex,
nsIDOMElement* &aCell, //out params
PRInt32& aStartRowIndex, PRInt32& aStartColIndex,
PRInt32& aRowSpan, PRInt32& aColSpan,
PRBool& aIsSelected)
PRInt32& aStartRowIndex,
PRInt32& aStartColIndex,
PRInt32& aRowSpan,
PRInt32& aColSpan,
PRBool& aIsSelected)
{
nsresult result;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aCell = nsnull;
aStartRowIndex = 0;
@ -4455,8 +4495,8 @@ nsTableFrame::GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex,
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = cellFrame->GetRowSpan();
colSpan = cellFrame->GetColSpan();
rowSpan = GetRowSpan(*cellFrame);
colSpan = GetColSpan(*cellFrame);
// Check if this extends into the location we want
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
@ -4479,8 +4519,8 @@ CELL_FOUND:
cellFrame = cellMap->GetCellFrameOriginatingAt(row, col);
if (cellFrame)
{
rowSpan = cellFrame->GetRowSpan();
colSpan = cellFrame->GetColSpan();
rowSpan = GetRowSpan(*cellFrame);
colSpan = GetColSpan(*cellFrame);
if( aRowIndex >= row && aRowIndex < row+rowSpan &&
aColIndex >= col && aColIndex < col+colSpan)
{
@ -4499,8 +4539,8 @@ CELL_FOUND:
if (NS_FAILED(result)) return result;
result = cellFrame->GetColIndex(aStartColIndex);
if (NS_FAILED(result)) return result;
aRowSpan = cellFrame->GetRowSpan();
aColSpan = cellFrame->GetColSpan();
aRowSpan = GetRowSpan(*cellFrame);
aColSpan = GetColSpan(*cellFrame);
result = cellFrame->GetSelected(&aIsSelected);
if (NS_FAILED(result)) return result;
@ -4519,7 +4559,7 @@ TEST_IF_SELECTED:
NS_IMETHODIMP nsTableFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
// Initialize out params
aRowCount = 0;
aColCount = 0;
@ -4534,7 +4574,7 @@ NS_IMETHODIMP nsTableFrame::GetTableSize(PRInt32& aRowCount, PRInt32& aColCount)
PRInt32 nsTableFrame::GetNumCellsOriginatingInCol(PRInt32 aColIndex) const
{
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
return cellMap->GetNumCellsOriginatingInCol(aColIndex);
}
@ -4617,7 +4657,7 @@ void nsTableFrame::DebugReflow(char* aMessage,
PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
{
PRBool result = PR_FALSE;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->RowHasSpanningCells(aRowIndex);
@ -4628,7 +4668,7 @@ PRBool nsTableFrame::RowHasSpanningCells(PRInt32 aRowIndex)
PRBool nsTableFrame::RowIsSpannedInto(PRInt32 aRowIndex)
{
PRBool result = PR_FALSE;
nsCellMap* cellMap = GetCellMap();
nsTableCellMap* cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->RowIsSpannedInto(aRowIndex);
@ -4639,7 +4679,7 @@ PRBool nsTableFrame::RowIsSpannedInto(PRInt32 aRowIndex)
PRBool nsTableFrame::ColIsSpannedInto(PRInt32 aColIndex)
{
PRBool result = PR_FALSE;
nsCellMap * cellMap = GetCellMap();
nsTableCellMap * cellMap = GetCellMap();
NS_PRECONDITION (cellMap, "bad call, cellMap not yet allocated.");
if (cellMap) {
result = cellMap->ColIsSpannedInto(aColIndex);

View File

@ -32,7 +32,7 @@
#include "nsTableColFrame.h"
#include "nsTableColGroupFrame.h"
class nsCellMap;
class nsTableCellMap;
class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowGroupFrame;
@ -141,12 +141,12 @@ public:
// calculate the width of aFrame including its border and padding given
// given its reflow state.
static nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
// calculate the height of aFrame including its border and padding given
// its reflow state.
static nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState,
PRBool aDoNavHacks);
// Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
// of type aChildType.
@ -309,11 +309,6 @@ public:
*/
PRInt32 GetEffectiveCOLSAttribute();
/** return the index of the next row that is not yet assigned.
* If no row is initialized, 0 is returned.
*/
PRInt32 GetNextAvailRowIndex() const;
/** return the column frame associated with aColIndex */
nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
@ -357,18 +352,21 @@ public:
nsTableCellFrame* aCellFrame,
PRInt32 aRowIndex);
void AppendRows(nsIPresContext& aPresContext,
nsVoidArray& aRowFrames);
void AppendRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aRowFrames);
PRInt32 InsertRow(nsIPresContext& aPresContext,
nsIFrame& aFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRow(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsIFrame& aFrame,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRows(nsIPresContext& aPresContext,
nsVoidArray& aFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
PRInt32 InsertRows(nsIPresContext& aPresContext,
nsTableRowGroupFrame& aRowGroupFrame,
nsVoidArray& aFrames,
PRInt32 aRowIndex,
PRBool aConsiderSpans);
virtual void RemoveRows(nsIPresContext& aPresContext,
PRInt32 aFirstRowFrame,
@ -700,7 +698,7 @@ public:
/** Get the cell map for this table frame. It is not always mCellMap.
* Only the firstInFlow has a legit cell map
*/
virtual nsCellMap *GetCellMap() const;
virtual nsTableCellMap* GetCellMap() const;
void AdjustRowIndices(PRInt32 aRowIndex,
PRInt32 aAdjustment);
@ -717,6 +715,15 @@ public:
nsVoidArray& GetColCache();
/**
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
*/
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay);
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
nsIAtom* aFrameTypeIn = nsnull);
protected:
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
@ -735,17 +742,8 @@ protected:
*/
virtual PRInt32 GetSpecifiedColumnCount ();
/**
* Return aFrame's child if aFrame is an nsScrollFrame, otherwise return aFrame
*/
nsTableRowGroupFrame* GetRowGroupFrameFor(nsIFrame* aFrame,
const nsStyleDisplay* aDisplay);
nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
nsIAtom* aFrameTypeIn = nsnull);
void CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection);
PRInt32 CollectRows(nsIFrame* aFrame,
nsVoidArray& aCollection);
public: /* ----- Cell Map public methods ----- */
@ -759,6 +757,9 @@ public: /* ----- Cell Map public methods ----- */
*/
virtual PRInt32 GetColCount();
PRInt32 GetRowSpan(nsTableCellFrame& aCellFrame);
PRInt32 GetColSpan(nsTableCellFrame& aCellFrame);
/** return the column frame at colIndex.
* returns nsnull if the col frame has not yet been allocated, or if aColIndex is out of range
*/
@ -838,7 +839,7 @@ protected:
int : 26; // unused
} mBits;
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
nsTableCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
nsFrameList mColGroups; // the list of colgroup frames

View File

@ -438,7 +438,7 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
if (PR_TRUE == innerTableNeedsReflow) {
// Compute the width to use for the table. In the case of an auto sizing
// table this represents the maximum available width
nscoord tableWidth = nsTableFrame::CalcBorderBoxWidth(aReflowState.reflowState);
nscoord tableWidth = ((nsTableFrame*)mInnerTableFrame)->CalcBorderBoxWidth(aReflowState.reflowState);
// If the caption max element size is larger, then use it instead.
// XXX: caption align = left|right ignored here!

View File

@ -472,23 +472,6 @@ nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
return tableFrame->GetCellSpacingY();
}
PRInt32 nsTableRowFrame::GetMaxColumns() const
{
int sum = 0;
nsIFrame *cell=mFrames.FirstChild();
while (nsnull!=cell)
{
const nsStyleDisplay *kidDisplay;
cell->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)kidDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == kidDisplay->mDisplay)
{
sum += ((nsTableCellFrame *)cell)->GetColSpan();
}
cell->GetNextSibling(&cell);
}
return sum;
}
/* GetMinRowSpan is needed for deviant cases where every cell in a row has a rowspan > 1.
* It sets mMinRowSpan, which is used in FixMinCellHeight and PlaceChild
*/
@ -1284,6 +1267,24 @@ NS_METHOD nsTableRowFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
if (oldMaximumWidth != desiredSize.mMaximumWidth) {
aReflowState.tableFrame->InvalidateMaximumWidth();
}
// Now that we know the minimum and preferred widths see if the column
// widths need to be rebalanced
if (aReflowState.tableFrame->ColumnsAreValidFor(*(nsTableCellFrame*)aNextFrame,
oldMinSize.width,
oldMaximumWidth)) {
// The column widths don't need to be rebalanced. Now reflow the cell
// again this time constraining the width back to the column width again
kidReflowState.reason = eReflowReason_Resize;
kidReflowState.availableWidth = cellAvailWidth;
rv = ReflowChild(aNextFrame, aPresContext, desiredSize, kidReflowState,
aReflowState.x, GetChildMaxTopMargin(), 0, aStatus);
} else {
// The column widths need to be rebalanced, so don't waste time reflowing
// the cell again. Tell the table to rebalance the column widths
aReflowState.tableFrame->InvalidateColumnWidths();
}
}
// Now that we know the minimum and preferred widths see if the column

View File

@ -166,8 +166,6 @@ public:
nscoord GetChildMaxTopMargin() const;
nscoord GetChildMaxBottomMargin() const;
PRInt32 GetMaxColumns() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;

View File

@ -112,33 +112,6 @@ PRInt32 nsTableRowGroupFrame::GetStartRowIndex()
return result;
}
NS_METHOD nsTableRowGroupFrame::GetMaxColumns(PRInt32 &aMaxColumns)
{
aMaxColumns=0;
// loop through children, remembering the max of the columns in each row
nsIFrame *childFrame = GetFirstFrame();
while (PR_TRUE)
{
if (nsnull==childFrame)
break;
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
PRInt32 colCount = ((nsTableRowFrame *)childFrame)->GetMaxColumns();
aMaxColumns = PR_MAX(aMaxColumns, colCount);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay) {
PRInt32 rgColCount;
((nsTableRowGroupFrame*)childFrame)->GetMaxColumns(rgColCount);
aMaxColumns = PR_MAX(aMaxColumns, rgColCount);
}
GetNextFrame(childFrame, &childFrame);
}
return NS_OK;
}
nsresult
nsTableRowGroupFrame::InitRepeatedFrame(nsTableRowGroupFrame* aHeaderFooterFrame)
{
@ -1209,7 +1182,7 @@ nsTableRowGroupFrame::AppendFrames(nsIPresContext* aPresContext,
nsTableFrame* tableFrame = nsnull;
nsTableFrame::GetTableFrame(this, tableFrame);
if (tableFrame) {
tableFrame->AppendRows(*aPresContext, rows);
tableFrame->AppendRows(*aPresContext, *this, rows);
// Because the number of columns may have changed invalidate the column widths
tableFrame->InvalidateColumnWidths();
@ -1257,7 +1230,7 @@ nsTableRowGroupFrame::InsertFrames(nsIPresContext* aPresContext,
if (tableFrame) {
nsTableRowFrame* prevRow = (nsTableRowFrame *)nsTableFrame::GetFrameAtOrBefore(this, aPrevFrame, nsLayoutAtoms::tableRowFrame);
PRInt32 rowIndex = (prevRow) ? prevRow->GetRowIndex() : 0;
tableFrame->InsertRows(*aPresContext, rows, rowIndex, PR_TRUE);
tableFrame->InsertRows(*aPresContext, *this, rows, rowIndex, PR_TRUE);
// Reflow the new frames. They're already marked dirty, so generate a reflow
// command that tells us to reflow our dirty child frames

View File

@ -171,9 +171,6 @@ public:
*/
PRInt32 GetStartRowIndex();
/** get the maximum number of columns taken up by any row in this rowgroup */
NS_METHOD GetMaxColumns(PRInt32 &aMaxColumns);
/**
* Used for header and footer row group frames that are repeated when
* splitting a table frame.

View File

@ -1773,11 +1773,11 @@ nsTreeRowGroupFrame::GetCellFrameAtIndex(PRInt32 aRowIndex, PRInt32 aColIndex,
printf("(screen index (%d,%d))\n", screenIndex, aColIndex);
#endif
nsCellMap * cellMap = tableFrame->GetCellMap();
nsTableCellMap * cellMap = tableFrame->GetCellMap();
CellData* cellData = cellMap->GetCellAt(screenIndex, aColIndex);
if (cellData) {
cellFrame = cellData->mOrigCell;
if (cellFrame) { // the cell originates at (rowX, colX)
if (cellData->IsOrig()) { // the cell originates at (rowX, colX)
cellFrame = cellData->GetCellFrame();
if (cellFrame) {
*aResult = (nsTreeCellFrame*)cellFrame; // XXX I am evil.
}
}
@ -1856,7 +1856,7 @@ nsTreeRowGroupFrame::AddRowToMap(nsTableFrame* aTableFrame,
PRInt32 numNewCols = 0;
if (aCurrentFrame) {
numNewCols = aTableFrame->InsertRow(aPresContext, *aCurrentFrame,
numNewCols = aTableFrame->InsertRow(aPresContext, *this, *aCurrentFrame,
insertionIndex, PR_FALSE);
}