bug 10636, 15499(partial) - correctly get margin,border,padding from reflow info. calculate it for percentage padding when reflow state not available. r=troy

This commit is contained in:
karnaze%netscape.com 2000-02-12 01:55:40 +00:00
parent aa85daed4b
commit 49f3412344
27 changed files with 586 additions and 498 deletions

View File

@ -80,9 +80,10 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
MOZ_COUNT_DTOR(BasicTableLayoutStrategy);
}
PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxWidth)
PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxWidth,
const nsHTMLReflowState& aReflowState)
{
ContinuingFrameCheck();
@ -94,29 +95,27 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
mCellSpacingTotal = 0;
mCols = mTableFrame->GetEffectiveCOLSAttribute();
// assign the width of all fixed-width columns
AssignPreliminaryColumnWidths(aPresContext, aMaxWidth);
AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState);
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
if (nsnull != aMaxElementSize) {
SetMaxElementSize(aMaxElementSize);
SetMaxElementSize(aMaxElementSize, aReflowState.mComputedPadding);
}
return result;
}
void BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize)
void
BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)
{
if (nsnull != aMaxElementSize) {
aMaxElementSize->height = 0;
nsMargin borderPadding;
const nsStylePosition* tablePosition;
const nsStyleSpacing* tableSpacing;
mTableFrame->GetStyleData(eStyleStruct_Position, ((const nsStyleStruct *&)tablePosition));
mTableFrame->GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
mTableFrame->GetTableBorder(borderPadding);
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aPadding;
nscoord horBorderPadding = borderPadding.left + borderPadding.right;
if (tablePosition->mWidth.GetUnit() == eStyleUnit_Coord) {
aMaxElementSize->width = tablePosition->mWidth.GetCoordValue();
@ -187,11 +186,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
// reduce the maxWidth by border and padding, since we will be dealing with content width
// XXX should this be done in aMaxWidthIn by the caller?
if (maxWidth != NS_UNCONSTRAINEDSIZE) {
const nsStyleSpacing* spacing;
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
nsMargin borderPadding;
spacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
maxWidth -= borderPadding.left + borderPadding.right;
maxWidth -= aReflowState.mComputedBorderPadding.left +
aReflowState.mComputedBorderPadding.right;
maxWidth = PR_MAX(0, maxWidth);
}
// initialize the col percent and cell percent values to 0.
@ -448,11 +444,12 @@ nscoord GetConstrainedWidth(nsTableColFrame* colFrame,
#define LIMIT_NONE 2
void
BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct)
BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct,
nscoord aPercentBase)
{
if (!aCellFrame || (aColIndex < 0) || (aColIndex < 0) || (aColSpan < 0)) {
NS_ASSERTION(PR_FALSE, "ComputeColspanWidths called incorrectly");
@ -472,12 +469,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
aCellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
// need to add padding into fixed width
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(aCellFrame, paddingMargin);
nscoord padding = paddingMargin.left + paddingMargin.right;
cellWidth = cellPosition->mWidth.GetCoordValue() + padding;
nsMargin padding = nsTableFrame::GetPadding(nsSize(aPercentBase, 0), aCellFrame);
cellWidth = cellPosition->mWidth.GetCoordValue() + padding.left + padding.right;
cellWidth = PR_MAX(cellWidth, aCellFrame->GetPass1MaxElementSize().width);
}
}
@ -691,10 +684,17 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
return result;
}
// XXX percent left and right padding are not figured in the calculations
// The table frame needs to be used as the percent base because the reflow
// state may have an unconstrained width. There should probably be a frame
// state bit indicating that horizontal padding is percentage based.
// Determine min, desired, fixed, and proportional sizes for the cols and
// and calculate min/max table width
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth)
PRBool
BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth,
const nsHTMLReflowState& aReflowState)
{
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d count=%d \n", aMaxWidth, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);}
PRBool rv = PR_FALSE;
@ -753,11 +753,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
nscoord coordValue = cellPosition->mWidth.GetCoordValue();
if (coordValue > 0) { // ignore if width == 0
// need to add padding into fixed width
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
nscoord newFixWidth = coordValue + paddingMargin.left + paddingMargin.right;
nsSize percentBase(aReflowState.mComputedWidth, 0);
nsMargin padding = nsTableFrame::GetPadding(percentBase, cellFrame);
nscoord newFixWidth = coordValue + padding.left + padding.right;
// 2nd part of condition is Nav Quirk like below
if ((newFixWidth > fixWidth) || ((newFixWidth == fixWidth) && (desContributor == cellFrame))) {
fixWidth = newFixWidth;
@ -864,7 +862,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
}
// set MIN_ADJ, DES_ADJ, FIX_ADJ
for (PRInt32 widthX = 0; widthX < NUM_MAJOR_WIDTHS; widthX++) {
ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE);
ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, aReflowState.mComputedWidth);
}
}
}
@ -894,8 +892,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
}
// Determine percentage col widths for each col frame
nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
PRBool aTableIsAutoWidth)
nscoord
BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
PRBool aTableIsAutoWidth)
{
PRInt32 numRows = mTableFrame->GetRowCount();
PRInt32 numCols = mTableFrame->GetColCount();
@ -1026,12 +1025,9 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
percentContributor = cellFrame;
if (!mIsNavQuirksMode) {
// need to add padding
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
maxColPctWidth += paddingMargin.left + paddingMargin.right;
// need to add padding
nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame);
maxColPctWidth += padding.left + padding.right;
}
}
}
@ -1082,11 +1078,8 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
cellPctWidth = NSToCoordRound( ((float)basis) * cellPct );
if (!mIsNavQuirksMode) {
// need to add padding
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
cellPctWidth += paddingMargin.left + paddingMargin.right;
nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame);
cellPctWidth += padding.left + padding.right;
}
}
if (cellPctWidth > 0) {

View File

@ -58,14 +58,16 @@ public:
* in the table (content, structure, or style)
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
*/
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxSize);
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxSize,
const nsHTMLReflowState& aReflowState);
/** compute the max element size of the table.
* assumes that Initialize has been called
*/
virtual void SetMaxElementSize(nsSize* aMaxElementSize);
virtual void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding);
void SetMinAndMaxTableContentWidths();
@ -99,8 +101,9 @@ protected:
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth);
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState);
/**
* Calculate the adjusted widths (min, desired, fixed, or pct) for a cell
@ -115,7 +118,8 @@ protected:
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct);
PRBool aConsiderPct,
nscoord aPercentBase);
/**
* main helper for above. For min width calculations, it can get called up to

View File

@ -56,8 +56,10 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aP
* otherwise the cell get a proportion of the remaining space
* as determined by the table width attribute. If no table width attribute, it gets 0 width
*/
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth)
PRBool
FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState)
{
// NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
const nsStylePosition* tablePosition;
@ -65,17 +67,15 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
eStyleUnit_Percent == tablePosition->mWidth.GetUnit();
const nsStyleSpacing* tableSpacing;
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)tableSpacing);
nsMargin borderPadding;
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
PRInt32 numCols = mTableFrame->GetColCount();
PRInt32 colX;
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
// minus table border, padding, & cellspacing
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
((numCols + 1) * mTableFrame->GetCellSpacingX());
nscoord availWidth = (NS_UNCONSTRAINEDSIZE == aComputedWidth)
? NS_UNCONSTRAINEDSIZE
: aComputedWidth - aReflowState.mComputedBorderPadding.left -
aReflowState.mComputedBorderPadding.right -
((numCols + 1) * mTableFrame->GetCellSpacingX());
PRInt32 specifiedCols = 0; // the number of columns whose width is given
nscoord totalColWidth = 0; // the sum of the widths of the columns
@ -106,7 +106,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
} // get the percentage width
else if ((eStyleUnit_Percent == colPosition->mWidth.GetUnit()) &&
(aComputedWidth != NS_UNCONSTRAINEDSIZE)) {
// Only apply percentages if we're unconstrained.
// Only apply percentages if we're constrained.
float percent = colPosition->mWidth.GetPercentValue();
colWidths[colX] = NSToCoordRound(percent * (float)availWidth);
}

View File

@ -96,8 +96,9 @@ protected:
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth);
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState);
};

View File

@ -29,6 +29,7 @@
class nsIPresContext;
class nsIStyleContext;
struct nsHTMLReflowState;
struct nsMargin;
class nsTableCellFrame;
class nsStyleCoord;
class nsISizeOfHandler;
@ -41,14 +42,16 @@ public:
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
* @param aComputedWidth the computed size of the table
*/
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aComputedWidth)=0;
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aComputedWidth,
const nsHTMLReflowState& aBorderPadding)=0;
/** compute the max-element-size for the table
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
*/
virtual void SetMaxElementSize(nsSize* aMaxElementSize)=0;
virtual void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)=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.

View File

@ -758,14 +758,16 @@ void nsTableBorderCollapser::ComputeBorderSegment(PRUint8 aSide,
return;
}
else if (spacing->GetBorderStyle(side)!=NS_STYLE_BORDER_STYLE_NONE) {
spacing->GetBorder(border);
nscoord borderWidth = GetWidthForSide(border, side);
if (borderWidth == maxWidth)
sameWidthBorders.AppendElement(spacing);
else if (borderWidth > maxWidth) {
maxWidth = borderWidth;
sameWidthBorders.Clear();
sameWidthBorders.AppendElement(spacing);
if (spacing->GetBorder(border)) {
nscoord borderWidth = GetWidthForSide(border, side);
if (borderWidth == maxWidth) {
sameWidthBorders.AppendElement(spacing);
}
else if (borderWidth > maxWidth) {
maxWidth = borderWidth;
sameWidthBorders.Clear();
sameWidthBorders.AppendElement(spacing);
}
}
}
}

View File

@ -436,19 +436,17 @@ void nsTableCellFrame::SetBorderEdge(PRUint8 aSide,
* Align the cell's child frame within the cell
*
*/
void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
const nsStyleText* textStyle =
(const nsStyleText*)mStyleContext->GetStyleData(eStyleStruct_Text);
/* XXX: remove tableFrame when border-collapse inherits */
nsTableFrame* tableFrame=nsnull;
nsTableFrame* tableFrame = nsnull;
(void) nsTableFrame::GetTableFrame(this, tableFrame);
nsMargin borderPadding;
GetCellBorder (borderPadding, tableFrame);
nsMargin padding;
spacing->GetPadding(padding);
nsMargin padding = nsTableFrame::GetPadding(aReflowState, this);
borderPadding += padding;
nscoord topInset = borderPadding.top;
@ -604,9 +602,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
/* XXX: remove tableFrame when border-collapse inherits */
nsTableFrame* tableFrame=nsnull;
rv = nsTableFrame::GetTableFrame(this, tableFrame);
nsMargin padding;
spacing->GetPadding(padding);
nsMargin borderPadding = padding;
nsMargin borderPadding = aReflowState.mComputedPadding;
nsMargin border;
GetCellBorder(border, tableFrame);
if ((NS_UNCONSTRAINEDSIZE == availSize.width) || !GetContentEmpty()) {
@ -681,6 +677,14 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Initial == aReflowState.reason) {
kidOrigin.MoveTo(leftInset, topInset);
} else {
// handle percent padding-left which was 0 during initial reflow
if (eStyleUnit_Percent == aReflowState.mStyleSpacing->mPadding.GetLeftUnit()) {
nsRect kidRect;
firstKid->GetRect(kidRect);
// only move in the x direction for the same reason as above
kidOrigin.MoveTo(leftInset, kidRect.y);
firstKid->MoveTo(aPresContext, leftInset, kidRect.y);
}
firstKid->GetOrigin(kidOrigin);
}
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
@ -733,7 +737,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nscoord spacingX = tableFrame->GetCellSpacingX();
nscoord spacingExtra = spacingX * (colspan - 1);
smallestMinWidth += spacingExtra;
if (padding.left > 0) {
if (aReflowState.mComputedPadding.left > 0) {
smallestMinWidth -= onePixel;
}
}
@ -1090,7 +1094,9 @@ PRUint8 nsTableCellFrame::GetOpposingEdge(PRUint8 aEdge)
return result;
}
void nsTableCellFrame::GetCellBorder(nsMargin &aBorder, nsTableFrame *aTableFrame)
void
nsTableCellFrame::GetCellBorder(nsMargin& aBorder,
nsTableFrame* aTableFrame)
{
aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
if (nsnull==aTableFrame) {

View File

@ -137,7 +137,8 @@ public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
virtual void VerticallyAlignChild(nsIPresContext* aPresContext);
virtual void VerticallyAlignChild(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
/**
* return the cell's specified row span. this is what was specified in the

View File

@ -354,6 +354,13 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsTableFrame::IsPercentageBase(PRBool& aBase) const
{
aBase = PR_TRUE;
return NS_OK;
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
@ -1393,9 +1400,7 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresCon
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nsSize kidMaxElementSize;
((nsTableRowGroupFrame*)kidFrame)->GetMaxElementSize(kidMaxElementSize);
@ -1440,19 +1445,18 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresCon
return NS_OK;
}
void nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight)
void
nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext,
nscoord aHeight,
const nsMargin& aBorderPadding)
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
spacing->CalcBorderPaddingFor(this, borderPadding);
nscoord colHeight = aHeight -= borderPadding.top + borderPadding.bottom;
nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom;
nscoord cellSpacingX = GetCellSpacingX();
nscoord halfCellSpacingX = NSToCoordRound(((float)cellSpacingX) / (float)2);
nsIFrame* colGroupFrame = mColGroups.FirstChild();
PRInt32 colX = 0;
nsPoint colGroupOrigin(borderPadding.left, borderPadding.top);
nsPoint colGroupOrigin(aBorderPadding.left, aBorderPadding.top);
PRInt32 numCols = GetColCount();
while (nsnull != colGroupFrame) {
nscoord colGroupWidth = 0;
@ -1515,6 +1519,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height = 0;
}
aStatus = NS_FRAME_COMPLETE;
// XXX yank this nasty code and see what happens, and then yank other
// similar calls to InvalidateFirstPassCache.
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) &&
(this == (nsTableFrame *)GetFirstInFlow())) {
InvalidateFirstPassCache();
@ -1545,7 +1551,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
}
if (mTableLayoutStrategy && (needsRecalc || !IsColumnWidthsValid())) {
nscoord boxWidth = CalcBorderBoxWidth(aReflowState);
mTableLayoutStrategy->Initialize(aPresContext, aDesiredSize.maxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aDesiredSize.maxElementSize,
boxWidth, aReflowState);
mBits.mColumnWidthsValid = PR_TRUE; //so we don't do this a second time below
}
@ -1556,7 +1563,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize);
// assign table width
SetTableWidth(aPresContext);
SetTableWidth(aPresContext, aReflowState);
}
if ((eReflowReason_Initial == aReflowState.reason) &&
@ -1606,7 +1613,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
// set aDesiredSize and aMaxElementSize
}
SetColumnDimensions(aPresContext, aDesiredSize.height);
SetColumnDimensions(aPresContext, aDesiredSize.height, aReflowState.mComputedBorderPadding);
if (pass1MaxElementSize) {
aDesiredSize.maxElementSize = pass1MaxElementSize;
}
@ -1621,7 +1628,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
if (isAutoWidth && !IsMaximumWidthValid()) {
// Initialize the strategy and have it compute the natural size of
// the table
mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE);
mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE, aReflowState);
// Now the maximum width is valid
mBits.mMaximumWidthValid = PR_TRUE;
@ -1918,13 +1925,9 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// set out param
aStatus = NS_FRAME_COMPLETE;
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding); // this gets the max border thickness at each edge
nsMargin padding;
mySpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, aReflowState, borderPadding);
@ -1981,13 +1984,9 @@ void nsTableFrame::ComputePercentBasisForRows(const nsHTMLReflowState& aReflowSt
nscoord height = CalcBorderBoxHeight(aReflowState, PR_TRUE);
if ((height > 0) && (height != NS_UNCONSTRAINEDSIZE)) {
// exclude our border and padding
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding(0,0,0,0);
// XXX handle percentages
if (spacing->GetBorderPadding(borderPadding)) {
height -= borderPadding.top + borderPadding.bottom;
}
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
height -= borderPadding.top + borderPadding.bottom;
// exclude cell spacing for all rows
height -= (1 + GetRowCount()) * GetCellSpacingY();
height = PR_MAX(0, height);
@ -2183,19 +2182,6 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
return NS_OK;
}
NS_METHOD nsTableFrame::GetBorderPlusMarginPadding(nsMargin& aResult)
{
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding);
nsMargin padding;
mySpacing->GetPadding(padding);
borderPadding += padding;
aResult = borderPadding;
return NS_OK;
}
// Sets the starting column index for aColGroupFrame and the siblings frames that
// follow
void
@ -2471,9 +2457,12 @@ NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext* aPresContext,
}
reflowState.availableWidth = pass1Width;
nsMargin borderPadding;
GetBorderPlusMarginPadding(borderPadding);
InnerTableReflowState state(aPresContext, reflowState, borderPadding);
// get margin + border + padding
nsMargin borderMarginPadding;
GetTableBorder (borderMarginPadding);
borderMarginPadding += aReflowState.mComputedMargin + aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, reflowState, borderMarginPadding);
// determine if this frame is the target or not
nsIFrame *target=nsnull;
@ -2659,9 +2648,7 @@ nsTableFrame::RecoverState(InnerTableReflowState& aReflowState,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nsSize kidMaxElementSize;
((nsTableRowGroupFrame*)frame)->GetMaxElementSize(kidMaxElementSize);
@ -2723,9 +2710,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nscoord kidWidth = kidMaxElementSize.width + borderPadding.left + borderPadding.right + cellSpacing*2;
aDesiredSize.maxElementSize->width = PR_MAX(aDesiredSize.maxElementSize->width, kidWidth);
@ -2854,9 +2839,7 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nscoord kidWidth = aKidMaxElementSize.width + borderPadding.left + borderPadding.right + cellSpacing*2;
aMaxElementSize->width = PR_MAX(aMaxElementSize->width, kidWidth);
@ -2922,9 +2905,7 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
GetTableBorderForRowGroup(GetRowGroupFrameFor(kidFrame, childDisplay), borderPadding);
const nsStyleSpacing* tableSpacing;
GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)tableSpacing));
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
// Reflow the child into the available space
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
@ -3219,13 +3200,13 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
else
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth, aReflowState);
mBits.mColumnWidthsValid=PR_TRUE;
}
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
// reflow gets called twice and the 2nd time has the correct space available.
else if (!IsAutoLayout(&aReflowState)) {
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth, aReflowState);
}
mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext, aReflowState, maxWidth);
@ -3243,7 +3224,8 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
add in table insets
set rect
*/
void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
nsTableCellMap* cellMap = GetCellMap();
@ -3279,9 +3261,7 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding); // this gets the max border value at every edge
nsMargin padding;
spacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.mComputedPadding;
nscoord rightInset = borderPadding.right;
nscoord leftInset = borderPadding.left;
@ -3293,7 +3273,8 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
}
// XXX percentage based margin/border/padding
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame, const nsIID& aIID)
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame,
const nsIID& aIID)
{
nscoord result = 0;
if (!aFrame) {
@ -3305,8 +3286,8 @@ nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame, const nsIID& aIID)
nsIHTMLContent* htmlContent = nsnull;
rv = iContent->QueryInterface(aIID, (void **)&htmlContent);
if (htmlContent && NS_SUCCEEDED(rv)) {
nsIStyleContext* styleContext;
aFrame->GetStyleContext(&styleContext); // XXX fix this leak
nsCOMPtr<nsIStyleContext> styleContext;
aFrame->GetStyleContext(getter_AddRefs(styleContext));
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)styleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
@ -3506,13 +3487,8 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
// the first row group's y position starts inside our padding
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
if (spacing->GetBorder(margin)) { // XXX see bug 10636 and handle percentages
rowGroupYPos = margin.top;
}
if (spacing->GetPadding(margin)) { // XXX see bug 10636 and handle percentages
rowGroupYPos += margin.top;
}
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
rowGroupYPos = borderPadding.top;
firstRowGroupFrame = childFrame;
}
}
@ -3849,6 +3825,91 @@ void nsTableFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
#endif
}
nscoord
CalcPercentPadding(nscoord aBasis,
nsStyleCoord aStyleCoord)
{
float percent = (NS_UNCONSTRAINEDSIZE == aBasis)
? 0 : aStyleCoord.GetPercentValue();
return NSToCoordRound(((float)aBasis) * percent);
}
void
GetPaddingFor(const nsSize& aBasis,
const nsStyleSpacing& aSpacing,
nsMargin& aPadding)
{
nsStyleCoord styleCoord;
aSpacing.mPadding.GetTop(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetTopUnit()) {
aPadding.top = CalcPercentPadding(aBasis.height, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.top = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetRight(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetRightUnit()) {
aPadding.right = CalcPercentPadding(aBasis.width, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.right = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetBottom(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetBottomUnit()) {
aPadding.bottom = CalcPercentPadding(aBasis.height, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.bottom = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetLeft(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetLeftUnit()) {
aPadding.left = CalcPercentPadding(aBasis.width, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.left = styleCoord.GetCoordValue();
}
}
nsMargin
nsTableFrame::GetPadding(const nsHTMLReflowState& aReflowState,
const nsTableCellFrame* aCellFrame)
{
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin padding(0,0,0,0);
if (!spacing->GetPadding(padding)) {
const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
while (parentRS) {
if (parentRS->frame) {
nsCOMPtr<nsIAtom> frameType;
parentRS->frame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableFrame == frameType.get()) {
nsSize basis(parentRS->mComputedWidth, parentRS->mComputedHeight);
GetPaddingFor(basis, *spacing, padding);
break;
}
}
parentRS = parentRS->parentReflowState;
}
}
return padding;
}
nsMargin
nsTableFrame::GetPadding(const nsSize& aBasis,
const nsTableCellFrame* aCellFrame)
{
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin padding(0,0,0,0);
if (!spacing->GetPadding(padding)) {
GetPaddingFor(aBasis, *spacing, padding);
}
return padding;
}
NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin)
{
@ -4169,10 +4230,12 @@ nscoord nsTableFrame::GetMaxTableContentWidth()
return result;
}
void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize)
void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)
{
if (nsnull!=mTableLayoutStrategy)
mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize);
if (nsnull!=mTableLayoutStrategy) {
mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize, aPadding);
}
}

View File

@ -106,6 +106,8 @@ public:
nsIFrame* aPrevInFlow);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame);
/*
@ -228,6 +230,12 @@ public:
*/
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
static nsMargin GetPadding(const nsHTMLReflowState& aReflowState,
const nsTableCellFrame* aCellFrame);
static nsMargin GetPadding(const nsSize& aBasis,
const nsTableCellFrame* aCellFrame);
nsFrameList& GetColGroups();
/** return PR_TRUE if the column width information has been set */
@ -404,8 +412,6 @@ public:
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
NS_METHOD GetBorderPlusMarginPadding(nsMargin& aResult);
PRBool HasNonPercentSpanningPercent() const;
void SetHasNonPercentSpanningPercent(PRBool aValue);
@ -624,7 +630,8 @@ protected:
nsSize* aMaxElementSize);
/** sets the width of the table according to the computed widths of each column. */
virtual void SetTableWidth(nsIPresContext* aPresContext);
virtual void SetTableWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
/** returns PR_TRUE if the cached pass 1 data is still valid */
virtual PRBool IsFirstPassValid() const;
@ -732,7 +739,9 @@ public:
protected:
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
void SetColumnDimensions(nsIPresContext* aPresContext,
nscoord aHeight,
const nsMargin& aReflowState);
#ifdef NS_DEBUG
/** for debugging only
@ -789,7 +798,8 @@ public: /* ----- Cell Map public methods ----- */
/** compute the max-element-size for the table
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
*/
void SetMaxElementSize(nsSize* aMaxElementSize);
void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding);
/** returns PR_TRUE if table layout requires a preliminary pass over the content */
virtual PRBool IsAutoLayout(const nsHTMLReflowState* aReflowState = nsnull);

View File

@ -386,39 +386,6 @@ PRBool nsTableOuterFrame::NeedsReflow(const nsHTMLReflowState& aReflowState)
nsresult nsTableOuterFrame::RecoverState(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame)
{
#if 0
// Get aKidFrame's previous sibling
nsIFrame* prevKidFrame = nsnull;
for (nsIFrame* frame = mFrames.FirstChild(); frame != aKidFrame;) {
prevKidFrame = frame;
frame->GetNextSibling(frame);
}
if (nsnull != prevKidFrame) {
nsRect rect;
// Set our running y-offset
prevKidFrame->GetRect(rect);
aReflowState.y = rect.YMost();
// Adjust the available space
if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aReflowState.y;
}
// Get the previous frame's bottom margin
const nsStyleSpacing* kidSpacing;
prevKidFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)kidSpacing);
nsMargin margin;
kidSpacing->CalcMarginFor(prevKidFrame, margin);
if (margin.bottom < 0) {
aReflowState.prevMaxNegBottomMargin = -margin.bottom;
} else {
aReflowState.prevMaxPosBottomMargin = margin.bottom;
}
}
#endif
aReflowState.y = 0;
// Set the inner table max size
@ -584,7 +551,8 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
innerTableSize.SizeTo(innerSize.width, innerSize.height);
// set maxElementSize width if requested
if (nsnull != aDesiredSize.maxElementSize) {
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize,
aReflowState.reflowState.mComputedPadding);
if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
@ -599,7 +567,7 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
// regardless of what we've done up to this point, place the caption and inner table
rv = SizeAndPlaceChildren(aPresContext, innerTableSize,
nsSize (captionSize.width, captionSize.height),
aReflowState);
aReflowState, captionReflowState.mComputedMargin);
return rv;
}
@ -707,7 +675,6 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
{
nsresult rv = NS_OK;
const nsStyleTable* captionTableStyle=nsnull;
nsMargin captionMargin;
// remember the old width and height
nsRect priorInnerTableRect;
mInnerTableFrame->GetRect(priorInnerTableRect);
@ -742,9 +709,10 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
mInnerTableMaximumWidth = innerSize.mMaximumWidth;
}
nsMargin captionMargin(0,0,0,0);
// if there is a caption and the width or height of the inner table changed from a successful reflow,
// then reflow or move the caption as needed
if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) {
if ((nsnull != mCaptionFrame) && NS_SUCCEEDED(rv)) {
// remember the old caption height
nsRect oldCaptionRect;
mCaptionFrame->GetRect(oldCaptionRect);
@ -761,19 +729,22 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
captionWasReflowed = PR_TRUE;
if ((oldCaptionRect.height!=captionSize.height) ||
(oldCaptionRect.width!=captionSize.width)) {
captionDimChanged=PR_TRUE;
if ((oldCaptionRect.height != captionSize.height) ||
(oldCaptionRect.width != captionSize.width)) {
captionDimChanged = PR_TRUE;
}
captionMargin = captionReflowState.mComputedMargin;
}
// XXX: should just call SizeAndPlaceChildren regardless
// find where to place the caption
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((const nsStyleStruct *&)captionTableStyle));
if ((priorInnerTableRect.height!=innerSize.height) ||
(PR_TRUE==captionDimChanged)) {
if ((priorInnerTableRect.height != innerSize.height) || captionDimChanged) {
if (!captionWasReflowed) { // get the computed margin by constructing a reflow state
nsHTMLReflowState rState(aPresContext, aReflowState.reflowState, mCaptionFrame,
nsSize(innerSize.width, aReflowState.reflowState.availableHeight),
eReflowReason_Resize);
captionMargin = rState.mComputedMargin;
}
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
@ -867,7 +838,8 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresConte
}
// set maxElementSize width if requested
if (nsnull != aDesiredSize.maxElementSize) {
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize,
aReflowState.reflowState.mComputedPadding);
if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
@ -876,7 +848,7 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresConte
rv = SizeAndPlaceChildren(aPresContext,
nsSize (innerSize.width, innerSize.height),
nsSize (captionSize.width, captionSize.height),
aReflowState);
aReflowState, captionReflowState.mComputedMargin);
return rv;
}
@ -891,23 +863,20 @@ PRBool nsTableOuterFrame::IR_CaptionChangedAxis(const nsStyleTable* aOldStyle,
nsresult nsTableOuterFrame::SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState)
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin)
{
nsresult rv = NS_OK;
// find where to place the caption
nsMargin captionMargin;
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
nscoord captionY = aCaptionMargin.top;
const nsStyleTable* captionTableStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Table, ((const nsStyleStruct *&)captionTableStyle));
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
captionY += aInnerSize.height;
}
// Place the caption
nsRect captionRect(captionMargin.left, captionY, 0, 0);
nsRect captionRect(aCaptionMargin.left, captionY, 0, 0);
captionRect.SizeTo(aCaptionSize.width, aCaptionSize.height);
mCaptionFrame->SetRect(aPresContext, captionRect);
@ -916,10 +885,10 @@ nsresult nsTableOuterFrame::SizeAndPlaceChildren(nsIPresContext* aPresCon
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
// bottom caption
innerY = 0;
aReflowState.y = captionRect.YMost() + captionMargin.bottom;
aReflowState.y = captionRect.YMost() + aCaptionMargin.bottom;
}
else { // top caption
innerY = captionRect.YMost() + captionMargin.bottom;
innerY = captionRect.YMost() + aCaptionMargin.bottom;
aReflowState.y = innerY + aInnerSize.height;
}
nsRect innerRect(0, innerY, aInnerSize.width, aInnerSize.height);
@ -1030,15 +999,14 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
// place the caption and the inner table
nscoord innerY = 0;
if (nsnull != mCaptionFrame) {
// Get the caption's margin
nsMargin captionMargin;
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
// construct the caption reflow state
nscoord captionAvailWidth = PR_MAX(innerSize.width, mMinCaptionWidth);
nsHTMLReflowState captionReflowState(aPresContext, state.reflowState, mCaptionFrame,
nsSize(captionAvailWidth, NS_UNCONSTRAINEDSIZE),
eReflowReason_Resize);
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
nscoord captionY = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.top)
? 0 : captionReflowState.mComputedMargin.top;
const nsStyleTable* captionTableStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Table, ((const nsStyleStruct *&)captionTableStyle));
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
@ -1046,13 +1014,10 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
}
// Reflow the caption. Let it be as high as it wants
nscoord captionAvailWidth = PR_MAX(innerSize.width, mMinCaptionWidth);
nsHTMLReflowState captionReflowState(aPresContext, state.reflowState, mCaptionFrame,
nsSize(captionAvailWidth, NS_UNCONSTRAINEDSIZE),
eReflowReason_Resize);
nsRect captionRect(captionMargin.left, captionY, 0, 0);
nscoord leftCapMargin = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.left)
? 0 : captionReflowState.mComputedMargin.left;
nsRect captionRect(leftCapMargin, captionY, 0, 0);
nsReflowStatus captionStatus;
captionSize.maxElementSize = nsnull;
ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
captionRect.x, captionRect.y, 0, captionStatus);
@ -1067,15 +1032,17 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
captionRect.x, captionRect.y, 0);
// Place the inner table
nscoord bottomCapMargin = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.bottom)
? 0 : captionReflowState.mComputedMargin.bottom;
if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) {
// top caption
innerY = captionRect.YMost() + captionMargin.bottom;
innerY = captionRect.YMost() + bottomCapMargin;
state.y = innerY + innerSize.height;
}
else {
// bottom caption
innerY = 0;
state.y = captionRect.YMost() + captionMargin.bottom;
state.y = captionRect.YMost() + bottomCapMargin;
}
}

View File

@ -248,9 +248,10 @@ protected:
/** set the size and the location of both the inner table frame and the caption. */
NS_IMETHOD SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize & aInnerSize,
const nsSize & aCaptionSize,
OuterTableReflowState& aReflowState);
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin);
// end Incremental Reflow methods

View File

@ -289,7 +289,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
// But some content crashes when this reflow is issued, to be investigated
//XXX nsReflowStatus status;
//ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status);
((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(aPresContext);
((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(aPresContext, aReflowState);
/* if we're collapsing borders, notify the cell that the border edge length has changed */
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
((nsTableCellFrame *)(cellFrame))->SetBorderEdgeLength(NS_SIDE_LEFT,
@ -948,12 +948,6 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
// get border padding values
nsMargin borderPadding;
const nsStyleSpacing* cellSpacingStyle;
kidFrame->GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)cellSpacingStyle));
cellSpacingStyle->CalcBorderPaddingFor(kidFrame, borderPadding);
// For the initial reflow 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
@ -1437,7 +1431,7 @@ void nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext,
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
aCellFrame->SizeTo(aPresContext, cellSize.width, aAvailableHeight);
aCellFrame->VerticallyAlignChild(aPresContext);
aCellFrame->VerticallyAlignChild(aPresContext, aReflowState);
aCellFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}

View File

@ -710,7 +710,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
// spans. Set the cell frame's height
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
// Realign cell content based on new height
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext, aReflowState);
}
else {
// the cell's height is larger than the available space of the rows it

View File

@ -80,9 +80,10 @@ BasicTableLayoutStrategy::~BasicTableLayoutStrategy()
MOZ_COUNT_DTOR(BasicTableLayoutStrategy);
}
PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxWidth)
PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxWidth,
const nsHTMLReflowState& aReflowState)
{
ContinuingFrameCheck();
@ -94,29 +95,27 @@ PRBool BasicTableLayoutStrategy::Initialize(nsIPresContext* aPresContext,
mCellSpacingTotal = 0;
mCols = mTableFrame->GetEffectiveCOLSAttribute();
// assign the width of all fixed-width columns
AssignPreliminaryColumnWidths(aPresContext, aMaxWidth);
AssignPreliminaryColumnWidths(aPresContext, aMaxWidth, aReflowState);
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
if (nsnull != aMaxElementSize) {
SetMaxElementSize(aMaxElementSize);
SetMaxElementSize(aMaxElementSize, aReflowState.mComputedPadding);
}
return result;
}
void BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize)
void
BasicTableLayoutStrategy::SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)
{
if (nsnull != aMaxElementSize) {
aMaxElementSize->height = 0;
nsMargin borderPadding;
const nsStylePosition* tablePosition;
const nsStyleSpacing* tableSpacing;
mTableFrame->GetStyleData(eStyleStruct_Position, ((const nsStyleStruct *&)tablePosition));
mTableFrame->GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
mTableFrame->GetTableBorder(borderPadding);
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aPadding;
nscoord horBorderPadding = borderPadding.left + borderPadding.right;
if (tablePosition->mWidth.GetUnit() == eStyleUnit_Coord) {
aMaxElementSize->width = tablePosition->mWidth.GetCoordValue();
@ -187,11 +186,8 @@ BasicTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aPresCont
// reduce the maxWidth by border and padding, since we will be dealing with content width
// XXX should this be done in aMaxWidthIn by the caller?
if (maxWidth != NS_UNCONSTRAINEDSIZE) {
const nsStyleSpacing* spacing;
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
nsMargin borderPadding;
spacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
maxWidth -= borderPadding.left + borderPadding.right;
maxWidth -= aReflowState.mComputedBorderPadding.left +
aReflowState.mComputedBorderPadding.right;
maxWidth = PR_MAX(0, maxWidth);
}
// initialize the col percent and cell percent values to 0.
@ -448,11 +444,12 @@ nscoord GetConstrainedWidth(nsTableColFrame* colFrame,
#define LIMIT_NONE 2
void
BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct)
BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct,
nscoord aPercentBase)
{
if (!aCellFrame || (aColIndex < 0) || (aColIndex < 0) || (aColSpan < 0)) {
NS_ASSERTION(PR_FALSE, "ComputeColspanWidths called incorrectly");
@ -472,12 +469,8 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
aCellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition);
if (eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) {
// need to add padding into fixed width
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(aCellFrame, paddingMargin);
nscoord padding = paddingMargin.left + paddingMargin.right;
cellWidth = cellPosition->mWidth.GetCoordValue() + padding;
nsMargin padding = nsTableFrame::GetPadding(nsSize(aPercentBase, 0), aCellFrame);
cellWidth = cellPosition->mWidth.GetCoordValue() + padding.left + padding.right;
cellWidth = PR_MAX(cellWidth, aCellFrame->GetPass1MaxElementSize().width);
}
}
@ -691,10 +684,17 @@ BasicTableLayoutStrategy::ComputeColspanWidths(PRInt32 aWidthIndex,
return result;
}
// XXX percent left and right padding are not figured in the calculations
// The table frame needs to be used as the percent base because the reflow
// state may have an unconstrained width. There should probably be a frame
// state bit indicating that horizontal padding is percentage based.
// Determine min, desired, fixed, and proportional sizes for the cols and
// and calculate min/max table width
PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth)
PRBool
BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aMaxWidth,
const nsHTMLReflowState& aReflowState)
{
if (gsDebugAssign) {printf("AssignPrelimColWidths en max=%d count=%d \n", aMaxWidth, gsDebugCount++); mTableFrame->Dump(aPresContext, PR_FALSE, PR_TRUE, PR_FALSE);}
PRBool rv = PR_FALSE;
@ -753,11 +753,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
nscoord coordValue = cellPosition->mWidth.GetCoordValue();
if (coordValue > 0) { // ignore if width == 0
// need to add padding into fixed width
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
nscoord newFixWidth = coordValue + paddingMargin.left + paddingMargin.right;
nsSize percentBase(aReflowState.mComputedWidth, 0);
nsMargin padding = nsTableFrame::GetPadding(percentBase, cellFrame);
nscoord newFixWidth = coordValue + padding.left + padding.right;
// 2nd part of condition is Nav Quirk like below
if ((newFixWidth > fixWidth) || ((newFixWidth == fixWidth) && (desContributor == cellFrame))) {
fixWidth = newFixWidth;
@ -864,7 +862,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
}
// set MIN_ADJ, DES_ADJ, FIX_ADJ
for (PRInt32 widthX = 0; widthX < NUM_MAJOR_WIDTHS; widthX++) {
ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE);
ComputeColspanWidths(widthX, cellFrame, colX, colSpan, PR_FALSE, aReflowState.mComputedWidth);
}
}
}
@ -894,8 +892,9 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
}
// Determine percentage col widths for each col frame
nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
PRBool aTableIsAutoWidth)
nscoord
BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
PRBool aTableIsAutoWidth)
{
PRInt32 numRows = mTableFrame->GetRowCount();
PRInt32 numCols = mTableFrame->GetColCount();
@ -1026,12 +1025,9 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
maxColPctWidth = NSToCoordRound( ((float)basis) * maxColPct );
percentContributor = cellFrame;
if (!mIsNavQuirksMode) {
// need to add padding
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
maxColPctWidth += paddingMargin.left + paddingMargin.right;
// need to add padding
nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame);
maxColPctWidth += padding.left + padding.right;
}
}
}
@ -1082,11 +1078,8 @@ nscoord BasicTableLayoutStrategy::AssignPercentageColumnWidths(nscoord aBasisIn,
cellPctWidth = NSToCoordRound( ((float)basis) * cellPct );
if (!mIsNavQuirksMode) {
// need to add padding
const nsStyleSpacing* spacing;
cellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin paddingMargin;
spacing->CalcPaddingFor(cellFrame, paddingMargin);
cellPctWidth += paddingMargin.left + paddingMargin.right;
nsMargin padding = nsTableFrame::GetPadding(nsSize(basis, 0), cellFrame);
cellPctWidth += padding.left + padding.right;
}
}
if (cellPctWidth > 0) {

View File

@ -58,14 +58,16 @@ public:
* in the table (content, structure, or style)
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
*/
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxSize);
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aMaxSize,
const nsHTMLReflowState& aReflowState);
/** compute the max element size of the table.
* assumes that Initialize has been called
*/
virtual void SetMaxElementSize(nsSize* aMaxElementSize);
virtual void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding);
void SetMinAndMaxTableContentWidths();
@ -99,8 +101,9 @@ protected:
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth);
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState);
/**
* Calculate the adjusted widths (min, desired, fixed, or pct) for a cell
@ -115,7 +118,8 @@ protected:
nsTableCellFrame* aCellFrame,
PRInt32 aColIndex,
PRInt32 aColSpan,
PRBool aConsiderPct);
PRBool aConsiderPct,
nscoord aPercentBase);
/**
* main helper for above. For min width calculations, it can get called up to

View File

@ -56,8 +56,10 @@ PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIPresContext* aP
* otherwise the cell get a proportion of the remaining space
* as determined by the table width attribute. If no table width attribute, it gets 0 width
*/
PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth)
PRBool
FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState)
{
// NS_ASSERTION(aComputedWidth != NS_UNCONSTRAINEDSIZE, "bad computed width");
const nsStylePosition* tablePosition;
@ -65,17 +67,15 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
PRBool tableIsFixedWidth = eStyleUnit_Coord == tablePosition->mWidth.GetUnit() ||
eStyleUnit_Percent == tablePosition->mWidth.GetUnit();
const nsStyleSpacing* tableSpacing;
mTableFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct*&)tableSpacing);
nsMargin borderPadding;
tableSpacing->CalcBorderPaddingFor(mTableFrame, borderPadding);
PRInt32 numCols = mTableFrame->GetColCount();
PRInt32 colX;
// availWidth is used as the basis for percentage width columns. It is aComputedWidth
// minus table border, padding, & cellspacing
nscoord availWidth = aComputedWidth - borderPadding.left - borderPadding.right -
((numCols + 1) * mTableFrame->GetCellSpacingX());
nscoord availWidth = (NS_UNCONSTRAINEDSIZE == aComputedWidth)
? NS_UNCONSTRAINEDSIZE
: aComputedWidth - aReflowState.mComputedBorderPadding.left -
aReflowState.mComputedBorderPadding.right -
((numCols + 1) * mTableFrame->GetCellSpacingX());
PRInt32 specifiedCols = 0; // the number of columns whose width is given
nscoord totalColWidth = 0; // the sum of the widths of the columns
@ -106,7 +106,7 @@ PRBool FixedTableLayoutStrategy::AssignPreliminaryColumnWidths(nsIPresContext* a
} // get the percentage width
else if ((eStyleUnit_Percent == colPosition->mWidth.GetUnit()) &&
(aComputedWidth != NS_UNCONSTRAINEDSIZE)) {
// Only apply percentages if we're unconstrained.
// Only apply percentages if we're constrained.
float percent = colPosition->mWidth.GetPercentValue();
colWidths[colX] = NSToCoordRound(percent * (float)availWidth);
}

View File

@ -96,8 +96,9 @@ protected:
* @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error
*
*/
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth);
virtual PRBool AssignPreliminaryColumnWidths(nsIPresContext* aPresContext,
nscoord aComputedWidth,
const nsHTMLReflowState& aReflowState);
};

View File

@ -29,6 +29,7 @@
class nsIPresContext;
class nsIStyleContext;
struct nsHTMLReflowState;
struct nsMargin;
class nsTableCellFrame;
class nsStyleCoord;
class nsISizeOfHandler;
@ -41,14 +42,16 @@ public:
* @param aMaxElementSize [OUT] if not null, the max element size is computed and returned in this param
* @param aComputedWidth the computed size of the table
*/
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aComputedWidth)=0;
virtual PRBool Initialize(nsIPresContext* aPresContext,
nsSize* aMaxElementSize,
nscoord aComputedWidth,
const nsHTMLReflowState& aBorderPadding)=0;
/** compute the max-element-size for the table
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
*/
virtual void SetMaxElementSize(nsSize* aMaxElementSize)=0;
virtual void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)=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.

View File

@ -436,19 +436,17 @@ void nsTableCellFrame::SetBorderEdge(PRUint8 aSide,
* Align the cell's child frame within the cell
*
*/
void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext)
void nsTableCellFrame::VerticallyAlignChild(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
const nsStyleText* textStyle =
(const nsStyleText*)mStyleContext->GetStyleData(eStyleStruct_Text);
/* XXX: remove tableFrame when border-collapse inherits */
nsTableFrame* tableFrame=nsnull;
nsTableFrame* tableFrame = nsnull;
(void) nsTableFrame::GetTableFrame(this, tableFrame);
nsMargin borderPadding;
GetCellBorder (borderPadding, tableFrame);
nsMargin padding;
spacing->GetPadding(padding);
nsMargin padding = nsTableFrame::GetPadding(aReflowState, this);
borderPadding += padding;
nscoord topInset = borderPadding.top;
@ -604,9 +602,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
/* XXX: remove tableFrame when border-collapse inherits */
nsTableFrame* tableFrame=nsnull;
rv = nsTableFrame::GetTableFrame(this, tableFrame);
nsMargin padding;
spacing->GetPadding(padding);
nsMargin borderPadding = padding;
nsMargin borderPadding = aReflowState.mComputedPadding;
nsMargin border;
GetCellBorder(border, tableFrame);
if ((NS_UNCONSTRAINEDSIZE == availSize.width) || !GetContentEmpty()) {
@ -681,6 +677,14 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
if (eReflowReason_Initial == aReflowState.reason) {
kidOrigin.MoveTo(leftInset, topInset);
} else {
// handle percent padding-left which was 0 during initial reflow
if (eStyleUnit_Percent == aReflowState.mStyleSpacing->mPadding.GetLeftUnit()) {
nsRect kidRect;
firstKid->GetRect(kidRect);
// only move in the x direction for the same reason as above
kidOrigin.MoveTo(leftInset, kidRect.y);
firstKid->MoveTo(aPresContext, leftInset, kidRect.y);
}
firstKid->GetOrigin(kidOrigin);
}
if (nsDebugTable::gRflArea) nsTableFrame::DebugReflow("Area::Rfl en", firstKid, &kidReflowState, nsnull);
@ -733,7 +737,7 @@ NS_METHOD nsTableCellFrame::Reflow(nsIPresContext* aPresContext,
nscoord spacingX = tableFrame->GetCellSpacingX();
nscoord spacingExtra = spacingX * (colspan - 1);
smallestMinWidth += spacingExtra;
if (padding.left > 0) {
if (aReflowState.mComputedPadding.left > 0) {
smallestMinWidth -= onePixel;
}
}
@ -1090,7 +1094,9 @@ PRUint8 nsTableCellFrame::GetOpposingEdge(PRUint8 aEdge)
return result;
}
void nsTableCellFrame::GetCellBorder(nsMargin &aBorder, nsTableFrame *aTableFrame)
void
nsTableCellFrame::GetCellBorder(nsMargin& aBorder,
nsTableFrame* aTableFrame)
{
aBorder.left = aBorder.right = aBorder.top = aBorder.bottom = 0;
if (nsnull==aTableFrame) {

View File

@ -137,7 +137,8 @@ public:
NS_IMETHOD SizeOf(nsISizeOfHandler* aSizer, PRUint32* aResult) const;
#endif
virtual void VerticallyAlignChild(nsIPresContext* aPresContext);
virtual void VerticallyAlignChild(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
/**
* return the cell's specified row span. this is what was specified in the

View File

@ -354,6 +354,13 @@ nsTableFrame::SetInitialChildList(nsIPresContext* aPresContext,
return rv;
}
NS_IMETHODIMP
nsTableFrame::IsPercentageBase(PRBool& aBase) const
{
aBase = PR_TRUE;
return NS_OK;
}
void nsTableFrame::AttributeChangedFor(nsIPresContext* aPresContext,
nsIFrame* aFrame,
nsIContent* aContent,
@ -1393,9 +1400,7 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresCon
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nsSize kidMaxElementSize;
((nsTableRowGroupFrame*)kidFrame)->GetMaxElementSize(kidMaxElementSize);
@ -1440,19 +1445,18 @@ nsresult nsTableFrame::AdjustSiblingsAfterReflow(nsIPresContext* aPresCon
return NS_OK;
}
void nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight)
void
nsTableFrame::SetColumnDimensions(nsIPresContext* aPresContext,
nscoord aHeight,
const nsMargin& aBorderPadding)
{
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
spacing->CalcBorderPaddingFor(this, borderPadding);
nscoord colHeight = aHeight -= borderPadding.top + borderPadding.bottom;
nscoord colHeight = aHeight -= aBorderPadding.top + aBorderPadding.bottom;
nscoord cellSpacingX = GetCellSpacingX();
nscoord halfCellSpacingX = NSToCoordRound(((float)cellSpacingX) / (float)2);
nsIFrame* colGroupFrame = mColGroups.FirstChild();
PRInt32 colX = 0;
nsPoint colGroupOrigin(borderPadding.left, borderPadding.top);
nsPoint colGroupOrigin(aBorderPadding.left, aBorderPadding.top);
PRInt32 numCols = GetColCount();
while (nsnull != colGroupFrame) {
nscoord colGroupWidth = 0;
@ -1515,6 +1519,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize->height = 0;
}
aStatus = NS_FRAME_COMPLETE;
// XXX yank this nasty code and see what happens, and then yank other
// similar calls to InvalidateFirstPassCache.
if ((NS_UNCONSTRAINEDSIZE == aReflowState.availableWidth) &&
(this == (nsTableFrame *)GetFirstInFlow())) {
InvalidateFirstPassCache();
@ -1545,7 +1551,8 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
}
if (mTableLayoutStrategy && (needsRecalc || !IsColumnWidthsValid())) {
nscoord boxWidth = CalcBorderBoxWidth(aReflowState);
mTableLayoutStrategy->Initialize(aPresContext, aDesiredSize.maxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aDesiredSize.maxElementSize,
boxWidth, aReflowState);
mBits.mColumnWidthsValid = PR_TRUE; //so we don't do this a second time below
}
@ -1556,7 +1563,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
aDesiredSize.maxElementSize);
// assign table width
SetTableWidth(aPresContext);
SetTableWidth(aPresContext, aReflowState);
}
if ((eReflowReason_Initial == aReflowState.reason) &&
@ -1606,7 +1613,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
// set aDesiredSize and aMaxElementSize
}
SetColumnDimensions(aPresContext, aDesiredSize.height);
SetColumnDimensions(aPresContext, aDesiredSize.height, aReflowState.mComputedBorderPadding);
if (pass1MaxElementSize) {
aDesiredSize.maxElementSize = pass1MaxElementSize;
}
@ -1621,7 +1628,7 @@ NS_METHOD nsTableFrame::Reflow(nsIPresContext* aPresContext,
if (isAutoWidth && !IsMaximumWidthValid()) {
// Initialize the strategy and have it compute the natural size of
// the table
mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE);
mTableLayoutStrategy->Initialize(aPresContext, nsnull, NS_UNCONSTRAINEDSIZE, aReflowState);
// Now the maximum width is valid
mBits.mMaximumWidthValid = PR_TRUE;
@ -1918,13 +1925,9 @@ NS_METHOD nsTableFrame::ResizeReflowPass2(nsIPresContext* aPresContext,
// set out param
aStatus = NS_FRAME_COMPLETE;
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding); // this gets the max border thickness at each edge
nsMargin padding;
mySpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, aReflowState, borderPadding);
@ -1981,13 +1984,9 @@ void nsTableFrame::ComputePercentBasisForRows(const nsHTMLReflowState& aReflowSt
nscoord height = CalcBorderBoxHeight(aReflowState, PR_TRUE);
if ((height > 0) && (height != NS_UNCONSTRAINEDSIZE)) {
// exclude our border and padding
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding(0,0,0,0);
// XXX handle percentages
if (spacing->GetBorderPadding(borderPadding)) {
height -= borderPadding.top + borderPadding.bottom;
}
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
height -= borderPadding.top + borderPadding.bottom;
// exclude cell spacing for all rows
height -= (1 + GetRowCount()) * GetCellSpacingY();
height = PR_MAX(0, height);
@ -2183,19 +2182,6 @@ NS_METHOD nsTableFrame::AdjustForCollapsingCols(nsIPresContext* aPresContext,
return NS_OK;
}
NS_METHOD nsTableFrame::GetBorderPlusMarginPadding(nsMargin& aResult)
{
const nsStyleSpacing* mySpacing = (const nsStyleSpacing*)
mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding);
nsMargin padding;
mySpacing->GetPadding(padding);
borderPadding += padding;
aResult = borderPadding;
return NS_OK;
}
// Sets the starting column index for aColGroupFrame and the siblings frames that
// follow
void
@ -2471,9 +2457,12 @@ NS_METHOD nsTableFrame::IncrementalReflow(nsIPresContext* aPresContext,
}
reflowState.availableWidth = pass1Width;
nsMargin borderPadding;
GetBorderPlusMarginPadding(borderPadding);
InnerTableReflowState state(aPresContext, reflowState, borderPadding);
// get margin + border + padding
nsMargin borderMarginPadding;
GetTableBorder (borderMarginPadding);
borderMarginPadding += aReflowState.mComputedMargin + aReflowState.mComputedPadding;
InnerTableReflowState state(aPresContext, reflowState, borderMarginPadding);
// determine if this frame is the target or not
nsIFrame *target=nsnull;
@ -2659,9 +2648,7 @@ nsTableFrame::RecoverState(InnerTableReflowState& aReflowState,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nsSize kidMaxElementSize;
((nsTableRowGroupFrame*)frame)->GetMaxElementSize(kidMaxElementSize);
@ -2723,9 +2710,7 @@ NS_METHOD nsTableFrame::IR_TargetIsChild(nsIPresContext* aPresContext,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nscoord kidWidth = kidMaxElementSize.width + borderPadding.left + borderPadding.right + cellSpacing*2;
aDesiredSize.maxElementSize->width = PR_MAX(aDesiredSize.maxElementSize->width, kidWidth);
@ -2854,9 +2839,7 @@ void nsTableFrame::PlaceChild(nsIPresContext* aPresContext,
GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)tableSpacing));
nsMargin borderPadding;
GetTableBorder (borderPadding); // gets the max border thickness for each edge
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
nscoord cellSpacing = GetCellSpacingX();
nscoord kidWidth = aKidMaxElementSize.width + borderPadding.left + borderPadding.right + cellSpacing*2;
aMaxElementSize->width = PR_MAX(aMaxElementSize->width, kidWidth);
@ -2922,9 +2905,7 @@ NS_METHOD nsTableFrame::ReflowMappedChildren(nsIPresContext* aPresContext,
GetTableBorderForRowGroup(GetRowGroupFrameFor(kidFrame, childDisplay), borderPadding);
const nsStyleSpacing* tableSpacing;
GetStyleData(eStyleStruct_Spacing, ((const nsStyleStruct *&)tableSpacing));
nsMargin padding;
tableSpacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.reflowState.mComputedPadding;
// Reflow the child into the available space
nsHTMLReflowState kidReflowState(aPresContext, aReflowState.reflowState,
@ -3219,13 +3200,13 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
mTableLayoutStrategy = new FixedTableLayoutStrategy(this);
else
mTableLayoutStrategy = new BasicTableLayoutStrategy(this, eCompatibility_NavQuirks == mode);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth, aReflowState);
mBits.mColumnWidthsValid=PR_TRUE;
}
// fixed-layout tables need to reinitialize the layout strategy. When there are scroll bars
// reflow gets called twice and the 2nd time has the correct space available.
else if (!IsAutoLayout(&aReflowState)) {
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth);
mTableLayoutStrategy->Initialize(aPresContext, aMaxElementSize, boxWidth, aReflowState);
}
mTableLayoutStrategy->BalanceColumnWidths(aPresContext, mStyleContext, aReflowState, maxWidth);
@ -3243,7 +3224,8 @@ void nsTableFrame::BalanceColumnWidths(nsIPresContext* aPresContext,
add in table insets
set rect
*/
void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState)
{
NS_ASSERTION(nsnull==mPrevInFlow, "never ever call me on a continuing frame!");
nsTableCellMap* cellMap = GetCellMap();
@ -3279,9 +3261,7 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin borderPadding;
GetTableBorder (borderPadding); // this gets the max border value at every edge
nsMargin padding;
spacing->GetPadding(padding);
borderPadding += padding;
borderPadding += aReflowState.mComputedPadding;
nscoord rightInset = borderPadding.right;
nscoord leftInset = borderPadding.left;
@ -3293,7 +3273,8 @@ void nsTableFrame::SetTableWidth(nsIPresContext* aPresContext)
}
// XXX percentage based margin/border/padding
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame, const nsIID& aIID)
nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame,
const nsIID& aIID)
{
nscoord result = 0;
if (!aFrame) {
@ -3305,8 +3286,8 @@ nscoord GetVerticalMarginBorderPadding(nsIFrame* aFrame, const nsIID& aIID)
nsIHTMLContent* htmlContent = nsnull;
rv = iContent->QueryInterface(aIID, (void **)&htmlContent);
if (htmlContent && NS_SUCCEEDED(rv)) {
nsIStyleContext* styleContext;
aFrame->GetStyleContext(&styleContext); // XXX fix this leak
nsCOMPtr<nsIStyleContext> styleContext;
aFrame->GetStyleContext(getter_AddRefs(styleContext));
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)styleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
@ -3506,13 +3487,8 @@ nscoord nsTableFrame::ComputeDesiredHeight(nsIPresContext* aPresContext
// the first row group's y position starts inside our padding
const nsStyleSpacing* spacing =
(const nsStyleSpacing*)mStyleContext->GetStyleData(eStyleStruct_Spacing);
nsMargin margin(0,0,0,0);
if (spacing->GetBorder(margin)) { // XXX see bug 10636 and handle percentages
rowGroupYPos = margin.top;
}
if (spacing->GetPadding(margin)) { // XXX see bug 10636 and handle percentages
rowGroupYPos += margin.top;
}
nsMargin borderPadding = aReflowState.mComputedBorderPadding;
rowGroupYPos = borderPadding.top;
firstRowGroupFrame = childFrame;
}
}
@ -3849,6 +3825,91 @@ void nsTableFrame::MapBorderMarginPadding(nsIPresContext* aPresContext)
#endif
}
nscoord
CalcPercentPadding(nscoord aBasis,
nsStyleCoord aStyleCoord)
{
float percent = (NS_UNCONSTRAINEDSIZE == aBasis)
? 0 : aStyleCoord.GetPercentValue();
return NSToCoordRound(((float)aBasis) * percent);
}
void
GetPaddingFor(const nsSize& aBasis,
const nsStyleSpacing& aSpacing,
nsMargin& aPadding)
{
nsStyleCoord styleCoord;
aSpacing.mPadding.GetTop(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetTopUnit()) {
aPadding.top = CalcPercentPadding(aBasis.height, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.top = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetRight(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetRightUnit()) {
aPadding.right = CalcPercentPadding(aBasis.width, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.right = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetBottom(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetBottomUnit()) {
aPadding.bottom = CalcPercentPadding(aBasis.height, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.bottom = styleCoord.GetCoordValue();
}
aSpacing.mPadding.GetLeft(styleCoord);
if (eStyleUnit_Percent == aSpacing.mPadding.GetLeftUnit()) {
aPadding.left = CalcPercentPadding(aBasis.width, styleCoord);
}
else if (eStyleUnit_Coord == aSpacing.mPadding.GetTopUnit()) {
aPadding.left = styleCoord.GetCoordValue();
}
}
nsMargin
nsTableFrame::GetPadding(const nsHTMLReflowState& aReflowState,
const nsTableCellFrame* aCellFrame)
{
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin padding(0,0,0,0);
if (!spacing->GetPadding(padding)) {
const nsHTMLReflowState* parentRS = aReflowState.parentReflowState;
while (parentRS) {
if (parentRS->frame) {
nsCOMPtr<nsIAtom> frameType;
parentRS->frame->GetFrameType(getter_AddRefs(frameType));
if (nsLayoutAtoms::tableFrame == frameType.get()) {
nsSize basis(parentRS->mComputedWidth, parentRS->mComputedHeight);
GetPaddingFor(basis, *spacing, padding);
break;
}
}
parentRS = parentRS->parentReflowState;
}
}
return padding;
}
nsMargin
nsTableFrame::GetPadding(const nsSize& aBasis,
const nsTableCellFrame* aCellFrame)
{
const nsStyleSpacing* spacing;
aCellFrame->GetStyleData(eStyleStruct_Spacing,(const nsStyleStruct *&)spacing);
nsMargin padding(0,0,0,0);
if (!spacing->GetPadding(padding)) {
GetPaddingFor(aBasis, *spacing, padding);
}
return padding;
}
NS_METHOD nsTableFrame::GetCellMarginData(nsTableCellFrame* aKidFrame, nsMargin& aMargin)
{
@ -4169,10 +4230,12 @@ nscoord nsTableFrame::GetMaxTableContentWidth()
return result;
}
void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize)
void nsTableFrame::SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding)
{
if (nsnull!=mTableLayoutStrategy)
mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize);
if (nsnull!=mTableLayoutStrategy) {
mTableLayoutStrategy->SetMaxElementSize(aMaxElementSize, aPadding);
}
}

View File

@ -106,6 +106,8 @@ public:
nsIFrame* aPrevInFlow);
NS_IMETHOD IsPercentageBase(PRBool& aBase) const;
static nsresult AddTableDirtyReflowCommand(nsIPresContext* aPresContext,
nsIFrame* aTableFrame);
/*
@ -228,6 +230,12 @@ public:
*/
NS_METHOD GetColumnFrame(PRInt32 aColIndex, nsTableColFrame *&aColFrame);
static nsMargin GetPadding(const nsHTMLReflowState& aReflowState,
const nsTableCellFrame* aCellFrame);
static nsMargin GetPadding(const nsSize& aBasis,
const nsTableCellFrame* aCellFrame);
nsFrameList& GetColGroups();
/** return PR_TRUE if the column width information has been set */
@ -404,8 +412,6 @@ public:
PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
NS_METHOD GetBorderPlusMarginPadding(nsMargin& aResult);
PRBool HasNonPercentSpanningPercent() const;
void SetHasNonPercentSpanningPercent(PRBool aValue);
@ -624,7 +630,8 @@ protected:
nsSize* aMaxElementSize);
/** sets the width of the table according to the computed widths of each column. */
virtual void SetTableWidth(nsIPresContext* aPresContext);
virtual void SetTableWidth(nsIPresContext* aPresContext,
const nsHTMLReflowState& aReflowState);
/** returns PR_TRUE if the cached pass 1 data is still valid */
virtual PRBool IsFirstPassValid() const;
@ -732,7 +739,9 @@ public:
protected:
void SetColumnDimensions(nsIPresContext* aPresContext, nscoord aHeight);
void SetColumnDimensions(nsIPresContext* aPresContext,
nscoord aHeight,
const nsMargin& aReflowState);
#ifdef NS_DEBUG
/** for debugging only
@ -789,7 +798,8 @@ public: /* ----- Cell Map public methods ----- */
/** compute the max-element-size for the table
* @param aMaxElementSize [OUT] width field set to the min legal width of the table
*/
void SetMaxElementSize(nsSize* aMaxElementSize);
void SetMaxElementSize(nsSize* aMaxElementSize,
const nsMargin& aPadding);
/** returns PR_TRUE if table layout requires a preliminary pass over the content */
virtual PRBool IsAutoLayout(const nsHTMLReflowState* aReflowState = nsnull);

View File

@ -386,39 +386,6 @@ PRBool nsTableOuterFrame::NeedsReflow(const nsHTMLReflowState& aReflowState)
nsresult nsTableOuterFrame::RecoverState(OuterTableReflowState& aReflowState,
nsIFrame* aKidFrame)
{
#if 0
// Get aKidFrame's previous sibling
nsIFrame* prevKidFrame = nsnull;
for (nsIFrame* frame = mFrames.FirstChild(); frame != aKidFrame;) {
prevKidFrame = frame;
frame->GetNextSibling(frame);
}
if (nsnull != prevKidFrame) {
nsRect rect;
// Set our running y-offset
prevKidFrame->GetRect(rect);
aReflowState.y = rect.YMost();
// Adjust the available space
if (PR_FALSE == aReflowState.unconstrainedHeight) {
aReflowState.availSize.height -= aReflowState.y;
}
// Get the previous frame's bottom margin
const nsStyleSpacing* kidSpacing;
prevKidFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)kidSpacing);
nsMargin margin;
kidSpacing->CalcMarginFor(prevKidFrame, margin);
if (margin.bottom < 0) {
aReflowState.prevMaxNegBottomMargin = -margin.bottom;
} else {
aReflowState.prevMaxPosBottomMargin = margin.bottom;
}
}
#endif
aReflowState.y = 0;
// Set the inner table max size
@ -584,7 +551,8 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
innerTableSize.SizeTo(innerSize.width, innerSize.height);
// set maxElementSize width if requested
if (nsnull != aDesiredSize.maxElementSize) {
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize,
aReflowState.reflowState.mComputedPadding);
if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
@ -599,7 +567,7 @@ nsresult nsTableOuterFrame::IR_TargetIsCaptionFrame(nsIPresContext* aPres
// regardless of what we've done up to this point, place the caption and inner table
rv = SizeAndPlaceChildren(aPresContext, innerTableSize,
nsSize (captionSize.width, captionSize.height),
aReflowState);
aReflowState, captionReflowState.mComputedMargin);
return rv;
}
@ -707,7 +675,6 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
{
nsresult rv = NS_OK;
const nsStyleTable* captionTableStyle=nsnull;
nsMargin captionMargin;
// remember the old width and height
nsRect priorInnerTableRect;
mInnerTableFrame->GetRect(priorInnerTableRect);
@ -742,9 +709,10 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
mInnerTableMaximumWidth = innerSize.mMaximumWidth;
}
nsMargin captionMargin(0,0,0,0);
// if there is a caption and the width or height of the inner table changed from a successful reflow,
// then reflow or move the caption as needed
if ((nsnull != mCaptionFrame) && (PR_TRUE==NS_SUCCEEDED(rv))) {
if ((nsnull != mCaptionFrame) && NS_SUCCEEDED(rv)) {
// remember the old caption height
nsRect oldCaptionRect;
mCaptionFrame->GetRect(oldCaptionRect);
@ -761,19 +729,22 @@ nsresult nsTableOuterFrame::IR_InnerTableReflow(nsIPresContext* aPresCont
rv = mCaptionFrame->Reflow(aPresContext, captionSize, captionReflowState, aStatus);
mCaptionFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
captionWasReflowed = PR_TRUE;
if ((oldCaptionRect.height!=captionSize.height) ||
(oldCaptionRect.width!=captionSize.width)) {
captionDimChanged=PR_TRUE;
if ((oldCaptionRect.height != captionSize.height) ||
(oldCaptionRect.width != captionSize.width)) {
captionDimChanged = PR_TRUE;
}
captionMargin = captionReflowState.mComputedMargin;
}
// XXX: should just call SizeAndPlaceChildren regardless
// find where to place the caption
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
mCaptionFrame->GetStyleData(eStyleStruct_Text, ((const nsStyleStruct *&)captionTableStyle));
if ((priorInnerTableRect.height!=innerSize.height) ||
(PR_TRUE==captionDimChanged)) {
if ((priorInnerTableRect.height != innerSize.height) || captionDimChanged) {
if (!captionWasReflowed) { // get the computed margin by constructing a reflow state
nsHTMLReflowState rState(aPresContext, aReflowState.reflowState, mCaptionFrame,
nsSize(innerSize.width, aReflowState.reflowState.availableHeight),
eReflowReason_Resize);
captionMargin = rState.mComputedMargin;
}
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
@ -867,7 +838,8 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresConte
}
// set maxElementSize width if requested
if (nsnull != aDesiredSize.maxElementSize) {
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize);
((nsTableFrame *)mInnerTableFrame)->SetMaxElementSize(aDesiredSize.maxElementSize,
aReflowState.reflowState.mComputedPadding);
if (mMinCaptionWidth > aDesiredSize.maxElementSize->width) {
aDesiredSize.maxElementSize->width = mMinCaptionWidth;
}
@ -876,7 +848,7 @@ nsresult nsTableOuterFrame::IR_CaptionInserted(nsIPresContext* aPresConte
rv = SizeAndPlaceChildren(aPresContext,
nsSize (innerSize.width, innerSize.height),
nsSize (captionSize.width, captionSize.height),
aReflowState);
aReflowState, captionReflowState.mComputedMargin);
return rv;
}
@ -891,23 +863,20 @@ PRBool nsTableOuterFrame::IR_CaptionChangedAxis(const nsStyleTable* aOldStyle,
nsresult nsTableOuterFrame::SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState)
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin)
{
nsresult rv = NS_OK;
// find where to place the caption
nsMargin captionMargin;
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
nscoord captionY = aCaptionMargin.top;
const nsStyleTable* captionTableStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Table, ((const nsStyleStruct *&)captionTableStyle));
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
captionY += aInnerSize.height;
}
// Place the caption
nsRect captionRect(captionMargin.left, captionY, 0, 0);
nsRect captionRect(aCaptionMargin.left, captionY, 0, 0);
captionRect.SizeTo(aCaptionSize.width, aCaptionSize.height);
mCaptionFrame->SetRect(aPresContext, captionRect);
@ -916,10 +885,10 @@ nsresult nsTableOuterFrame::SizeAndPlaceChildren(nsIPresContext* aPresCon
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
// bottom caption
innerY = 0;
aReflowState.y = captionRect.YMost() + captionMargin.bottom;
aReflowState.y = captionRect.YMost() + aCaptionMargin.bottom;
}
else { // top caption
innerY = captionRect.YMost() + captionMargin.bottom;
innerY = captionRect.YMost() + aCaptionMargin.bottom;
aReflowState.y = innerY + aInnerSize.height;
}
nsRect innerRect(0, innerY, aInnerSize.width, aInnerSize.height);
@ -1030,15 +999,14 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
// place the caption and the inner table
nscoord innerY = 0;
if (nsnull != mCaptionFrame) {
// Get the caption's margin
nsMargin captionMargin;
const nsStyleSpacing* spacing;
mCaptionFrame->GetStyleData(eStyleStruct_Spacing, (const nsStyleStruct *&)spacing);
spacing->CalcMarginFor(mCaptionFrame, captionMargin);
// construct the caption reflow state
nscoord captionAvailWidth = PR_MAX(innerSize.width, mMinCaptionWidth);
nsHTMLReflowState captionReflowState(aPresContext, state.reflowState, mCaptionFrame,
nsSize(captionAvailWidth, NS_UNCONSTRAINEDSIZE),
eReflowReason_Resize);
// Compute the caption's y-origin
nscoord captionY = captionMargin.top;
nscoord captionY = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.top)
? 0 : captionReflowState.mComputedMargin.top;
const nsStyleTable* captionTableStyle;
mCaptionFrame->GetStyleData(eStyleStruct_Table, ((const nsStyleStruct *&)captionTableStyle));
if (NS_SIDE_BOTTOM == captionTableStyle->mCaptionSide) {
@ -1046,13 +1014,10 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
}
// Reflow the caption. Let it be as high as it wants
nscoord captionAvailWidth = PR_MAX(innerSize.width, mMinCaptionWidth);
nsHTMLReflowState captionReflowState(aPresContext, state.reflowState, mCaptionFrame,
nsSize(captionAvailWidth, NS_UNCONSTRAINEDSIZE),
eReflowReason_Resize);
nsRect captionRect(captionMargin.left, captionY, 0, 0);
nscoord leftCapMargin = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.left)
? 0 : captionReflowState.mComputedMargin.left;
nsRect captionRect(leftCapMargin, captionY, 0, 0);
nsReflowStatus captionStatus;
captionSize.maxElementSize = nsnull;
ReflowChild(mCaptionFrame, aPresContext, captionSize, captionReflowState,
captionRect.x, captionRect.y, 0, captionStatus);
@ -1067,15 +1032,17 @@ NS_METHOD nsTableOuterFrame::Reflow(nsIPresContext* aPresContext,
captionRect.x, captionRect.y, 0);
// Place the inner table
nscoord bottomCapMargin = (NS_AUTOMARGIN == captionReflowState.mComputedMargin.bottom)
? 0 : captionReflowState.mComputedMargin.bottom;
if (NS_SIDE_BOTTOM != captionTableStyle->mCaptionSide) {
// top caption
innerY = captionRect.YMost() + captionMargin.bottom;
innerY = captionRect.YMost() + bottomCapMargin;
state.y = innerY + innerSize.height;
}
else {
// bottom caption
innerY = 0;
state.y = captionRect.YMost() + captionMargin.bottom;
state.y = captionRect.YMost() + bottomCapMargin;
}
}

View File

@ -248,9 +248,10 @@ protected:
/** set the size and the location of both the inner table frame and the caption. */
NS_IMETHOD SizeAndPlaceChildren(nsIPresContext* aPresContext,
const nsSize & aInnerSize,
const nsSize & aCaptionSize,
OuterTableReflowState& aReflowState);
const nsSize& aInnerSize,
const nsSize& aCaptionSize,
OuterTableReflowState& aReflowState,
const nsMargin& aCaptionMargin);
// end Incremental Reflow methods

View File

@ -289,7 +289,7 @@ nsTableRowFrame::DidResize(nsIPresContext* aPresContext,
// But some content crashes when this reflow is issued, to be investigated
//XXX nsReflowStatus status;
//ReflowChild(cellFrame, aPresContext, desiredSize, kidReflowState, status);
((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(aPresContext);
((nsTableCellFrame *)cellFrame)->VerticallyAlignChild(aPresContext, aReflowState);
/* if we're collapsing borders, notify the cell that the border edge length has changed */
if (NS_STYLE_BORDER_COLLAPSE == tableFrame->GetBorderCollapseStyle()) {
((nsTableCellFrame *)(cellFrame))->SetBorderEdgeLength(NS_SIDE_LEFT,
@ -948,12 +948,6 @@ nsTableRowFrame::InitialReflow(nsIPresContext* aPresContext,
nsMargin kidMargin;
aReflowState.tableFrame->GetCellMarginData((nsTableCellFrame *)kidFrame, kidMargin);
// get border padding values
nsMargin borderPadding;
const nsStyleSpacing* cellSpacingStyle;
kidFrame->GetStyleData(eStyleStruct_Spacing , ((const nsStyleStruct *&)cellSpacingStyle));
cellSpacingStyle->CalcBorderPaddingFor(kidFrame, borderPadding);
// For the initial reflow 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
@ -1437,7 +1431,7 @@ void nsTableRowFrame::ReflowCellFrame(nsIPresContext* aPresContext,
ReflowChild(aCellFrame, aPresContext, desiredSize, cellReflowState,
0, 0, NS_FRAME_NO_MOVE_FRAME, aStatus);
aCellFrame->SizeTo(aPresContext, cellSize.width, aAvailableHeight);
aCellFrame->VerticallyAlignChild(aPresContext);
aCellFrame->VerticallyAlignChild(aPresContext, aReflowState);
aCellFrame->DidReflow(aPresContext, NS_FRAME_REFLOW_FINISHED);
}

View File

@ -710,7 +710,7 @@ void nsTableRowGroupFrame::CalculateRowHeights(nsIPresContext* aPresContext,
// spans. Set the cell frame's height
cellFrame->SizeTo(aPresContext, cellFrameSize.width, availHeightOfRowsSpanned);
// Realign cell content based on new height
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext);
((nsTableCellFrame*)cellFrame)->VerticallyAlignChild(aPresContext, aReflowState);
}
else {
// the cell's height is larger than the available space of the rows it