all frame initialization and related logic has moved into the various table frames' Init() methods

from their respective InitalReflow() methods.
table-layout=fixed now completely skips pass1 reflow and doesn't require maxElementSize
information, saving a tremendous amount of time during initial reflow.
This commit is contained in:
buster%netscape.com 1998-09-23 21:48:26 +00:00
parent af07672e54
commit 1fba5ac7dc
19 changed files with 469 additions and 311 deletions

View File

@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
mSpan=1;
// values inherited
if (nsnull!=aParent)
mLayoutStrategy = aParent->mLayoutStrategy;

View File

@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
mSpan=1;
// values inherited
if (nsnull!=aParent)
mLayoutStrategy = aParent->mLayoutStrategy;

View File

@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext);
#ifdef NS_DEBUG
static PRBool gsDebug = PR_TRUE;
static PRBool gsDebug = PR_FALSE;
#else
static const PRBool gsDebug = PR_FALSE;
#endif

View File

@ -23,6 +23,8 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLParts.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
@ -48,14 +50,18 @@ nsTableColGroupFrame::~nsTableColGroupFrame()
nsresult
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
nsresult rv=NS_OK;
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
// Process the newly added column frames
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
// Set the preliminary values for the column frame
nsIContent* kid;
kidFrame->GetContent(kid);
// should use style to get this value
PRInt32 repeat=1;
nsIHTMLTableColElement* colContent = nsnull;
nsresult rv = kid->QueryInterface(kIHTMLTableColElementIID,
rv = kid->QueryInterface(kIHTMLTableColElementIID,
(void**) &colContent); // colContent: ADDREF++
NS_RELEASE(kid);
if (rv==NS_OK)
@ -66,17 +72,67 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
PRInt32 colIndex = mStartColIndex + mColCount;
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
mColCount+= repeat;
// Set nsColFrame-specific information
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
SetStyleContextForFirstPass(&aPresContext, colIndex);
}
// colgroup's span attribute is how many columns the group represents
// in the absence of any COL children
if (0==mColCount)
{
nsIFrame *firstImplicitCol=nsnull;
nsIFrame *prevColFrame=nsnull;
nsAutoString colTag;
nsHTMLAtoms::col->ToString(colTag);
mColCount = GetSpan();
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
{
nsIHTMLContent *col=nsnull;
// create an implicit col
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
//XXX mark the col implicit
mContent->AppendChildTo((nsIContent*)col, PR_FALSE);
return NS_OK;
// Create a new col frame
nsIFrame* colFrame;
NS_NewTableColFrame(col, this, colFrame);
// Set its style context
nsIStyleContextPtr colStyleContext =
aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
colFrame->SetStyleContext(&aPresContext, colStyleContext);
colFrame->Init(aPresContext, nsnull);
// Set nsColFrame-specific information
PRInt32 absColIndex = mStartColIndex + colIndex;
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
//hook into list of children
if (nsnull==firstImplicitCol)
firstImplicitCol = colFrame;
else
prevColFrame->SetNextSibling(colFrame);
prevColFrame = colFrame;
}
// hook new columns into col group child list
if (nsnull==mFirstChild)
mFirstChild = firstImplicitCol;
else
{
nsIFrame *lastChild = mFirstChild;
nsIFrame *nextChild = lastChild;
while (nsnull!=nextChild)
{
lastChild = nextChild;
nextChild->GetNextSibling(nextChild);
}
lastChild->SetNextSibling(firstImplicitCol);
}
}
SetStyleContextForFirstPass(&aPresContext);
return rv;
}
nsresult
@ -97,7 +153,10 @@ nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aC
NS_IMETHODIMP
nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
return AppendNewFrames(aPresContext, aChildList);
nsresult result = AppendNewFrames(aPresContext, aChildList);
if (NS_OK==result)
result = InitNewFrames(aPresContext, mFirstChild);
return result;
}
NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
@ -123,12 +182,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
// create a frame and adjust it's style
nsIFrame* kidFrame = nsnull;
if (eReflowReason_Initial == aReflowState.reason) {
// XXX Don't do this in the Init() member function, because the cell
// map hasn't been created yet..
InitNewFrames(aPresContext, mFirstChild);
} else if (eReflowReason_Incremental == aReflowState.reason) {
if (eReflowReason_Incremental == aReflowState.reason) {
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
// Get the type of reflow command
@ -172,18 +226,15 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
}
// Subclass hook for style post processing
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext,
PRInt32 aColIndex)
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
{
// get the table frame
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
tableFrame->GetGeometricParent(tableFrame); // get the outer frame
// get the style for the table frame
nsIStyleContextPtr tableSC;
tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
nsStyleTable *tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
nsStyleTable *tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
// if COLS is set, then map it into the COL frames
if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
@ -197,32 +248,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
// for every column effected, set its width style
PRInt32 colIndex=0;
nsIFrame *colFrame=nsnull;
nsIStyleContextPtr colStyleContext;
colFrame = FrameAt(mFirstChild, aColIndex);
if (nsnull!=colFrame)
nsIFrame *colFrame=mFirstChild;
while (nsnull!=colFrame)
{
nsStylePosition * colPosition=nsnull;
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
nsStyleCoord width (1, eStyleUnit_Proportional);
colPosition->mWidth = width;
colStyleContext->RecalcAutomaticData(aPresContext);
// if there are more columns, there width is set to "minimum"
// XXX FIX USE OF LengthOf() and ChildAt()...
PRInt32 numChildFrames = LengthOf(mFirstChild);
for (; aColIndex<numChildFrames-1; colIndex++)
nsStyleDisplay * colDisplay=nsnull;
colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
{
colFrame = FrameAt(mFirstChild, colIndex);
if (nsnull==colFrame)
break;
nsIStyleContextPtr colStyleContext;
nsStylePosition * colPosition=nsnull;
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
colPosition->mWidth.SetCoordValue(0);
if (colIndex<numCols)
{
nsStyleCoord width (1, eStyleUnit_Proportional);
colPosition->mWidth = width;
}
else
{
colPosition->mWidth.SetCoordValue(0);
}
colStyleContext->RecalcAutomaticData(aPresContext);
colIndex++;
}
colFrame->GetNextSibling(colFrame);
}
mStyleContext->RecalcAutomaticData(aPresContext);
@ -260,6 +309,18 @@ int nsTableColGroupFrame::GetColumnCount ()
return mColCount;
}
PRInt32 nsTableColGroupFrame::GetSpan()
{
PRInt32 span=1;
nsStyleTable* tableStyle=nsnull;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (nsnull!=tableStyle)
{
span = tableStyle->mSpan;
}
return span;
}
/* ----- global methods ----- */
nsresult

View File

@ -70,6 +70,9 @@ public:
virtual void SetStartColumnIndex (PRInt32 aIndex);
/** helper method to get the span attribute for this colgroup */
PRInt32 GetSpan();
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:
@ -82,8 +85,7 @@ protected:
* Since we need to know the full column structure before the COLS attribute
* can be interpreted, we can't just use DidSetStyleContext
*/
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext,
PRInt32 aColIndex);
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);

View File

@ -269,6 +269,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
mIsInvariantWidth(PR_FALSE)
{
mEffectiveColCount = -1; // -1 means uninitialized
mCellMap = new nsCellMap(0, 0);
}
nsTableFrame::~nsTableFrame()
@ -290,6 +291,7 @@ NS_IMETHODIMP
nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
EnsureColumns(&aPresContext);
return NS_OK;
}
@ -610,13 +612,11 @@ void nsTableFrame::ResetCellMap ()
* add extra implicit columns to the content tree.
*/
// XXX this and ENsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all"
void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
// XXX this and EnsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all"
void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext)
{
nsresult rv;
NS_PRECONDITION(nsnull!=mCellMap, "bad state: null cellmap");
// XXX sec should only be called on firstInFlow
SetMinColSpanForTable();
if (nsnull==mCellMap)
@ -639,22 +639,29 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount();
actualColumns += numCols;
lastColGroupFrame = (nsTableColGroupFrame *)childFrame;
if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
{
firstRowGroupFrame = childFrame;
if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
break;
}
prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
if (actualColumns < GetColCount())
}
PRInt32 colCount = GetColCount();
if (PR_TRUE==gsDebug) printf("EC: actual = %d, colCount=%d\n", actualColumns, colCount);
if (actualColumns < colCount)
{
PRBool lastColGroupNeedsInit=PR_FALSE;
nsIHTMLContent *lastColGroup=nsnull;
if (nsnull==lastColGroupFrame)
{
lastColGroupNeedsInit=PR_TRUE;
if (PR_TRUE==gsDebug) printf("EC:creating colgroup\n", actualColumns, colCount);
// create an implicit colgroup
nsAutoString colGroupTag;
nsHTMLAtoms::colgroup->ToString(colGroupTag);
@ -705,6 +712,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsIFrame* lastNewColFrame = nsnull;
for ( ; excessColumns > 0; excessColumns--)
{
if (PR_TRUE==gsDebug) printf("EC:creating col\n", actualColumns, colCount);
nsIHTMLContent *col=nsnull;
// create an implicit col
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
@ -719,6 +727,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsIStyleContextPtr colStyleContext =
aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE);
colFrame->SetStyleContext(aPresContext, colStyleContext);
colFrame->Init(*aPresContext, nsnull);
// XXX Don't release this style context (or we'll end up with a double-free).\
// This code is doing what nsTableColGroupFrame::Reflow() does...
@ -733,20 +742,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
lastNewColFrame = colFrame;
NS_RELEASE(col); // ADDREF: col--
}
if (PR_TRUE==lastColGroupNeedsInit)
lastColGroupFrame->Init(*aPresContext, firstNewColFrame);
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
// Generate an appended reflow command
// XXX This is really yucky...
nsIReflowCommand* reflowCmd;
NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended,
firstNewColFrame);
nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize);
incrReflowState.reflowCommand = reflowCmd;
incrReflowState.reason = eReflowReason_Incremental;
// Reflow the frames
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus);
}
}
@ -756,10 +754,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
*/
// XXX should be nsresult, not void
void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
nsIPresContext* aPresContext)
{
nsresult rv;
PRInt32 actualColumns = 0;
@ -873,19 +868,6 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
NS_RELEASE(col); // ADDREF: col--
}
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
// Generate an appended reflow command
// XXX This is really yucky...
nsIReflowCommand* reflowCmd;
NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended,
firstNewColFrame);
nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize);
incrReflowState.reflowCommand = reflowCmd;
incrReflowState.reason = eReflowReason_Incremental;
// Reflow the frames
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus);
}
}
@ -1584,10 +1566,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (PR_TRUE==NeedsReflow(aReflowState.maxSize))
{
if (PR_FALSE==IsFirstPassValid())
{ // we treat the table as if we've never seen the layout data before
if (mCellMap!=nsnull)
delete mCellMap;
mCellMap = new nsCellMap(0, 0);
{
// XXX TROY: we used to rebuild the cellmap here for incremental reflow.
// now that the cellmap is built in the constructor
// we need to reset the cellmap during incremental reflow before we get here
mPass = kPASS_FIRST;
aStatus = ResizeReflowPass1(&aPresContext, aDesiredSize, aReflowState, aStatus);
// check result
@ -1685,7 +1667,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (1||NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
{
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
nsSize maxKidElementSize(0,0);
@ -1973,6 +1955,16 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
PRBool result = PR_TRUE;
nsReflowReason reason;
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy)
{
reason = aState.reflowState.reason;
}
else
reason = eReflowReason_Resize;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsSize kidAvailSize(aState.availSize);
nsReflowMetrics desiredSize(pKidMaxElementSize);
@ -2000,10 +1992,10 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
if (PR_FALSE == aState.unconstrainedWidth) {
kidAvailSize.width -= kidMargin.left + kidMargin.right;
}
// Reflow the child into the available space
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Resize);
reason);
kidFrame->WillReflow(*aPresContext);
nscoord x = aState.leftInset + kidMargin.left;
nscoord y = aState.topInset + aState.y + topMargin;
@ -2514,7 +2506,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
EnsureColumns(aPresContext, aDesiredSize, aReflowState, aStatus);
EnsureColumns(aPresContext);
if (nsnull==mColCache)
{
mColCache = new ColumnInfoCache(mColCount);

View File

@ -211,10 +211,7 @@ public:
* if not, create the needed col frames
*/
virtual void EnsureColumnFrameAt(PRInt32 aColIndex,
nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
nsIPresContext* aPresContext);
/** return the index of the next row that is not yet assigned.
* If no row is initialized, 0 is returned.
@ -394,10 +391,7 @@ protected:
* 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);
virtual void EnsureColumns (nsIPresContext* aPresContext);
/** Set the min col span for every column in the table. Scans the whole table. */
virtual void SetMinColSpanForTable();

View File

@ -100,9 +100,62 @@ NS_IMETHODIMP
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
nsTableFrame* table = nsnull;
nsresult result;
result = GetTableFrame((nsIFrame *&)table);
if ((NS_OK==result) && (table != nsnull))
{
SetRowIndex(table->GetNextAvailRowIndex());
PRInt32 colIndex = 0;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
{
// what column does this cell belong to?
colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
/* for style context optimization, set the content's column index if possible.
* this can only be done if we really have an nsTableCell.
* other tags mapped to table cell display won't benefit from this optimization
* see nsHTMLStyleSheet::RulesMatching
*/
nsIContent* cell;
kidFrame->GetContent(cell);
nsIHTMLTableCellElement *cellContent = nsnull;
nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
(void **)&cellContent); // cellContent: REFCNT++
NS_RELEASE(cell);
if (NS_SUCCEEDED(rv))
{ // we know it's a table cell
cellContent->SetColIndex(colIndex);
if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
NS_RELEASE(cellContent);
}
// part of the style optimization is to ensure that the column frame for the cell exists
//table->EnsureColumnFrameAt(colIndex, &aPresContext);
// this sets the frame's notion of it's column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
// add the cell frame to the table's cell map
table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
}
}
return NS_OK;
}
NS_METHOD nsTableRowFrame::GetTableFrame(nsIFrame *& aFrame)
{
nsresult result = GetContentParent(aFrame);
while ((NS_OK==result) && (nsnull!=aFrame))
{
const nsStyleDisplay *display;
aFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
break;
result = aFrame->GetContentParent(aFrame);
}
return result;
}
/**
* Post-reflow hook. This is where the table row does its post-processing
*/
@ -536,65 +589,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize)
{
// Place our children, one at a time, until we are out of children
nsSize kidMaxElementSize;
nsSize kidMaxElementSize(0,0);
PRInt32 kidIndex = 0;
PRInt32 colIndex = 0;
nsIFrame* prevKidFrame = nsnull;
nscoord maxTopMargin = 0;
nscoord maxBottomMargin = 0;
nscoord x = 0;
nsresult result = NS_OK;
PRBool isFirst=PR_TRUE;
PRBool tableLayoutStrategy=NS_STYLE_TABLE_LAYOUT_AUTO;
nsTableFrame* table = nsnull;
nsresult result = GetTableFrame((nsIFrame *&)table);
if ((NS_OK==result) && (table != nsnull))
{
nsStyleTable* tableStyle;
table->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
tableLayoutStrategy = tableStyle->mLayoutStrategy;
}
else
return NS_ERROR_UNEXPECTED;
// what row am I?
// to handle rows with no cells, this block must be done before the "Get the next content object" block
SetRowIndex(aState.tableFrame->GetNextAvailRowIndex());
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
// what column does this cell belong to?
colIndex = aState.tableFrame->GetNextAvailColIndex(mRowIndex, colIndex);
if (gsDebug) printf("%p : next col index = %d\n", this, colIndex);
// XXX CONSTRUCTION
// This code doesn't really belong here...
/* for style context optimization, set the content's column index if possible.
* this can only be done if we really have an nsTableCell.
* other tags mapped to table cell display won't benefit from this optimization
* see nsHTMLStyleSheet::RulesMatching
*/
nsIContent* cell;
kidFrame->GetContent(cell);
nsIHTMLTableCellElement *cellContent = nsnull;
nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
(void **)&cellContent); // cellContent: REFCNT++
NS_RELEASE(cell);
if (NS_SUCCEEDED(rv))
{ // we know it's a table cell
cellContent->SetColIndex(colIndex);
if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
NS_RELEASE(cellContent);
}
// part of the style optimization is to ensure that the column frame for the cell exists
// we used to do this post-pass1, now we do it incrementally for the optimization
nsReflowStatus status;
aState.tableFrame->EnsureColumnFrameAt(colIndex,
&aPresContext,
aDesiredSize,
aState.reflowState,
status);
// this sets the frame's notion of it's column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
// add the cell frame to the table's cell map
aState.tableFrame->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
// Because we're not splittable always allow the child to be as high as
// it wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
{
// Get the child's margins
nsMargin margin;
nscoord topMargin = 0;
@ -606,16 +622,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
maxTopMargin = PR_MAX(margin.top, maxTopMargin);
maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin);
// Reflow the child. We always want back the max element size even if the
// caller doesn't ask for it, because the table needs it to compute column
// widths
nsReflowMetrics kidSize(&kidMaxElementSize);
// Because we're not splittable always allow the child to be as high as
// it wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize;
nsReflowMetrics kidSize(nsnull);
if (NS_STYLE_TABLE_LAYOUT_AUTO==tableLayoutStrategy)
{
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
kidSize.maxElementSize=&kidMaxElementSize;
}
else
{
PRInt32 colIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE);
}
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Initial);
kidFrame->WillReflow(aPresContext);
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
nsresult status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
if (gsDebug)
printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n",
this, kidFrame, kidSize.width, kidMaxElementSize.width);

View File

@ -114,6 +114,9 @@ public:
/** set this row's starting row index */
virtual void SetRowIndex (int aRowIndex);
/** get the row's enclosing table frame in a safe way */
NS_IMETHOD GetTableFrame(nsIFrame *& aFrame);
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:

View File

@ -553,7 +553,6 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
return result;
}
#include "nsIPresShell.h"
/**
*/
void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,

View File

@ -549,7 +549,7 @@ void StyleTableImpl::ResetFrom(const nsStyleTable* aParent, nsIPresContext* aPre
mRules = NS_STYLE_TABLE_RULES_NONE;
mCellPadding.Reset();
mCellSpacing.Reset();
mSpan=0;
mSpan=1;
// values inherited
if (nsnull!=aParent)
mLayoutStrategy = aParent->mLayoutStrategy;

View File

@ -30,7 +30,7 @@ NS_DEF_PTR(nsIStyleContext);
#ifdef NS_DEBUG
static PRBool gsDebug = PR_TRUE;
static PRBool gsDebug = PR_FALSE;
#else
static const PRBool gsDebug = PR_FALSE;
#endif

View File

@ -23,6 +23,8 @@
#include "nsIStyleContext.h"
#include "nsStyleConsts.h"
#include "nsIPresContext.h"
#include "nsIHTMLContent.h"
#include "nsHTMLParts.h"
#include "nsIPtr.h"
#include "nsHTMLAtoms.h"
@ -48,14 +50,18 @@ nsTableColGroupFrame::~nsTableColGroupFrame()
nsresult
nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
nsresult rv=NS_OK;
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
// Process the newly added column frames
for (nsIFrame* kidFrame = aChildList; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
// Set the preliminary values for the column frame
nsIContent* kid;
kidFrame->GetContent(kid);
// should use style to get this value
PRInt32 repeat=1;
nsIHTMLTableColElement* colContent = nsnull;
nsresult rv = kid->QueryInterface(kIHTMLTableColElementIID,
rv = kid->QueryInterface(kIHTMLTableColElementIID,
(void**) &colContent); // colContent: ADDREF++
NS_RELEASE(kid);
if (rv==NS_OK)
@ -66,17 +72,67 @@ nsTableColGroupFrame::InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChi
PRInt32 colIndex = mStartColIndex + mColCount;
((nsTableColFrame *)(kidFrame))->InitColFrame (colIndex, repeat);
mColCount+= repeat;
// Set nsColFrame-specific information
((nsTableColFrame *)kidFrame)->SetColumnIndex(colIndex);
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)kidFrame);
SetStyleContextForFirstPass(&aPresContext, colIndex);
}
// colgroup's span attribute is how many columns the group represents
// in the absence of any COL children
if (0==mColCount)
{
nsIFrame *firstImplicitCol=nsnull;
nsIFrame *prevColFrame=nsnull;
nsAutoString colTag;
nsHTMLAtoms::col->ToString(colTag);
mColCount = GetSpan();
for (PRInt32 colIndex=0; colIndex<mColCount; colIndex++)
{
nsIHTMLContent *col=nsnull;
// create an implicit col
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
//XXX mark the col implicit
mContent->AppendChildTo((nsIContent*)col, PR_FALSE);
return NS_OK;
// Create a new col frame
nsIFrame* colFrame;
NS_NewTableColFrame(col, this, colFrame);
// Set its style context
nsIStyleContextPtr colStyleContext =
aPresContext.ResolveStyleContextFor(col, this, PR_TRUE);
colFrame->SetStyleContext(&aPresContext, colStyleContext);
colFrame->Init(aPresContext, nsnull);
// Set nsColFrame-specific information
PRInt32 absColIndex = mStartColIndex + colIndex;
((nsTableColFrame *)(colFrame))->InitColFrame (absColIndex, 1);
((nsTableColFrame *)colFrame)->SetColumnIndex(absColIndex);
((nsTableFrame *)tableFrame)->AddColumnFrame((nsTableColFrame *)colFrame);
//hook into list of children
if (nsnull==firstImplicitCol)
firstImplicitCol = colFrame;
else
prevColFrame->SetNextSibling(colFrame);
prevColFrame = colFrame;
}
// hook new columns into col group child list
if (nsnull==mFirstChild)
mFirstChild = firstImplicitCol;
else
{
nsIFrame *lastChild = mFirstChild;
nsIFrame *nextChild = lastChild;
while (nsnull!=nextChild)
{
lastChild = nextChild;
nextChild->GetNextSibling(nextChild);
}
lastChild->SetNextSibling(firstImplicitCol);
}
}
SetStyleContextForFirstPass(&aPresContext);
return rv;
}
nsresult
@ -97,7 +153,10 @@ nsTableColGroupFrame::AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aC
NS_IMETHODIMP
nsTableColGroupFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
return AppendNewFrames(aPresContext, aChildList);
nsresult result = AppendNewFrames(aPresContext, aChildList);
if (NS_OK==result)
result = InitNewFrames(aPresContext, mFirstChild);
return result;
}
NS_METHOD nsTableColGroupFrame::Paint(nsIPresContext& aPresContext,
@ -123,12 +182,7 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
// create a frame and adjust it's style
nsIFrame* kidFrame = nsnull;
if (eReflowReason_Initial == aReflowState.reason) {
// XXX Don't do this in the Init() member function, because the cell
// map hasn't been created yet..
InitNewFrames(aPresContext, mFirstChild);
} else if (eReflowReason_Incremental == aReflowState.reason) {
if (eReflowReason_Incremental == aReflowState.reason) {
NS_ASSERTION(nsnull != aReflowState.reflowCommand, "null reflow command");
// Get the type of reflow command
@ -172,18 +226,15 @@ NS_METHOD nsTableColGroupFrame::Reflow(nsIPresContext& aPresContext,
}
// Subclass hook for style post processing
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext,
PRInt32 aColIndex)
NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPresContext)
{
// get the table frame
nsIFrame* tableFrame=nsnull;
GetGeometricParent(tableFrame);
tableFrame->GetGeometricParent(tableFrame); // get the outer frame
// get the style for the table frame
nsIStyleContextPtr tableSC;
tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
nsStyleTable *tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
nsStyleTable *tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
// if COLS is set, then map it into the COL frames
if (NS_STYLE_TABLE_COLS_NONE != tableStyle->mCols)
@ -197,32 +248,30 @@ NS_METHOD nsTableColGroupFrame::SetStyleContextForFirstPass(nsIPresContext* aPre
// for every column effected, set its width style
PRInt32 colIndex=0;
nsIFrame *colFrame=nsnull;
nsIStyleContextPtr colStyleContext;
colFrame = FrameAt(mFirstChild, aColIndex);
if (nsnull!=colFrame)
nsIFrame *colFrame=mFirstChild;
while (nsnull!=colFrame)
{
nsStylePosition * colPosition=nsnull;
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
nsStyleCoord width (1, eStyleUnit_Proportional);
colPosition->mWidth = width;
colStyleContext->RecalcAutomaticData(aPresContext);
// if there are more columns, there width is set to "minimum"
// XXX FIX USE OF LengthOf() and ChildAt()...
PRInt32 numChildFrames = LengthOf(mFirstChild);
for (; aColIndex<numChildFrames-1; colIndex++)
nsStyleDisplay * colDisplay=nsnull;
colFrame->GetStyleData(eStyleStruct_Display, ((nsStyleStruct *&)colDisplay));
if (NS_STYLE_DISPLAY_TABLE_COLUMN == colDisplay->mDisplay)
{
colFrame = FrameAt(mFirstChild, colIndex);
if (nsnull==colFrame)
break;
nsIStyleContextPtr colStyleContext;
nsStylePosition * colPosition=nsnull;
colFrame->GetStyleContext(aPresContext, colStyleContext.AssignRef());
colPosition = (nsStylePosition*)colStyleContext->GetMutableStyleData(eStyleStruct_Position);
colPosition->mWidth.SetCoordValue(0);
if (colIndex<numCols)
{
nsStyleCoord width (1, eStyleUnit_Proportional);
colPosition->mWidth = width;
}
else
{
colPosition->mWidth.SetCoordValue(0);
}
colStyleContext->RecalcAutomaticData(aPresContext);
colIndex++;
}
colFrame->GetNextSibling(colFrame);
}
mStyleContext->RecalcAutomaticData(aPresContext);
@ -260,6 +309,18 @@ int nsTableColGroupFrame::GetColumnCount ()
return mColCount;
}
PRInt32 nsTableColGroupFrame::GetSpan()
{
PRInt32 span=1;
nsStyleTable* tableStyle=nsnull;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (nsnull!=tableStyle)
{
span = tableStyle->mSpan;
}
return span;
}
/* ----- global methods ----- */
nsresult

View File

@ -70,6 +70,9 @@ public:
virtual void SetStartColumnIndex (PRInt32 aIndex);
/** helper method to get the span attribute for this colgroup */
PRInt32 GetSpan();
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:
@ -82,8 +85,7 @@ protected:
* Since we need to know the full column structure before the COLS attribute
* can be interpreted, we can't just use DidSetStyleContext
*/
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext,
PRInt32 aColIndex);
NS_METHOD SetStyleContextForFirstPass(nsIPresContext* aPresContext);
nsresult InitNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);
nsresult AppendNewFrames(nsIPresContext& aPresContext, nsIFrame* aChildList);

View File

@ -269,6 +269,7 @@ nsTableFrame::nsTableFrame(nsIContent* aContent, nsIFrame* aParentFrame)
mIsInvariantWidth(PR_FALSE)
{
mEffectiveColCount = -1; // -1 means uninitialized
mCellMap = new nsCellMap(0, 0);
}
nsTableFrame::~nsTableFrame()
@ -290,6 +291,7 @@ NS_IMETHODIMP
nsTableFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
EnsureColumns(&aPresContext);
return NS_OK;
}
@ -610,13 +612,11 @@ void nsTableFrame::ResetCellMap ()
* add extra implicit columns to the content tree.
*/
// XXX this and ENsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all"
void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
// XXX this and EnsureColumnsAt should be 1 method, with -1 for aColIndex meaning "do them all"
void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext)
{
nsresult rv;
NS_PRECONDITION(nsnull!=mCellMap, "bad state: null cellmap");
// XXX sec should only be called on firstInFlow
SetMinColSpanForTable();
if (nsnull==mCellMap)
@ -639,22 +639,29 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
PRInt32 numCols = ((nsTableColGroupFrame*)childFrame)->GetColumnCount();
actualColumns += numCols;
lastColGroupFrame = (nsTableColGroupFrame *)childFrame;
if (PR_TRUE==gsDebug) printf("EC: found a col group %p\n", lastColGroupFrame);
}
else if (NS_STYLE_DISPLAY_TABLE_ROW_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == childDisplay->mDisplay ||
NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == childDisplay->mDisplay )
{
firstRowGroupFrame = childFrame;
if (PR_TRUE==gsDebug) printf("EC: found a row group %p\n", firstRowGroupFrame);
break;
}
prevSibFrame = childFrame;
childFrame->GetNextSibling(childFrame);
}
if (actualColumns < GetColCount())
}
PRInt32 colCount = GetColCount();
if (PR_TRUE==gsDebug) printf("EC: actual = %d, colCount=%d\n", actualColumns, colCount);
if (actualColumns < colCount)
{
PRBool lastColGroupNeedsInit=PR_FALSE;
nsIHTMLContent *lastColGroup=nsnull;
if (nsnull==lastColGroupFrame)
{
lastColGroupNeedsInit=PR_TRUE;
if (PR_TRUE==gsDebug) printf("EC:creating colgroup\n", actualColumns, colCount);
// create an implicit colgroup
nsAutoString colGroupTag;
nsHTMLAtoms::colgroup->ToString(colGroupTag);
@ -705,6 +712,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsIFrame* lastNewColFrame = nsnull;
for ( ; excessColumns > 0; excessColumns--)
{
if (PR_TRUE==gsDebug) printf("EC:creating col\n", actualColumns, colCount);
nsIHTMLContent *col=nsnull;
// create an implicit col
rv = NS_CreateHTMLElement(&col, colTag); // ADDREF: col++
@ -719,6 +727,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
nsIStyleContextPtr colStyleContext =
aPresContext->ResolveStyleContextFor(col, lastColGroupFrame, PR_TRUE);
colFrame->SetStyleContext(aPresContext, colStyleContext);
colFrame->Init(*aPresContext, nsnull);
// XXX Don't release this style context (or we'll end up with a double-free).\
// This code is doing what nsTableColGroupFrame::Reflow() does...
@ -733,20 +742,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
lastNewColFrame = colFrame;
NS_RELEASE(col); // ADDREF: col--
}
if (PR_TRUE==lastColGroupNeedsInit)
lastColGroupFrame->Init(*aPresContext, firstNewColFrame);
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
// Generate an appended reflow command
// XXX This is really yucky...
nsIReflowCommand* reflowCmd;
NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended,
firstNewColFrame);
nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize);
incrReflowState.reflowCommand = reflowCmd;
incrReflowState.reason = eReflowReason_Incremental;
// Reflow the frames
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus);
}
}
@ -756,10 +754,7 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext,
*/
// XXX should be nsresult, not void
void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
nsIPresContext* aPresContext)
{
nsresult rv;
PRInt32 actualColumns = 0;
@ -873,19 +868,6 @@ void nsTableFrame::EnsureColumnFrameAt(PRInt32 aColIndex,
NS_RELEASE(col); // ADDREF: col--
}
NS_RELEASE(lastColGroup); // ADDREF: lastColGroup--
// Generate an appended reflow command
// XXX This is really yucky...
nsIReflowCommand* reflowCmd;
NS_NewHTMLReflowCommand(&reflowCmd, lastColGroupFrame, nsIReflowCommand::FrameAppended,
firstNewColFrame);
nsReflowState incrReflowState(lastColGroupFrame, aReflowState, aReflowState.maxSize);
incrReflowState.reflowCommand = reflowCmd;
incrReflowState.reason = eReflowReason_Incremental;
// Reflow the frames
lastColGroupFrame->Reflow(*aPresContext, aDesiredSize, incrReflowState, aStatus);
}
}
@ -1584,10 +1566,10 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
if (PR_TRUE==NeedsReflow(aReflowState.maxSize))
{
if (PR_FALSE==IsFirstPassValid())
{ // we treat the table as if we've never seen the layout data before
if (mCellMap!=nsnull)
delete mCellMap;
mCellMap = new nsCellMap(0, 0);
{
// XXX TROY: we used to rebuild the cellmap here for incremental reflow.
// now that the cellmap is built in the constructor
// we need to reset the cellmap during incremental reflow before we get here
mPass = kPASS_FIRST;
aStatus = ResizeReflowPass1(&aPresContext, aDesiredSize, aReflowState, aStatus);
// check result
@ -1685,7 +1667,7 @@ nsReflowStatus nsTableFrame::ResizeReflowPass1(nsIPresContext* aPresContext,
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (1||NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
if (NS_STYLE_TABLE_LAYOUT_FIXED!=tableStyle->mLayoutStrategy)
{
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
nsSize maxKidElementSize(0,0);
@ -1973,6 +1955,16 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
nsSize* pKidMaxElementSize = (nsnull != aMaxElementSize) ? &kidMaxElementSize : nsnull;
PRBool result = PR_TRUE;
nsReflowReason reason;
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
if (NS_STYLE_TABLE_LAYOUT_FIXED==tableStyle->mLayoutStrategy)
{
reason = aState.reflowState.reason;
}
else
reason = eReflowReason_Resize;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
nsSize kidAvailSize(aState.availSize);
nsReflowMetrics desiredSize(pKidMaxElementSize);
@ -2000,10 +1992,10 @@ PRBool nsTableFrame::ReflowMappedChildren( nsIPresContext* aPresContext,
if (PR_FALSE == aState.unconstrainedWidth) {
kidAvailSize.width -= kidMargin.left + kidMargin.right;
}
// Reflow the child into the available space
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Resize);
reason);
kidFrame->WillReflow(*aPresContext);
nscoord x = aState.leftInset + kidMargin.left;
nscoord y = aState.topInset + aState.y + topMargin;
@ -2514,7 +2506,7 @@ void nsTableFrame::BuildColumnCache( nsIPresContext* aPresContext,
NS_ASSERTION(nsnull!=mCellMap, "never ever call me until the cell map is built!");
nsStyleTable* tableStyle;
GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
EnsureColumns(aPresContext, aDesiredSize, aReflowState, aStatus);
EnsureColumns(aPresContext);
if (nsnull==mColCache)
{
mColCache = new ColumnInfoCache(mColCount);

View File

@ -211,10 +211,7 @@ public:
* if not, create the needed col frames
*/
virtual void EnsureColumnFrameAt(PRInt32 aColIndex,
nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
nsIPresContext* aPresContext);
/** return the index of the next row that is not yet assigned.
* If no row is initialized, 0 is returned.
@ -394,10 +391,7 @@ protected:
* 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);
virtual void EnsureColumns (nsIPresContext* aPresContext);
/** Set the min col span for every column in the table. Scans the whole table. */
virtual void SetMinColSpanForTable();

View File

@ -100,9 +100,62 @@ NS_IMETHODIMP
nsTableRowFrame::Init(nsIPresContext& aPresContext, nsIFrame* aChildList)
{
mFirstChild = aChildList;
nsTableFrame* table = nsnull;
nsresult result;
result = GetTableFrame((nsIFrame *&)table);
if ((NS_OK==result) && (table != nsnull))
{
SetRowIndex(table->GetNextAvailRowIndex());
PRInt32 colIndex = 0;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
{
// what column does this cell belong to?
colIndex = table->GetNextAvailColIndex(mRowIndex, colIndex);
/* for style context optimization, set the content's column index if possible.
* this can only be done if we really have an nsTableCell.
* other tags mapped to table cell display won't benefit from this optimization
* see nsHTMLStyleSheet::RulesMatching
*/
nsIContent* cell;
kidFrame->GetContent(cell);
nsIHTMLTableCellElement *cellContent = nsnull;
nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
(void **)&cellContent); // cellContent: REFCNT++
NS_RELEASE(cell);
if (NS_SUCCEEDED(rv))
{ // we know it's a table cell
cellContent->SetColIndex(colIndex);
if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
NS_RELEASE(cellContent);
}
// part of the style optimization is to ensure that the column frame for the cell exists
//table->EnsureColumnFrameAt(colIndex, &aPresContext);
// this sets the frame's notion of it's column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
// add the cell frame to the table's cell map
table->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
}
}
return NS_OK;
}
NS_METHOD nsTableRowFrame::GetTableFrame(nsIFrame *& aFrame)
{
nsresult result = GetContentParent(aFrame);
while ((NS_OK==result) && (nsnull!=aFrame))
{
const nsStyleDisplay *display;
aFrame->GetStyleData(eStyleStruct_Display, (nsStyleStruct *&)display);
if (NS_STYLE_DISPLAY_TABLE == display->mDisplay)
break;
result = aFrame->GetContentParent(aFrame);
}
return result;
}
/**
* Post-reflow hook. This is where the table row does its post-processing
*/
@ -536,65 +589,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
nsReflowMetrics& aDesiredSize)
{
// Place our children, one at a time, until we are out of children
nsSize kidMaxElementSize;
nsSize kidMaxElementSize(0,0);
PRInt32 kidIndex = 0;
PRInt32 colIndex = 0;
nsIFrame* prevKidFrame = nsnull;
nscoord maxTopMargin = 0;
nscoord maxBottomMargin = 0;
nscoord x = 0;
nsresult result = NS_OK;
PRBool isFirst=PR_TRUE;
PRBool tableLayoutStrategy=NS_STYLE_TABLE_LAYOUT_AUTO;
nsTableFrame* table = nsnull;
nsresult result = GetTableFrame((nsIFrame *&)table);
if ((NS_OK==result) && (table != nsnull))
{
nsStyleTable* tableStyle;
table->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
tableLayoutStrategy = tableStyle->mLayoutStrategy;
}
else
return NS_ERROR_UNEXPECTED;
// what row am I?
// to handle rows with no cells, this block must be done before the "Get the next content object" block
SetRowIndex(aState.tableFrame->GetNextAvailRowIndex());
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame)) {
// what column does this cell belong to?
colIndex = aState.tableFrame->GetNextAvailColIndex(mRowIndex, colIndex);
if (gsDebug) printf("%p : next col index = %d\n", this, colIndex);
// XXX CONSTRUCTION
// This code doesn't really belong here...
/* for style context optimization, set the content's column index if possible.
* this can only be done if we really have an nsTableCell.
* other tags mapped to table cell display won't benefit from this optimization
* see nsHTMLStyleSheet::RulesMatching
*/
nsIContent* cell;
kidFrame->GetContent(cell);
nsIHTMLTableCellElement *cellContent = nsnull;
nsresult rv = cell->QueryInterface(kIHTMLTableCellElementIID,
(void **)&cellContent); // cellContent: REFCNT++
NS_RELEASE(cell);
if (NS_SUCCEEDED(rv))
{ // we know it's a table cell
cellContent->SetColIndex(colIndex);
if (gsDebug) printf("%p : set cell content %p to col index = %d\n", this, cellContent, colIndex);
NS_RELEASE(cellContent);
}
// part of the style optimization is to ensure that the column frame for the cell exists
// we used to do this post-pass1, now we do it incrementally for the optimization
nsReflowStatus status;
aState.tableFrame->EnsureColumnFrameAt(colIndex,
&aPresContext,
aDesiredSize,
aState.reflowState,
status);
// this sets the frame's notion of it's column index
((nsTableCellFrame *)kidFrame)->InitCellFrame(colIndex);
if (gsDebug) printf("%p : set cell frame %p to col index = %d\n", this, kidFrame, colIndex);
// add the cell frame to the table's cell map
aState.tableFrame->AddCellToTable(this, (nsTableCellFrame *)kidFrame, kidFrame == mFirstChild);
// Because we're not splittable always allow the child to be as high as
// it wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; kidFrame->GetNextSibling(kidFrame))
{
// Get the child's margins
nsMargin margin;
nscoord topMargin = 0;
@ -606,16 +622,28 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext,
maxTopMargin = PR_MAX(margin.top, maxTopMargin);
maxBottomMargin = PR_MAX(margin.bottom, maxBottomMargin);
// Reflow the child. We always want back the max element size even if the
// caller doesn't ask for it, because the table needs it to compute column
// widths
nsReflowMetrics kidSize(&kidMaxElementSize);
// Because we're not splittable always allow the child to be as high as
// it wants. The default available width is also unconstrained so we can
// get the child's maximum width
nsSize kidAvailSize;
nsReflowMetrics kidSize(nsnull);
if (NS_STYLE_TABLE_LAYOUT_AUTO==tableLayoutStrategy)
{
kidAvailSize.SizeTo(NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE);
kidSize.maxElementSize=&kidMaxElementSize;
}
else
{
PRInt32 colIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
kidAvailSize.SizeTo(table->GetColumnWidth(colIndex), NS_UNCONSTRAINEDSIZE);
}
nsReflowState kidReflowState(kidFrame, aState.reflowState, kidAvailSize,
eReflowReason_Initial);
kidFrame->WillReflow(aPresContext);
if (gsDebug) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width);
status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
nsresult status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState);
if (gsDebug)
printf ("TR %p for cell %p Initial Reflow: desired=%d, MES=%d\n",
this, kidFrame, kidSize.width, kidMaxElementSize.width);

View File

@ -114,6 +114,9 @@ public:
/** set this row's starting row index */
virtual void SetRowIndex (int aRowIndex);
/** get the row's enclosing table frame in a safe way */
NS_IMETHOD GetTableFrame(nsIFrame *& aFrame);
NS_IMETHOD List(FILE* out = stdout, PRInt32 aIndent = 0, nsIListFilter *aFilter = nsnull) const;
protected:

View File

@ -553,7 +553,6 @@ PRBool nsTableRowGroupFrame::PullUpChildren(nsIPresContext* aPresContext,
return result;
}
#include "nsIPresShell.h"
/**
*/
void nsTableRowGroupFrame::ShrinkWrapChildren(nsIPresContext* aPresContext,