fundemental overhaul of the BasicTableLayoutStrategy

We now cache lots of useful info in the colframes
we now properly account for margins just as uniform cellspacing
This commit is contained in:
buster%netscape.com 1998-07-16 23:23:31 +00:00
parent dff21bbf04
commit 51fe86ee79
18 changed files with 1324 additions and 1280 deletions

File diff suppressed because it is too large Load Diff

View File

@ -31,20 +31,24 @@ struct nsStylePosition;
struct SpanInfo
{
nscoord span;
PRInt32 span;
const PRInt32 initialColSpan;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
SpanInfo(nscoord aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
};
SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
: initialColSpan(aSpan)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
}
/* ---------- BasicTableLayoutStrategy ---------- */
@ -60,86 +64,69 @@ public:
~BasicTableLayoutStrategy();
virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth,
nscoord &aTotalFixedWidth,
nscoord &aMinTableWidth,
nscoord &aMaxTableWidth,
nsSize* aMaxElementSize);
/** call once every time any table thing changes (content, structure, or style) */
virtual PRBool Initialize(nsSize* aMaxElementSize);
/** assign widths for each column that has fixed width.
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth);
/** assign widths for each column.
* if the column has a fixed coord width, use it.
* if the column includes col spanning cells,
* then distribute the fixed space between cells proportionately.
* Computes the minimum and maximum table widths.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aMaxWidth the maximum width of the table
* @param aTableStyle the resolved style for the table
* @param aTotalFixedWidth out param, the sum of the fixed width columns
* @param aMinTableWidth out param, the min possible table width
* @param aMaxTableWidth out param, the max table width
* Set column width information in each column frame and in the table frame.
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
* TODO: should be renamed to "AssignKnownWidthInformation
*/
virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth,
nscoord & aTotalFixedWidth,
nscoord & aMinTableWidth,
nscoord & aMaxTableWidth);
virtual PRBool AssignPreliminaryColumnWidths();
/** assign widths for each column that has proportional width inside a table that
* has auto width (width set by the content and available space.)
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aMinTableWidth the min possible table width
* @param aMaxTableWidth the max table width
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableSpecifiedWidth the width of the table based on its attributes and its parent's width
* @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aMinTableWidth,
nscoord aMaxTableWidth,
nscoord aTableFixedWidth,
nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign the minimum allowed width for each column that has proportional width.
* Typically called when the min table width doesn't fit in the available space.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext);
virtual PRBool SetColumnsToMinWidth();
/** assign the maximum allowed width for each column that has proportional width.
* Typically called when the desired max table width fits in the available space.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableFixedWidth the specified width of the table. If there is none,
* this param is 0
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableSpecifiedWidth the specified width of the table. If there is none,
* this param is 0
* @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aTableFixedWidth,
nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign widths for each column that has proportional width inside a table that
@ -147,7 +134,6 @@ public:
* HTML 4 specification.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
@ -158,23 +144,19 @@ public:
*
* TODO: rename this method to reflect that it is a Nav4 compatibility method
*/
virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceColumnsConstrained(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aMinTableWidth,
nscoord aMaxTableWidth);
nscoord aMaxWidth);
/** post-process to AssignFixedColumnWidths
*
* @param aColSpanList a list of fixed-width columns that have colspans
* @param aColWidths the effective column widths (ignoring col span cells)
*
* NOTE: does not yet properly handle overlapping col spans
*
* @return void
*/
virtual void DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths);
virtual void DistributeFixedSpace(nsVoidArray *aColSpanList);
/** starting with a partially balanced table, compute the amount
* of space to pad each column by to completely balance the table.
@ -189,8 +171,7 @@ public:
*/
virtual void DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
nscoord aWidthOfFixedTableColumns,
nscoord *aColWidths);
nscoord aWidthOfFixedTableColumns);
/** starting with a partially balanced table, compute the amount
* of space to remove from each column to completely balance the table.
@ -203,14 +184,18 @@ public:
* @return void
*/
virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
nscoord aComputedTableWidth,
nscoord *aMinColWidths,
nscoord *aMaxColWidths);
nscoord aComputedTableWidth);
/** force all cells to be at least their minimum width, removing any excess space
* created in the process from fat cells that can afford to lose a little tonnage.
*/
virtual void EnsureCellMinWidths(nscoord *aMinColWidths);
virtual void EnsureCellMinWidths();
virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
nscoord aTableWidth);
virtual void AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
nscoord aTableWidth);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
@ -218,12 +203,15 @@ public:
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
virtual PRBool IsAutoWidth(const nsStylePosition* aStylePosition);
protected:
nsTableFrame * mTableFrame;
PRInt32 mCols;
PRInt32 mNumCols;
// cached data
nscoord mMinTableWidth; // the absolute smallest width for the table
nscoord mMaxTableWidth; // the "natural" size for the table, if unconstrained
nscoord mFixedTableWidth; // the amount of space taken up by fixed-width columns
};

View File

@ -22,7 +22,6 @@
#include "nscore.h"
#include "nsSize.h"
class nsIPresContext;
class nsIStyleContext;
struct nsReflowState;
@ -30,25 +29,21 @@ class nsITableLayoutStrategy
{
public:
/** call once every time any table thing changes (content, structure, or style)
* @param aMaxElementSize [OUT] the min possible size of the table
*/
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aReflowState the reflow state for the calling table frame
* @param aMaxWidth the width constraint
* @param aTotalFixedWidth [OUT] the computed fixed width of the table
* @param aMinTableWidth [OUT] the computed min width of the table
* @param aMinTableWidth [OUT] the computed max width of the table
* @param aMaxElementSize [OUT] the min size of the largest indivisible object
*/
virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
virtual PRBool BalanceColumnWidths(nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth,
nscoord &aTotalFixedWidth,
nscoord &aMinTableWidth,
nscoord &aMaxTableWidth,
nsSize* aMaxElementSize)=0;
nscoord aMaxWidth)=0;
};
#endif

View File

@ -511,10 +511,10 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
return;
// get the table frame style context, and from it get cellpadding, cellspacing, and border info
nsIStyleContextPtr tableSC;
tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
nsStyleTable* tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
nsStyleSpacing* tableSpacingStyle = (nsStyleSpacing*)tableSC->GetStyleData(eStyleStruct_Spacing);
nsStyleTable* tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
nsStyleSpacing* tableSpacingStyle;
tableFrame->GetStyleData(eStyleStruct_Spacing,(nsStyleStruct *&)tableSpacingStyle);
nsStyleSpacing* spacingData = (nsStyleSpacing*)mStyleContext->GetMutableStyleData(eStyleStruct_Spacing);
// check to see if cellpadding or cellspacing is defined

View File

@ -38,6 +38,10 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
mColIndex = 0;
mRepeat = 0;
mMaxColWidth = 0;
mMinColWidth = 0;
mMaxEffectiveColWidth = 0;
mMinEffectiveColWidth = 0;
}
@ -55,11 +59,12 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
}
NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext,
NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
NS_ASSERTION(nsnull!=aPresContext, "bad arg");
aDesiredSize.width=0;
aDesiredSize.height=0;
if (nsnull!=aDesiredSize.maxElementSize)

View File

@ -34,7 +34,7 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
@ -51,6 +51,18 @@ public:
/** convenience method, calls into cellmap */
nsVoidArray * GetCells();
nscoord GetMaxColWidth();
void SetMaxColWidth(nscoord aMaxColWidth);
nscoord GetMinColWidth();
void SetMinColWidth(nscoord aMinColWidth);
nscoord GetEffectiveMaxColWidth();
void SetEffectiveMaxColWidth(nscoord aMaxColWidth);
nscoord GetEffectiveMinColWidth();
void SetEffectiveMinColWidth(nscoord aMinColWidth);
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@ -66,11 +78,11 @@ protected:
/** the number of columns that the attributes of this column extend to */
PRInt32 mRepeat;
nscoord mMaxWidth;
nscoord mMinWidth;
nscoord mMaxColWidth;
nscoord mMinColWidth;
nscoord mMaxEffectiveWidth;
nscoord mMinEffectiveWidth;
nscoord mMaxEffectiveColWidth;
nscoord mMinEffectiveColWidth;
};
@ -93,5 +105,29 @@ inline nsTableColFrame::GetRepeat()
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
inline nscoord nsTableColFrame::GetMaxColWidth()
{ return mMaxColWidth; }
inline void nsTableColFrame::SetMaxColWidth(nscoord aMaxColWidth)
{ mMaxColWidth = aMaxColWidth; }
inline nscoord nsTableColFrame::GetMinColWidth()
{ return mMinColWidth; }
inline void nsTableColFrame::SetMinColWidth(nscoord aMinColWidth)
{ mMinColWidth = aMinColWidth; }
inline nscoord nsTableColFrame::GetEffectiveMaxColWidth()
{ return mMaxEffectiveColWidth; }
inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth)
{ mMaxEffectiveColWidth = aMaxColWidth; }
inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
{ return mMinEffectiveColWidth; }
inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
{ mMinEffectiveColWidth = aMinColWidth; }
#endif

View File

@ -396,7 +396,7 @@ nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
}
// return the rows spanned by aCell starting at aRowIndex
// return the number of rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
//
@ -416,6 +416,24 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
// return the number of cols spanned by aCell starting at aColIndex
// note that this is different from just the colspan of aCell
// (that would be GetEffectiveColSpan (indexOfColThatContains_aCell, aCell)
//
// XXX Should be moved to colgroup, as GetEffectiveRowSpan should be moved to rowgroup?
PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *aCell)
{
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
NS_PRECONDITION (0<=aColIndex && aColIndex<mCellMap->GetColCount(), "bad col index arg");
int colSpan = aCell->GetColSpan();
int colCount = mCellMap->GetColCount();
if (colCount < (aColIndex + colSpan))
return (colCount - aColIndex);
return colSpan;
}
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@ -1198,6 +1216,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
// XXX For the time being just fall through and treat it like a
// pass 2 reflow...
mPass = kPASS_SECOND;
// calling intialize here resets all the cached info based on new table content
if (nsnull!=mTableLayoutStrategy)
{
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
}
#else
// XXX Hack...
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
@ -2231,9 +2254,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
if (gsDebug)
printf ("BalanceColumnWidths...\n");
if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
@ -2244,11 +2264,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
nsCRT::memset (mColumnWidths, 0, numCols*sizeof(PRInt32));
}
// need to track min and max table widths
PRInt32 minTableWidth = 0;
PRInt32 maxTableWidth = 0;
PRInt32 totalFixedWidth = 0;
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
@ -2308,13 +2323,9 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (nsnull==mTableLayoutStrategy)
{ // TODO: build a different strategy based on the compatibility mode
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
mTableLayoutStrategy->Initialize(aMaxElementSize);
}
mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext,
aReflowState, maxWidth,
totalFixedWidth,
minTableWidth, maxTableWidth,
aMaxElementSize);
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
}
/**
@ -2608,7 +2619,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
nsIStyleContext* kidStyleContext =
aPresContext.ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsIContentDelegate* kidDel = nsnull;
kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
nsIFrame* duplicateFrame;
nsresult rv = kidDel->CreateFrame(&aPresContext, content, cf,
kidStyleContext, duplicateFrame);
@ -2825,6 +2836,19 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
return result;
}
nscoord nsTableFrame::GetCellSpacing()
{
nsTableFrame* tableFrame = this;
//XXX remove when table style is fully resolved!
GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
nsStyleTable* tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
nscoord cellSpacing = 0;
if (tableStyle->mCellSpacing.GetUnit() == eStyleUnit_Coord)
cellSpacing = tableStyle->mCellSpacing.GetCoordValue();
return cellSpacing;
}
void nsTableFrame::GetColumnsByType(const nsStyleUnit aType,
PRInt32& aOutNumColumns,
PRInt32 *& aOutColumnIndexes)
@ -2989,27 +3013,34 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsReflowState& aReflowState)
}
else
{
nsSize tableSize;
table->GetSize(tableSize);
parentWidth = tableSize.width;
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row group
childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(childFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row
grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the cell
greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (nsnull!=((nsTableFrame*)table)->mColumnWidths)
{
PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
parentWidth = ((nsTableFrame*)table)->GetColumnWidth(colIndex);
}
else
{
nsSize tableSize;
table->GetSize(tableSize);
parentWidth = tableSize.width;
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row group
childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(childFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row
grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the cell
greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
}
if (PR_TRUE==gsDebugNT)
printf("%p: found a table frame %p, returning parentWidth %d from frame width %d\n",
aReflowState.frame, table, parentWidth, tableSize.width);
printf("%p: found a table frame %p, returning parentWidth %d \n",
aReflowState.frame, table, parentWidth);
}
break;
}

View File

@ -142,6 +142,9 @@ public:
/** set the width of the column at aColIndex to aWidth */
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
/** helper to get the cell spacing style value */
virtual nscoord GetCellSpacing();
/**
* Calculate Layout Information
@ -167,13 +170,26 @@ public:
/** 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
*
* @param aRowIndex the row from which to measure effective row span
* @param aCell 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);
/** return the col span of a cell, taking into account col span magic at the edge
* of a table.
*
* @param aColIndex the column from which to measure effective col span
* @param aCell the cell
*
* @return the col span, correcting for col spans that extend beyond the edge
* of the table.
*/
virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);

View File

@ -336,19 +336,22 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
if (PR_TRUE==gsDebug1) printf("%p: RR\n", this);
// Reflow each of our existing cell frames
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
// Get the frame's margins, and compare the top and bottom margin
// against our current max values
nsMargin kidMargin;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
{
nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
// just cellSpacing? QQQ
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
// left and right margins already taken into account by table layout strategy
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
@ -357,10 +360,14 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
{
aState.x += aState.tableFrame->GetColumnWidth(colIndex);
aState.x += kidMargin.left + kidMargin.right;
aState.x += cellSpacing;
if (PR_TRUE==gsDebug1)
printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
}
}
aState.x += kidMargin.left;
aState.x += cellSpacing;
if (PR_TRUE==gsDebug1) printf(" past loop, aState.x set to %d\n", aState.x);
// at this point, we know the column widths.
// so we get the avail width from the known column widths
@ -369,13 +376,15 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
{
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
if (0<numColSpan)
if (numColSpan != 0)
{
availWidth += kidMargin.right;
if (0!=cellColIndex)
availWidth += kidMargin.left;
availWidth += cellSpacing;
}
if (PR_TRUE==gsDebug1)
printf(" in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
availWidth, cellColIndex, aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
}
if (PR_TRUE==gsDebug1) printf(" availWidth for this cell is %d\n", availWidth);
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
@ -461,7 +470,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
aState.x += kidMargin.right; // add in right margin only after cell has been placed
if (PR_TRUE==gsDebug1) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
// Get the next child
kidFrame->GetNextSibling(kidFrame);

File diff suppressed because it is too large Load Diff

View File

@ -31,20 +31,24 @@ struct nsStylePosition;
struct SpanInfo
{
nscoord span;
PRInt32 span;
const PRInt32 initialColSpan;
nscoord cellMinWidth;
nscoord cellDesiredWidth;
SpanInfo(nscoord aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
};
SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth);
~SpanInfo() {};
};
inline SpanInfo::SpanInfo(PRInt32 aSpan, nscoord aMinWidth, nscoord aDesiredWidth)
: initialColSpan(aSpan)
{
span = aSpan;
cellMinWidth = aMinWidth;
cellDesiredWidth = aDesiredWidth;
}
/* ---------- BasicTableLayoutStrategy ---------- */
@ -60,86 +64,69 @@ public:
~BasicTableLayoutStrategy();
virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth,
nscoord &aTotalFixedWidth,
nscoord &aMinTableWidth,
nscoord &aMaxTableWidth,
nsSize* aMaxElementSize);
/** call once every time any table thing changes (content, structure, or style) */
virtual PRBool Initialize(nsSize* aMaxElementSize);
/** assign widths for each column that has fixed width.
virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth);
/** assign widths for each column.
* if the column has a fixed coord width, use it.
* if the column includes col spanning cells,
* then distribute the fixed space between cells proportionately.
* Computes the minimum and maximum table widths.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aMaxWidth the maximum width of the table
* @param aTableStyle the resolved style for the table
* @param aTotalFixedWidth out param, the sum of the fixed width columns
* @param aMinTableWidth out param, the min possible table width
* @param aMaxTableWidth out param, the max table width
* Set column width information in each column frame and in the table frame.
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
* TODO: should be renamed to "AssignKnownWidthInformation
*/
virtual PRBool AssignFixedColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth,
nscoord & aTotalFixedWidth,
nscoord & aMinTableWidth,
nscoord & aMaxTableWidth);
virtual PRBool AssignPreliminaryColumnWidths();
/** assign widths for each column that has proportional width inside a table that
* has auto width (width set by the content and available space.)
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aMinTableWidth the min possible table width
* @param aMaxTableWidth the max table width
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableSpecifiedWidth the width of the table based on its attributes and its parent's width
* @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool BalanceProportionalColumns(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceProportionalColumns(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aMinTableWidth,
nscoord aMaxTableWidth,
nscoord aTableFixedWidth,
nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign the minimum allowed width for each column that has proportional width.
* Typically called when the min table width doesn't fit in the available space.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
virtual PRBool SetColumnsToMinWidth(nsIPresContext* aPresContext);
virtual PRBool SetColumnsToMinWidth();
/** assign the maximum allowed width for each column that has proportional width.
* Typically called when the desired max table width fits in the available space.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableFixedWidth the specified width of the table. If there is none,
* this param is 0
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
* @param aTableSpecifiedWidth the specified width of the table. If there is none,
* this param is 0
* @param aTableIsAutoWidth PR_TRUE if the table is auto-width
*
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*/
virtual PRBool BalanceColumnsTableFits(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceColumnsTableFits(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aTableFixedWidth,
nscoord aTableSpecifiedWidth,
PRBool aTableIsAutoWidth);
/** assign widths for each column that has proportional width inside a table that
@ -147,7 +134,6 @@ public:
* HTML 4 specification.
* Sets mColumnWidths as a side effect.
*
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aAvailWidth the remaining amount of horizontal space available
* @param aMaxWidth the total amount of horizontal space available
@ -158,23 +144,19 @@ public:
*
* TODO: rename this method to reflect that it is a Nav4 compatibility method
*/
virtual PRBool BalanceColumnsConstrained(nsIPresContext* aPresContext,
const nsReflowState& aReflowState,
virtual PRBool BalanceColumnsConstrained(const nsReflowState& aReflowState,
nscoord aAvailWidth,
nscoord aMaxWidth,
nscoord aMinTableWidth,
nscoord aMaxTableWidth);
nscoord aMaxWidth);
/** post-process to AssignFixedColumnWidths
*
* @param aColSpanList a list of fixed-width columns that have colspans
* @param aColWidths the effective column widths (ignoring col span cells)
*
* NOTE: does not yet properly handle overlapping col spans
*
* @return void
*/
virtual void DistributeFixedSpace(nsVoidArray *aColSpanList, nscoord *aColWidths);
virtual void DistributeFixedSpace(nsVoidArray *aColSpanList);
/** starting with a partially balanced table, compute the amount
* of space to pad each column by to completely balance the table.
@ -189,8 +171,7 @@ public:
*/
virtual void DistributeExcessSpace(nscoord aAvailWidth,
nscoord aTableWidth,
nscoord aWidthOfFixedTableColumns,
nscoord *aColWidths);
nscoord aWidthOfFixedTableColumns);
/** starting with a partially balanced table, compute the amount
* of space to remove from each column to completely balance the table.
@ -203,14 +184,18 @@ public:
* @return void
*/
virtual void DistributeRemainingSpace(nscoord aTableFixedWidth,
nscoord aComputedTableWidth,
nscoord *aMinColWidths,
nscoord *aMaxColWidths);
nscoord aComputedTableWidth);
/** force all cells to be at least their minimum width, removing any excess space
* created in the process from fat cells that can afford to lose a little tonnage.
*/
virtual void EnsureCellMinWidths(nscoord *aMinColWidths);
virtual void EnsureCellMinWidths();
virtual void AdjustTableThatIsTooWide(nscoord aComputedWidth,
nscoord aTableWidth);
virtual void AdjustTableThatIsTooNarrow(nscoord aComputedWidth,
nscoord aTableWidth);
/** return true if the style indicates that the width is a specific width
* for the purposes of column width determination.
@ -218,12 +203,15 @@ public:
*/
virtual PRBool IsFixedWidth(const nsStylePosition* aStylePosition);
virtual PRBool IsAutoWidth(const nsStylePosition* aStylePosition);
protected:
nsTableFrame * mTableFrame;
PRInt32 mCols;
PRInt32 mNumCols;
// cached data
nscoord mMinTableWidth; // the absolute smallest width for the table
nscoord mMaxTableWidth; // the "natural" size for the table, if unconstrained
nscoord mFixedTableWidth; // the amount of space taken up by fixed-width columns
};

View File

@ -22,7 +22,6 @@
#include "nscore.h"
#include "nsSize.h"
class nsIPresContext;
class nsIStyleContext;
struct nsReflowState;
@ -30,25 +29,21 @@ class nsITableLayoutStrategy
{
public:
/** call once every time any table thing changes (content, structure, or style)
* @param aMaxElementSize [OUT] the min possible size of the table
*/
virtual PRBool Initialize(nsSize* aMaxElementSize)=0;
/** assign widths for each column, taking into account the table content, the effective style,
* the layout constraints, and the compatibility mode. Sets mColumnWidths as a side effect.
* @param aPresContext the presentation context
* @param aTableStyle the resolved style for the table
* @param aReflowState the reflow state for the calling table frame
* @param aMaxWidth the width constraint
* @param aTotalFixedWidth [OUT] the computed fixed width of the table
* @param aMinTableWidth [OUT] the computed min width of the table
* @param aMinTableWidth [OUT] the computed max width of the table
* @param aMaxElementSize [OUT] the min size of the largest indivisible object
*/
virtual PRBool BalanceColumnWidths(nsIPresContext* aPresContext,
nsIStyleContext *aTableStyle,
virtual PRBool BalanceColumnWidths(nsIStyleContext *aTableStyle,
const nsReflowState& aReflowState,
nscoord aMaxWidth,
nscoord &aTotalFixedWidth,
nscoord &aMinTableWidth,
nscoord &aMaxTableWidth,
nsSize* aMaxElementSize)=0;
nscoord aMaxWidth)=0;
};
#endif

View File

@ -511,10 +511,10 @@ void nsTableCellFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
return;
// get the table frame style context, and from it get cellpadding, cellspacing, and border info
nsIStyleContextPtr tableSC;
tableFrame->GetStyleContext(aPresContext, tableSC.AssignRef());
nsStyleTable* tableStyle = (nsStyleTable*)tableSC->GetStyleData(eStyleStruct_Table);
nsStyleSpacing* tableSpacingStyle = (nsStyleSpacing*)tableSC->GetStyleData(eStyleStruct_Spacing);
nsStyleTable* tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
nsStyleSpacing* tableSpacingStyle;
tableFrame->GetStyleData(eStyleStruct_Spacing,(nsStyleStruct *&)tableSpacingStyle);
nsStyleSpacing* spacingData = (nsStyleSpacing*)mStyleContext->GetMutableStyleData(eStyleStruct_Spacing);
// check to see if cellpadding or cellspacing is defined

View File

@ -38,6 +38,10 @@ nsTableColFrame::nsTableColFrame(nsIContent* aContent, nsIFrame* aParentFrame)
{
mColIndex = 0;
mRepeat = 0;
mMaxColWidth = 0;
mMinColWidth = 0;
mMaxEffectiveColWidth = 0;
mMinEffectiveColWidth = 0;
}
@ -55,11 +59,12 @@ NS_METHOD nsTableColFrame::Paint(nsIPresContext& aPresContext,
}
NS_METHOD nsTableColFrame::Reflow(nsIPresContext& aPresContext,
NS_METHOD nsTableColFrame::Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus)
{
NS_ASSERTION(nsnull!=aPresContext, "bad arg");
aDesiredSize.width=0;
aDesiredSize.height=0;
if (nsnull!=aDesiredSize.maxElementSize)

View File

@ -34,7 +34,7 @@ public:
nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
NS_IMETHOD Reflow(nsIPresContext& aPresContext,
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
nsReflowMetrics& aDesiredSize,
const nsReflowState& aReflowState,
nsReflowStatus& aStatus);
@ -51,6 +51,18 @@ public:
/** convenience method, calls into cellmap */
nsVoidArray * GetCells();
nscoord GetMaxColWidth();
void SetMaxColWidth(nscoord aMaxColWidth);
nscoord GetMinColWidth();
void SetMinColWidth(nscoord aMinColWidth);
nscoord GetEffectiveMaxColWidth();
void SetEffectiveMaxColWidth(nscoord aMaxColWidth);
nscoord GetEffectiveMinColWidth();
void SetEffectiveMinColWidth(nscoord aMinColWidth);
/** convenience method, calls into cellmap */
PRInt32 Count() const;
@ -66,11 +78,11 @@ protected:
/** the number of columns that the attributes of this column extend to */
PRInt32 mRepeat;
nscoord mMaxWidth;
nscoord mMinWidth;
nscoord mMaxColWidth;
nscoord mMinColWidth;
nscoord mMaxEffectiveWidth;
nscoord mMinEffectiveWidth;
nscoord mMaxEffectiveColWidth;
nscoord mMinEffectiveColWidth;
};
@ -93,5 +105,29 @@ inline nsTableColFrame::GetRepeat()
inline void nsTableColFrame::SetColumnIndex (int aColIndex)
{ mColIndex = aColIndex;}
inline nscoord nsTableColFrame::GetMaxColWidth()
{ return mMaxColWidth; }
inline void nsTableColFrame::SetMaxColWidth(nscoord aMaxColWidth)
{ mMaxColWidth = aMaxColWidth; }
inline nscoord nsTableColFrame::GetMinColWidth()
{ return mMinColWidth; }
inline void nsTableColFrame::SetMinColWidth(nscoord aMinColWidth)
{ mMinColWidth = aMinColWidth; }
inline nscoord nsTableColFrame::GetEffectiveMaxColWidth()
{ return mMaxEffectiveColWidth; }
inline void nsTableColFrame::SetEffectiveMaxColWidth(nscoord aMaxColWidth)
{ mMaxEffectiveColWidth = aMaxColWidth; }
inline nscoord nsTableColFrame::GetEffectiveMinColWidth()
{ return mMinEffectiveColWidth; }
inline void nsTableColFrame::SetEffectiveMinColWidth(nscoord aMinColWidth)
{ mMinEffectiveColWidth = aMinColWidth; }
#endif

View File

@ -396,7 +396,7 @@ nsTableCellFrame * nsTableFrame::GetCellAt(PRInt32 aRowIndex, PRInt32 aColIndex)
}
// return the rows spanned by aCell starting at aRowIndex
// return the number of rows spanned by aCell starting at aRowIndex
// note that this is different from just the rowspan of aCell
// (that would be GetEffectiveRowSpan (indexOfRowThatContains_aCell, aCell)
//
@ -416,6 +416,24 @@ PRInt32 nsTableFrame::GetEffectiveRowSpan (PRInt32 aRowIndex, nsTableCellFrame *
return rowSpan;
}
// return the number of cols spanned by aCell starting at aColIndex
// note that this is different from just the colspan of aCell
// (that would be GetEffectiveColSpan (indexOfColThatContains_aCell, aCell)
//
// XXX Should be moved to colgroup, as GetEffectiveRowSpan should be moved to rowgroup?
PRInt32 nsTableFrame::GetEffectiveColSpan (PRInt32 aColIndex, nsTableCellFrame *aCell)
{
NS_PRECONDITION (nsnull!=aCell, "bad cell arg");
NS_PRECONDITION (nsnull!=mCellMap, "bad call, mCellMap not yet allocated.");
NS_PRECONDITION (0<=aColIndex && aColIndex<mCellMap->GetColCount(), "bad col index arg");
int colSpan = aCell->GetColSpan();
int colCount = mCellMap->GetColCount();
if (colCount < (aColIndex + colSpan))
return (colCount - aColIndex);
return colSpan;
}
/* call when the cell structure has changed. mCellMap will be rebuilt on demand. */
void nsTableFrame::ResetCellMap ()
{
@ -1198,6 +1216,11 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext& aPresContext,
// XXX For the time being just fall through and treat it like a
// pass 2 reflow...
mPass = kPASS_SECOND;
// calling intialize here resets all the cached info based on new table content
if (nsnull!=mTableLayoutStrategy)
{
mTableLayoutStrategy->Initialize(aDesiredSize.maxElementSize);
}
#else
// XXX Hack...
AdjustSiblingsAfterReflow(&aPresContext, state, kidFrame, desiredSize.height -
@ -2231,9 +2254,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
if (gsDebug)
printf ("BalanceColumnWidths...\n");
if (nsnull==mCellMap)
return; // we don't have any information yet, so we can't do any useful work
@ -2244,11 +2264,6 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
nsCRT::memset (mColumnWidths, 0, numCols*sizeof(PRInt32));
}
// need to track min and max table widths
PRInt32 minTableWidth = 0;
PRInt32 maxTableWidth = 0;
PRInt32 totalFixedWidth = 0;
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
@ -2308,13 +2323,9 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
if (nsnull==mTableLayoutStrategy)
{ // TODO: build a different strategy based on the compatibility mode
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, numCols);
mTableLayoutStrategy->Initialize(aMaxElementSize);
}
mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext,
aReflowState, maxWidth,
totalFixedWidth,
minTableWidth, maxTableWidth,
aMaxElementSize);
mTableLayoutStrategy->BalanceColumnWidths(mStyleContext, aReflowState, maxWidth);
}
/**
@ -2608,7 +2619,7 @@ nsTableFrame::CreateContinuingFrame(nsIPresContext& aPresContext,
nsIStyleContext* kidStyleContext =
aPresContext.ResolveStyleContextFor(content, cf); // kidStyleContext: REFCNT++
nsIContentDelegate* kidDel = nsnull;
kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
kidDel = content->GetDelegate(&aPresContext); // kidDel: REFCNT++
nsIFrame* duplicateFrame;
nsresult rv = kidDel->CreateFrame(&aPresContext, content, cf,
kidStyleContext, duplicateFrame);
@ -2825,6 +2836,19 @@ NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin&
return result;
}
nscoord nsTableFrame::GetCellSpacing()
{
nsTableFrame* tableFrame = this;
//XXX remove when table style is fully resolved!
GetGeometricParent((nsIFrame *&)tableFrame); // get the outer frame
nsStyleTable* tableStyle;
tableFrame->GetStyleData(eStyleStruct_Table, (nsStyleStruct *&)tableStyle);
nscoord cellSpacing = 0;
if (tableStyle->mCellSpacing.GetUnit() == eStyleUnit_Coord)
cellSpacing = tableStyle->mCellSpacing.GetCoordValue();
return cellSpacing;
}
void nsTableFrame::GetColumnsByType(const nsStyleUnit aType,
PRInt32& aOutNumColumns,
PRInt32 *& aOutColumnIndexes)
@ -2989,27 +3013,34 @@ nscoord nsTableFrame::GetTableContainerWidth(const nsReflowState& aReflowState)
}
else
{
nsSize tableSize;
table->GetSize(tableSize);
parentWidth = tableSize.width;
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row group
childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(childFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row
grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the cell
greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
if (nsnull!=((nsTableFrame*)table)->mColumnWidths)
{
PRInt32 colIndex = ((nsTableCellFrame*)greatgrandchildFrame)->GetColIndex();
parentWidth = ((nsTableFrame*)table)->GetColumnWidth(colIndex);
}
else
{
nsSize tableSize;
table->GetSize(tableSize);
parentWidth = tableSize.width;
spacing->CalcBorderPaddingFor(rs->frame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row group
childFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(childFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the row
grandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(grandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
// same for the cell
greatgrandchildFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcBorderPaddingFor(greatgrandchildFrame, borderPadding);
parentWidth -= (borderPadding.right + borderPadding.left);
}
if (PR_TRUE==gsDebugNT)
printf("%p: found a table frame %p, returning parentWidth %d from frame width %d\n",
aReflowState.frame, table, parentWidth, tableSize.width);
printf("%p: found a table frame %p, returning parentWidth %d \n",
aReflowState.frame, table, parentWidth);
}
break;
}

View File

@ -142,6 +142,9 @@ public:
/** set the width of the column at aColIndex to aWidth */
virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
/** helper to get the cell spacing style value */
virtual nscoord GetCellSpacing();
/**
* Calculate Layout Information
@ -167,13 +170,26 @@ public:
/** 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
*
* @param aRowIndex the row from which to measure effective row span
* @param aCell 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);
/** return the col span of a cell, taking into account col span magic at the edge
* of a table.
*
* @param aColIndex the column from which to measure effective col span
* @param aCell the cell
*
* @return the col span, correcting for col spans that extend beyond the edge
* of the table.
*/
virtual PRInt32 GetEffectiveColSpan(PRInt32 aColIndex, nsTableCellFrame *aCell);
// For DEBUGGING Purposes Only
NS_IMETHOD MoveTo(nscoord aX, nscoord aY);
NS_IMETHOD SizeTo(nscoord aWidth, nscoord aHeight);

View File

@ -336,19 +336,22 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
nscoord maxCellTopMargin = 0;
nscoord maxCellBottomMargin = 0;
if (PR_TRUE==gsDebug1) printf("%p: RR\n", this);
// Reflow each of our existing cell frames
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; ) {
// Get the frame's margins, and compare the top and bottom margin
// against our current max values
nsMargin kidMargin;
for (nsIFrame* kidFrame = mFirstChild; nsnull != kidFrame; )
{
nscoord cellSpacing = aState.tableFrame->GetCellSpacing();
// just cellSpacing? QQQ
nsMargin kidMargin;
aState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame,kidMargin);
if (kidMargin.top > maxCellTopMargin)
maxCellTopMargin = kidMargin.top;
if (kidMargin.bottom > maxCellBottomMargin)
maxCellBottomMargin = kidMargin.bottom;
// left and right margins already taken into account by table layout strategy
// Compute the x-origin for the child, taking into account straddlers (cells from prior
// rows with rowspans > 1)
PRInt32 cellColIndex = ((nsTableCellFrame *)kidFrame)->GetColIndex();
@ -357,10 +360,14 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 colIndex=prevColIndex+1; colIndex<cellColIndex; colIndex++)
{
aState.x += aState.tableFrame->GetColumnWidth(colIndex);
aState.x += kidMargin.left + kidMargin.right;
aState.x += cellSpacing;
if (PR_TRUE==gsDebug1)
printf(" in loop, aState.x set to %d from cellSpacing %d and col width\n",
aState.x, aState.tableFrame->GetColumnWidth(colIndex), cellSpacing);
}
}
aState.x += kidMargin.left;
aState.x += cellSpacing;
if (PR_TRUE==gsDebug1) printf(" past loop, aState.x set to %d\n", aState.x);
// at this point, we know the column widths.
// so we get the avail width from the known column widths
@ -369,13 +376,15 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
for (PRInt32 numColSpan=0; numColSpan<cellColSpan; numColSpan++)
{
availWidth += aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan);
if (0<numColSpan)
if (numColSpan != 0)
{
availWidth += kidMargin.right;
if (0!=cellColIndex)
availWidth += kidMargin.left;
availWidth += cellSpacing;
}
if (PR_TRUE==gsDebug1)
printf(" in loop, availWidth set to %d from colIndex %d width %d and cellSpacing\n",
availWidth, cellColIndex, aState.tableFrame->GetColumnWidth(cellColIndex+numColSpan), cellSpacing);
}
if (PR_TRUE==gsDebug1) printf(" availWidth for this cell is %d\n", availWidth);
prevColIndex = cellColIndex + (cellColSpan-1); // remember the rightmost column this cell spans into
@ -461,7 +470,8 @@ nsresult nsTableRowFrame::ResizeReflow(nsIPresContext& aPresContext,
PlaceChild(aPresContext, aState, kidFrame, kidRect, aDesiredSize.maxElementSize,
pKidMaxElementSize);
aState.x += kidMargin.right; // add in right margin only after cell has been placed
if (PR_TRUE==gsDebug1) printf(" past PlaceChild, aState.x set to %d\n", aState.x);
// Get the next child
kidFrame->GetNextSibling(kidFrame);