From 1979c23f3b0f3646313b0ce557043f7d4cc1f7af Mon Sep 17 00:00:00 2001 From: "karnaze%netscape.com" Date: Tue, 16 May 2000 22:55:34 +0000 Subject: [PATCH] bug 28811, 29459, 32507 - added flag to reflow state to handle table cells. changed table min and max width calculations to include percent and proportional cells. Include border and padding in min table width calc. git-svn-id: svn://10.0.0.236/trunk@70140 18797224-902f-48f8-a5cc-f745e15eee43 --- .../layout/base/public/nsHTMLReflowState.h | 6 ++++ mozilla/layout/generic/nsHTMLReflowState.cpp | 35 +++++++++++++++---- mozilla/layout/generic/nsHTMLReflowState.h | 6 ++++ .../html/base/src/nsHTMLReflowState.cpp | 35 +++++++++++++++---- .../table/src/BasicTableLayoutStrategy.cpp | 18 +++++++--- .../html/tests/table/bugs/file_list.txt | 2 +- .../tables/BasicTableLayoutStrategy.cpp | 18 +++++++--- 7 files changed, 99 insertions(+), 21 deletions(-) diff --git a/mozilla/layout/base/public/nsHTMLReflowState.h b/mozilla/layout/base/public/nsHTMLReflowState.h index 4fce25dc16f..36e5d258503 100644 --- a/mozilla/layout/base/public/nsHTMLReflowState.h +++ b/mozilla/layout/base/public/nsHTMLReflowState.h @@ -202,6 +202,12 @@ struct nsHTMLReflowState { // set it. if false, the reflow sets alignCharOffset PRPackedBool mUseAlignCharOffset; + // a table cell has a constrained mComputedWidth to accomodate its inner block. + // since it is treated like a containing block for percent calculations, this flag + // indicates not to use mComputedWidth for percent calculations if true. + // it also propogates into descendants whose width is percentage. + PRBool mIsAutoWidthPctBase; + // Cached pointers to the various style structs used during intialization const nsStyleDisplay* mStyleDisplay; const nsStylePosition* mStylePosition; diff --git a/mozilla/layout/generic/nsHTMLReflowState.cpp b/mozilla/layout/generic/nsHTMLReflowState.cpp index dd5d753cc63..b718325833b 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.cpp +++ b/mozilla/layout/generic/nsHTMLReflowState.cpp @@ -170,6 +170,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext, mCompactMarginWidth = 0; mAlignCharOffset = 0; mUseAlignCharOffset = 0; + mIsAutoWidthPctBase = PR_FALSE; frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)mStylePosition); @@ -1509,15 +1510,13 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, // the containingBlockHeight calcuation. if (cbrs->parentReflowState) { nsIFrame* f = cbrs->parentReflowState->frame; - nsIAtom* cbFrameType; - - f->GetFrameType(&cbFrameType); - if (nsLayoutAtoms::scrollFrame == cbFrameType) { + nsCOMPtr fType; + f->GetFrameType(getter_AddRefs(fType)); + if (nsLayoutAtoms::scrollFrame == fType.get()) { // Use the scroll frame's computed height instead aContainingBlockHeight = ((nsHTMLReflowState*)cbrs->parentReflowState)->mComputedHeight; } - NS_IF_RELEASE(cbFrameType); } } @@ -1536,14 +1535,33 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, nsStyleUnit widthUnit = mStylePosition->mWidth.GetUnit(); nsStyleUnit heightUnit = mStylePosition->mHeight.GetUnit(); + nsCOMPtr frameType; + frame->GetFrameType(getter_AddRefs(frameType)); + // Check for a percentage based width and an unconstrained containing // block width if (eStyleUnit_Percent == widthUnit) { - if (NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) { + if ((NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) || + ((cbrs->mIsAutoWidthPctBase) && + (nsLayoutAtoms::tableOuterFrame != frameType.get()) && + (nsLayoutAtoms::tableFrame != frameType.get()))) { // Interpret the width like 'auto' widthUnit = eStyleUnit_Auto; } } + // if the cbrs is an auto width descendant (non table) from a table cell and + // our width may be determined using it, then propogate the flag. + if (cbrs->mIsAutoWidthPctBase) { + if ((eStyleUnit_Auto == widthUnit) || + (eStyleUnit_Percent == widthUnit) || + (eStyleUnit_Inherit == widthUnit)) { + if ((nsLayoutAtoms::tableOuterFrame != frameType.get()) && + (nsLayoutAtoms::tableFrame != frameType.get())) { + mIsAutoWidthPctBase = PR_TRUE; + } + } + } + // Check for a percentage based height and a containing block height // that depends on the content height if (eStyleUnit_Percent == heightUnit) { @@ -1714,6 +1732,11 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, if (eStyleUnit_Inherit == widthUnit) { mComputedWidth = aContainingBlockWidth; } else if (eStyleUnit_Auto == widthUnit) { + if (NS_STYLE_DISPLAY_TABLE_CELL == mStyleDisplay->mDisplay) { + // set the flag to ignore mComputedWidth for percent calculations + // when the cell is a containing block. + mIsAutoWidthPctBase = PR_TRUE; + } mComputedWidth = availableWidth; if (mComputedWidth != NS_UNCONSTRAINEDSIZE) { diff --git a/mozilla/layout/generic/nsHTMLReflowState.h b/mozilla/layout/generic/nsHTMLReflowState.h index 4fce25dc16f..36e5d258503 100644 --- a/mozilla/layout/generic/nsHTMLReflowState.h +++ b/mozilla/layout/generic/nsHTMLReflowState.h @@ -202,6 +202,12 @@ struct nsHTMLReflowState { // set it. if false, the reflow sets alignCharOffset PRPackedBool mUseAlignCharOffset; + // a table cell has a constrained mComputedWidth to accomodate its inner block. + // since it is treated like a containing block for percent calculations, this flag + // indicates not to use mComputedWidth for percent calculations if true. + // it also propogates into descendants whose width is percentage. + PRBool mIsAutoWidthPctBase; + // Cached pointers to the various style structs used during intialization const nsStyleDisplay* mStyleDisplay; const nsStylePosition* mStylePosition; diff --git a/mozilla/layout/html/base/src/nsHTMLReflowState.cpp b/mozilla/layout/html/base/src/nsHTMLReflowState.cpp index dd5d753cc63..b718325833b 100644 --- a/mozilla/layout/html/base/src/nsHTMLReflowState.cpp +++ b/mozilla/layout/html/base/src/nsHTMLReflowState.cpp @@ -170,6 +170,7 @@ nsHTMLReflowState::Init(nsIPresContext* aPresContext, mCompactMarginWidth = 0; mAlignCharOffset = 0; mUseAlignCharOffset = 0; + mIsAutoWidthPctBase = PR_FALSE; frame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct*&)mStylePosition); @@ -1509,15 +1510,13 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, // the containingBlockHeight calcuation. if (cbrs->parentReflowState) { nsIFrame* f = cbrs->parentReflowState->frame; - nsIAtom* cbFrameType; - - f->GetFrameType(&cbFrameType); - if (nsLayoutAtoms::scrollFrame == cbFrameType) { + nsCOMPtr fType; + f->GetFrameType(getter_AddRefs(fType)); + if (nsLayoutAtoms::scrollFrame == fType.get()) { // Use the scroll frame's computed height instead aContainingBlockHeight = ((nsHTMLReflowState*)cbrs->parentReflowState)->mComputedHeight; } - NS_IF_RELEASE(cbFrameType); } } @@ -1536,14 +1535,33 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, nsStyleUnit widthUnit = mStylePosition->mWidth.GetUnit(); nsStyleUnit heightUnit = mStylePosition->mHeight.GetUnit(); + nsCOMPtr frameType; + frame->GetFrameType(getter_AddRefs(frameType)); + // Check for a percentage based width and an unconstrained containing // block width if (eStyleUnit_Percent == widthUnit) { - if (NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) { + if ((NS_UNCONSTRAINEDSIZE == aContainingBlockWidth) || + ((cbrs->mIsAutoWidthPctBase) && + (nsLayoutAtoms::tableOuterFrame != frameType.get()) && + (nsLayoutAtoms::tableFrame != frameType.get()))) { // Interpret the width like 'auto' widthUnit = eStyleUnit_Auto; } } + // if the cbrs is an auto width descendant (non table) from a table cell and + // our width may be determined using it, then propogate the flag. + if (cbrs->mIsAutoWidthPctBase) { + if ((eStyleUnit_Auto == widthUnit) || + (eStyleUnit_Percent == widthUnit) || + (eStyleUnit_Inherit == widthUnit)) { + if ((nsLayoutAtoms::tableOuterFrame != frameType.get()) && + (nsLayoutAtoms::tableFrame != frameType.get())) { + mIsAutoWidthPctBase = PR_TRUE; + } + } + } + // Check for a percentage based height and a containing block height // that depends on the content height if (eStyleUnit_Percent == heightUnit) { @@ -1714,6 +1732,11 @@ nsHTMLReflowState::InitConstraints(nsIPresContext* aPresContext, if (eStyleUnit_Inherit == widthUnit) { mComputedWidth = aContainingBlockWidth; } else if (eStyleUnit_Auto == widthUnit) { + if (NS_STYLE_DISPLAY_TABLE_CELL == mStyleDisplay->mDisplay) { + // set the flag to ignore mComputedWidth for percent calculations + // when the cell is a containing block. + mIsAutoWidthPctBase = PR_TRUE; + } mComputedWidth = availableWidth; if (mComputedWidth != NS_UNCONSTRAINEDSIZE) { diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index 09e05353da4..3666b4d35d4 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -1186,6 +1186,9 @@ nscoord BasicTableLayoutStrategy::GetTableMinWidth() const for (PRInt32 colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); minWidth += PR_MAX(colFrame->GetMinWidth(), colFrame->GetWidth(MIN_ADJ)); + if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { + minWidth += spacingX; + } } // if it is not a degenerate table, add the last spacing on the right if (minWidth > 0) { @@ -1201,10 +1204,17 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const nscoord maxWidth = 0; for (PRInt32 colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - nscoord max = PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth()); - max = PR_MAX(max, colFrame->GetPctWidth()); - max = PR_MAX(max, colFrame->GetWidth(MIN_PRO)); - maxWidth += max; + nscoord width = colFrame->GetPctWidth(); + if (width <= 0) { + width = colFrame->GetFixWidth(); + if (width <= 0) { + width = colFrame->GetWidth(MIN_PRO); + if (width <= 0) { + width = colFrame->GetDesWidth(); + } + } + } + maxWidth += width; if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { maxWidth += spacingX; } diff --git a/mozilla/layout/html/tests/table/bugs/file_list.txt b/mozilla/layout/html/tests/table/bugs/file_list.txt index c44d7927276..f498f9d1ecd 100644 --- a/mozilla/layout/html/tests/table/bugs/file_list.txt +++ b/mozilla/layout/html/tests/table/bugs/file_list.txt @@ -164,7 +164,7 @@ file:///s|/mozilla/layout/html/tests/table/bugs/bug2997.html file:///s|/mozilla/layout/html/tests/table/bugs/bug30273.html file:///s|/mozilla/layout/html/tests/table/bugs/bug30332-1.html file:///s|/mozilla/layout/html/tests/table/bugs/bug30332-2.html -file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-1.html +#file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-1.html file:///s|/mozilla/layout/html/tests/table/bugs/bug3037-2.html file:///s|/mozilla/layout/html/tests/table/bugs/bug30559.html file:///s|/mozilla/layout/html/tests/table/bugs/bug30985.html diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index 09e05353da4..3666b4d35d4 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -1186,6 +1186,9 @@ nscoord BasicTableLayoutStrategy::GetTableMinWidth() const for (PRInt32 colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); minWidth += PR_MAX(colFrame->GetMinWidth(), colFrame->GetWidth(MIN_ADJ)); + if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { + minWidth += spacingX; + } } // if it is not a degenerate table, add the last spacing on the right if (minWidth > 0) { @@ -1201,10 +1204,17 @@ nscoord BasicTableLayoutStrategy::GetTableMaxWidth() const nscoord maxWidth = 0; for (PRInt32 colX = 0; colX < numCols; colX++) { nsTableColFrame* colFrame = mTableFrame->GetColFrame(colX); - nscoord max = PR_MAX(colFrame->GetDesWidth(), colFrame->GetFixWidth()); - max = PR_MAX(max, colFrame->GetPctWidth()); - max = PR_MAX(max, colFrame->GetWidth(MIN_PRO)); - maxWidth += max; + nscoord width = colFrame->GetPctWidth(); + if (width <= 0) { + width = colFrame->GetFixWidth(); + if (width <= 0) { + width = colFrame->GetWidth(MIN_PRO); + if (width <= 0) { + width = colFrame->GetDesWidth(); + } + } + } + maxWidth += width; if (mTableFrame->GetNumCellsOriginatingInCol(colX) > 0) { maxWidth += spacingX; }