From a264875bff2dee8dfd2d5e54ce80b6917b8c47de Mon Sep 17 00:00:00 2001 From: "buster%netscape.com" Date: Sun, 26 Jul 1998 04:23:01 +0000 Subject: [PATCH] COLS attribute ignored if any column width info is specified (like ) fixed lots of COLS related bugs. handle min width spec () major fix to colspan handling git-svn-id: svn://10.0.0.236/trunk@6493 18797224-902f-48f8-a5cc-f745e15eee43 --- .../table/src/BasicTableLayoutStrategy.cpp | 36 ++++++++++------ .../layout/html/table/src/nsTableFrame.cpp | 41 ++++++++++++++++++- mozilla/layout/html/table/src/nsTableFrame.h | 6 +++ .../layout/html/table/src/nsTableRowFrame.cpp | 4 +- .../tables/BasicTableLayoutStrategy.cpp | 36 ++++++++++------ mozilla/layout/tables/nsTableFrame.cpp | 41 ++++++++++++++++++- mozilla/layout/tables/nsTableFrame.h | 6 +++ mozilla/layout/tables/nsTableRowFrame.cpp | 4 +- 8 files changed, 142 insertions(+), 32 deletions(-) diff --git a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp index d2a7cb0272f..36df92e5c79 100644 --- a/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/html/table/src/BasicTableLayoutStrategy.cpp @@ -282,6 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() nsSize cellMinSize = cellFrame->GetPass1MaxElementSize(); nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize(); nscoord cellDesiredWidth = cellDesiredSize.width; + nscoord cellMinWidth = cellMinSize.width; if (gsDebug==PR_TRUE) printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n", rowIndex, colSpan, cellMinSize.width, cellMinSize.height, @@ -292,15 +293,24 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() // This col has a specified fixed width so set the min and max width to the larger of // (specified width, largest max_element_size of the cells in the column) // factoring in the min width of the prior cells (stored in minColWidth) - nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue()); + nscoord widthForThisCell = specifiedFixedColWidth; + if (0==specifiedFixedColWidth) // set to min + specifiedFixedColWidth = cellMinWidth; widthForThisCell = PR_MAX(widthForThisCell, minColWidth); - widthForThisCell = widthForThisCell/colSpan; mTableFrame->SetColumnWidth(colIndex, widthForThisCell); maxColWidth = widthForThisCell; - if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell)) - effectiveMaxColumnWidth = widthForThisCell; - if (gsDebug) - printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell); + minColWidth = widthForThisCell; + if (1==colSpan) + { + effectiveMaxColumnWidth = PR_MAX(effectiveMaxColumnWidth, widthForThisCell); + if (0==effectiveMinColumnWidth) + effectiveMinColumnWidth = widthForThisCell; + else + effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, widthForThisCell); + //above line works for most tables, but it can't be right + //effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, cellMinWidth); + //above line seems right and works for xT1, but breaks lots of other tables. + } } else { @@ -308,6 +318,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() maxColWidth = cellDesiredWidth; if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth)) effectiveMaxColumnWidth = cellDesiredWidth; + if (minColWidth < cellMinWidth) + minColWidth = cellMinWidth; + // effectiveMinColumnWidth is the min width as if no cells with colspans existed + if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth)) + effectiveMinColumnWidth = cellMinWidth; } //bookkeeping: is this the cell that gave the column it's fixed width attribute? @@ -320,13 +335,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width } - // cellMinWidth can override fixed width, so factor it in here - nscoord cellMinWidth = cellMinSize.width; - if (minColWidth < cellMinWidth) - minColWidth = cellMinWidth; - // effectiveMinColumnWidth is the min width as if no cells with colspans existed - if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth)) - effectiveMinColumnWidth = cellMinWidth; if (1GetColumnFrame(effectedColIndex, colFrame); colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected) colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths); + if (gsDebug) printf ("col %d now has max col width %d\n", effectedColIndex, maxOfMaxColWidths); } delete [] minColWidthArray; delete [] maxColWidthArray; diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 19bf9e80e27..fe63b571ea8 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -520,6 +520,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, if (nsnull==mCellMap) return; // no info yet, so nothing useful to do + // make sure we've accounted for the COLS attribute + AdjustColumnsForCOLSAttribute(); + PRInt32 actualColumns = 0; nsTableColGroupFrame *lastColGroupFrame = nsnull; nsIFrame * firstRowGroupFrame=nsnull; @@ -2438,13 +2441,47 @@ void nsTableFrame::VerticallyAlignChildren(nsIPresContext* aPresContext, { } +void nsTableFrame::AdjustColumnsForCOLSAttribute() +{ + NS_ASSERTION(nsnull!=mCellMap, "bad cell map"); + + // any specified-width column turns off COLS attribute + nsStyleTable* tableStyle = (nsStyleTable *)mStyleContext->GetMutableStyleData(eStyleStruct_Table); + if (tableStyle->mCols != NS_STYLE_TABLE_COLS_NONE) + { + PRInt32 numCols = GetColCount(); + PRInt32 numRows = GetRowCount(); + for (PRInt32 rowIndex=0; rowIndexGetCellFrameAt(rowIndex, colIndex); + // get the cell style info + const nsStylePosition* cellPosition; + if (nsnull!=cellFrame) + { + cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition); + if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) || + (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) + { + tableStyle->mCols = NS_STYLE_TABLE_COLS_NONE; + break; + } + } + } + } + } +} + NS_METHOD nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext, nsTableCellFrame* aCellFrame, nsTableRowFrame * aRowFrame) { - // if this cell is in the first row, then the width attribute - // also acts as the width attribute for the entire column + // if this cell is the first non-col-spanning cell to have a width attribute, + // then the width attribute also acts as the width attribute for the entire column + // if the cell has a colspan, the width is used provisionally, divided equally among + // the spanned columns if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame)) { // get the cell style info diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index efcf534cc40..846baf643cc 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -123,6 +123,12 @@ public: nsTableCellFrame* aCellFrame, nsTableRowFrame * aRowFrame); + /** the COLS attribute can be modified by any cell's width attribute. + * deal with it here. Must be called before any call to + * ColumnInfoCache::AddColumnInfo + */ + virtual void AdjustColumnsForCOLSAttribute(); + /** return the column frame corresponding to the given column index * there are two ways to do this, depending on whether we have cached * column information yet. diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index 60215797861..73f9f2eff41 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -574,7 +574,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, kidFrame->WillReflow(aPresContext); if (gsDebug1) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width); status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); - if (gsDebug1) printf ("%p InitR: desired=%d\n", this, kidSize.width); + if (gsDebug1) + printf ("%p InitR: desired=%d, MES=%d\n", + this, kidSize.width, kidMaxElementSize.width); ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status"); diff --git a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp index d2a7cb0272f..36df92e5c79 100644 --- a/mozilla/layout/tables/BasicTableLayoutStrategy.cpp +++ b/mozilla/layout/tables/BasicTableLayoutStrategy.cpp @@ -282,6 +282,7 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() nsSize cellMinSize = cellFrame->GetPass1MaxElementSize(); nsSize cellDesiredSize = cellFrame->GetPass1DesiredSize(); nscoord cellDesiredWidth = cellDesiredSize.width; + nscoord cellMinWidth = cellMinSize.width; if (gsDebug==PR_TRUE) printf (" for cell %d with colspan=%d, min = %d,%d and des = %d,%d\n", rowIndex, colSpan, cellMinSize.width, cellMinSize.height, @@ -292,15 +293,24 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() // This col has a specified fixed width so set the min and max width to the larger of // (specified width, largest max_element_size of the cells in the column) // factoring in the min width of the prior cells (stored in minColWidth) - nscoord widthForThisCell = PR_MAX(cellMinSize.width, colPosition->mWidth.GetCoordValue()); + nscoord widthForThisCell = specifiedFixedColWidth; + if (0==specifiedFixedColWidth) // set to min + specifiedFixedColWidth = cellMinWidth; widthForThisCell = PR_MAX(widthForThisCell, minColWidth); - widthForThisCell = widthForThisCell/colSpan; mTableFrame->SetColumnWidth(colIndex, widthForThisCell); maxColWidth = widthForThisCell; - if ((1==colSpan) && (effectiveMaxColumnWidth < widthForThisCell)) - effectiveMaxColumnWidth = widthForThisCell; - if (gsDebug) - printf (" setting min and max col width to specified fixed width %d\n", widthForThisCell); + minColWidth = widthForThisCell; + if (1==colSpan) + { + effectiveMaxColumnWidth = PR_MAX(effectiveMaxColumnWidth, widthForThisCell); + if (0==effectiveMinColumnWidth) + effectiveMinColumnWidth = widthForThisCell; + else + effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, widthForThisCell); + //above line works for most tables, but it can't be right + //effectiveMinColumnWidth = PR_MIN(effectiveMinColumnWidth, cellMinWidth); + //above line seems right and works for xT1, but breaks lots of other tables. + } } else { @@ -308,6 +318,11 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() maxColWidth = cellDesiredWidth; if ((1==colSpan) && (effectiveMaxColumnWidth < maxColWidth)) effectiveMaxColumnWidth = cellDesiredWidth; + if (minColWidth < cellMinWidth) + minColWidth = cellMinWidth; + // effectiveMinColumnWidth is the min width as if no cells with colspans existed + if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth)) + effectiveMinColumnWidth = cellMinWidth; } //bookkeeping: is this the cell that gave the column it's fixed width attribute? @@ -320,13 +335,6 @@ PRBool BasicTableLayoutStrategy::AssignPreliminaryColumnWidths() cellGrantingWidth=PR_FALSE; //I've found the cell that gave the col it's width } - // cellMinWidth can override fixed width, so factor it in here - nscoord cellMinWidth = cellMinSize.width; - if (minColWidth < cellMinWidth) - minColWidth = cellMinWidth; - // effectiveMinColumnWidth is the min width as if no cells with colspans existed - if ((1==colSpan) && (effectiveMinColumnWidth < cellMinWidth)) - effectiveMinColumnWidth = cellMinWidth; if (1GetColumnFrame(effectedColIndex, colFrame); colFrame->SetMaxColWidth(maxOfMaxColWidths); // cache the new column max width (min width is uneffected) colFrame->SetEffectiveMaxColWidth(maxOfMaxColWidths); + if (gsDebug) printf ("col %d now has max col width %d\n", effectedColIndex, maxOfMaxColWidths); } delete [] minColWidthArray; delete [] maxColWidthArray; diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 19bf9e80e27..fe63b571ea8 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -520,6 +520,9 @@ void nsTableFrame::EnsureColumns(nsIPresContext* aPresContext, if (nsnull==mCellMap) return; // no info yet, so nothing useful to do + // make sure we've accounted for the COLS attribute + AdjustColumnsForCOLSAttribute(); + PRInt32 actualColumns = 0; nsTableColGroupFrame *lastColGroupFrame = nsnull; nsIFrame * firstRowGroupFrame=nsnull; @@ -2438,13 +2441,47 @@ void nsTableFrame::VerticallyAlignChildren(nsIPresContext* aPresContext, { } +void nsTableFrame::AdjustColumnsForCOLSAttribute() +{ + NS_ASSERTION(nsnull!=mCellMap, "bad cell map"); + + // any specified-width column turns off COLS attribute + nsStyleTable* tableStyle = (nsStyleTable *)mStyleContext->GetMutableStyleData(eStyleStruct_Table); + if (tableStyle->mCols != NS_STYLE_TABLE_COLS_NONE) + { + PRInt32 numCols = GetColCount(); + PRInt32 numRows = GetRowCount(); + for (PRInt32 rowIndex=0; rowIndexGetCellFrameAt(rowIndex, colIndex); + // get the cell style info + const nsStylePosition* cellPosition; + if (nsnull!=cellFrame) + { + cellFrame->GetStyleData(eStyleStruct_Position, (const nsStyleStruct *&)cellPosition); + if ((eStyleUnit_Coord == cellPosition->mWidth.GetUnit()) || + (eStyleUnit_Percent==cellPosition->mWidth.GetUnit())) + { + tableStyle->mCols = NS_STYLE_TABLE_COLS_NONE; + break; + } + } + } + } + } +} + NS_METHOD nsTableFrame::SetColumnStyleFromCell(nsIPresContext * aPresContext, nsTableCellFrame* aCellFrame, nsTableRowFrame * aRowFrame) { - // if this cell is in the first row, then the width attribute - // also acts as the width attribute for the entire column + // if this cell is the first non-col-spanning cell to have a width attribute, + // then the width attribute also acts as the width attribute for the entire column + // if the cell has a colspan, the width is used provisionally, divided equally among + // the spanned columns if ((nsnull!=aPresContext) && (nsnull!=aCellFrame) && (nsnull!=aRowFrame)) { // get the cell style info diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index efcf534cc40..846baf643cc 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -123,6 +123,12 @@ public: nsTableCellFrame* aCellFrame, nsTableRowFrame * aRowFrame); + /** the COLS attribute can be modified by any cell's width attribute. + * deal with it here. Must be called before any call to + * ColumnInfoCache::AddColumnInfo + */ + virtual void AdjustColumnsForCOLSAttribute(); + /** return the column frame corresponding to the given column index * there are two ways to do this, depending on whether we have cached * column information yet. diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index 60215797861..73f9f2eff41 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -574,7 +574,9 @@ nsTableRowFrame::InitialReflow(nsIPresContext& aPresContext, kidFrame->WillReflow(aPresContext); if (gsDebug1) printf ("%p InitR: avail=%d\n", this, kidAvailSize.width); status = ReflowChild(kidFrame, &aPresContext, kidSize, kidReflowState); - if (gsDebug1) printf ("%p InitR: desired=%d\n", this, kidSize.width); + if (gsDebug1) + printf ("%p InitR: desired=%d, MES=%d\n", + this, kidSize.width, kidMaxElementSize.width); ((nsTableCellFrame *)kidFrame)->SetPass1DesiredSize(kidSize); ((nsTableCellFrame *)kidFrame)->SetPass1MaxElementSize(kidMaxElementSize); NS_ASSERTION(NS_FRAME_IS_COMPLETE(status), "unexpected child reflow status");