Separated table content from table layout. This paves the way for XML/CSS-2 tables.

Lots and lots of optimizations.
This commit is contained in:
buster 1998-06-17 16:38:24 +00:00
Родитель dc63c63db0
Коммит 3f9f422457
46 изменённых файлов: 2132 добавлений и 1531 удалений

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

@ -530,6 +530,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
}

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

@ -1257,10 +1257,23 @@ static PRInt32 kDirectionKTable[] = {
};
static PRInt32 kDisplayKTable[] = {
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_MARKER, NS_STYLE_DISPLAY_MARKER,
KEYWORD_RUN_IN, NS_STYLE_DISPLAY_RUN_IN,
KEYWORD_COMPACT, NS_STYLE_DISPLAY_COMPACT,
KEYWORD_TABLE, NS_STYLE_DISPLAY_TABLE,
KEYWORD_INLINE_TABLE, NS_STYLE_DISPLAY_INLINE_TABLE,
KEYWORD_TABLE_ROW_GROUP, NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
KEYWORD_TABLE_COLUMN, NS_STYLE_DISPLAY_TABLE_COLUMN,
KEYWORD_TABLE_COLUMN_GROUP, NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP,
KEYWORD_TABLE_HEADER_GROUP, NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
KEYWORD_TABLE_FOOTER_GROUP, NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP,
KEYWORD_TABLE_ROW, NS_STYLE_DISPLAY_TABLE_ROW,
KEYWORD_TABLE_CELL, NS_STYLE_DISPLAY_TABLE_CELL,
KEYWORD_TABLE_CAPTION, NS_STYLE_DISPLAY_TABLE_CAPTION,
-1
};

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

@ -158,6 +158,7 @@ struct nsStyleTable: public nsStyleStruct {
nsStyleCoord mCellPadding; // [reset]
nsStyleCoord mCellSpacing; // [reset]
PRInt32 mCols; // an integer if set, or see nsStyleConsts.h NS_STYLE_TABLE_COLS_*
PRInt32 mSpan; // the number of columns spanned by a colgroup
protected:
nsStyleTable(void);

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

@ -87,6 +87,19 @@
#define NS_STYLE_DISPLAY_BLOCK 1
#define NS_STYLE_DISPLAY_INLINE 2
#define NS_STYLE_DISPLAY_LIST_ITEM 3
#define NS_STYLE_DISPLAY_MARKER 4
#define NS_STYLE_DISPLAY_RUN_IN 5
#define NS_STYLE_DISPLAY_COMPACT 6
#define NS_STYLE_DISPLAY_TABLE 7
#define NS_STYLE_DISPLAY_INLINE_TABLE 8
#define NS_STYLE_DISPLAY_TABLE_ROW_GROUP 9
#define NS_STYLE_DISPLAY_TABLE_COLUMN 10
#define NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP 11
#define NS_STYLE_DISPLAY_TABLE_HEADER_GROUP 12
#define NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP 13
#define NS_STYLE_DISPLAY_TABLE_ROW 14
#define NS_STYLE_DISPLAY_TABLE_CELL 15
#define NS_STYLE_DISPLAY_TABLE_CAPTION 16
// See nsStyleDisplay
#define NS_STYLE_FLOAT_NONE 0

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

@ -530,6 +530,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
}

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

@ -209,7 +209,7 @@ PLAINTEXT, XMP, PRE {
// Table tags
TABLE {
display: block;
display: table;
border-style: outset;
border-color: #C0C0C0;
cell-spacing: 4px;
@ -225,7 +225,7 @@ TD, TH {
font-weight: normal;
font-size: 11pt;
line-height: 1.1;
display: block;
display: table-cell;
cursor: arrow;
}
TH {
@ -234,8 +234,14 @@ TH {
}
CAPTION {
text-align: center;
display: block;
display: table-caption;
}
TBODY { display: table-row-group; }
THEAD { display: table-header-group; }
TFOOT { display: table-footer-group; }
COL { display: table-column; }
COLGROUP { display: table-column-group;}
MULTICOL {
display: block;
}

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

@ -1257,10 +1257,23 @@ static PRInt32 kDirectionKTable[] = {
};
static PRInt32 kDisplayKTable[] = {
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_MARKER, NS_STYLE_DISPLAY_MARKER,
KEYWORD_RUN_IN, NS_STYLE_DISPLAY_RUN_IN,
KEYWORD_COMPACT, NS_STYLE_DISPLAY_COMPACT,
KEYWORD_TABLE, NS_STYLE_DISPLAY_TABLE,
KEYWORD_INLINE_TABLE, NS_STYLE_DISPLAY_INLINE_TABLE,
KEYWORD_TABLE_ROW_GROUP, NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
KEYWORD_TABLE_COLUMN, NS_STYLE_DISPLAY_TABLE_COLUMN,
KEYWORD_TABLE_COLUMN_GROUP, NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP,
KEYWORD_TABLE_HEADER_GROUP, NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
KEYWORD_TABLE_FOOTER_GROUP, NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP,
KEYWORD_TABLE_ROW, NS_STYLE_DISPLAY_TABLE_ROW,
KEYWORD_TABLE_CELL, NS_STYLE_DISPLAY_TABLE_CELL,
KEYWORD_TABLE_CAPTION, NS_STYLE_DISPLAY_TABLE_CAPTION,
-1
};

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

@ -463,7 +463,10 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
{ // this col has proportional width, so determine its width requirements
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
NS_ASSERTION(nsnull != data, "bad data");
if (nsnull==data)
{ // For cells that span rows there's only cell layout data for the first row
continue;
}
nsSize * cellMinSize = data->GetMaxElementSize();
NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();

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

@ -15,8 +15,10 @@
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsCRT.h"
#include "nsCellLayoutData.h"
#include "nsTableCellFrame.h" // should be removed, make only generic nsIFrame calls
#include "nsCRT.h"
#include "nsSize.h"
#include "nsVoidArray.h"
#include "nsIFrame.h"

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

@ -1,196 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#ifndef nsCellLayoutData_h__
#define nsCellLayoutData_h__
#include "nscore.h"
#include "nsSize.h"
#include "nsIFrame.h"
#include "nsTableCellFrame.h"
class nsColLayoutData;
class nsTableFrame;
class nsIStyleContext;
struct nsStyleSpacing;
/** Simple data class that represents in-process reflow information about a cell.
* Each cell is represented by a nsTableCellFrame together with the results
* of the "first pass" layout results (where "first pass" means the cell was told
* to lay itself out with unrestricted height and width.)
* There is one nsCellLayoutData object per nsTableFrame for each cell.
*
* TODO: All methods will be inline.
*/
class nsCellLayoutData
{
public:
/** public constructor. Does not allocate any of its own data.
* @param aCellFrame the frame representing the cell
* @param aDesiredSize the max size of the cell if given infinite height and width
* @param aMaxElementSize the min size of the largest indivisible element within the cell
*/
nsCellLayoutData(nsTableCellFrame *aCellFrame,
nsReflowMetrics * aDesiredSize, nsSize * aMaxElementSize);
/** destructor, not responsible for destroying any of the stored data */
virtual ~nsCellLayoutData();
/** return the frame mapping the cell */
nsTableCellFrame * GetCellFrame();
/** set the frame mapping the cell */
void SetCellFrame(nsTableCellFrame * aCellFrame);
/** return the max size of the cell if given infinite height and width */
nsReflowMetrics * GetDesiredSize();
/** set the max size of the cell if given infinite height and width.
* called after pass 1 of table reflow is complete.
*/
void SetDesiredSize(nsReflowMetrics * aDesiredSize);
/** get the min size of the largest indivisible element within the cell */
nsSize * GetMaxElementSize();
/** set the min size of the largest indivisible element within the cell.
* called after pass 1 of table reflow is complete.
*/
void SetMaxElementSize(nsSize * aMaxElementSize);
/** debug method outputs data about this cell to FILE *out */
void List(FILE* out = stdout, PRInt32 aIndent = 0) const;
/** returns the style context associated with this cell */
nsIStyleContext* GetStyleContext();
private:
// All these methods are support methods for RecalcLayoutData
nsIFrame* GetFrameAt(nsVoidArray* aList, PRInt32 aIndex);
nscoord GetMargin(nsIFrame* aFrame, PRUint8 aEdge) const;
nscoord GetBorderWidth(nsIFrame* aFrame, PRUint8 aEdge) const;
nscoord GetPadding(nsIFrame* aFrame, PRUint8 aEdge) const;
PRUint8 GetOpposingEdge(PRUint8 aEdge);
nsIFrame* CompareCellBorders(nsIFrame* aFrame1,
PRUint8 aEdge1,
nsIFrame* aFrame2,
PRUint8 aEdge2);
nsIFrame* FindHighestPrecedentBorder(nsVoidArray* aList,
PRUint8 aEdge);
nsIFrame* FindInnerBorder( nsVoidArray* aList,
PRUint8 aEdge);
nsIFrame* FindOuterBorder( nsTableFrame* aTableFrame,
PRUint8 aEdge);
nsIFrame* FindBorderFrame(nsTableFrame* aTableFrame,
nsVoidArray* aCellList,
PRUint8 aEdge);
void CalculateBorders(nsTableFrame* aTableFrame,
nsVoidArray* aBoundaryCells[4]);
nscoord FindLargestMargin(nsVoidArray* aList,PRUint8 aEdge);
void CalculateMargins(nsTableFrame* aTableFrame,
nsVoidArray* aBoundaryCells[4]);
public:
void RecalcLayoutData(nsTableFrame* aTableFrame,
nsVoidArray* aBoundaryCells[4]);
NS_IMETHOD GetMargin(nsMargin& aMargin);
private:
#if 0 // these come on line when we do character-based cell content alignment
/** the kinds of width information stored */
enum {WIDTH_NORMAL=0, WIDTH_LEFT_ALIGNED=1, WIDTH_RIGHT_ALIGNED=2};
/** the width information for a cell */
PRInt32 mWidth[3];
#endif
nsColLayoutData *mColLayoutData;
nsTableCellFrame *mCellFrame;
nsReflowMetrics mDesiredSize;
nsSize mMaxElementSize;
nsresult mCalculated;
nsMargin mMargin;
nsIFrame* mBorderFrame[4]; // the frame whose border is used
};
inline nsTableCellFrame * nsCellLayoutData::GetCellFrame()
{ return mCellFrame; }
inline void nsCellLayoutData::SetCellFrame(nsTableCellFrame * aCellFrame)
{ mCellFrame = aCellFrame; }
inline nsReflowMetrics * nsCellLayoutData::GetDesiredSize()
{ return &mDesiredSize; }
inline void nsCellLayoutData::SetDesiredSize(nsReflowMetrics * aDesiredSize)
{
if (nsnull!=aDesiredSize)
mDesiredSize = *aDesiredSize;
}
inline nsSize * nsCellLayoutData::GetMaxElementSize()
{ return &mMaxElementSize; }
inline void nsCellLayoutData::SetMaxElementSize(nsSize * aMaxElementSize)
{
if (nsnull!=aMaxElementSize)
mMaxElementSize = *aMaxElementSize;
}
inline void nsCellLayoutData::CalculateBorders(nsTableFrame* aTableFrame,
nsVoidArray* aBoundaryCells[4])
{
for (PRInt32 edge = 0; edge < 4; edge++)
mBorderFrame[edge] = FindBorderFrame(aTableFrame, aBoundaryCells[edge], edge);
}
inline NS_METHOD nsCellLayoutData::GetMargin(nsMargin& aMargin)
{
if (mCalculated == NS_OK)
{
aMargin = mMargin;
return NS_OK;
}
return NS_ERROR_NOT_INITIALIZED;
}
#endif

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

@ -28,12 +28,11 @@ class CellData;
* Each cell is represented by a CellData object.
*
* @see CellData
* @see nsTablePart::BuildCellMap
* @see nsTablePart::GrowCellMap
* @see nsTablePart::BuildCellIntoMap
* @see nsTableFrame::BuildCellMap
* @see nsTableFrame::GrowCellMap
* @see nsTableFrame::BuildCellIntoMap
*
* acts like a 2-dimensional array, so all offsets are 0-indexed
TODO: inline methods
*/
class nsCellMap
{

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

@ -1,109 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "nsColLayoutData.h"
#include "nsVoidArray.h"
#include "nsCellLayoutData.h"
#include "nsTableCell.h"
nsColLayoutData::nsColLayoutData(nsTableColFrame* aColFrame, PRInt32 aNumRows)
{
mColFrame = aColFrame;
mCells = new nsVoidArray(aNumRows);
}
nsColLayoutData::~nsColLayoutData()
{
if (nsnull!=mCells)
{
PRInt32 count = mCells->Count();
for (PRInt32 i = 0; i < count; i++)
{
nsCellLayoutData *data = (nsCellLayoutData *)(mCells->ElementAt(i));
delete data;
}
delete mCells;
}
mCells = 0;
}
PRInt32 nsColLayoutData::IndexOf(nsIContent* aCell) const
{
PRInt32 count = this->Count();
PRInt32 result = -1;
if (aCell != nsnull)
{
for (PRInt32 index = 0; index < count; index++)
{
nsCellLayoutData* cellData = ElementAt(index);
if (cellData != nsnull)
{
nsTableCellFrame* frame = cellData->GetCellFrame();
if (frame != nsnull)
{
nsIContent* cell;
frame->GetContent(cell);
if (cell == aCell)
{
result = index;
NS_RELEASE(cell);
break;
}
NS_IF_RELEASE(cell);
}
}
}
}
return result;
}
nsCellLayoutData* nsColLayoutData::GetNext(nsCellLayoutData* aCellLayoutData) const
{
PRInt32 index = IndexOf(aCellLayoutData);
if (index != -1)
return ElementAt(index+1);
return (nsCellLayoutData*)nsnull;
}
nsCellLayoutData* nsColLayoutData::GetPrevious(nsCellLayoutData* aCellLayoutData) const
{
PRInt32 index = IndexOf(aCellLayoutData);
if (index != -1)
return ElementAt(index-1);
return (nsCellLayoutData*)nsnull;
}
void nsColLayoutData::List(FILE* out, PRInt32 aIndent) const
{
if (nsnull!=mCells)
{
PRInt32 count = mCells->Count();
for (PRInt32 i = 0; i < count; i++)
{
for (PRInt32 indent = aIndent; --indent >= 0; ) fputs(" ", out);
fprintf(out,"Cell Data [%d] \n",i);
nsCellLayoutData *data = (nsCellLayoutData *)(mCells->ElementAt(i));
data->List(out,aIndent+1);
}
}
}

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

@ -16,6 +16,7 @@
* Reserved.
*/
#include "nsTableCellFrame.h"
#include "nsCellLayoutData.h"
#include "nsBodyFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
@ -48,7 +49,8 @@ static const PRBool gsDebug = PR_FALSE;
*/
nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame)
: nsContainerFrame(aContent, aParentFrame),
mCellLayoutData(nsnull)
{
mRowSpan=1;
mColSpan=1;
@ -57,6 +59,8 @@ nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsTableCellFrame::~nsTableCellFrame()
{
if (nsnull!=mCellLayoutData)
delete mCellLayoutData;
}
NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,

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

@ -22,6 +22,7 @@
#include "nsContainerFrame.h"
#include "nsTableFrame.h"
class nsCellLayoutData;
struct nsStyleSpacing;
/**
@ -68,11 +69,16 @@ public:
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
virtual void SetColIndex (int aColIndex);
virtual ~nsTableCellFrame();
// Get the TableFrame that contains this cell frame
virtual nsTableFrame* GetTableFrame();
nsCellLayoutData * GetCellLayoutData();
void SetCellLayoutData(nsCellLayoutData *aData);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -106,6 +112,8 @@ protected:
/** the starting column for this cell */
int mColIndex;
nsCellLayoutData *mCellLayoutData;
};
inline void nsTableCellFrame::Init(PRInt32 aRowSpan, PRInt32 aColSpan, PRInt32 aColIndex)
@ -127,5 +135,16 @@ inline PRInt32 nsTableCellFrame::GetColSpan()
inline PRInt32 nsTableCellFrame::GetColIndex()
{ return mColIndex;}
inline void nsTableCellFrame::SetColIndex (int aColIndex)
{
NS_ASSERTION(0<=aColIndex, "illegal negative column index.");
mColIndex = aColIndex;
}
inline nsCellLayoutData * nsTableCellFrame::GetCellLayoutData()
{ return mCellLayoutData;}
inline void nsTableCellFrame::SetCellLayoutData(nsCellLayoutData *aData)
{ mCellLayoutData = aData;}
#endif

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

@ -21,7 +21,6 @@
#include "nscore.h"
#include "nsContainerFrame.h"
class nsTableColFrame : public nsFrame {
public:
@ -46,6 +45,9 @@ public:
/** return the number of the columns the col represents. always >= 0 */
virtual int GetRepeat ();
/** set the index of the column this content object represents. must be >= 0 */
virtual void SetColumnIndex (int aColIndex);
protected:
nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@ -75,6 +77,9 @@ inline nsTableColFrame::GetColumnIndex()
inline nsTableColFrame::GetRepeat()
{ return mRepeat; }
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
#endif

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

@ -141,8 +141,6 @@ int nsTableColGroup::GetColumnCount ()
void nsTableColGroup::ResetColumns ()
{
mColCount = 0;
if (nsnull != mTable)
mTable->ResetColumns ();
}
NS_IMETHODIMP

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

@ -16,13 +16,13 @@
* Reserved.
*/
#include "nsTableColGroupFrame.h"
#include "nsTableColFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIPtr.h"
#include "nsIContentDelegate.h"
#include "nsTableContent.h"
#include "nsHTMLAtoms.h"
NS_DEF_PTR(nsIContent);
@ -35,6 +35,7 @@ nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame)
{
mColCount=0;
}
nsTableColGroupFrame::~nsTableColGroupFrame()
@ -66,7 +67,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
LastChild(prevKidFrame); // XXX remember this...
PRInt32 kidIndex = 0;
for (;;)
for (PRInt32 colIndex = 0; ;colIndex++) // colIndex is used to set the column frames' index field
{
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
if (kid.IsNull()) {
@ -75,7 +76,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
// Resolve style
nsIStyleContextPtr kidSC =
aPresContext->ResolveStyleContextFor(kid, this);
aPresContext->ResolveStyleContextFor(kid, this, PR_TRUE);
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
kidSC->GetStyleData(eStyleStruct_Spacing);
@ -95,6 +96,9 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
// note that DidReflow is called as the result of some ancestor firing off a DidReflow above me
kidFrame->SetRect(nsRect(0,0,0,0));
// set nsColFrame-specific information
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex+mStartColIndex);
// Link child frame into the list of children
if (nsnull != prevKidFrame) {
prevKidFrame->SetNextSibling(kidFrame);
@ -178,6 +182,42 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
return NS_OK;
}
/** returns the number of columns represented by this group.
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
int nsTableColGroupFrame::GetColumnCount ()
{
if (0 == mColCount)
{
int count;
ChildCount (count);
if (0 < count)
{
nsIFrame * child = nsnull;
ChildAt(0, child);
NS_ASSERTION(nsnull!=child, "bad child");
while (nsnull!=child)
{
nsTableColFrame *col = (nsTableColFrame *)child;
col->SetColumnIndex (mStartColIndex + mColCount);
mColCount += col->GetRepeat ();
child->GetNextSibling(child);
}
}
else
{
const nsStyleTable *tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
mColCount = tableStyle->mSpan;
}
}
return mColCount;
}
/* ----- static methods ----- */
nsresult nsTableColGroupFrame::NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent)
@ -193,3 +233,5 @@ nsresult nsTableColGroupFrame::NewFrame(nsIFrame** aInstancePtrResult,
*aInstancePtrResult = it;
return NS_OK;
}

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

@ -50,6 +50,16 @@ public:
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** returns the number of columns represented by this group.
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
virtual PRInt32 GetColumnCount ();
virtual PRInt32 GetStartColumnIndex ();
virtual void SetStartColumnIndex (PRInt32 aIndex);
protected:
nsTableColGroupFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@ -62,6 +72,22 @@ protected:
*/
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
PRInt32 mColCount;
/** the starting column index this col group represents. Must be >= 0. */
PRInt32 mStartColIndex;
};
inline int nsTableColGroupFrame::GetStartColumnIndex ()
{ return mStartColIndex;}
inline void nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
{
if (aIndex != mStartColIndex)
mColCount = 0; // our index is being changed, trigger reset of col indicies, don't propogate back to table
mStartColIndex = aIndex;
}
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -22,11 +22,12 @@
#include "nsContainerFrame.h"
#include "nsStyleCoord.h"
class nsCellMap;
class nsCellLayoutData;
class nsTableCell;
class nsVoidArray;
class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowFrame;
class CellData;
class nsITableLayoutStrategy;
class nsHTMLValue;
@ -120,6 +121,14 @@ public:
nsReflowMetrics& aDesiredSize,
nsSize* aMaxElementSize);
/** allow the cell and row attributes to effect the column frame
* currently, the only reason this exists is to support the HTML "rule"
* that a width attribute on a cell in the first column sets the column width.
*/
virtual NS_METHOD SetColumnStyleFromCell(nsIPresContext * aPresContext,
nsTableCellFrame* aCellFrame,
nsTableRowFrame * aRowFrame);
/** return the column frame corresponding to the given column index
* there are two ways to do this, depending on whether we have cached
* column information yet.
@ -140,15 +149,15 @@ public:
* @return PR_TRUE if the data was successfully associated with a Cell
* PR_FALSE if there was an error, such as aRow or aCol being invalid
*/
virtual PRBool SetCellLayoutData(nsIPresContext* aPresContext,
virtual PRBool SetCellLayoutData(nsIPresContext * aPresContext,
nsCellLayoutData * aData,
nsTableCell *aCell);
nsTableCellFrame * aCell);
/** Get the layout data associated with the cell at (aRow,aCol)
* @return PR_NULL if there was an error, such as aRow or aCol being invalid
* otherwise, the data is returned.
*/
virtual nsCellLayoutData * GetCellLayoutData(nsTableCell *aCell);
virtual nsCellLayoutData * GetCellLayoutData(nsTableCellFrame *aCell);
/**
* DEBUG METHOD
@ -167,16 +176,11 @@ public:
* Calculate Layout Information
*
*/
void AppendLayoutData(nsVoidArray* aList, nsTableCell* aTableCell);
void AppendLayoutData(nsVoidArray* aList, nsTableCellFrame* aTableCell);
void RecalcLayoutData();
void ResetCellLayoutData( nsTableCell* aCell,
nsTableCell* aAbove,
nsTableCell* aBelow,
nsTableCell* aLeft,
nsTableCell* aRight);
// Get cell margin information
NS_IMETHOD GetCellMarginData(nsIFrame* aKidFrame, nsMargin& aMargin);
NS_IMETHOD GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin);
/** get cached column information for a subset of the columns
*
@ -220,7 +224,8 @@ protected:
*/
virtual nsReflowStatus ResizeReflowPass1(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState);
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** second pass of ResizeReflow.
* lays out all table content with aMaxSize(computed_table_width, given_table_height)
@ -328,6 +333,85 @@ protected:
void MapHTMLBorderStyle(nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth);
PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult);
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table.
* @param aRowIndex the first row that contains the cell
* @param aCell the content object representing the cell
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aRowIndex, nsTableCellFrame *aCell);
/** build as much of the CellMap as possible from the info we have so far
*/
virtual void BuildCellMap ();
/** called whenever the number of columns changes, to increase the storage in mCellMap
*/
virtual void GrowCellMap(PRInt32 aColCount);
/** ResetCellMap is called when the cell structure of the table is changed.
* Call with caution, only when changing the structure of the table such as
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetCellMap ();
/** ResetColumns is called when the column structure of the table is changed.
* Call with caution, only when adding or removing columns, changing
* column attributes, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetColumns ();
/** sum the columns represented by all nsTableColGroup objects.
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
*/
virtual void EnsureColumns (nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** Ensure that the cell map has been built for the table
*/
virtual void EnsureCellMap();
virtual void BuildColumnCache(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** called every time we discover we have a new cell to add to the table.
* This could be because we got actual cell content, because of rowspan/colspan attributes, etc.
* This method changes mCellMap as necessary to account for the new cell.
*
* @param aCell the content object created for the cell
* @param aRowIndex the row into which the cell is to be inserted
* @param aColIndex the col into which the cell is to be inserted
*/
virtual void BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex, PRInt32 aColIndex);
/** returns the index of the first child after aStartIndex that is a row group
*/
virtual PRInt32 NextRowGroup (PRInt32 aStartIndex);
/** returns the number of rows in this table.
* if mCellMap has been created, it is asked for the number of rows.<br>
* otherwise, the content is enumerated and the rows are counted.
*/
virtual PRInt32 GetRowCount();
/** return the number of columns as specified by the input.
* has 2 side effects:<br>
* calls SetStartColumnIndex on each nsTableColumn<br>
* sets mSpecifiedColCount.<br>
*/
virtual PRInt32 GetSpecifiedColumnCount ();
public:
virtual void DumpCellMap() const;
virtual nsCellMap* GetCellMap() const;
private:
void DebugPrintCount() const; // Debugging routine
@ -346,6 +430,8 @@ private:
PRInt32 mPass; // which Reflow pass are we currently in?
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
PRInt32 mColCount; // the number of columns in this table
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
};
#endif

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

@ -232,7 +232,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
mInnerTableFrame->SetReflowPass(nsTableFrame::kPASS_FIRST);
nsReflowState innerTableReflowState(mInnerTableFrame, aReflowState, aReflowState.maxSize);
aStatus = mInnerTableFrame->ResizeReflowPass1(aPresContext, aDesiredSize,
innerTableReflowState);
innerTableReflowState, aStatus);
}
mInnerTableFrame->SetReflowPass(nsTableFrame::kPASS_SECOND);
// assign table width info only if the inner table frame is a first-in-flow
@ -468,11 +468,8 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
kidFrame, aState.processingCaption?"caption":"inner");
// Get top margin for this kid
nsIStyleContextPtr kidSC;
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
const nsStyleSpacing* kidSpacing =
(const nsStyleSpacing*)kidSC->GetStyleData(eStyleStruct_Spacing);
const nsStyleSpacing* kidSpacing;
kidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing);
nsMargin kidMargin;
kidSpacing->CalcMarginFor(kidFrame, kidMargin);
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
@ -904,12 +901,8 @@ nsTableOuterFrame::ReflowChild( nsIFrame* aKidFrame,
if (PR_TRUE==aState.processingCaption)
{ // it's a caption, find out if it's top or bottom
// Resolve style
nsIStyleContextPtr captionStyleContext;
aKidFrame->GetStyleContext(aPresContext, captionStyleContext.AssignRef());
NS_ASSERTION(captionStyleContext.IsNotNull(), "null style context for caption");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
const nsStyleText* captionStyle;
aKidFrame->GetStyleData(eStyleStruct_Text, ( nsStyleStruct *&)captionStyle);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
@ -975,31 +968,32 @@ void nsTableOuterFrame::CreateChildFrames(nsIPresContext* aPresContext)
mCaptionFrames = new nsVoidArray();
// create caption frames as needed
nsIFrame *lastTopCaption = nsnull;
for (PRInt32 kidIndex=0; /* nada */ ;kidIndex++) {
nsIContentPtr caption = mContent->ChildAt(kidIndex); // caption: REFCNT++
if (caption.IsNull()) {
for (PRInt32 kidIndex=0; /* nada */ ;kidIndex++)
{
nsIContentPtr caption = mContent->ChildAt(kidIndex);
if (PR_TRUE==caption.IsNull()) {
break;
}
const PRInt32 contentType = ((nsTableContent *)(nsIContent*)caption)->GetType();
if (contentType==nsITableContent::kTableCaptionType)
// Resolve style
nsIStyleContextPtr captionSC =
aPresContext->ResolveStyleContextFor(caption, this);
NS_ASSERTION(captionSC.IsNotNull(), "bad style context for caption.");
nsStyleDisplay *childDisplay = (nsStyleDisplay*)captionSC->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_DISPLAY_TABLE_CAPTION == childDisplay->mDisplay)
{
// Resolve style
nsIStyleContextPtr captionStyleContext =
aPresContext->ResolveStyleContextFor(caption, this);
NS_ASSERTION(captionStyleContext.IsNotNull(), "bad style context for caption.");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
const nsStyleText* captionTextStyle =
(const nsStyleText*)captionSC->GetStyleData(eStyleStruct_Text);
// create the frame
nsIFrame *captionFrame=nsnull;
frameCreated = ((nsIHTMLContent*)(nsIContent*)caption)->CreateFrame(aPresContext,
this, captionStyleContext, captionFrame);
this, captionSC, captionFrame);
if (NS_OK!=frameCreated)
return; // SEC: an error!!!!
mChildCount++;
// Link child frame into the list of children
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
if ((eStyleUnit_Enumerated == captionTextStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionTextStyle->mVerticalAlign.GetIntValue()))
{ // bottom captions get added to the end of the outer frame child list
prevKidFrame->SetNextSibling(captionFrame);
prevKidFrame = captionFrame;
@ -1027,7 +1021,8 @@ void nsTableOuterFrame::CreateChildFrames(nsIPresContext* aPresContext)
mCaptionFrames->AppendElement(captionFrame);
}
else
{
{ // otherwise I know there are no more captions
// I'm assuming the frames were created in the correct order
break;
}
}
@ -1085,16 +1080,12 @@ nsTableOuterFrame::ResizeReflowTopCaptionsPass2(nsIPresContext* aPresCont
nsTableCaptionFrame *captionFrame = (nsTableCaptionFrame *)mCaptionFrames->ElementAt(captionIndex);
// Resolve style
nsIStyleContextPtr captionStyleContext;
captionFrame->GetStyleContext(aPresContext, captionStyleContext.AssignRef());
NS_ASSERTION(captionStyleContext.IsNotNull(), "null style context for caption");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
const nsStyleText* captionTextStyle;
captionFrame->GetStyleData(eStyleStruct_Text, (nsStyleStruct *&)captionTextStyle);
NS_ASSERTION(nsnull != captionTextStyle, "null style molecule for caption");
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
if ((eStyleUnit_Enumerated == captionTextStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionTextStyle->mVerticalAlign.GetIntValue()))
{
}
else
@ -1158,10 +1149,10 @@ nsTableOuterFrame::ResizeReflowBottomCaptionsPass2(nsIPresContext* aPresContext
// Resolve style
/*
nsIStyleContextPtr captionStyleContext = captionFrame->GetStyleContext(aPresContext);
NS_ASSERTION(nsnull != captionStyleContext, "null style context for caption");
nsIStyleContextPtr captionSC = captionFrame->GetStyleContext(aPresContext);
NS_ASSERTION(nsnull != captionSC, "null style context for caption");
nsStyleMolecule* captionStyle =
(nsStyleMolecule*)captionStyleContext->GetData(eStyleStruct_Molecule);
(nsStyleMolecule*)captionSC->GetData(eStyleStruct_Molecule);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
*/
// reflow the caption

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

@ -24,7 +24,6 @@
#include "nsTableCaption.h"
#include "nsTableRow.h"
#include "nsTableCell.h"
#include "nsCellMap.h"
#include "nsHTMLParts.h"
#include "nsIPresContext.h"
#include "nsContainerFrame.h"
@ -57,17 +56,6 @@ const char *nsTablePart::kColTagString="COL";
const char *nsTablePart::kDataCellTagString="TD";
const char *nsTablePart::kHeaderCellTagString="TH";
CellData::CellData()
{
mCell = nsnull;
mRealCell = nsnull;
mOverlap = nsnull;
}
CellData::~CellData()
{}
/*---------- nsTablePart implementation -----------*/
/**
@ -118,14 +106,15 @@ CellData::~CellData()
*
*/
//QQQ can remove mColCount?
/** constructor
* I do not check or addref aTag because my superclass does that for me
*/
nsTablePart::nsTablePart(nsIAtom* aTag)
: nsHTMLContainer(aTag),
mColCount(0),
mSpecifiedColCount(0),
mCellMap(0)
mSpecifiedColCount(0)
{
}
@ -135,8 +124,7 @@ nsTablePart::nsTablePart(nsIAtom* aTag)
nsTablePart::nsTablePart (nsIAtom* aTag, PRInt32 aColumnCount)
: nsHTMLContainer(aTag),
mColCount(aColumnCount),
mSpecifiedColCount(0),
mCellMap(0)
mSpecifiedColCount(0)
{
}
@ -144,10 +132,6 @@ nsTablePart::nsTablePart (nsIAtom* aTag, PRInt32 aColumnCount)
*/
nsTablePart::~nsTablePart()
{
if (nsnull!=mCellMap)
{
delete mCellMap;
}
}
/**
@ -177,153 +161,13 @@ nsrefcnt nsTablePart::Release(void)
return mRefCnt;
}
/** assumes that mColCount has been set */
///QQQQQ can be removed?
PRInt32 nsTablePart::GetMaxColumns ()
{
if (nsnull == mCellMap)
{
BuildCellMap ();
}
return mColCount;
}
// XXX what do rows with no cells turn into?
PRInt32 nsTablePart::GetRowCount ()
{
// if we've already built the cellMap, ask it for the row count
if (nsnull != mCellMap)
return mCellMap->GetRowCount();
// otherwise, we need to compute it by walking our children
int rowCount = 0;
int index = ChildCount ();
while (0 < index)
{
nsIContent *child = ChildAt (--index); // child: REFCNT++
nsTableContent *tableContent = (nsTableContent *)child;
const int contentType = tableContent->GetType();
if (contentType == nsITableContent::kTableRowGroupType)
rowCount += ((nsTableRowGroup *)tableContent)->GetRowCount ();
NS_RELEASE(child); // child: REFCNT--
}
return rowCount;
}
/* counts columns in column groups */
PRInt32 nsTablePart::GetSpecifiedColumnCount ()
{
if (mSpecifiedColCount < 0)
{
mSpecifiedColCount = 0;
int count = ChildCount ();
for (int index = 0; index < count; index++)
{
nsIContent *child = ChildAt (index); // child: REFCNT++
nsTableContent *tableContent = (nsTableContent *)child;
const int contentType = tableContent->GetType();
if (contentType == nsITableContent::kTableColGroupType)
{
((nsTableColGroup *)tableContent)->SetStartColumnIndex (mSpecifiedColCount);
mSpecifiedColCount += ((nsTableColGroup *)tableContent)->GetColumnCount ();
}
NS_RELEASE(child); // child: REFCNT--
}
}
return mSpecifiedColCount;
}
// returns the actual cell map, not a copy, so don't mess with it!
nsCellMap* nsTablePart::GetCellMap() const
{
return mCellMap;
}
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTablePart::ResetCellMap ()
{
if (nsnull==mCellMap)
delete mCellMap;
mCellMap = nsnull; // for now, will rebuild when needed
}
/* call when column structure has changed. */
void nsTablePart::ResetColumns ()
{
mSpecifiedColCount = -1;
if (nsnull != mCellMap)
{
int colCount = GetSpecifiedColumnCount ();
GrowCellMap (colCount); // make sure we're at least as big as specified columns
}
else
mColCount = 0; // we'll compute later (as part of building cell map)
}
/** sum the columns represented by all nsTableColGroup objects
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
*/
void nsTablePart::EnsureColumns()
{
if (nsnull!=mCellMap)
{
PRInt32 actualColumns = 0;
PRInt32 numColGroups = ChildCount();
nsTableColGroup *lastColGroup = nsnull;
for (PRInt32 colGroupIndex = 0; colGroupIndex < numColGroups; colGroupIndex++)
{
nsTableContent *colGroup = (nsTableContent*)ChildAt(colGroupIndex); // colGroup: REFCNT++
const int contentType = colGroup->GetType();
if (contentType==nsTableContent::kTableColGroupType)
{
PRInt32 numCols = ((nsTableColGroup *)colGroup)->GetColumnCount();
actualColumns += numCols;
lastColGroup = (nsTableColGroup *)colGroup;
NS_RELEASE(colGroup);
}
else if (contentType==nsTableContent::kTableRowGroupType)
{
NS_RELEASE(colGroup);
break;
}
}
if (actualColumns < mCellMap->GetColCount())
{
if (nsnull==lastColGroup)
{
lastColGroup = new nsTableColGroup (PR_TRUE);
AppendColGroup(lastColGroup);
}
PRInt32 excessColumns = mCellMap->GetColCount() - actualColumns;
for ( ; excessColumns > 0; excessColumns--)
{
nsTableCol *col = new nsTableCol(PR_TRUE);
lastColGroup->AppendChild (col, PR_FALSE);
}
}
}
}
void nsTablePart::EnsureCellMap()
{
if (mCellMap == nsnull)
BuildCellMap();
}
/**
*/
void nsTablePart::ReorderChildren()
{
NS_ASSERTION(PR_FALSE, "not yet implemented.");
}
void nsTablePart::NotifyContentComplete()
{
// set the children in order
ReorderChildren();
}
/** add a child to the table content.
* tables are special because they require the content to be normalized, in order.
* so this function doesn't really "append" the content, but adds it in the proper place,
@ -336,13 +180,11 @@ void nsTablePart::NotifyContentComplete()
* TFOOTs (optional)
* TBODY (at least 1, possibly implicit)
*
* should be broken out into separate functions!
*/
NS_IMETHODIMP
nsTablePart::AppendChild (nsIContent * aContent, PRBool aNotify)
{
NS_PRECONDITION(nsnull!=aContent, "bad arg");
PRBool newCells = PR_FALSE;
PRBool contentHandled = PR_FALSE;
// wait, stop! need to check to see if this is really tableContent or not!
@ -400,7 +242,6 @@ nsTablePart::AppendChild (nsIContent * aContent, PRBool aNotify)
}
// group is guaranteed to be allocated at this point
rv = group->AppendChild(aContent, PR_FALSE);
newCells = (PRBool)(NS_OK==rv);
contentHandled = PR_TRUE;
NS_RELEASE(group); // group: REFCNT--
}
@ -408,7 +249,6 @@ nsTablePart::AppendChild (nsIContent * aContent, PRBool aNotify)
{
// TODO: switch Append* to COM interfaces
result = AppendColumn((nsTableCol *)aContent);
newCells = result;
contentHandled = PR_TRUE;
}
else if (contentType == nsITableContent::kTableCaptionType)
@ -419,22 +259,14 @@ nsTablePart::AppendChild (nsIContent * aContent, PRBool aNotify)
else if (contentType == nsITableContent::kTableRowGroupType)
{
result = AppendRowGroup((nsTableRowGroup *)aContent);
if (PR_TRUE==result)
{
newCells = PR_TRUE;
}
else
if (PR_FALSE==result)
rv=NS_ERROR_FAILURE;
contentHandled = PR_TRUE; // whether we succeeded or not, we've "handled" this request
}
else if (contentType == nsITableContent::kTableColGroupType)
{
result = AppendColGroup((nsTableColGroup *)aContent);
if (PR_TRUE==result)
{
newCells = PR_TRUE;
}
else
if (PR_FALSE==result)
rv = NS_ERROR_FAILURE;
contentHandled = PR_TRUE; // whether we succeeded or not, we've "handled" this request
}
@ -462,11 +294,6 @@ nsTablePart::AppendChild (nsIContent * aContent, PRBool aNotify)
}
result = caption->AppendChild (aContent, PR_FALSE);
}
/* if we added new cells, we need to fix up the cell map */
if (newCells)
{
ResetCellMap ();
}
}
NS_RELEASE(tableContentInterface); // tableContentInterface: REFCNT--
@ -492,7 +319,6 @@ nsTablePart::InsertChildAt(nsIContent * aContent, PRInt32 aIndex,
if (NS_OK == rv)
{
tableContent->SetTable (this);
ResetCellMap ();
}
}
@ -522,7 +348,6 @@ nsTablePart::ReplaceChildAt (nsIContent *aContent, PRInt32 aIndex,
if (nsnull != lastChild)
tableContent->SetTable (nsnull);
tableContent->SetTable (this);
ResetCellMap ();
}
NS_IF_RELEASE(lastChild); // lastChild: REFCNT--
}
@ -552,7 +377,6 @@ nsTablePart::RemoveChildAt (PRInt32 aIndex, PRBool aNotify)
if (nsnull != lastChild)
((nsTableRow *)tableContent)->SetRowGroup (nsnull);
tableContent->SetTable(nsnull);
ResetCellMap ();
}
}
NS_IF_RELEASE(lastChild);
@ -752,287 +576,6 @@ PRBool nsTablePart::AppendCaption(nsTableCaption *aContent)
return (PRBool)(NS_OK==rv);
}
/* return the index of the first row group after aStartIndex */
PRInt32 nsTablePart::NextRowGroup (PRInt32 aStartIndex)
{
int index = aStartIndex;
int count = ChildCount ();
while (++index < count)
{
nsIContent * child = ChildAt (index); // child: REFCNT++
nsTableContent *tableContent = (nsTableColGroup *)child;
const int contentType = tableContent->GetType();
NS_RELEASE(child); // child: REFCNT--
if (contentType == nsITableContent::kTableRowGroupType)
return index;
}
return count;
}
// XXX This should be computed incrementally and updated
// automatically when rows are added/deleted. To do this, however,
// we need to change the way the ContentSink works and somehow
// notify this table when a row is modified. We can give the rows
// parent pointers, but that would bite.
// XXX nuke this; instead pretend the content sink is working
// incrementally like we want it to and build up the data a row at a
// time.
void nsTablePart::BuildCellMap ()
{
if (gsDebug==PR_TRUE) printf("Build Cell Map...\n");
int rowCount = GetRowCount ();
if (0 == rowCount)
{
if (gsDebug==PR_TRUE) printf("0 row count. Returning.\n");
mColCount = GetSpecifiedColumnCount (); // at least set known column count
EnsureColumns();
return;
}
// Make an educated guess as to how many columns we have. It's
// only a guess because we can't know exactly until we have
// processed the last row.
int childCount = ChildCount ();
int groupIndex = NextRowGroup (-1);
if (0 == mColCount)
mColCount = GetSpecifiedColumnCount ();
if (0 == mColCount) // no column parts
{
nsTableRowGroup *rowGroup = (nsTableRowGroup*)(ChildAt (groupIndex)); // rowGroup: REFCNT++
nsTableRow *row = (nsTableRow *)(rowGroup->ChildAt (0)); // row: REFCNT++
mColCount = row->GetMaxColumns ();
if (gsDebug==PR_TRUE) printf("mColCount=0 at start. Guessing col count to be %d from a row.\n", mColCount);
NS_RELEASE(rowGroup); // rowGroup: REFCNT--
NS_RELEASE(row); // row: REFCNT--
}
if (nsnull==mCellMap)
mCellMap = new nsCellMap(rowCount, mColCount);
else
mCellMap->Reset(rowCount, mColCount);
if (gsDebug==PR_TRUE) printf("mCellMap set to (%d, %d)\n", rowCount, mColCount);
int rowStart = 0;
if (gsDebug==PR_TRUE) printf("childCount is %d\n", childCount);
while (groupIndex < childCount)
{
if (gsDebug==PR_TRUE) printf(" groupIndex is %d\n", groupIndex);
if (gsDebug==PR_TRUE) printf(" rowStart is %d\n", rowStart);
nsTableRowGroup *rowGroup = (nsTableRowGroup *)ChildAt (groupIndex); // rowGroup: REFCNT++
int groupRowCount = rowGroup->ChildCount ();
if (gsDebug==PR_TRUE) printf(" groupRowCount is %d\n", groupRowCount);
for (int rowIndex = 0; rowIndex < groupRowCount; rowIndex++)
{
nsTableRow *row = (nsTableRow *)(rowGroup->ChildAt (rowIndex)); // row: REFCNT++
int cellCount = row->ChildCount ();
int cellIndex = 0;
int colIndex = 0;
if (gsDebug==PR_TRUE)
DumpCellMap();
if (gsDebug==PR_TRUE) printf(" rowIndex is %d, row->SetRowIndex(%d)\n", rowIndex, rowIndex + rowStart);
row->SetRowIndex (rowIndex + rowStart);
while (colIndex < mColCount)
{
if (gsDebug==PR_TRUE) printf(" colIndex = %d, with mColCount = %d\n", colIndex, mColCount);
CellData *data =mCellMap->GetCellAt(rowIndex + rowStart, colIndex);
if (nsnull == data)
{
if (gsDebug==PR_TRUE) printf(" null data from GetCellAt(%d,%d)\n", rowIndex+rowStart, colIndex);
if (gsDebug==PR_TRUE) printf(" cellIndex=%d, cellCount=%d)\n", cellIndex, cellCount);
if (cellIndex < cellCount)
{
nsTableCell* cell = (nsTableCell *) row->ChildAt (cellIndex); // cell: REFCNT++
if (gsDebug==PR_TRUE) printf(" calling BuildCellIntoMap(cell, %d, %d), and incrementing cellIndex\n", rowIndex + rowStart, colIndex);
BuildCellIntoMap (cell, rowIndex + rowStart, colIndex);
NS_RELEASE(cell); // cell: REFCNT--
cellIndex++;
}
}
colIndex++;
}
if (cellIndex < cellCount)
{
// We didn't use all the cells in this row up. Grow the cell
// data because we now know that we have more columns than we
// originally thought we had.
if (gsDebug==PR_TRUE) printf(" calling GrowCellMap because cellIndex < %d\n", cellIndex, cellCount);
GrowCellMap (cellCount);
while (cellIndex < cellCount)
{
if (gsDebug==PR_TRUE) printf(" calling GrowCellMap again because cellIndex < %d\n", cellIndex, cellCount);
GrowCellMap (colIndex + 1); // ensure enough cols in map, may be low due to colspans
CellData *data =mCellMap->GetCellAt(rowIndex + rowStart, colIndex);
if (data == nsnull)
{
nsTableCell* cell = (nsTableCell *) row->ChildAt (cellIndex); // cell: REFCNT++
BuildCellIntoMap (cell, rowIndex + rowStart, colIndex);
cellIndex++;
NS_RELEASE(cell); // cell: REFCNT--
}
colIndex++;
}
}
NS_RELEASE(row); // row: REFCNT--
}
NS_RELEASE(rowGroup); // rowGroup: REFCNT--
rowStart += groupRowCount;
groupIndex = NextRowGroup (groupIndex);
}
if (gsDebug==PR_TRUE)
DumpCellMap ();
EnsureColumns();
}
/**
*/
void nsTablePart::DumpCellMap () const
{
printf("dumping CellMap:\n");
if (nsnull != mCellMap)
{
int rowCount = mCellMap->GetRowCount();
int cols = mCellMap->GetColCount();
for (int r = 0; r < rowCount; r++)
{
if (gsDebug==PR_TRUE)
{ printf("row %d", r);
printf(": ");
}
for (int c = 0; c < cols; c++)
{
CellData *cd =mCellMap->GetCellAt(r, c);
if (cd != nsnull)
{
if (cd->mCell != nsnull)
{
printf("C%d,%d ", r, c);
printf(" ");
}
else
{
nsTableCell *cell = cd->mRealCell->mCell;
nsTableRow *row = cell->GetRow();
int rr = row->GetRowIndex ();
int cc = cell->GetColIndex ();
printf("S%d,%d ", rr, cc);
if (cd->mOverlap != nsnull)
{
cell = cd->mOverlap->mCell;
nsTableRow* row2 = cell->GetRow();
rr = row2->GetRowIndex ();
cc = cell->GetColIndex ();
printf("O%d,%c ", rr, cc);
NS_RELEASE(row2);
}
else
printf(" ");
NS_RELEASE(row);
}
}
else
printf("---- ");
}
printf("\n");
}
}
else
printf ("[nsnull]");
}
void nsTablePart::BuildCellIntoMap (nsTableCell *aCell, PRInt32 aRowIndex, PRInt32 aColIndex)
{
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (aColIndex < mColCount, "bad column index arg");
NS_PRECONDITION (aRowIndex < GetRowCount(), "bad row index arg");
// Setup CellMap for this cell
int rowSpan = GetEffectiveRowSpan (aRowIndex, aCell);
int colSpan = aCell->GetColSpan ();
if (gsDebug==PR_TRUE) printf(" BuildCellIntoMap. rowSpan = %d, colSpan = %d\n", rowSpan, colSpan);
// Grow the mCellMap array if we will end up addressing
// some new columns.
if (mColCount < (aColIndex + colSpan))
{
if (gsDebug==PR_TRUE) printf(" mColCount=%d<aColIndex+colSpan so calling GrowCellMap(%d)\n", mColCount, aColIndex+colSpan);
GrowCellMap (aColIndex + colSpan);
}
// Setup CellMap for this cell in the table
CellData *data = new CellData ();
data->mCell = aCell;
data->mRealCell = data;
if (gsDebug==PR_TRUE) printf(" calling mCellMap->SetCellAt(data, %d, %d)\n", aRowIndex, aColIndex);
mCellMap->SetCellAt(data, aRowIndex, aColIndex);
aCell->SetColIndex (aColIndex);
// Create CellData objects for the rows that this cell spans. Set
// their mCell to nsnull and their mRealCell to point to data. If
// there were no column overlaps then we could use the same
// CellData object for each row that we span...
if ((1 < rowSpan) || (1 < colSpan))
{
if (gsDebug==PR_TRUE) printf(" spans\n");
for (int rowIndex = 0; rowIndex < rowSpan; rowIndex++)
{
if (gsDebug==PR_TRUE) printf(" rowIndex = %d\n", rowIndex);
int workRow = aRowIndex + rowIndex;
if (gsDebug==PR_TRUE) printf(" workRow = %d\n", workRow);
for (int colIndex = 0; colIndex < colSpan; colIndex++)
{
if (gsDebug==PR_TRUE) printf(" colIndex = %d\n", colIndex);
int workCol = aColIndex + colIndex;
if (gsDebug==PR_TRUE) printf(" workCol = %d\n", workCol);
CellData *testData = mCellMap->GetCellAt(workRow, workCol);
if (nsnull == testData)
{
CellData *spanData = new CellData ();
spanData->mRealCell = data;
if (gsDebug==PR_TRUE) printf(" null GetCellAt(%d, %d) so setting to spanData\n", workRow, workCol);
mCellMap->SetCellAt(spanData, workRow, workCol);
}
else if ((0 < rowIndex) || (0 < colIndex))
{ // we overlap, replace existing data, it might be shared
if (gsDebug==PR_TRUE) printf(" overlapping Cell from GetCellAt(%d, %d) so setting to spanData\n", workRow, workCol);
CellData *overlap = new CellData ();
overlap->mCell = testData->mCell;
overlap->mRealCell = testData->mRealCell;
overlap->mOverlap = data;
mCellMap->SetCellAt(overlap, workRow, workCol);
}
}
}
}
}
void nsTablePart::GrowCellMap (PRInt32 aColCount)
{
if (nsnull!=mCellMap)
{
if (mColCount < aColCount)
{
mCellMap->GrowTo(aColCount);
}
mColCount = aColCount;
}
}
PRInt32 nsTablePart::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCell *aCell)
{
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (0<=aRowIndex && aRowIndex<GetRowCount(), "bad row index arg");
int rowSpan = aCell->GetRowSpan ();
int rowCount = GetRowCount ();
if (rowCount < (aRowIndex + rowSpan))
return (rowCount - aRowIndex);
return rowSpan;
}
/**
* Create a frame object that will layout this table.
*/

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

@ -23,7 +23,7 @@
#include "nsHTMLContainer.h"
// forward declarations
class nsTableCell;
class nsTableCellFrame;
class nsCellMap;
class nsTableRowGroup;
class nsTableColGroup;
@ -35,15 +35,15 @@ class nsTableCaption;
* in addition, if fOverlap is non-null then it will point to the
* other cell that overlaps this position
* @see nsCellMap
* @see nsTablePart::BuildCellMap
* @see nsTablePart::GrowCellMap
* @see nsTablePart::BuildCellIntoMap
* @see nsTableFrame::BuildCellMap
* @see nsTableFrame::GrowCellMap
* @see nsTableFrame::BuildCellIntoMap
*
*/
class CellData
{
public:
nsTableCell *mCell;
nsTableCellFrame *mCell;
CellData *mRealCell;
CellData *mOverlap;
@ -100,41 +100,6 @@ public:
/* public Table methods */
/** ResetCellMap is called when the cell structure of the table is changed.
* Call with caution, only when changing the structure of the table such as
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetCellMap ();
/** ResetColumns is called when the column structure of the table is changed.
* Call with caution, only when adding or removing columns, changing
* column attributes, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetColumns ();
/** sum the columns represented by all nsTableColGroup objects.
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
*/
virtual void EnsureColumns ();
/** Ensure that the cell map has been built for the table
*/
virtual void EnsureCellMap();
/** return the number of columns as specified by the input.
* has 2 side effects:<br>
* calls SetStartColumnIndex on each nsTableColumn<br>
* sets mSpecifiedColCount.<br>
*/
virtual PRInt32 GetSpecifiedColumnCount ();
/** returns the number of rows in this table.
* if mCellMap has been created, it is asked for the number of rows.<br>
* otherwise, the content is enumerated and the rows are counted.
*/
virtual PRInt32 GetRowCount();
/** returns the actual number of columns in this table.<br>
* as a side effect, will call BuildCellMap to constuct mCellMap if needed.
*/
@ -153,10 +118,6 @@ public:
nsIStyleContext* aStyleContext,
nsIFrame*& aResult);
/** called when the input stream knows that the input has been completely consumed.
* this is a hook for future optimizations.
*/
virtual void NotifyContentComplete();
static void GetTableBorder(nsIHTMLContent* aContent,
nsIStyleContext* aContext,
@ -169,40 +130,6 @@ protected:
*/
virtual ~nsTablePart();
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table.
* @param aRowIndex the first row that contains the cell
* @param aCell the content object representing the cell
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aRowIndex, nsTableCell *aCell);
/** build as much of the CellMap as possible from the info we have so far
*/
virtual void BuildCellMap ();
/** called whenever the number of columns changes, to increase the storage in mCellMap
*/
virtual void GrowCellMap(PRInt32 aColCount);
/** called every time we discover we have a new cell to add to the table.
* This could be because we got actual cell content, because of rowspan/colspan attributes, etc.
* This method changes mCellMap as necessary to account for the new cell.
*
* @param aCell the content object created for the cell
* @param aRowIndex the row into which the cell is to be inserted
* @param aColIndex the col into which the cell is to be inserted
*/
virtual void BuildCellIntoMap (nsTableCell *aCell, PRInt32 aRowIndex, PRInt32 aColIndex);
/** returns the index of the first child after aStartIndex that is a row group
*/
virtual PRInt32 NextRowGroup (PRInt32 aStartIndex);
/** obsolete! */
virtual void ReorderChildren();
/** append aContent to my child list
* @return PR_TRUE on success, PR_FALSE if aContent could not be appended
*/
@ -223,16 +150,10 @@ protected:
*/
virtual PRBool AppendCaption(nsTableCaption *aContent);
public:
virtual void DumpCellMap() const;
virtual nsCellMap* GetCellMap() const;
private:
PRInt32 mColCount;
PRInt32 mSpecifiedColCount;
nsCellMap* mCellMap;
static nsIAtom *kDefaultTag;
};

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

@ -110,6 +110,7 @@ nsrefcnt nsTableRow::Release(void)
return mRefCnt;
}
//QQQ could be removed
PRInt32 nsTableRow::GetMaxColumns()
{
int sum = 0;

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

@ -25,7 +25,6 @@
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
#include "nsTableCellFrame.h"
#include "nsTableCell.h"
#include "nsCellLayoutData.h"
#include "nsColLayoutData.h"
#include "nsIView.h"
@ -186,6 +185,10 @@ void nsTableRowFrame::PaintChildren(nsIPresContext& aPresContext,
}
}
void nsTableRowFrame::SetRowIndex (int aRowIndex)
{
mRowIndex = aRowIndex;
}
/** returns the height of the tallest child in this row (ignoring any cell with rowspans) */
nscoord nsTableRowFrame::GetTallestChild() const
@ -203,6 +206,18 @@ nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
return mCellMaxBottomMargin;
}
PRInt32 nsTableRowFrame::GetMaxColumns() const
{
int sum = 0;
nsTableCellFrame *cell=nsnull;
ChildAt(0, (nsIFrame *&)cell);
while (nsnull!=cell) {
sum += cell->GetColSpan();
cell->GetNextSibling((nsIFrame *&)cell);
}
return sum;
}
// Collapse child's top margin with previous bottom margin
nscoord nsTableRowFrame::GetTopMarginFor( nsIPresContext* aCX,
@ -264,7 +279,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
{
nsMargin margin(0,0,0,0);
if (aState.tableFrame->GetCellMarginData(aKidFrame, margin) == NS_OK)
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
{
nscoord height = aKidRect.height + margin.top + margin.bottom;
@ -324,11 +339,6 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nscoord maxCellBottomMargin = 0;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsIContent* content = nsnull;
kidFrame->GetContent(content); // cell: REFCNT++
nsTableCell* cell = (nsTableCell*)content;
nsSize kidAvailSize(aState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
@ -338,13 +348,11 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsReflowStatus status;
nsMargin kidMargin(0,0,0,0);
aState.tableFrame->GetCellMarginData(kidFrame,kidMargin);
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
// Figure out the amount of available size for the child (subtract
// off the top margin we are going to apply to it)
@ -365,14 +373,14 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, desiredSize,
kidReflowState);
nsCellLayoutData kidLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
aState.tableFrame->SetCellLayoutData(aPresContext, &kidLayoutData, cell);
nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
}
else
{ // we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData(cell);
PRInt32 cellStartingCol = cell->GetColIndex();
PRInt32 cellColSpan = cell->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -395,8 +403,6 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
desiredSize.width, desiredSize.height);
}
NS_RELEASE(content); // cell: REFCNT--
cell = nsnull;
// Did the child fit?
if ((kidFrame != mFirstChild) &&
@ -656,14 +662,10 @@ PRBool nsTableRowFrame::PullUpChildren(nsIPresContext* aPresContext,
break;
}
nsIContent *content = nsnull;
kidFrame->GetContent(content); // cell: REFNCT++
nsTableCell* cell = (nsTableCell*)content;
// we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData(cell);
PRInt32 cellStartingCol = cell->GetColIndex();
PRInt32 cellColSpan = cell->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -688,8 +690,6 @@ PRBool nsTableRowFrame::PullUpChildren(nsIPresContext* aPresContext,
desiredSize.width, desiredSize.height);
}
}
NS_RELEASE(content); // cell: REFCNT--
cell = nsnull;
// Did the child fit?
if ((desiredSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
@ -900,7 +900,7 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
nsIFrame* kidFrame;
// Create a child frame -- always an nsTableCell frame
nsIStyleContext* kidStyleContext = aPresContext->ResolveStyleContextFor(cell, this);
nsIStyleContext* kidStyleContext = aPresContext->ResolveStyleContextFor(cell, this, PR_TRUE);
if (nsnull == kidPrevInFlow) {
nsIContentDelegate* kidDel = nsnull;
kidDel = cell->GetDelegate(aPresContext);
@ -911,11 +911,6 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
kidPrevInFlow->CreateContinuingFrame(aPresContext, this,
kidStyleContext, kidFrame);
}
/* since I'm creating the cell frame, this is the first time through reflow
* it's a good time to set the column style from the cell's width attribute
* if this is the first row
*/
SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)kidFrame, kidStyleContext);
NS_RELEASE(kidStyleContext);
@ -923,7 +918,7 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
nscoord topMargin = 0;
nscoord bottomMargin = 0;
if (aState.tableFrame->GetCellMarginData(kidFrame, margin) == NS_OK)
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
topMargin = margin.top;
bottomMargin = margin.bottom;
@ -944,14 +939,14 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
// Reflow the child into the available space
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
nsCellLayoutData kidLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
aState.tableFrame->SetCellLayoutData(aPresContext, &kidLayoutData, (nsTableCell *)cell);
nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
}
else
{ // we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCell *)cell);
PRInt32 cellStartingCol = ((nsTableCell *)cell)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCell *)cell)->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -1154,53 +1149,6 @@ nsTableRowFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
return NS_OK;
}
NS_METHOD
nsTableRowFrame::SetColumnStyleFromCell(nsIPresContext* aPresContext,
nsTableCellFrame* aCellFrame,
nsIStyleContext* aCellSC)
{
// if this cell is in the first row, then the width attribute
// also acts as the width attribute for the entire column
if ((nsnull!=aCellSC) && (nsnull!=aCellFrame))
{
if (0==mRowIndex)
{
// get the cell style info
const nsStylePosition* cellPosition = (const nsStylePosition*) aCellSC->GetStyleData(eStyleStruct_Position);
if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
(eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
// compute the width per column spanned
PRInt32 colSpan = aCellFrame->GetColSpan();
nsTableFrame *tableFrame;
mGeometricParent->GetGeometricParent((nsIFrame *&)tableFrame);
for (PRInt32 i=0; i<colSpan; i++)
{
// get the appropriate column frame
nsTableColFrame *colFrame;
tableFrame->GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
// get the column style and set the width attribute
nsIStyleContextPtr colSC;
colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
// set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width/colSpan);
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
}
}
}
}
}
return NS_OK;
}
nsresult nsTableRowFrame::NewFrame( nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent)

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

@ -102,6 +102,14 @@ public:
nscoord GetChildMaxTopMargin() const;
nscoord GetChildMaxBottomMargin() const;
PRInt32 GetMaxColumns() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;
/** set this row's starting row index */
virtual void SetRowIndex (int aRowIndex);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -163,10 +171,6 @@ protected:
RowReflowState& aState,
nsSize* aMaxElementSize);
NS_METHOD SetColumnStyleFromCell(nsIPresContext * aPresContext,
nsTableCellFrame* aCellFrame,
nsIStyleContext * aCellSC);
private:
PRInt32 mRowIndex;
nscoord mTallestCell; // not my height, but the height of my tallest child
@ -182,4 +186,10 @@ inline void nsTableRowFrame::Init(PRInt32 aRowIndex)
mRowIndex = aRowIndex;
}
inline PRInt32 nsTableRowFrame::GetRowIndex() const
{
NS_ASSERTION(0<=mRowIndex, "bad state: row index");
return (mRowIndex);
}
#endif

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

@ -89,6 +89,7 @@ nsTableRowGroup::~nsTableRowGroup()
}
/** return the number of columns in the widest row in this group */
///QQQ could be removed
PRInt32 nsTableRowGroup::GetMaxColumns()
{ // computed every time for now, could be cached
PRInt32 result = 0;
@ -187,10 +188,7 @@ nsTableRowGroup::CreateFrame(nsIPresContext* aPresContext,
void nsTableRowGroup::ResetCellMap ()
{
// GREG: enable this assertion when the content notification code is checked in
// NS_ASSERTION(nsnull!=mTable, "illegal table content state");
if (nsnull != mTable)
mTable->ResetCellMap ();
}
NS_IMETHODIMP
@ -211,10 +209,7 @@ nsTableRowGroup::AppendChild (nsIContent *aContent, PRBool aNotify)
if (NS_OK==result)
{
((nsTableRow *)aContent)->SetRowGroup (this);
// after each row insertion, make sure we have corresponding column content objects
if (nsnull!=mTable)
mTable->EnsureColumns();
// also make sure the table cell map gets rebuilt
// make sure the table cell map gets rebuilt
ResetCellMap ();
}
}

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

@ -743,7 +743,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
// Resolve style
nsIStyleContextPtr kidSC =
aPresContext->ResolveStyleContextFor(kid, this);
aPresContext->ResolveStyleContextFor(kid, this, PR_TRUE);
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
kidSC->GetStyleData(eStyleStruct_Spacing);
nsMargin kidMargin;

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

@ -91,6 +91,9 @@ public:
*/
NS_IMETHOD GetRowGroupType(nsIAtom *& aType);
/** return the number of contained rows */
PRInt32 GetRowCount ();
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -157,5 +160,13 @@ private:
};
//XXX: change this if row groups can contain non-row types
// in this case, iterate through kids and add 1 if the kid's display type is "row"
inline PRInt32 nsTableRowGroupFrame::GetRowCount ()
{
PRInt32 result = 0;
ChildCount(result);
return result;
}
#endif

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

@ -1257,10 +1257,23 @@ static PRInt32 kDirectionKTable[] = {
};
static PRInt32 kDisplayKTable[] = {
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_NONE, NS_STYLE_DISPLAY_NONE,
KEYWORD_BLOCK, NS_STYLE_DISPLAY_BLOCK,
KEYWORD_INLINE, NS_STYLE_DISPLAY_INLINE,
KEYWORD_LIST_ITEM, NS_STYLE_DISPLAY_LIST_ITEM,
KEYWORD_MARKER, NS_STYLE_DISPLAY_MARKER,
KEYWORD_RUN_IN, NS_STYLE_DISPLAY_RUN_IN,
KEYWORD_COMPACT, NS_STYLE_DISPLAY_COMPACT,
KEYWORD_TABLE, NS_STYLE_DISPLAY_TABLE,
KEYWORD_INLINE_TABLE, NS_STYLE_DISPLAY_INLINE_TABLE,
KEYWORD_TABLE_ROW_GROUP, NS_STYLE_DISPLAY_TABLE_ROW_GROUP,
KEYWORD_TABLE_COLUMN, NS_STYLE_DISPLAY_TABLE_COLUMN,
KEYWORD_TABLE_COLUMN_GROUP, NS_STYLE_DISPLAY_TABLE_COLUMN_GROUP,
KEYWORD_TABLE_HEADER_GROUP, NS_STYLE_DISPLAY_TABLE_HEADER_GROUP,
KEYWORD_TABLE_FOOTER_GROUP, NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP,
KEYWORD_TABLE_ROW, NS_STYLE_DISPLAY_TABLE_ROW,
KEYWORD_TABLE_CELL, NS_STYLE_DISPLAY_TABLE_CELL,
KEYWORD_TABLE_CAPTION, NS_STYLE_DISPLAY_TABLE_CAPTION,
-1
};

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

@ -530,6 +530,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
}

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

@ -209,7 +209,7 @@ PLAINTEXT, XMP, PRE {
// Table tags
TABLE {
display: block;
display: table;
border-style: outset;
border-color: #C0C0C0;
cell-spacing: 4px;
@ -225,7 +225,7 @@ TD, TH {
font-weight: normal;
font-size: 11pt;
line-height: 1.1;
display: block;
display: table-cell;
cursor: arrow;
}
TH {
@ -234,8 +234,14 @@ TH {
}
CAPTION {
text-align: center;
display: block;
display: table-caption;
}
TBODY { display: table-row-group; }
THEAD { display: table-header-group; }
TFOOT { display: table-footer-group; }
COL { display: table-column; }
COLGROUP { display: table-column-group;}
MULTICOL {
display: block;
}

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

@ -463,7 +463,10 @@ PRBool BasicTableLayoutStrategy::SetColumnsToMinWidth(nsIPresContext* aPresConte
for (PRInt32 cellIndex = 0; cellIndex<numCells; cellIndex++)
{ // this col has proportional width, so determine its width requirements
nsCellLayoutData * data = (nsCellLayoutData *)(cells->ElementAt(cellIndex));
NS_ASSERTION(nsnull != data, "bad data");
if (nsnull==data)
{ // For cells that span rows there's only cell layout data for the first row
continue;
}
nsSize * cellMinSize = data->GetMaxElementSize();
NS_ASSERTION(nsnull != cellMinSize, "bad cellMinSize");
nsReflowMetrics * cellDesiredSize = data->GetDesiredSize();

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

@ -28,12 +28,11 @@ class CellData;
* Each cell is represented by a CellData object.
*
* @see CellData
* @see nsTablePart::BuildCellMap
* @see nsTablePart::GrowCellMap
* @see nsTablePart::BuildCellIntoMap
* @see nsTableFrame::BuildCellMap
* @see nsTableFrame::GrowCellMap
* @see nsTableFrame::BuildCellIntoMap
*
* acts like a 2-dimensional array, so all offsets are 0-indexed
TODO: inline methods
*/
class nsCellMap
{

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

@ -16,6 +16,7 @@
* Reserved.
*/
#include "nsTableCellFrame.h"
#include "nsCellLayoutData.h"
#include "nsBodyFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
@ -48,7 +49,8 @@ static const PRBool gsDebug = PR_FALSE;
*/
nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame)
: nsContainerFrame(aContent, aParentFrame),
mCellLayoutData(nsnull)
{
mRowSpan=1;
mColSpan=1;
@ -57,6 +59,8 @@ nsTableCellFrame::nsTableCellFrame(nsIContent* aContent,
nsTableCellFrame::~nsTableCellFrame()
{
if (nsnull!=mCellLayoutData)
delete mCellLayoutData;
}
NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,

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

@ -22,6 +22,7 @@
#include "nsContainerFrame.h"
#include "nsTableFrame.h"
class nsCellLayoutData;
struct nsStyleSpacing;
/**
@ -68,11 +69,16 @@ public:
/** return the mapped cell's column index (starting at 0 for the first column) */
virtual PRInt32 GetColIndex();
virtual void SetColIndex (int aColIndex);
virtual ~nsTableCellFrame();
// Get the TableFrame that contains this cell frame
virtual nsTableFrame* GetTableFrame();
nsCellLayoutData * GetCellLayoutData();
void SetCellLayoutData(nsCellLayoutData *aData);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -106,6 +112,8 @@ protected:
/** the starting column for this cell */
int mColIndex;
nsCellLayoutData *mCellLayoutData;
};
inline void nsTableCellFrame::Init(PRInt32 aRowSpan, PRInt32 aColSpan, PRInt32 aColIndex)
@ -127,5 +135,16 @@ inline PRInt32 nsTableCellFrame::GetColSpan()
inline PRInt32 nsTableCellFrame::GetColIndex()
{ return mColIndex;}
inline void nsTableCellFrame::SetColIndex (int aColIndex)
{
NS_ASSERTION(0<=aColIndex, "illegal negative column index.");
mColIndex = aColIndex;
}
inline nsCellLayoutData * nsTableCellFrame::GetCellLayoutData()
{ return mCellLayoutData;}
inline void nsTableCellFrame::SetCellLayoutData(nsCellLayoutData *aData)
{ mCellLayoutData = aData;}
#endif

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

@ -21,7 +21,6 @@
#include "nscore.h"
#include "nsContainerFrame.h"
class nsTableColFrame : public nsFrame {
public:
@ -46,6 +45,9 @@ public:
/** return the number of the columns the col represents. always >= 0 */
virtual int GetRepeat ();
/** set the index of the column this content object represents. must be >= 0 */
virtual void SetColumnIndex (int aColIndex);
protected:
nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@ -75,6 +77,9 @@ inline nsTableColFrame::GetColumnIndex()
inline nsTableColFrame::GetRepeat()
{ return mRepeat; }
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
#endif

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

@ -16,13 +16,13 @@
* Reserved.
*/
#include "nsTableColGroupFrame.h"
#include "nsTableColFrame.h"
#include "nsIReflowCommand.h"
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIPtr.h"
#include "nsIContentDelegate.h"
#include "nsTableContent.h"
#include "nsHTMLAtoms.h"
NS_DEF_PTR(nsIContent);
@ -35,6 +35,7 @@ nsTableColGroupFrame::nsTableColGroupFrame(nsIContent* aContent,
nsIFrame* aParentFrame)
: nsContainerFrame(aContent, aParentFrame)
{
mColCount=0;
}
nsTableColGroupFrame::~nsTableColGroupFrame()
@ -66,7 +67,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
LastChild(prevKidFrame); // XXX remember this...
PRInt32 kidIndex = 0;
for (;;)
for (PRInt32 colIndex = 0; ;colIndex++) // colIndex is used to set the column frames' index field
{
nsIContentPtr kid = mContent->ChildAt(kidIndex); // kid: REFCNT++
if (kid.IsNull()) {
@ -75,7 +76,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
// Resolve style
nsIStyleContextPtr kidSC =
aPresContext->ResolveStyleContextFor(kid, this);
aPresContext->ResolveStyleContextFor(kid, this, PR_TRUE);
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
kidSC->GetStyleData(eStyleStruct_Spacing);
@ -95,6 +96,9 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext* aPresContext,
// note that DidReflow is called as the result of some ancestor firing off a DidReflow above me
kidFrame->SetRect(nsRect(0,0,0,0));
// set nsColFrame-specific information
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex+mStartColIndex);
// Link child frame into the list of children
if (nsnull != prevKidFrame) {
prevKidFrame->SetNextSibling(kidFrame);
@ -178,6 +182,42 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
return NS_OK;
}
/** returns the number of columns represented by this group.
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
int nsTableColGroupFrame::GetColumnCount ()
{
if (0 == mColCount)
{
int count;
ChildCount (count);
if (0 < count)
{
nsIFrame * child = nsnull;
ChildAt(0, child);
NS_ASSERTION(nsnull!=child, "bad child");
while (nsnull!=child)
{
nsTableColFrame *col = (nsTableColFrame *)child;
col->SetColumnIndex (mStartColIndex + mColCount);
mColCount += col->GetRepeat ();
child->GetNextSibling(child);
}
}
else
{
const nsStyleTable *tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
mColCount = tableStyle->mSpan;
}
}
return mColCount;
}
/* ----- static methods ----- */
nsresult nsTableColGroupFrame::NewFrame(nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent)
@ -193,3 +233,5 @@ nsresult nsTableColGroupFrame::NewFrame(nsIFrame** aInstancePtrResult,
*aInstancePtrResult = it;
return NS_OK;
}

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

@ -50,6 +50,16 @@ public:
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** returns the number of columns represented by this group.
* if there are col children, count them (taking into account the span of each)
* else, check my own span attribute.
*/
virtual PRInt32 GetColumnCount ();
virtual PRInt32 GetStartColumnIndex ();
virtual void SetStartColumnIndex (PRInt32 aIndex);
protected:
nsTableColGroupFrame(nsIContent* aContent, nsIFrame* aParentFrame);
@ -62,6 +72,22 @@ protected:
*/
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
PRInt32 mColCount;
/** the starting column index this col group represents. Must be >= 0. */
PRInt32 mStartColIndex;
};
inline int nsTableColGroupFrame::GetStartColumnIndex ()
{ return mStartColIndex;}
inline void nsTableColGroupFrame::SetStartColumnIndex (int aIndex)
{
if (aIndex != mStartColIndex)
mColCount = 0; // our index is being changed, trigger reset of col indicies, don't propogate back to table
mStartColIndex = aIndex;
}
#endif

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -22,11 +22,12 @@
#include "nsContainerFrame.h"
#include "nsStyleCoord.h"
class nsCellMap;
class nsCellLayoutData;
class nsTableCell;
class nsVoidArray;
class nsTableCellFrame;
class nsTableColFrame;
class nsTableRowFrame;
class CellData;
class nsITableLayoutStrategy;
class nsHTMLValue;
@ -120,6 +121,14 @@ public:
nsReflowMetrics& aDesiredSize,
nsSize* aMaxElementSize);
/** allow the cell and row attributes to effect the column frame
* currently, the only reason this exists is to support the HTML "rule"
* that a width attribute on a cell in the first column sets the column width.
*/
virtual NS_METHOD SetColumnStyleFromCell(nsIPresContext * aPresContext,
nsTableCellFrame* aCellFrame,
nsTableRowFrame * aRowFrame);
/** return the column frame corresponding to the given column index
* there are two ways to do this, depending on whether we have cached
* column information yet.
@ -140,15 +149,15 @@ public:
* @return PR_TRUE if the data was successfully associated with a Cell
* PR_FALSE if there was an error, such as aRow or aCol being invalid
*/
virtual PRBool SetCellLayoutData(nsIPresContext* aPresContext,
virtual PRBool SetCellLayoutData(nsIPresContext * aPresContext,
nsCellLayoutData * aData,
nsTableCell *aCell);
nsTableCellFrame * aCell);
/** Get the layout data associated with the cell at (aRow,aCol)
* @return PR_NULL if there was an error, such as aRow or aCol being invalid
* otherwise, the data is returned.
*/
virtual nsCellLayoutData * GetCellLayoutData(nsTableCell *aCell);
virtual nsCellLayoutData * GetCellLayoutData(nsTableCellFrame *aCell);
/**
* DEBUG METHOD
@ -167,16 +176,11 @@ public:
* Calculate Layout Information
*
*/
void AppendLayoutData(nsVoidArray* aList, nsTableCell* aTableCell);
void AppendLayoutData(nsVoidArray* aList, nsTableCellFrame* aTableCell);
void RecalcLayoutData();
void ResetCellLayoutData( nsTableCell* aCell,
nsTableCell* aAbove,
nsTableCell* aBelow,
nsTableCell* aLeft,
nsTableCell* aRight);
// Get cell margin information
NS_IMETHOD GetCellMarginData(nsIFrame* aKidFrame, nsMargin& aMargin);
NS_IMETHOD GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin);
/** get cached column information for a subset of the columns
*
@ -220,7 +224,8 @@ protected:
*/
virtual nsReflowStatus ResizeReflowPass1(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState);
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** second pass of ResizeReflow.
* lays out all table content with aMaxSize(computed_table_width, given_table_height)
@ -328,6 +333,85 @@ protected:
void MapHTMLBorderStyle(nsStyleSpacing& aSpacingStyle, nscoord aBorderWidth);
PRBool ConvertToPixelValue(nsHTMLValue& aValue, PRInt32 aDefault, PRInt32& aResult);
/** return the row span of a cell, taking into account row span magic at the bottom
* of a table.
* @param aRowIndex the first row that contains the cell
* @param aCell the content object representing the cell
* @return the row span, correcting for row spans that extend beyond the bottom
* of the table.
*/
virtual PRInt32 GetEffectiveRowSpan(PRInt32 aRowIndex, nsTableCellFrame *aCell);
/** build as much of the CellMap as possible from the info we have so far
*/
virtual void BuildCellMap ();
/** called whenever the number of columns changes, to increase the storage in mCellMap
*/
virtual void GrowCellMap(PRInt32 aColCount);
/** ResetCellMap is called when the cell structure of the table is changed.
* Call with caution, only when changing the structure of the table such as
* inserting or removing rows, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetCellMap ();
/** ResetColumns is called when the column structure of the table is changed.
* Call with caution, only when adding or removing columns, changing
* column attributes, changing the rowspan or colspan attribute of a cell, etc.
*/
virtual void ResetColumns ();
/** sum the columns represented by all nsTableColGroup objects.
* if the cell map says there are more columns than this,
* add extra implicit columns to the content tree.
*/
virtual void EnsureColumns (nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** Ensure that the cell map has been built for the table
*/
virtual void EnsureCellMap();
virtual void BuildColumnCache(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
/** called every time we discover we have a new cell to add to the table.
* This could be because we got actual cell content, because of rowspan/colspan attributes, etc.
* This method changes mCellMap as necessary to account for the new cell.
*
* @param aCell the content object created for the cell
* @param aRowIndex the row into which the cell is to be inserted
* @param aColIndex the col into which the cell is to be inserted
*/
virtual void BuildCellIntoMap (nsTableCellFrame *aCell, PRInt32 aRowIndex, PRInt32 aColIndex);
/** returns the index of the first child after aStartIndex that is a row group
*/
virtual PRInt32 NextRowGroup (PRInt32 aStartIndex);
/** returns the number of rows in this table.
* if mCellMap has been created, it is asked for the number of rows.<br>
* otherwise, the content is enumerated and the rows are counted.
*/
virtual PRInt32 GetRowCount();
/** return the number of columns as specified by the input.
* has 2 side effects:<br>
* calls SetStartColumnIndex on each nsTableColumn<br>
* sets mSpecifiedColCount.<br>
*/
virtual PRInt32 GetSpecifiedColumnCount ();
public:
virtual void DumpCellMap() const;
virtual nsCellMap* GetCellMap() const;
private:
void DebugPrintCount() const; // Debugging routine
@ -346,6 +430,8 @@ private:
PRInt32 mPass; // which Reflow pass are we currently in?
PRBool mIsInvariantWidth; // PR_TRUE if table width cannot change
nsITableLayoutStrategy * mTableLayoutStrategy; // the layout strategy for this frame
PRInt32 mColCount; // the number of columns in this table
nsCellMap* mCellMap; // maintains the relationships between rows, cols, and cells
};
#endif

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

@ -232,7 +232,7 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
mInnerTableFrame->SetReflowPass(nsTableFrame::kPASS_FIRST);
nsReflowState innerTableReflowState(mInnerTableFrame, aReflowState, aReflowState.maxSize);
aStatus = mInnerTableFrame->ResizeReflowPass1(aPresContext, aDesiredSize,
innerTableReflowState);
innerTableReflowState, aStatus);
}
mInnerTableFrame->SetReflowPass(nsTableFrame::kPASS_SECOND);
// assign table width info only if the inner table frame is a first-in-flow
@ -468,11 +468,8 @@ PRBool nsTableOuterFrame::ReflowMappedChildren( nsIPresContext* aPresContex
kidFrame, aState.processingCaption?"caption":"inner");
// Get top margin for this kid
nsIStyleContextPtr kidSC;
kidFrame->GetStyleContext(aPresContext, kidSC.AssignRef());
const nsStyleSpacing* kidSpacing =
(const nsStyleSpacing*)kidSC->GetStyleData(eStyleStruct_Spacing);
const nsStyleSpacing* kidSpacing;
kidFrame->GetStyleData(eStyleStruct_Spacing, (nsStyleStruct *&)kidSpacing);
nsMargin kidMargin;
kidSpacing->CalcMarginFor(kidFrame, kidMargin);
nscoord topMargin = GetTopMarginFor(aPresContext, aState, kidMargin);
@ -904,12 +901,8 @@ nsTableOuterFrame::ReflowChild( nsIFrame* aKidFrame,
if (PR_TRUE==aState.processingCaption)
{ // it's a caption, find out if it's top or bottom
// Resolve style
nsIStyleContextPtr captionStyleContext;
aKidFrame->GetStyleContext(aPresContext, captionStyleContext.AssignRef());
NS_ASSERTION(captionStyleContext.IsNotNull(), "null style context for caption");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
const nsStyleText* captionStyle;
aKidFrame->GetStyleData(eStyleStruct_Text, ( nsStyleStruct *&)captionStyle);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
@ -975,31 +968,32 @@ void nsTableOuterFrame::CreateChildFrames(nsIPresContext* aPresContext)
mCaptionFrames = new nsVoidArray();
// create caption frames as needed
nsIFrame *lastTopCaption = nsnull;
for (PRInt32 kidIndex=0; /* nada */ ;kidIndex++) {
nsIContentPtr caption = mContent->ChildAt(kidIndex); // caption: REFCNT++
if (caption.IsNull()) {
for (PRInt32 kidIndex=0; /* nada */ ;kidIndex++)
{
nsIContentPtr caption = mContent->ChildAt(kidIndex);
if (PR_TRUE==caption.IsNull()) {
break;
}
const PRInt32 contentType = ((nsTableContent *)(nsIContent*)caption)->GetType();
if (contentType==nsITableContent::kTableCaptionType)
// Resolve style
nsIStyleContextPtr captionSC =
aPresContext->ResolveStyleContextFor(caption, this);
NS_ASSERTION(captionSC.IsNotNull(), "bad style context for caption.");
nsStyleDisplay *childDisplay = (nsStyleDisplay*)captionSC->GetStyleData(eStyleStruct_Display);
if (NS_STYLE_DISPLAY_TABLE_CAPTION == childDisplay->mDisplay)
{
// Resolve style
nsIStyleContextPtr captionStyleContext =
aPresContext->ResolveStyleContextFor(caption, this);
NS_ASSERTION(captionStyleContext.IsNotNull(), "bad style context for caption.");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
const nsStyleText* captionTextStyle =
(const nsStyleText*)captionSC->GetStyleData(eStyleStruct_Text);
// create the frame
nsIFrame *captionFrame=nsnull;
frameCreated = ((nsIHTMLContent*)(nsIContent*)caption)->CreateFrame(aPresContext,
this, captionStyleContext, captionFrame);
this, captionSC, captionFrame);
if (NS_OK!=frameCreated)
return; // SEC: an error!!!!
mChildCount++;
// Link child frame into the list of children
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
if ((eStyleUnit_Enumerated == captionTextStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionTextStyle->mVerticalAlign.GetIntValue()))
{ // bottom captions get added to the end of the outer frame child list
prevKidFrame->SetNextSibling(captionFrame);
prevKidFrame = captionFrame;
@ -1027,7 +1021,8 @@ void nsTableOuterFrame::CreateChildFrames(nsIPresContext* aPresContext)
mCaptionFrames->AppendElement(captionFrame);
}
else
{
{ // otherwise I know there are no more captions
// I'm assuming the frames were created in the correct order
break;
}
}
@ -1085,16 +1080,12 @@ nsTableOuterFrame::ResizeReflowTopCaptionsPass2(nsIPresContext* aPresCont
nsTableCaptionFrame *captionFrame = (nsTableCaptionFrame *)mCaptionFrames->ElementAt(captionIndex);
// Resolve style
nsIStyleContextPtr captionStyleContext;
captionFrame->GetStyleContext(aPresContext, captionStyleContext.AssignRef());
NS_ASSERTION(captionStyleContext.IsNotNull(), "null style context for caption");
const nsStyleText* captionStyle =
(const nsStyleText*)captionStyleContext->GetStyleData(eStyleStruct_Text);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
const nsStyleText* captionTextStyle;
captionFrame->GetStyleData(eStyleStruct_Text, (nsStyleStruct *&)captionTextStyle);
NS_ASSERTION(nsnull != captionTextStyle, "null style molecule for caption");
if ((eStyleUnit_Enumerated == captionStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionStyle->mVerticalAlign.GetIntValue()))
if ((eStyleUnit_Enumerated == captionTextStyle->mVerticalAlign.GetUnit()) &&
(NS_STYLE_VERTICAL_ALIGN_BOTTOM==captionTextStyle->mVerticalAlign.GetIntValue()))
{
}
else
@ -1158,10 +1149,10 @@ nsTableOuterFrame::ResizeReflowBottomCaptionsPass2(nsIPresContext* aPresContext
// Resolve style
/*
nsIStyleContextPtr captionStyleContext = captionFrame->GetStyleContext(aPresContext);
NS_ASSERTION(nsnull != captionStyleContext, "null style context for caption");
nsIStyleContextPtr captionSC = captionFrame->GetStyleContext(aPresContext);
NS_ASSERTION(nsnull != captionSC, "null style context for caption");
nsStyleMolecule* captionStyle =
(nsStyleMolecule*)captionStyleContext->GetData(eStyleStruct_Molecule);
(nsStyleMolecule*)captionSC->GetData(eStyleStruct_Molecule);
NS_ASSERTION(nsnull != captionStyle, "null style molecule for caption");
*/
// reflow the caption

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

@ -25,7 +25,6 @@
#include "nsTableFrame.h"
#include "nsTableColFrame.h"
#include "nsTableCellFrame.h"
#include "nsTableCell.h"
#include "nsCellLayoutData.h"
#include "nsColLayoutData.h"
#include "nsIView.h"
@ -186,6 +185,10 @@ void nsTableRowFrame::PaintChildren(nsIPresContext& aPresContext,
}
}
void nsTableRowFrame::SetRowIndex (int aRowIndex)
{
mRowIndex = aRowIndex;
}
/** returns the height of the tallest child in this row (ignoring any cell with rowspans) */
nscoord nsTableRowFrame::GetTallestChild() const
@ -203,6 +206,18 @@ nscoord nsTableRowFrame::GetChildMaxBottomMargin() const
return mCellMaxBottomMargin;
}
PRInt32 nsTableRowFrame::GetMaxColumns() const
{
int sum = 0;
nsTableCellFrame *cell=nsnull;
ChildAt(0, (nsIFrame *&)cell);
while (nsnull!=cell) {
sum += cell->GetColSpan();
cell->GetNextSibling((nsIFrame *&)cell);
}
return sum;
}
// Collapse child's top margin with previous bottom margin
nscoord nsTableRowFrame::GetTopMarginFor( nsIPresContext* aCX,
@ -264,7 +279,7 @@ void nsTableRowFrame::PlaceChild(nsIPresContext* aPresContext,
{
nsMargin margin(0,0,0,0);
if (aState.tableFrame->GetCellMarginData(aKidFrame, margin) == NS_OK)
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)aKidFrame, margin) == NS_OK)
{
nscoord height = aKidRect.height + margin.top + margin.bottom;
@ -324,11 +339,6 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nscoord maxCellBottomMargin = 0;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsIContent* content = nsnull;
kidFrame->GetContent(content); // cell: REFCNT++
nsTableCell* cell = (nsTableCell*)content;
nsSize kidAvailSize(aState.availSize);
if (0>=kidAvailSize.height)
kidAvailSize.height = 1; // XXX: HaCk - we don't handle negative heights yet
@ -338,13 +348,11 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
nsReflowStatus status;
nsMargin kidMargin(0,0,0,0);
aState.tableFrame->GetCellMarginData(kidFrame,kidMargin);
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
// Figure out the amount of available size for the child (subtract
// off the top margin we are going to apply to it)
@ -365,14 +373,14 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, desiredSize,
kidReflowState);
nsCellLayoutData kidLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
aState.tableFrame->SetCellLayoutData(aPresContext, &kidLayoutData, cell);
nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
}
else
{ // we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData(cell);
PRInt32 cellStartingCol = cell->GetColIndex();
PRInt32 cellColSpan = cell->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -395,8 +403,6 @@ PRBool nsTableRowFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
NS_FRAME_IS_COMPLETE(status)?"complete":"NOT complete",
desiredSize.width, desiredSize.height);
}
NS_RELEASE(content); // cell: REFCNT--
cell = nsnull;
// Did the child fit?
if ((kidFrame != mFirstChild) &&
@ -656,14 +662,10 @@ PRBool nsTableRowFrame::PullUpChildren(nsIPresContext* aPresContext,
break;
}
nsIContent *content = nsnull;
kidFrame->GetContent(content); // cell: REFNCT++
nsTableCell* cell = (nsTableCell*)content;
// we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData(cell);
PRInt32 cellStartingCol = cell->GetColIndex();
PRInt32 cellColSpan = cell->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -688,8 +690,6 @@ PRBool nsTableRowFrame::PullUpChildren(nsIPresContext* aPresContext,
desiredSize.width, desiredSize.height);
}
}
NS_RELEASE(content); // cell: REFCNT--
cell = nsnull;
// Did the child fit?
if ((desiredSize.height > aState.availSize.height) && (nsnull != mFirstChild)) {
@ -900,7 +900,7 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
nsIFrame* kidFrame;
// Create a child frame -- always an nsTableCell frame
nsIStyleContext* kidStyleContext = aPresContext->ResolveStyleContextFor(cell, this);
nsIStyleContext* kidStyleContext = aPresContext->ResolveStyleContextFor(cell, this, PR_TRUE);
if (nsnull == kidPrevInFlow) {
nsIContentDelegate* kidDel = nsnull;
kidDel = cell->GetDelegate(aPresContext);
@ -911,11 +911,6 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
kidPrevInFlow->CreateContinuingFrame(aPresContext, this,
kidStyleContext, kidFrame);
}
/* since I'm creating the cell frame, this is the first time through reflow
* it's a good time to set the column style from the cell's width attribute
* if this is the first row
*/
SetColumnStyleFromCell(aPresContext, (nsTableCellFrame *)kidFrame, kidStyleContext);
NS_RELEASE(kidStyleContext);
@ -923,7 +918,7 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
nscoord topMargin = 0;
nscoord bottomMargin = 0;
if (aState.tableFrame->GetCellMarginData(kidFrame, margin) == NS_OK)
if (aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, margin) == NS_OK)
{
topMargin = margin.top;
bottomMargin = margin.bottom;
@ -944,14 +939,14 @@ nsTableRowFrame::ReflowUnmappedChildren( nsIPresContext* aPresContext,
// Reflow the child into the available space
kidFrame->WillReflow(*aPresContext);
status = ReflowChild(kidFrame, aPresContext, desiredSize, kidReflowState);
nsCellLayoutData kidLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
aState.tableFrame->SetCellLayoutData(aPresContext, &kidLayoutData, (nsTableCell *)cell);
nsCellLayoutData *kidLayoutData = new nsCellLayoutData((nsTableCellFrame *)kidFrame, &desiredSize, pKidMaxElementSize);
((nsTableCellFrame *)kidFrame)->SetCellLayoutData(kidLayoutData);
}
else
{ // we're in a constrained situation, so get the avail width from the known column widths
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCell *)cell);
PRInt32 cellStartingCol = ((nsTableCell *)cell)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCell *)cell)->GetColSpan();
nsCellLayoutData *cellData = aState.tableFrame->GetCellLayoutData((nsTableCellFrame *)kidFrame);
PRInt32 cellStartingCol = ((nsTableCellFrame *)kidFrame)->GetColIndex();
PRInt32 cellColSpan = ((nsTableCellFrame *)kidFrame)->GetColSpan();
nscoord availWidth = 0;
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
availWidth += aState.tableFrame->GetColumnWidth(cellStartingCol+numColSpan);
@ -1154,53 +1149,6 @@ nsTableRowFrame::CreateContinuingFrame(nsIPresContext* aPresContext,
return NS_OK;
}
NS_METHOD
nsTableRowFrame::SetColumnStyleFromCell(nsIPresContext* aPresContext,
nsTableCellFrame* aCellFrame,
nsIStyleContext* aCellSC)
{
// if this cell is in the first row, then the width attribute
// also acts as the width attribute for the entire column
if ((nsnull!=aCellSC) && (nsnull!=aCellFrame))
{
if (0==mRowIndex)
{
// get the cell style info
const nsStylePosition* cellPosition = (const nsStylePosition*) aCellSC->GetStyleData(eStyleStruct_Position);
if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) ||
(eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) {
// compute the width per column spanned
PRInt32 colSpan = aCellFrame->GetColSpan();
nsTableFrame *tableFrame;
mGeometricParent->GetGeometricParent((nsIFrame *&)tableFrame);
for (PRInt32 i=0; i<colSpan; i++)
{
// get the appropriate column frame
nsTableColFrame *colFrame;
tableFrame->GetColumnFrame(i+aCellFrame->GetColIndex(), colFrame);
// get the column style and set the width attribute
nsIStyleContextPtr colSC;
colFrame->GetStyleContext(aPresContext, colSC.AssignRef());
nsStylePosition* colPosition = (nsStylePosition*) colSC->GetMutableStyleData(eStyleStruct_Position);
// set the column width attribute
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit())
{
nscoord width = cellPosition->mWidth.GetCoordValue();
colPosition->mWidth.SetCoordValue(width/colSpan);
}
else
{
float width = cellPosition->mWidth.GetPercentValue();
colPosition->mWidth.SetPercentValue(width/colSpan);
}
}
}
}
}
return NS_OK;
}
nsresult nsTableRowFrame::NewFrame( nsIFrame** aInstancePtrResult,
nsIContent* aContent,
nsIFrame* aParent)

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

@ -102,6 +102,14 @@ public:
nscoord GetChildMaxTopMargin() const;
nscoord GetChildMaxBottomMargin() const;
PRInt32 GetMaxColumns() const;
/** returns the ordinal position of this row in its table */
virtual PRInt32 GetRowIndex() const;
/** set this row's starting row index */
virtual void SetRowIndex (int aRowIndex);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -163,10 +171,6 @@ protected:
RowReflowState& aState,
nsSize* aMaxElementSize);
NS_METHOD SetColumnStyleFromCell(nsIPresContext * aPresContext,
nsTableCellFrame* aCellFrame,
nsIStyleContext * aCellSC);
private:
PRInt32 mRowIndex;
nscoord mTallestCell; // not my height, but the height of my tallest child
@ -182,4 +186,10 @@ inline void nsTableRowFrame::Init(PRInt32 aRowIndex)
mRowIndex = aRowIndex;
}
inline PRInt32 nsTableRowFrame::GetRowIndex() const
{
NS_ASSERTION(0<=mRowIndex, "bad state: row index");
return (mRowIndex);
}
#endif

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

@ -743,7 +743,7 @@ nsTableRowGroupFrame::ReflowUnmappedChildren(nsIPresContext* aPresContext,
// Resolve style
nsIStyleContextPtr kidSC =
aPresContext->ResolveStyleContextFor(kid, this);
aPresContext->ResolveStyleContextFor(kid, this, PR_TRUE);
const nsStyleSpacing* kidSpacing = (const nsStyleSpacing*)
kidSC->GetStyleData(eStyleStruct_Spacing);
nsMargin kidMargin;

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

@ -91,6 +91,9 @@ public:
*/
NS_IMETHOD GetRowGroupType(nsIAtom *& aType);
/** return the number of contained rows */
PRInt32 GetRowCount ();
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);
@ -157,5 +160,13 @@ private:
};
//XXX: change this if row groups can contain non-row types
// in this case, iterate through kids and add 1 if the kid's display type is "row"
inline PRInt32 nsTableRowGroupFrame::GetRowCount ()
{
PRInt32 result = 0;
ChildCount(result);
return result;
}
#endif