collapsing rows, row groups, cols, col groups

This commit is contained in:
karnaze%netscape.com 1999-02-11 06:22:33 +00:00
Родитель 53038aad55
Коммит e844c3e177
18 изменённых файлов: 854 добавлений и 156 удалений

Просмотреть файл

@ -30,11 +30,15 @@ static const PRBool gsDebug = PR_FALSE;
nsCellMap::nsCellMap(int aRowCount, int aColCount)
: mRowCount(0),
mColCount(0),
mTotalRowCount(0)
mTotalRowCount(0),
mNumCollapsedRows(0),
mNumCollapsedCols(0)
{
mRows = nsnull;
mColFrames = nsnull;
mMinColSpans = nsnull;
mIsCollapsedRows = nsnull;
mIsCollapsedCols = nsnull;
Reset(aRowCount, aColCount);
}
@ -62,6 +66,16 @@ nsCellMap::~nsCellMap()
// mMinColSpans may be null, it is only set for tables that need it
if (nsnull != mMinColSpans)
delete [] mMinColSpans;
if (nsnull != mIsCollapsedRows) {
delete [] mIsCollapsedRows;
mIsCollapsedRows = nsnull;
mNumCollapsedRows = 0;
}
if (nsnull != mIsCollapsedCols) {
delete [] mIsCollapsedCols;
mIsCollapsedCols = nsnull;
mNumCollapsedCols = 0;
}
mRows = nsnull;
mColFrames = nsnull;
mMinColSpans = nsnull;
@ -97,19 +111,20 @@ void nsCellMap::Reset(int aRowCount, int aColCount)
// if the number of rows has increased, add the extra rows
PRInt32 newRows = aRowCount-mTotalRowCount; // (new row count) - (total row allocation)
for ( ; newRows>0; newRows--)
{
for ( ; newRows > 0; newRows--) {
nsVoidArray *row;
if (0!=aColCount)
if (0 != aColCount) {
row = new nsVoidArray(aColCount);
else
} else {
row = new nsVoidArray();
}
mRows->AppendElement(row);
}
mRowCount = aRowCount;
mTotalRowCount = PR_MAX(mTotalRowCount, mRowCount);
mColCount = aColCount;
if (gsDebug) printf("leaving Reset with mRC=%d, mCC=%d, mTRC=%d\n",
mRowCount, mColCount, mTotalRowCount);
}
@ -413,5 +428,73 @@ PRBool nsCellMap::ColHasSpanningCells(PRInt32 aColIndex)
return result;
}
PRInt32 nsCellMap::GetNumCollapsedRows()
{
return mNumCollapsedRows;
}
PRBool nsCellMap::IsRowCollapsedAt(PRInt32 aRow)
{
if ((aRow >= 0) && (aRow < mTotalRowCount)) {
if (mIsCollapsedRows) {
return mIsCollapsedRows[aRow];
}
}
return PR_FALSE;
}
void nsCellMap::SetRowCollapsedAt(PRInt32 aRow, PRBool aValue)
{
if ((aRow >= 0) && (aRow < mRowCount)) {
if (nsnull == mIsCollapsedRows) {
mIsCollapsedRows = new PRBool[mRowCount];
for (PRInt32 i = 0; i < mRowCount; i++) {
mIsCollapsedRows[i] = PR_FALSE;
}
}
if (mIsCollapsedRows[aRow] != aValue) {
if (PR_TRUE == aValue) {
mNumCollapsedRows++;
} else {
mNumCollapsedRows--;
}
mIsCollapsedRows[aRow] = aValue;
}
}
}
PRInt32 nsCellMap::GetNumCollapsedCols()
{
return mNumCollapsedCols;
}
PRBool nsCellMap::IsColCollapsedAt(PRInt32 aCol)
{
if ((aCol >= 0) && (aCol < mColCount)) {
if (mIsCollapsedCols) {
return mIsCollapsedCols[aCol];
}
}
return PR_FALSE;
}
void nsCellMap::SetColCollapsedAt(PRInt32 aCol, PRBool aValue)
{
if ((aCol >= 0) && (aCol < mColCount)) {
if (nsnull == mIsCollapsedCols) {
mIsCollapsedCols = new PRBool[mColCount];
for (PRInt32 i = 0; i < mColCount; i++) {
mIsCollapsedCols[i] = PR_FALSE;
}
}
if (mIsCollapsedCols[aCol] != aValue) {
if (PR_TRUE == aValue) {
mNumCollapsedCols++;
} else {
mNumCollapsedCols--;
}
mIsCollapsedCols[aCol] = aValue;
}
}
}

Просмотреть файл

@ -53,6 +53,14 @@ protected:
/** a cache of the column frames, by col index */
nsVoidArray * mColFrames;
// an array of booleans where the ith element indicates if the ith row is collapsed
PRBool* mIsCollapsedRows;
PRInt32 mNumCollapsedRows;
// an array of booleans where the ith element indicates if the ith col is collapsed
PRBool* mIsCollapsedCols;
PRInt32 mNumCollapsedCols;
/** the number of rows. mRows[0] - mRows[mRowCount-1] are non-null. */
PRInt32 mRowCount;
@ -86,6 +94,14 @@ public:
/** assign aCellData to the cell at (aRow,aColumn) */
void SetCellAt(CellData *aCellData, PRInt32 aRow, PRInt32 aColumn);
PRInt32 GetNumCollapsedRows();
PRBool IsRowCollapsedAt(PRInt32 aRow);
void SetRowCollapsedAt(PRInt32 aRow, PRBool aValue);
PRInt32 GetNumCollapsedCols();
PRBool IsColCollapsedAt(PRInt32 aCol);
void SetColCollapsedAt(PRInt32 aCol, PRBool aValue);
/** expand the CellMap to have aRowCount rows. The number of columns remains the same */
void GrowToRow(PRInt32 aRowCount);

Просмотреть файл

@ -86,6 +86,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
mBorderEdges.mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd);
}
}
mCollapseOffset = nsPoint(0,0);
}
}
@ -168,7 +169,21 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
}
// if the cell originates in a row and/or col that is collapsed, the bottom and/or
// right portion of the cell is painted by translating the rendering context.
// XXX What about content that can leak outside the cell?
PRBool clipState;
aRenderingContext.PushState();
nsPoint offset = mCollapseOffset;
if ((0 != offset.x) || (0 != offset.y)) {
aRenderingContext.Translate(offset.x, offset.y);
}
aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height),
nsClipCombine_kIntersect, clipState);
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
aRenderingContext.PopState(clipState);
return NS_OK;
}
@ -1062,3 +1077,19 @@ nsTableCellFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TableCell", aResult);
}
void nsTableCellFrame::SetCollapseOffsetX(nscoord aXOffset)
{
mCollapseOffset.x = aXOffset;
}
void nsTableCellFrame::SetCollapseOffsetY(nscoord aYOffset)
{
mCollapseOffset.y = aYOffset;
}
nsPoint nsTableCellFrame::GetCollapseOffset()
{
return mCollapseOffset;
}

Просмотреть файл

@ -143,6 +143,11 @@ public:
PRBool GetContentEmpty();
void SetContentEmpty(PRBool aContentEmpty);
// The collapse offset is (0,0) except for cells originating in a row/col which is collapsed
void SetCollapseOffsetX(nscoord aXOffset);
void SetCollapseOffsetY(nscoord aYOffset);
nsPoint GetCollapseOffset();
protected:
/** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const;
@ -211,6 +216,9 @@ protected:
PRBool mIsContentEmpty; // PR_TRUE if the cell's contents take up no space
//XXX: mIsContentEmpty should get yanked in favor of using free a bit on the frame base class
// the FrameState slot (mState; GetFrameState/SetFrameState)
nsPoint mCollapseOffset;
public:
nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame
// used only for the collapsing border model

Просмотреть файл

@ -634,21 +634,22 @@ nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
PRInt32 count=0;
PRInt32 count = 0;
nsIFrame *childFrame = mFrames.FirstChild();
while (nsnull!=childFrame)
{
while (nsnull!=childFrame) {
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay) {
nsTableColFrame *col = (nsTableColFrame *)childFrame;
count += col->GetSpan();
if (aColIndex<=count)
if (aColIndex<=count) {
result = col;
}
}
childFrame->GetNextSibling(&childFrame);
}
return result;
}

Просмотреть файл

@ -385,13 +385,14 @@ NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFra
{
const nsStyleDisplay *rowDisplay;
nextRow->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay) {
rv = ((nsTableRowFrame *)nextRow)->InitChildren();
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
return rv;
}
}
}
return rv;
}
@ -947,74 +948,77 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
void nsTableFrame::DumpCellMap ()
{
printf("dumping CellMap:\n");
if (nsnull != mCellMap)
{
if (nsnull != mCellMap) {
PRInt32 colIndex;
PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 colCount = mCellMap->GetColCount();
printf("rowCount=%d, colCount=%d\n", rowCount, colCount);
for (PRInt32 rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
if (gsDebug==PR_TRUE)
{ printf("row %d", rowIndex);
printf(": ");
}
for (colIndex = 0; colIndex < colCount; colIndex++)
{
CellData *cd =mCellMap->GetCellAt(rowIndex, colIndex);
if (cd != nsnull)
{
if (cd->mCell != nsnull)
{
printf("C%d,%d ", rowIndex, colIndex);
printf(" ");
}
else
{
nsTableCellFrame *cell = cd->mRealCell->mCell;
nsTableRowFrame *row;
cell->GetParent((nsIFrame **)&row);
int rr = row->GetRowIndex ();
for (PRInt32 rowIndex = 0; rowIndex < rowCount; rowIndex++) {
printf("row %d : ", rowIndex);
for (colIndex = 0; colIndex < colCount; colIndex++) {
CellData* cd = mCellMap->GetCellAt(rowIndex, colIndex);
if (cd != nsnull) {
if (cd->mCell != nsnull) {
printf("C%d,%d ", rowIndex, colIndex);
} else {
nsTableCellFrame* cell = cd->mRealCell->mCell;
nsTableRowFrame* row;
cell->GetParent((nsIFrame**)&row);
int rr = row->GetRowIndex();
int cc;
cell->GetColIndex(cc);
printf("S%d,%d ", rr, cc);
if (cd->mOverlap != nsnull)
{
printf("S%d,%d ", rr, cc);
if (cd->mOverlap != nsnull){
cell = cd->mOverlap->mCell;
nsTableRowFrame* row2;
cell->GetParent((nsIFrame **)&row2);
rr = row2->GetRowIndex ();
cell->GetColIndex (cc);
cell->GetParent((nsIFrame**)&row2);
rr = row2->GetRowIndex();
cell->GetColIndex(cc);
printf("O%d,%c ", rr, cc);
}
else
printf(" ");
}
}
}
else
} else {
printf("---- ");
}
}
PRBool spanners = RowHasSpanningCells(rowIndex);
PRBool spannedInto = RowIsSpannedInto(rowIndex);
printf (" spanners=%s spannedInto=%s\n", spanners?"T":"F", spannedInto?"T":"F");
}
// output info mapping Ci,j to cell address
PRInt32 cellCount = 0;
for (PRInt32 rIndex = 0; rIndex < rowCount; rIndex++) {
for (colIndex = 0; colIndex < colCount; colIndex++) {
CellData* cd = mCellMap->GetCellAt(rIndex, colIndex);
if (cd != nsnull) {
if (cd->mCell != nsnull) {
printf("C%d,%d=%p ", rIndex, colIndex, cd->mCell);
cellCount++;
}
}
if (0 == (cellCount % 4)) {
printf("\n");
}
}
}
// output colspan info
for (colIndex=0; colIndex<colCount; colIndex++)
{
for (colIndex=0; colIndex<colCount; colIndex++) {
PRBool colSpanners = ColHasSpanningCells(colIndex);
PRBool colSpannedInto = ColIsSpannedInto(colIndex);
printf ("%d colSpanners=%s colSpannedInto=%s\n",
colIndex, colSpanners?"T":"F", colSpannedInto?"T":"F");
}
// output col frame info
for (colIndex=0; colIndex<colCount; colIndex++)
{
for (colIndex=0; colIndex<colCount; colIndex++) {
nsTableColFrame *colFrame = mCellMap->GetColumnFrame(colIndex);
printf ("col index %d has frame=%p\n", colIndex, colFrame);
}
}
else
} else {
printf ("[nsnull]");
}
}
#endif
@ -2636,7 +2640,10 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
nscoord defaultHeight = state.y + borderPadding.top + borderPadding.bottom;
aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
AdjustForCollapsingRows(aPresContext, aDesiredSize.height);
AdjustForCollapsingCols(aPresContext, aDesiredSize.width);
// once horizontal borders are computed and all row heights are set,
// we need to fix up length of vertical edges
// XXX need to figure start row and end row correctly
@ -2651,6 +2658,224 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
}
// collapsing row groups, rows, col groups and cols are accounted for after both passes of
// reflow so that it has no effect on the calculations of reflow.
NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight)
{
// determine which row groups and rows are collapsed
nsIFrame* childFrame;
FirstChild(nsnull, &childFrame);
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
PRInt32 rowX = 0;
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(rowX, PR_TRUE);
}
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
rowX++;
}
}
childFrame->GetNextSibling(&childFrame);
}
if (mCellMap->GetNumCollapsedRows() <= 0) {
return NS_OK; // no collapsed rows, we're done
}
// collapse the rows and/or row groups
nsIFrame* groupFrame = mFrames.FirstChild();
nscoord yGroupOffset = 0; // total offset among rows within a single row group
nscoord yTotalOffset = 0; // total offset among all rows in all row groups
PRInt32 rowX = 0;
PRBool collapseGroup;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
groupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
yGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-yGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= yGroupOffset;
rowFrame->SetRect(rowRect);
}
rowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
}
nsRect groupRect;
groupFrame->GetRect(groupRect);
groupRect.height -= yGroupOffset;
groupRect.y -= yTotalOffset;
groupFrame->SetRect(groupRect);
yTotalOffset += yGroupOffset;
yGroupOffset = 0;
groupFrame->GetNextSibling(&groupFrame);
} // end group frame while
aHeight -= yTotalOffset;
return NS_OK;
}
NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
nscoord& aWidth)
{
// determine which col groups and cols are collapsed
nsIFrame* childFrame = mColGroups.FirstChild();
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableColFrame* colFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&colFrame);
PRInt32 colX = 0;
while (nsnull != colFrame) {
const nsStyleDisplay *colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible)) {
mCellMap->SetColCollapsedAt(colX, PR_TRUE);
}
}
colFrame->GetNextSibling((nsIFrame**)&colFrame);
colX++;
}
childFrame->GetNextSibling(&childFrame);
}
if (mCellMap->GetNumCollapsedCols() <= 0) {
return NS_OK; // no collapsed cols, we're done
}
// collapse the cols and/or col groups
PRInt32 numRows = mCellMap->GetRowCount();
nsIFrame* groupFrame = mColGroups.FirstChild();
nscoord cellSpacingX = GetCellSpacingX();
nscoord xOffset = 0;
PRInt32 colX = 0;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsRect zeroRect(0, 0, 0, 0);
nsIFrame* colFrame;
groupFrame->FirstChild(nsnull, &colFrame);
while (nsnull != colFrame) {
const nsStyleDisplay* colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
PRBool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible);
PRInt32 colSpan = ((nsTableColFrame*)colFrame)->GetSpan();
for (PRInt32 spanX = 0; spanX < colSpan; spanX++) {
PRInt32 colWidth = GetColumnWidth(colX+spanX);
if (collapseGroup || collapseCol) {
xOffset += colWidth + cellSpacingX;
}
nsTableCellFrame* lastCell = nsnull;
nsTableCellFrame* cellFrame = nsnull;
for (PRInt32 rowX = 0; rowX < numRows; rowX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX+spanX);
nsRect cellRect;
if (cellData) {
cellFrame = cellData->mCell;
if (cellFrame) { // the cell originates at (rowX, colX)
cellFrame->GetRect(cellRect);
if (collapseGroup || collapseCol) {
if (lastCell != cellFrame) { // do it only once if there is a row span
cellRect.width -= colWidth;
cellFrame->SetCollapseOffsetX(-xOffset);
}
} else { // the cell is not in a collapsed col but needs to move
cellRect.x -= xOffset;
}
cellFrame->SetRect(cellRect);
// if the cell does not originate at (rowX, colX), adjust the real cells width
} else if (collapseGroup || collapseCol) {
cellFrame = cellData->mRealCell->mCell;
if ((cellFrame) && (lastCell != cellFrame)) {
cellFrame->GetRect(cellRect);
cellRect.width -= colWidth + cellSpacingX;
cellFrame->SetRect(cellRect);
}
}
}
lastCell = cellFrame;
}
}
colX += colSpan;
}
colFrame->GetNextSibling(&colFrame);
} // inner while
groupFrame->GetNextSibling(&groupFrame);
} // outer while
aWidth -= xOffset;
return NS_OK;
}
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,

Просмотреть файл

@ -560,6 +560,12 @@ protected:
InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame,
nscoord aDeltaY);
NS_METHOD AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight);
NS_METHOD AdjustForCollapsingCols(nsIPresContext& aPresContext,
nscoord& aWidth);
// end incremental reflow methods
/** return the desired width of this table accounting for the current

Просмотреть файл

@ -1421,16 +1421,6 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
break;
}
// check the visibility in the final pass. If it is collapse, set our desired size to 0
if (nsTableFrame::IsFinalPass(aReflowState)) {
const nsStyleDisplay *display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
aDesiredSize.width = 0;
aDesiredSize.height = 0;
}
}
// XXX TROY
#if 0

Просмотреть файл

@ -643,8 +643,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if ((NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) &&
(NS_STYLE_VISIBILITY_COLLAPSE != childDisplay->mVisible))
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
// get the height of the tallest cell in the row (excluding cells that span rows)
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
@ -1031,16 +1030,6 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
}
}
// check the visibility in the final pass. If it is collapse, set our desired size to 0
if (nsTableFrame::IsFinalPass(aReflowState)) {
const nsStyleDisplay *display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
aDesiredSize.width = 0;
aDesiredSize.height = 0;
}
}
if (gsDebug==PR_TRUE)
{
if (nsnull!=aDesiredSize.maxElementSize)

Просмотреть файл

@ -30,11 +30,15 @@ static const PRBool gsDebug = PR_FALSE;
nsCellMap::nsCellMap(int aRowCount, int aColCount)
: mRowCount(0),
mColCount(0),
mTotalRowCount(0)
mTotalRowCount(0),
mNumCollapsedRows(0),
mNumCollapsedCols(0)
{
mRows = nsnull;
mColFrames = nsnull;
mMinColSpans = nsnull;
mIsCollapsedRows = nsnull;
mIsCollapsedCols = nsnull;
Reset(aRowCount, aColCount);
}
@ -62,6 +66,16 @@ nsCellMap::~nsCellMap()
// mMinColSpans may be null, it is only set for tables that need it
if (nsnull != mMinColSpans)
delete [] mMinColSpans;
if (nsnull != mIsCollapsedRows) {
delete [] mIsCollapsedRows;
mIsCollapsedRows = nsnull;
mNumCollapsedRows = 0;
}
if (nsnull != mIsCollapsedCols) {
delete [] mIsCollapsedCols;
mIsCollapsedCols = nsnull;
mNumCollapsedCols = 0;
}
mRows = nsnull;
mColFrames = nsnull;
mMinColSpans = nsnull;
@ -97,19 +111,20 @@ void nsCellMap::Reset(int aRowCount, int aColCount)
// if the number of rows has increased, add the extra rows
PRInt32 newRows = aRowCount-mTotalRowCount; // (new row count) - (total row allocation)
for ( ; newRows>0; newRows--)
{
for ( ; newRows > 0; newRows--) {
nsVoidArray *row;
if (0!=aColCount)
if (0 != aColCount) {
row = new nsVoidArray(aColCount);
else
} else {
row = new nsVoidArray();
}
mRows->AppendElement(row);
}
mRowCount = aRowCount;
mTotalRowCount = PR_MAX(mTotalRowCount, mRowCount);
mColCount = aColCount;
if (gsDebug) printf("leaving Reset with mRC=%d, mCC=%d, mTRC=%d\n",
mRowCount, mColCount, mTotalRowCount);
}
@ -413,5 +428,73 @@ PRBool nsCellMap::ColHasSpanningCells(PRInt32 aColIndex)
return result;
}
PRInt32 nsCellMap::GetNumCollapsedRows()
{
return mNumCollapsedRows;
}
PRBool nsCellMap::IsRowCollapsedAt(PRInt32 aRow)
{
if ((aRow >= 0) && (aRow < mTotalRowCount)) {
if (mIsCollapsedRows) {
return mIsCollapsedRows[aRow];
}
}
return PR_FALSE;
}
void nsCellMap::SetRowCollapsedAt(PRInt32 aRow, PRBool aValue)
{
if ((aRow >= 0) && (aRow < mRowCount)) {
if (nsnull == mIsCollapsedRows) {
mIsCollapsedRows = new PRBool[mRowCount];
for (PRInt32 i = 0; i < mRowCount; i++) {
mIsCollapsedRows[i] = PR_FALSE;
}
}
if (mIsCollapsedRows[aRow] != aValue) {
if (PR_TRUE == aValue) {
mNumCollapsedRows++;
} else {
mNumCollapsedRows--;
}
mIsCollapsedRows[aRow] = aValue;
}
}
}
PRInt32 nsCellMap::GetNumCollapsedCols()
{
return mNumCollapsedCols;
}
PRBool nsCellMap::IsColCollapsedAt(PRInt32 aCol)
{
if ((aCol >= 0) && (aCol < mColCount)) {
if (mIsCollapsedCols) {
return mIsCollapsedCols[aCol];
}
}
return PR_FALSE;
}
void nsCellMap::SetColCollapsedAt(PRInt32 aCol, PRBool aValue)
{
if ((aCol >= 0) && (aCol < mColCount)) {
if (nsnull == mIsCollapsedCols) {
mIsCollapsedCols = new PRBool[mColCount];
for (PRInt32 i = 0; i < mColCount; i++) {
mIsCollapsedCols[i] = PR_FALSE;
}
}
if (mIsCollapsedCols[aCol] != aValue) {
if (PR_TRUE == aValue) {
mNumCollapsedCols++;
} else {
mNumCollapsedCols--;
}
mIsCollapsedCols[aCol] = aValue;
}
}
}

Просмотреть файл

@ -53,6 +53,14 @@ protected:
/** a cache of the column frames, by col index */
nsVoidArray * mColFrames;
// an array of booleans where the ith element indicates if the ith row is collapsed
PRBool* mIsCollapsedRows;
PRInt32 mNumCollapsedRows;
// an array of booleans where the ith element indicates if the ith col is collapsed
PRBool* mIsCollapsedCols;
PRInt32 mNumCollapsedCols;
/** the number of rows. mRows[0] - mRows[mRowCount-1] are non-null. */
PRInt32 mRowCount;
@ -86,6 +94,14 @@ public:
/** assign aCellData to the cell at (aRow,aColumn) */
void SetCellAt(CellData *aCellData, PRInt32 aRow, PRInt32 aColumn);
PRInt32 GetNumCollapsedRows();
PRBool IsRowCollapsedAt(PRInt32 aRow);
void SetRowCollapsedAt(PRInt32 aRow, PRBool aValue);
PRInt32 GetNumCollapsedCols();
PRBool IsColCollapsedAt(PRInt32 aCol);
void SetColCollapsedAt(PRInt32 aCol, PRBool aValue);
/** expand the CellMap to have aRowCount rows. The number of columns remains the same */
void GrowToRow(PRInt32 aRowCount);

Просмотреть файл

@ -86,6 +86,7 @@ void nsTableCellFrame::InitCellFrame(PRInt32 aColIndex)
mBorderEdges.mEdges[NS_SIDE_BOTTOM].AppendElement(borderToAdd);
}
}
mCollapseOffset = nsPoint(0,0);
}
}
@ -168,7 +169,21 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height);
}
// if the cell originates in a row and/or col that is collapsed, the bottom and/or
// right portion of the cell is painted by translating the rendering context.
// XXX What about content that can leak outside the cell?
PRBool clipState;
aRenderingContext.PushState();
nsPoint offset = mCollapseOffset;
if ((0 != offset.x) || (0 != offset.y)) {
aRenderingContext.Translate(offset.x, offset.y);
}
aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height),
nsClipCombine_kIntersect, clipState);
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
aRenderingContext.PopState(clipState);
return NS_OK;
}
@ -1062,3 +1077,19 @@ nsTableCellFrame::GetFrameName(nsString& aResult) const
{
return MakeFrameName("TableCell", aResult);
}
void nsTableCellFrame::SetCollapseOffsetX(nscoord aXOffset)
{
mCollapseOffset.x = aXOffset;
}
void nsTableCellFrame::SetCollapseOffsetY(nscoord aYOffset)
{
mCollapseOffset.y = aYOffset;
}
nsPoint nsTableCellFrame::GetCollapseOffset()
{
return mCollapseOffset;
}

Просмотреть файл

@ -143,6 +143,11 @@ public:
PRBool GetContentEmpty();
void SetContentEmpty(PRBool aContentEmpty);
// The collapse offset is (0,0) except for cells originating in a row/col which is collapsed
void SetCollapseOffsetX(nscoord aXOffset);
void SetCollapseOffsetY(nscoord aYOffset);
nsPoint GetCollapseOffset();
protected:
/** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const;
@ -211,6 +216,9 @@ protected:
PRBool mIsContentEmpty; // PR_TRUE if the cell's contents take up no space
//XXX: mIsContentEmpty should get yanked in favor of using free a bit on the frame base class
// the FrameState slot (mState; GetFrameState/SetFrameState)
nsPoint mCollapseOffset;
public:
nsBorderEdges mBorderEdges; // one list of border segments for each side of the table frame
// used only for the collapsing border model

Просмотреть файл

@ -634,21 +634,22 @@ nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
nsTableColFrame * nsTableColGroupFrame::GetColumnAt (PRInt32 aColIndex)
{
nsTableColFrame *result = nsnull;
PRInt32 count=0;
PRInt32 count = 0;
nsIFrame *childFrame = mFrames.FirstChild();
while (nsnull!=childFrame)
{
while (nsnull!=childFrame) {
const nsStyleDisplay *childDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_COLUMN == childDisplay->mDisplay) {
nsTableColFrame *col = (nsTableColFrame *)childFrame;
count += col->GetSpan();
if (aColIndex<=count)
if (aColIndex<=count) {
result = col;
}
}
childFrame->GetNextSibling(&childFrame);
}
return result;
}

Просмотреть файл

@ -385,13 +385,14 @@ NS_IMETHODIMP nsTableFrame::DidAppendRowGroup(nsTableRowGroupFrame *aRowGroupFra
{
const nsStyleDisplay *rowDisplay;
nextRow->GetStyleData(eStyleStruct_Display, (const nsStyleStruct *&)rowDisplay);
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay)
{
if (NS_STYLE_DISPLAY_TABLE_ROW==rowDisplay->mDisplay) {
rv = ((nsTableRowFrame *)nextRow)->InitChildren();
if (NS_FAILED(rv))
if (NS_FAILED(rv)) {
return rv;
}
}
}
return rv;
}
@ -947,74 +948,77 @@ NS_METHOD nsTableFrame::ReBuildCellMap()
void nsTableFrame::DumpCellMap ()
{
printf("dumping CellMap:\n");
if (nsnull != mCellMap)
{
if (nsnull != mCellMap) {
PRInt32 colIndex;
PRInt32 rowCount = mCellMap->GetRowCount();
PRInt32 colCount = mCellMap->GetColCount();
printf("rowCount=%d, colCount=%d\n", rowCount, colCount);
for (PRInt32 rowIndex = 0; rowIndex < rowCount; rowIndex++)
{
if (gsDebug==PR_TRUE)
{ printf("row %d", rowIndex);
printf(": ");
}
for (colIndex = 0; colIndex < colCount; colIndex++)
{
CellData *cd =mCellMap->GetCellAt(rowIndex, colIndex);
if (cd != nsnull)
{
if (cd->mCell != nsnull)
{
printf("C%d,%d ", rowIndex, colIndex);
printf(" ");
}
else
{
nsTableCellFrame *cell = cd->mRealCell->mCell;
nsTableRowFrame *row;
cell->GetParent((nsIFrame **)&row);
int rr = row->GetRowIndex ();
for (PRInt32 rowIndex = 0; rowIndex < rowCount; rowIndex++) {
printf("row %d : ", rowIndex);
for (colIndex = 0; colIndex < colCount; colIndex++) {
CellData* cd = mCellMap->GetCellAt(rowIndex, colIndex);
if (cd != nsnull) {
if (cd->mCell != nsnull) {
printf("C%d,%d ", rowIndex, colIndex);
} else {
nsTableCellFrame* cell = cd->mRealCell->mCell;
nsTableRowFrame* row;
cell->GetParent((nsIFrame**)&row);
int rr = row->GetRowIndex();
int cc;
cell->GetColIndex(cc);
printf("S%d,%d ", rr, cc);
if (cd->mOverlap != nsnull)
{
printf("S%d,%d ", rr, cc);
if (cd->mOverlap != nsnull){
cell = cd->mOverlap->mCell;
nsTableRowFrame* row2;
cell->GetParent((nsIFrame **)&row2);
rr = row2->GetRowIndex ();
cell->GetColIndex (cc);
cell->GetParent((nsIFrame**)&row2);
rr = row2->GetRowIndex();
cell->GetColIndex(cc);
printf("O%d,%c ", rr, cc);
}
else
printf(" ");
}
}
}
else
} else {
printf("---- ");
}
}
PRBool spanners = RowHasSpanningCells(rowIndex);
PRBool spannedInto = RowIsSpannedInto(rowIndex);
printf (" spanners=%s spannedInto=%s\n", spanners?"T":"F", spannedInto?"T":"F");
}
// output info mapping Ci,j to cell address
PRInt32 cellCount = 0;
for (PRInt32 rIndex = 0; rIndex < rowCount; rIndex++) {
for (colIndex = 0; colIndex < colCount; colIndex++) {
CellData* cd = mCellMap->GetCellAt(rIndex, colIndex);
if (cd != nsnull) {
if (cd->mCell != nsnull) {
printf("C%d,%d=%p ", rIndex, colIndex, cd->mCell);
cellCount++;
}
}
if (0 == (cellCount % 4)) {
printf("\n");
}
}
}
// output colspan info
for (colIndex=0; colIndex<colCount; colIndex++)
{
for (colIndex=0; colIndex<colCount; colIndex++) {
PRBool colSpanners = ColHasSpanningCells(colIndex);
PRBool colSpannedInto = ColIsSpannedInto(colIndex);
printf ("%d colSpanners=%s colSpannedInto=%s\n",
colIndex, colSpanners?"T":"F", colSpannedInto?"T":"F");
}
// output col frame info
for (colIndex=0; colIndex<colCount; colIndex++)
{
for (colIndex=0; colIndex<colCount; colIndex++) {
nsTableColFrame *colFrame = mCellMap->GetColumnFrame(colIndex);
printf ("col index %d has frame=%p\n", colIndex, colFrame);
}
}
else
} else {
printf ("[nsnull]");
}
}
#endif
@ -2636,7 +2640,10 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
aDesiredSize.width = ComputeDesiredWidth(aReflowState);
nscoord defaultHeight = state.y + borderPadding.top + borderPadding.bottom;
aDesiredSize.height = ComputeDesiredHeight(aPresContext, aReflowState, defaultHeight);
AdjustForCollapsingRows(aPresContext, aDesiredSize.height);
AdjustForCollapsingCols(aPresContext, aDesiredSize.width);
// once horizontal borders are computed and all row heights are set,
// we need to fix up length of vertical edges
// XXX need to figure start row and end row correctly
@ -2651,6 +2658,224 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext& aPresContext,
}
// collapsing row groups, rows, col groups and cols are accounted for after both passes of
// reflow so that it has no effect on the calculations of reflow.
NS_METHOD nsTableFrame::AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight)
{
// determine which row groups and rows are collapsed
nsIFrame* childFrame;
FirstChild(nsnull, &childFrame);
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
childFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableRowFrame* rowFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&rowFrame);
PRInt32 rowX = 0;
while (nsnull != rowFrame) {
const nsStyleDisplay *rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
mCellMap->SetRowCollapsedAt(rowX, PR_TRUE);
}
}
rowFrame->GetNextSibling((nsIFrame**)&rowFrame);
rowX++;
}
}
childFrame->GetNextSibling(&childFrame);
}
if (mCellMap->GetNumCollapsedRows() <= 0) {
return NS_OK; // no collapsed rows, we're done
}
// collapse the rows and/or row groups
nsIFrame* groupFrame = mFrames.FirstChild();
nscoord yGroupOffset = 0; // total offset among rows within a single row group
nscoord yTotalOffset = 0; // total offset among all rows in all row groups
PRInt32 rowX = 0;
PRBool collapseGroup;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
if (IsRowGroup(groupDisplay->mDisplay)) {
collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsIFrame* rowFrame;
groupFrame->FirstChild(nsnull, &rowFrame);
while (nsnull != rowFrame) {
const nsStyleDisplay* rowDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)rowDisplay));
if (NS_STYLE_DISPLAY_TABLE_ROW == rowDisplay->mDisplay) {
nsRect rowRect;
rowFrame->GetRect(rowRect);
if (collapseGroup || (NS_STYLE_VISIBILITY_COLLAPSE == rowDisplay->mVisible)) {
yGroupOffset += rowRect.height;
rowRect.height = 0;
rowFrame->SetRect(rowRect);
nsIFrame* cellFrame;
rowFrame->FirstChild(nsnull, &cellFrame);
while (nsnull != cellFrame) {
const nsStyleDisplay* cellDisplay;
cellFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)cellDisplay));
if (NS_STYLE_DISPLAY_TABLE_CELL == cellDisplay->mDisplay) {
nsTableCellFrame* cFrame = (nsTableCellFrame*)cellFrame;
nsRect cRect;
cFrame->GetRect(cRect);
cRect.height -= rowRect.height;
cFrame->SetCollapseOffsetY(-yGroupOffset);
cFrame->SetRect(cRect);
}
cellFrame->GetNextSibling(&cellFrame);
}
// check if a cell above spans into here
//if (!collapseGroup) {
PRInt32 numCols = mCellMap->GetColCount();
nsTableCellFrame* lastCell = nsnull;
for (int colX = 0; colX < numCols; colX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX);
if (cellData && !cellData->mCell) { // a cell above is spanning into here
// adjust the real cell's rect only once
nsTableCellFrame* realCell = cellData->mRealCell->mCell;
if (realCell != lastCell) {
nsRect realRect;
realCell->GetRect(realRect);
realRect.height -= rowRect.height;
realCell->SetRect(realRect);
}
lastCell = realCell;
}
}
//}
} else { // row is not collapsed but needs to be adjusted by those that are
rowRect.y -= yGroupOffset;
rowFrame->SetRect(rowRect);
}
rowX++;
}
rowFrame->GetNextSibling(&rowFrame);
} // end row frame while
}
nsRect groupRect;
groupFrame->GetRect(groupRect);
groupRect.height -= yGroupOffset;
groupRect.y -= yTotalOffset;
groupFrame->SetRect(groupRect);
yTotalOffset += yGroupOffset;
yGroupOffset = 0;
groupFrame->GetNextSibling(&groupFrame);
} // end group frame while
aHeight -= yTotalOffset;
return NS_OK;
}
NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext& aPresContext,
nscoord& aWidth)
{
// determine which col groups and cols are collapsed
nsIFrame* childFrame = mColGroups.FirstChild();
while (nsnull != childFrame) {
const nsStyleDisplay* groupDisplay;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool groupIsCollapsed = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsTableColFrame* colFrame = nsnull;
childFrame->FirstChild(nsnull, (nsIFrame**)&colFrame);
PRInt32 colX = 0;
while (nsnull != colFrame) {
const nsStyleDisplay *colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
if (groupIsCollapsed || (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible)) {
mCellMap->SetColCollapsedAt(colX, PR_TRUE);
}
}
colFrame->GetNextSibling((nsIFrame**)&colFrame);
colX++;
}
childFrame->GetNextSibling(&childFrame);
}
if (mCellMap->GetNumCollapsedCols() <= 0) {
return NS_OK; // no collapsed cols, we're done
}
// collapse the cols and/or col groups
PRInt32 numRows = mCellMap->GetRowCount();
nsIFrame* groupFrame = mColGroups.FirstChild();
nscoord cellSpacingX = GetCellSpacingX();
nscoord xOffset = 0;
PRInt32 colX = 0;
while (nsnull != groupFrame) {
const nsStyleDisplay* groupDisplay;
groupFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)groupDisplay));
PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupDisplay->mVisible);
nsRect zeroRect(0, 0, 0, 0);
nsIFrame* colFrame;
groupFrame->FirstChild(nsnull, &colFrame);
while (nsnull != colFrame) {
const nsStyleDisplay* colDisplay;
colFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay) {
PRBool collapseCol = (NS_STYLE_VISIBILITY_COLLAPSE == colDisplay->mVisible);
PRInt32 colSpan = ((nsTableColFrame*)colFrame)->GetSpan();
for (PRInt32 spanX = 0; spanX < colSpan; spanX++) {
PRInt32 colWidth = GetColumnWidth(colX+spanX);
if (collapseGroup || collapseCol) {
xOffset += colWidth + cellSpacingX;
}
nsTableCellFrame* lastCell = nsnull;
nsTableCellFrame* cellFrame = nsnull;
for (PRInt32 rowX = 0; rowX < numRows; rowX++) {
CellData* cellData = mCellMap->GetCellAt(rowX, colX+spanX);
nsRect cellRect;
if (cellData) {
cellFrame = cellData->mCell;
if (cellFrame) { // the cell originates at (rowX, colX)
cellFrame->GetRect(cellRect);
if (collapseGroup || collapseCol) {
if (lastCell != cellFrame) { // do it only once if there is a row span
cellRect.width -= colWidth;
cellFrame->SetCollapseOffsetX(-xOffset);
}
} else { // the cell is not in a collapsed col but needs to move
cellRect.x -= xOffset;
}
cellFrame->SetRect(cellRect);
// if the cell does not originate at (rowX, colX), adjust the real cells width
} else if (collapseGroup || collapseCol) {
cellFrame = cellData->mRealCell->mCell;
if ((cellFrame) && (lastCell != cellFrame)) {
cellFrame->GetRect(cellRect);
cellRect.width -= colWidth + cellSpacingX;
cellFrame->SetRect(cellRect);
}
}
}
lastCell = cellFrame;
}
}
colX += colSpan;
}
colFrame->GetNextSibling(&colFrame);
} // inner while
groupFrame->GetNextSibling(&groupFrame);
} // outer while
aWidth -= xOffset;
return NS_OK;
}
NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,

Просмотреть файл

@ -560,6 +560,12 @@ protected:
InnerTableReflowState& aReflowState,
nsIFrame* aKidFrame,
nscoord aDeltaY);
NS_METHOD AdjustForCollapsingRows(nsIPresContext& aPresContext,
nscoord& aHeight);
NS_METHOD AdjustForCollapsingCols(nsIPresContext& aPresContext,
nscoord& aWidth);
// end incremental reflow methods
/** return the desired width of this table accounting for the current

Просмотреть файл

@ -1421,16 +1421,6 @@ nsTableRowFrame::Reflow(nsIPresContext& aPresContext,
break;
}
// check the visibility in the final pass. If it is collapse, set our desired size to 0
if (nsTableFrame::IsFinalPass(aReflowState)) {
const nsStyleDisplay *display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
aDesiredSize.width = 0;
aDesiredSize.height = 0;
}
}
// XXX TROY
#if 0

Просмотреть файл

@ -643,8 +643,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext& aPresContext,
{
const nsStyleDisplay *childDisplay;
rowFrame->GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)childDisplay));
if ((NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay) &&
(NS_STYLE_VISIBILITY_COLLAPSE != childDisplay->mVisible))
if (NS_STYLE_DISPLAY_TABLE_ROW == childDisplay->mDisplay)
{
// get the height of the tallest cell in the row (excluding cells that span rows)
nscoord maxCellHeight = ((nsTableRowFrame*)rowFrame)->GetTallestChild();
@ -1031,16 +1030,6 @@ nsTableRowGroupFrame::Reflow(nsIPresContext& aPresContext,
}
}
// check the visibility in the final pass. If it is collapse, set our desired size to 0
if (nsTableFrame::IsFinalPass(aReflowState)) {
const nsStyleDisplay *display;
GetStyleData(eStyleStruct_Display, ((const nsStyleStruct *&)display));
if (NS_STYLE_VISIBILITY_COLLAPSE == display->mVisible) {
aDesiredSize.width = 0;
aDesiredSize.height = 0;
}
}
if (gsDebug==PR_TRUE)
{
if (nsnull!=aDesiredSize.maxElementSize)