diff --git a/layout/html/table/src/FixedTableLayoutStrategy.cpp b/layout/html/table/src/FixedTableLayoutStrategy.cpp new file mode 100644 index 00000000000..f6bfba434a1 --- /dev/null +++ b/layout/html/table/src/FixedTableLayoutStrategy.cpp @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "FixedTableLayoutStrategy.h" +#include "nsTableFrame.h" +#include "nsTableColFrame.h" +#include "nsTableCellFrame.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsVoidArray.h" +#include "nsIPtr.h" +#include "nsHTMLIIDs.h" + +NS_DEF_PTR(nsIStyleContext); + + +#ifdef NS_DEBUG +static PRBool gsDebug = PR_TRUE; +#else +static const PRBool gsDebug = PR_FALSE; +#endif + +FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols) + : BasicTableLayoutStrategy(aFrame, aNumCols) +{ +} + +FixedTableLayoutStrategy::~FixedTableLayoutStrategy() +{ +} + +PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle, + const nsReflowState& aReflowState, + nscoord aMaxWidth) +{ +#ifdef NS_DEBUG + nsIFrame *tablePIF=nsnull; + mTableFrame->GetPrevInFlow(tablePIF); + NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!"); +#endif + + PRBool result; + + NS_ASSERTION(nsnull!=aTableStyle, "bad arg"); + if (nsnull==aTableStyle) + return PR_FALSE; + + + if (PR_TRUE==gsDebug) + { + printf("\n%p: BALANCE COLUMN WIDTHS\n", mTableFrame); + for (PRInt32 i=0; iGetColumnWidth(i)); + printf("\n"); + } + + return result; +} + +/* assign the width of all columns + * if there is a colframe with a width attribute, use it as the column width + * otherwise if there is a cell in the first row and it has a width attribute, use it + * if this cell includes a colspan, width is divided equally among spanned columns + * 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() +{ + if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame); + + PRInt32 colIndex; + PRInt32 specifiedColumns=0; // the number of columns whose width is given + nscoord totalWidth = 0; // the sum of the widths of the columns whose width is given + + PRBool * autoWidthColumns = new PRBool[mNumCols]; + nsCRT::memset(autoWidthColumns, PR_TRUE, mNumCols*sizeof(PRBool)); + + // for every column, determine it's specified width + for (colIndex = 0; colIndexGetColFrame(colIndex); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + + // Get the columns's style + const nsStylePosition* colPosition; + colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + + // Get fixed column width if it has one + if (eStyleUnit_Coord==colPosition->mWidth.GetUnit()) + { + nscoord colWidth = colPosition->mWidth.GetCoordValue(); + mTableFrame->SetColumnWidth(colIndex, colWidth); + totalWidth += colWidth; + specifiedColumns++; + autoWidthColumns[colIndex]=PR_FALSE; + if (PR_TRUE==gsDebug) + printf ("from col, col %d set to width %d\n", colIndex, colWidth); + } + else + { + nsTableCellFrame *cellFrame = mTableFrame->GetCellFrameAt(0, colIndex); + if (nsnull!=cellFrame) + { + // Get the cell's style + const nsStylePosition* cellPosition; + cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition); + + // Get fixed column width if it has one + if (eStyleUnit_Coord==cellPosition->mWidth.GetUnit()) + { + PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame); + nscoord effectiveWidth = cellPosition->mWidth.GetCoordValue()/colSpan; + mTableFrame->SetColumnWidth(colIndex, effectiveWidth); + totalWidth += effectiveWidth; + specifiedColumns++; + autoWidthColumns[colIndex]=PR_FALSE; + if (PR_TRUE==gsDebug) + printf ("from cell, col %d set to width %d\n", colIndex, effectiveWidth); + } + } + } + } + + // for every column that did not have a specified width, compute its width from the remaining space + if (mNumCols > specifiedColumns) + { + // Get the table's style + const nsStylePosition* tablePosition; + mTableFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)tablePosition); + if (eStyleUnit_Coord==tablePosition->mWidth.GetUnit()) + { + nscoord specifiedTableWidth = tablePosition->mWidth.GetCoordValue(); + nscoord remainingTableWidth = specifiedTableWidth - totalWidth; + if (PR_TRUE==gsDebug) + printf ("%p: specifiedTW=%d, remainingTW=%d\n", + mTableFrame, specifiedTableWidth, remainingTableWidth); + if (0SetColumnWidth(colIndex, widthPerColumn); + totalWidth += widthPerColumn; + if (PR_TRUE==gsDebug) + printf ("auto col %d set to width %d\n", colIndex, widthPerColumn); + } + } + } + } + } + // min/MaxTW is max of (specified table width, sum of specified column(cell) widths) + mMinTableWidth = mMaxTableWidth = totalWidth; + if (PR_TRUE==gsDebug) + printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth); + + // clean up + if (nsnull!=autoWidthColumns) + { + delete [] autoWidthColumns; + } + + return PR_TRUE; +} + + + + diff --git a/layout/html/table/src/FixedTableLayoutStrategy.h b/layout/html/table/src/FixedTableLayoutStrategy.h new file mode 100644 index 00000000000..333ef6d3e04 --- /dev/null +++ b/layout/html/table/src/FixedTableLayoutStrategy.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef FixedTableLayoutStrategy_h__ +#define FixedTableLayoutStrategy_h__ + +#include "nscore.h" +#include "BasicTableLayoutStrategy.h" +#include "nsCoord.h" + +class nsVoidArray; +class nsTableFrame; +struct nsStylePosition; + + +/* ---------- FixedTableLayoutStrategy ---------- */ + +/** Implementation of HTML4 "table-layout=fixed" table layout. + * The input to this class is the resolved styles for both the + * table columns and the cells in row0. + * The output from this class is to set the column widths in + * mTableFrame. + */ +class FixedTableLayoutStrategy : public BasicTableLayoutStrategy +{ +public: + + /** Public constructor. + * @paran aFrame the table frame for which this delegate will do layout + * @param aNumCols the total number of columns in the table + */ + FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols); + + /** destructor */ + virtual ~FixedTableLayoutStrategy(); + + /** no need to override Initialize since it calls our AssignPreliminaryColumnWidths */ + // virtual PRBool Initialize(nsSize* aMaxElementSize); + + /** Called during resize reflow to determine the new column widths + * @param aTableStyle - the resolved style for mTableFrame + * @param aReflowState - the reflow state for mTableFrame + * @param aMaxWidth - the computed max width for columns to fit into + */ + virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle, + const nsReflowState& aReflowState, + nscoord aMaxWidth); + +protected: + /* assign the width of all columns + * if there is a colframe with a width attribute, use it as the column width. + * otherwise if there is a cell in the first row and it has a width attribute, use it. + * if this cell includes a colspan, width is divided equally among spanned columns + * 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 + * Computes the minimum and maximum table widths. + * + * Set column width information in each column frame and in the table frame. + * + * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error + * + */ + virtual PRBool AssignPreliminaryColumnWidths(); + + +}; + + +#endif + diff --git a/layout/tables/FixedTableLayoutStrategy.cpp b/layout/tables/FixedTableLayoutStrategy.cpp new file mode 100644 index 00000000000..f6bfba434a1 --- /dev/null +++ b/layout/tables/FixedTableLayoutStrategy.cpp @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "FixedTableLayoutStrategy.h" +#include "nsTableFrame.h" +#include "nsTableColFrame.h" +#include "nsTableCellFrame.h" +#include "nsIStyleContext.h" +#include "nsStyleConsts.h" +#include "nsVoidArray.h" +#include "nsIPtr.h" +#include "nsHTMLIIDs.h" + +NS_DEF_PTR(nsIStyleContext); + + +#ifdef NS_DEBUG +static PRBool gsDebug = PR_TRUE; +#else +static const PRBool gsDebug = PR_FALSE; +#endif + +FixedTableLayoutStrategy::FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols) + : BasicTableLayoutStrategy(aFrame, aNumCols) +{ +} + +FixedTableLayoutStrategy::~FixedTableLayoutStrategy() +{ +} + +PRBool FixedTableLayoutStrategy::BalanceColumnWidths(nsIStyleContext *aTableStyle, + const nsReflowState& aReflowState, + nscoord aMaxWidth) +{ +#ifdef NS_DEBUG + nsIFrame *tablePIF=nsnull; + mTableFrame->GetPrevInFlow(tablePIF); + NS_ASSERTION(nsnull==tablePIF, "never ever call me on a continuing frame!"); +#endif + + PRBool result; + + NS_ASSERTION(nsnull!=aTableStyle, "bad arg"); + if (nsnull==aTableStyle) + return PR_FALSE; + + + if (PR_TRUE==gsDebug) + { + printf("\n%p: BALANCE COLUMN WIDTHS\n", mTableFrame); + for (PRInt32 i=0; iGetColumnWidth(i)); + printf("\n"); + } + + return result; +} + +/* assign the width of all columns + * if there is a colframe with a width attribute, use it as the column width + * otherwise if there is a cell in the first row and it has a width attribute, use it + * if this cell includes a colspan, width is divided equally among spanned columns + * 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() +{ + if (gsDebug==PR_TRUE) printf ("** %p: AssignPreliminaryColumnWidths **\n", mTableFrame); + + PRInt32 colIndex; + PRInt32 specifiedColumns=0; // the number of columns whose width is given + nscoord totalWidth = 0; // the sum of the widths of the columns whose width is given + + PRBool * autoWidthColumns = new PRBool[mNumCols]; + nsCRT::memset(autoWidthColumns, PR_TRUE, mNumCols*sizeof(PRBool)); + + // for every column, determine it's specified width + for (colIndex = 0; colIndexGetColFrame(colIndex); + NS_ASSERTION(nsnull!=colFrame, "bad col frame"); + + // Get the columns's style + const nsStylePosition* colPosition; + colFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)colPosition); + + // Get fixed column width if it has one + if (eStyleUnit_Coord==colPosition->mWidth.GetUnit()) + { + nscoord colWidth = colPosition->mWidth.GetCoordValue(); + mTableFrame->SetColumnWidth(colIndex, colWidth); + totalWidth += colWidth; + specifiedColumns++; + autoWidthColumns[colIndex]=PR_FALSE; + if (PR_TRUE==gsDebug) + printf ("from col, col %d set to width %d\n", colIndex, colWidth); + } + else + { + nsTableCellFrame *cellFrame = mTableFrame->GetCellFrameAt(0, colIndex); + if (nsnull!=cellFrame) + { + // Get the cell's style + const nsStylePosition* cellPosition; + cellFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)cellPosition); + + // Get fixed column width if it has one + if (eStyleUnit_Coord==cellPosition->mWidth.GetUnit()) + { + PRInt32 colSpan = mTableFrame->GetEffectiveColSpan(colIndex, cellFrame); + nscoord effectiveWidth = cellPosition->mWidth.GetCoordValue()/colSpan; + mTableFrame->SetColumnWidth(colIndex, effectiveWidth); + totalWidth += effectiveWidth; + specifiedColumns++; + autoWidthColumns[colIndex]=PR_FALSE; + if (PR_TRUE==gsDebug) + printf ("from cell, col %d set to width %d\n", colIndex, effectiveWidth); + } + } + } + } + + // for every column that did not have a specified width, compute its width from the remaining space + if (mNumCols > specifiedColumns) + { + // Get the table's style + const nsStylePosition* tablePosition; + mTableFrame->GetStyleData(eStyleStruct_Position, (nsStyleStruct*&)tablePosition); + if (eStyleUnit_Coord==tablePosition->mWidth.GetUnit()) + { + nscoord specifiedTableWidth = tablePosition->mWidth.GetCoordValue(); + nscoord remainingTableWidth = specifiedTableWidth - totalWidth; + if (PR_TRUE==gsDebug) + printf ("%p: specifiedTW=%d, remainingTW=%d\n", + mTableFrame, specifiedTableWidth, remainingTableWidth); + if (0SetColumnWidth(colIndex, widthPerColumn); + totalWidth += widthPerColumn; + if (PR_TRUE==gsDebug) + printf ("auto col %d set to width %d\n", colIndex, widthPerColumn); + } + } + } + } + } + // min/MaxTW is max of (specified table width, sum of specified column(cell) widths) + mMinTableWidth = mMaxTableWidth = totalWidth; + if (PR_TRUE==gsDebug) + printf ("%p: aMinTW=%d, aMaxTW=%d\n", mTableFrame, mMinTableWidth, mMaxTableWidth); + + // clean up + if (nsnull!=autoWidthColumns) + { + delete [] autoWidthColumns; + } + + return PR_TRUE; +} + + + + diff --git a/layout/tables/FixedTableLayoutStrategy.h b/layout/tables/FixedTableLayoutStrategy.h new file mode 100644 index 00000000000..333ef6d3e04 --- /dev/null +++ b/layout/tables/FixedTableLayoutStrategy.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * The contents of this file are subject to the Netscape Public License + * Version 1.0 (the "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef FixedTableLayoutStrategy_h__ +#define FixedTableLayoutStrategy_h__ + +#include "nscore.h" +#include "BasicTableLayoutStrategy.h" +#include "nsCoord.h" + +class nsVoidArray; +class nsTableFrame; +struct nsStylePosition; + + +/* ---------- FixedTableLayoutStrategy ---------- */ + +/** Implementation of HTML4 "table-layout=fixed" table layout. + * The input to this class is the resolved styles for both the + * table columns and the cells in row0. + * The output from this class is to set the column widths in + * mTableFrame. + */ +class FixedTableLayoutStrategy : public BasicTableLayoutStrategy +{ +public: + + /** Public constructor. + * @paran aFrame the table frame for which this delegate will do layout + * @param aNumCols the total number of columns in the table + */ + FixedTableLayoutStrategy(nsTableFrame *aFrame, PRInt32 aNumCols); + + /** destructor */ + virtual ~FixedTableLayoutStrategy(); + + /** no need to override Initialize since it calls our AssignPreliminaryColumnWidths */ + // virtual PRBool Initialize(nsSize* aMaxElementSize); + + /** Called during resize reflow to determine the new column widths + * @param aTableStyle - the resolved style for mTableFrame + * @param aReflowState - the reflow state for mTableFrame + * @param aMaxWidth - the computed max width for columns to fit into + */ + virtual PRBool BalanceColumnWidths(nsIStyleContext * aTableStyle, + const nsReflowState& aReflowState, + nscoord aMaxWidth); + +protected: + /* assign the width of all columns + * if there is a colframe with a width attribute, use it as the column width. + * otherwise if there is a cell in the first row and it has a width attribute, use it. + * if this cell includes a colspan, width is divided equally among spanned columns + * 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 + * Computes the minimum and maximum table widths. + * + * Set column width information in each column frame and in the table frame. + * + * @return PR_TRUE if all is well, PR_FALSE if there was an unrecoverable error + * + */ + virtual PRBool AssignPreliminaryColumnWidths(); + + +}; + + +#endif +