1998-04-30 21:57:09 +04:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
1999-11-06 06:40:37 +03:00
* The contents of this file are subject to the Netscape Public
* License Version 1.1 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.mozilla.org/NPL/
1998-04-30 21:57:09 +04:00
*
1999-11-06 06:40:37 +03:00
* Software distributed under the License is distributed on an " AS
* IS " basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied . See the License for the specific language governing
* rights and limitations under the License .
1998-04-30 21:57:09 +04:00
*
1999-11-06 06:40:37 +03:00
* The Original Code is mozilla . org code .
*
* The Initial Developer of the Original Code is Netscape
1998-04-30 21:57:09 +04:00
* Communications Corporation . Portions created by Netscape are
1999-11-06 06:40:37 +03:00
* Copyright ( C ) 1998 Netscape Communications Corporation . All
* Rights Reserved .
*
* Contributor ( s ) :
1998-04-30 21:57:09 +04:00
*/
# include "BasicTableLayoutStrategy.h"
2000-09-01 05:29:50 +04:00
# include "nsIPresContext.h"
1998-04-30 21:57:09 +04:00
# include "nsTableFrame.h"
1998-05-30 02:08:19 +04:00
# include "nsTableColFrame.h"
1998-04-30 21:57:09 +04:00
# include "nsTableCellFrame.h"
# include "nsIStyleContext.h"
# include "nsStyleConsts.h"
1998-07-11 04:00:31 +04:00
# include "nsVoidArray.h"
1998-05-31 01:21:51 +04:00
# include "nsHTMLIIDs.h"
1998-04-30 21:57:09 +04:00
1999-10-18 17:48:19 +04:00
# if 1
1999-08-21 10:38:07 +04:00
static PRBool gsDebugAssign = PR_FALSE ;
static PRBool gsDebugBalance = PR_FALSE ;
1999-10-18 17:48:19 +04:00
# else
static PRBool gsDebugAssign = PR_TRUE ;
static PRBool gsDebugBalance = PR_TRUE ;
# endif
2000-02-02 03:48:30 +03:00
static PRInt32 gsDebugCount = 0 ;
1999-08-21 10:38:07 +04:00
2000-09-01 05:29:50 +04:00
// the logic here is kept in synch with that in CalculateTotals.
1999-10-04 09:19:32 +04:00
PRBool CanAllocate ( PRInt32 aTypeToAllocate ,
PRInt32 aTypeAlreadyAllocated ,
1999-11-06 01:36:59 +03:00
nsTableColFrame * aColFrame ,
2000-09-01 05:29:50 +04:00
PRBool aIsNavQuirks ,
1999-11-06 01:36:59 +03:00
PRBool & aConsiderAdj )
1999-10-04 09:19:32 +04:00
{
1999-11-06 01:36:59 +03:00
aConsiderAdj = PR_TRUE ;
1999-10-04 09:19:32 +04:00
if ( ( aTypeToAllocate = = FIX_ADJ ) & & ( aTypeAlreadyAllocated = = FIX ) ) {
return PR_TRUE ;
}
2000-09-01 05:29:50 +04:00
if ( aIsNavQuirks & & ( aTypeToAllocate = = DES_CON ) & & ( aTypeAlreadyAllocated = = FIX_ADJ ) ) {
1999-11-06 01:36:59 +03:00
aConsiderAdj = PR_FALSE ;
2000-09-01 05:29:50 +04:00
if ( aColFrame - > GetWidth ( FIX ) < = 0 ) { // there is no FIX width
return PR_TRUE ;
}
1999-10-04 09:19:32 +04:00
}
return PR_FALSE ;
}
1998-05-30 02:08:19 +04:00
/* ---------- BasicTableLayoutStrategy ---------- */
1999-10-09 00:41:19 +04:00
MOZ_DECL_CTOR_COUNTER ( BasicTableLayoutStrategy ) ;
1998-05-27 02:03:16 +04:00
1999-05-27 02:22:23 +04:00
BasicTableLayoutStrategy : : BasicTableLayoutStrategy ( nsTableFrame * aFrame , PRBool aIsNavQuirks )
1998-04-30 21:57:09 +04:00
{
1999-10-09 00:41:19 +04:00
MOZ_COUNT_CTOR ( BasicTableLayoutStrategy ) ;
1999-04-04 03:02:43 +04:00
NS_ASSERTION ( nsnull ! = aFrame , " bad frame arg " ) ;
1998-06-24 03:23:21 +04:00
1999-07-28 12:09:02 +04:00
mTableFrame = aFrame ;
mCellSpacingTotal = 0 ;
mIsNavQuirksMode = aIsNavQuirks ;
1998-04-30 21:57:09 +04:00
}
BasicTableLayoutStrategy : : ~ BasicTableLayoutStrategy ( )
{
1999-10-09 00:41:19 +04:00
MOZ_COUNT_DTOR ( BasicTableLayoutStrategy ) ;
1998-04-30 21:57:09 +04:00
}
2000-02-12 04:55:40 +03:00
PRBool BasicTableLayoutStrategy : : Initialize ( nsIPresContext * aPresContext ,
nsSize * aMaxElementSize ,
nscoord aMaxWidth ,
const nsHTMLReflowState & aReflowState )
1998-04-30 21:57:09 +04:00
{
1999-07-28 12:09:02 +04:00
ContinuingFrameCheck ( ) ;
1998-07-17 03:23:31 +04:00
1998-04-30 21:57:09 +04:00
PRBool result = PR_TRUE ;
1998-05-27 02:03:16 +04:00
1998-07-22 22:22:12 +04:00
// re-init instance variables
1999-07-28 12:09:02 +04:00
mCellSpacingTotal = 0 ;
mCols = mTableFrame - > GetEffectiveCOLSAttribute ( ) ;
// assign the width of all fixed-width columns
2000-09-01 05:29:50 +04:00
float p2t ;
aPresContext - > GetScaledPixelsToTwips ( & p2t ) ;
AssignPreliminaryColumnWidths ( aPresContext , aMaxWidth , aReflowState , p2t ) ;
1998-04-30 21:57:09 +04:00
1998-07-17 03:23:31 +04:00
// set aMaxElementSize here because we compute mMinTableWidth in AssignPreliminaryColumnWidths
1999-04-04 03:02:43 +04:00
if ( nsnull ! = aMaxElementSize ) {
2000-02-12 04:55:40 +03:00
SetMaxElementSize ( aMaxElementSize , aReflowState . mComputedPadding ) ;
1998-10-09 23:59:45 +04:00
}
return result ;
}
2000-02-12 04:55:40 +03:00
void
BasicTableLayoutStrategy : : SetMaxElementSize ( nsSize * aMaxElementSize ,
const nsMargin & aPadding )
1998-10-09 23:59:45 +04:00
{
1999-04-04 03:02:43 +04:00
if ( nsnull ! = aMaxElementSize ) {
1998-07-17 03:23:31 +04:00
aMaxElementSize - > height = 0 ;
1998-08-07 06:11:51 +04:00
nsMargin borderPadding ;
const nsStylePosition * tablePosition ;
1998-11-20 12:29:58 +03:00
mTableFrame - > GetStyleData ( eStyleStruct_Position , ( ( const nsStyleStruct * & ) tablePosition ) ) ;
1998-12-23 18:47:43 +03:00
mTableFrame - > GetTableBorder ( borderPadding ) ;
2000-02-12 04:55:40 +03:00
borderPadding + = aPadding ;
1999-07-28 12:09:02 +04:00
nscoord horBorderPadding = borderPadding . left + borderPadding . right ;
2000-05-10 04:54:00 +04:00
nscoord minTableWidth = GetTableMinWidth ( ) ;
1999-04-04 03:02:43 +04:00
if ( tablePosition - > mWidth . GetUnit ( ) = = eStyleUnit_Coord ) {
1998-08-04 00:27:59 +04:00
aMaxElementSize - > width = tablePosition - > mWidth . GetCoordValue ( ) ;
2000-05-10 04:54:00 +04:00
if ( minTableWidth + horBorderPadding > aMaxElementSize - > width ) {
aMaxElementSize - > width = minTableWidth + horBorderPadding ;
1999-07-28 12:09:02 +04:00
}
1998-08-04 04:56:57 +04:00
}
1999-04-04 03:02:43 +04:00
else {
2000-05-10 04:54:00 +04:00
aMaxElementSize - > width = minTableWidth + horBorderPadding ;
1998-08-07 06:11:51 +04:00
}
1998-04-30 21:57:09 +04:00
}
}
1999-07-28 12:09:02 +04:00
void BasicTableLayoutStrategy : : ContinuingFrameCheck ( )
1998-04-30 21:57:09 +04:00
{
1998-09-23 03:36:06 +04:00
# ifdef NS_DEBUG
1999-07-28 12:09:02 +04:00
nsIFrame * tablePIF = nsnull ;
1999-02-24 07:48:08 +03:00
mTableFrame - > GetPrevInFlow ( & tablePIF ) ;
1999-07-28 12:09:02 +04:00
NS_ASSERTION ( ! tablePIF , " never ever call me on a continuing frame! " ) ;
1998-04-30 21:57:09 +04:00
# endif
1999-07-28 12:09:02 +04:00
}
1998-04-30 21:57:09 +04:00
2000-01-22 04:16:50 +03:00
PRBool BCW_Wrapup ( nsIPresContext * aPresContext ,
BasicTableLayoutStrategy * aStrategy ,
1999-08-21 10:38:07 +04:00
nsTableFrame * aTableFrame ,
PRInt32 * aAllocTypes )
1999-07-28 12:09:02 +04:00
{
1999-08-21 10:38:07 +04:00
if ( aAllocTypes )
delete [ ] aAllocTypes ;
2000-01-22 04:16:50 +03:00
if ( gsDebugBalance ) { printf ( " BalanceColumnWidths ex \n " ) ; aTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
1999-07-28 12:09:02 +04:00
return PR_TRUE ;
}
1998-07-17 03:23:31 +04:00
1999-10-04 09:19:32 +04:00
// The priority of allocations for a given column are as follows
// 1) max(MIN, MIN_ADJ)
// 2) max (PCT, PCT_ADJ) go to 7
// 3) FIX
// 4) FIX_ADJ, if FIX was not set do DES_CON, go to 7
// 5) PROportional go to 7
// 6) max(DES_CON, DES_ADJ)
// 7) for a fixed width table, the column may get more
// space if the sum of the col allocations is insufficient
1999-07-28 12:09:02 +04:00
PRBool
2000-01-22 04:16:50 +03:00
BasicTableLayoutStrategy : : BalanceColumnWidths ( nsIPresContext * aPresContext ,
nsIStyleContext * aTableStyle ,
1999-07-28 12:09:02 +04:00
const nsHTMLReflowState & aReflowState ,
nscoord aMaxWidthIn )
{
2000-02-02 03:48:30 +03:00
if ( gsDebugBalance ) { printf ( " BalanceColumnWidths en max=%d count=%d \n " , aMaxWidthIn , gsDebugCount + + ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
2000-09-01 05:29:50 +04:00
float p2t ;
aPresContext - > GetScaledPixelsToTwips ( & p2t ) ;
1999-08-21 10:38:07 +04:00
1999-07-28 12:09:02 +04:00
ContinuingFrameCheck ( ) ;
if ( ! aTableStyle ) {
NS_ASSERTION ( aTableStyle , " bad style arg " ) ;
1998-07-17 03:23:31 +04:00
return PR_FALSE ;
1999-04-04 03:02:43 +04:00
}
1998-07-17 03:23:31 +04:00
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-07-28 12:09:02 +04:00
// determine if the table is auto/fixed and get the fixed width if available
nscoord maxWidth = aMaxWidthIn ;
2000-01-03 01:55:48 +03:00
nscoord specifiedTableWidth = mTableFrame - > CalcBorderBoxWidth ( aReflowState ) ;
PRBool tableIsAutoWidth = mTableFrame - > IsAutoWidth ( ) ;
1999-07-28 12:09:02 +04:00
// a specifiedTableWidth of <= 0 indicates percentage based
if ( ! tableIsAutoWidth & & ( specifiedTableWidth > 0 ) ) {
maxWidth = PR_MIN ( specifiedTableWidth , aMaxWidthIn ) ; // specifiedWidth usually == aMaxWidthIn for fixed table
}
1999-09-14 01:45:58 +04:00
// 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 ) {
2000-02-12 04:55:40 +03:00
maxWidth - = aReflowState . mComputedBorderPadding . left +
aReflowState . mComputedBorderPadding . right ;
1999-09-14 01:45:58 +04:00
maxWidth = PR_MAX ( 0 , maxWidth ) ;
1999-07-28 12:09:02 +04:00
}
// initialize the col percent and cell percent values to 0.
PRInt32 colX ;
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
colFrame - > SetWidth ( PCT , WIDTH_NOT_SET ) ;
colFrame - > SetWidth ( PCT_ADJ , WIDTH_NOT_SET ) ;
}
1999-10-26 02:49:51 +04:00
// set PCT and PCT_ADJ widths on col frames. An auto table returns
1999-10-04 09:19:32 +04:00
// a new table width based on percent cells/cols if they exist
1999-10-26 02:49:51 +04:00
nscoord perAdjTableWidth = 0 ;
if ( ( NS_UNCONSTRAINEDSIZE ! = maxWidth ) | | ( tableIsAutoWidth ) ) {
// for an auto width table, use a large basis just so that the quirky
// auto table sizing will get as big as it should
2000-02-09 17:22:00 +03:00
nscoord basis = ( NS_UNCONSTRAINEDSIZE = = maxWidth )
? NS_UNCONSTRAINEDSIZE : maxWidth - mCellSpacingTotal ;
2000-09-01 05:29:50 +04:00
perAdjTableWidth = AssignPercentageColumnWidths ( basis , tableIsAutoWidth , p2t ) ;
1999-10-26 02:49:51 +04:00
}
1999-10-04 09:19:32 +04:00
// set the table's columns to the min width
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 09:19:32 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord colMinWidth = colFrame - > GetMinWidth ( ) ;
mTableFrame - > SetColumnWidth ( colX , colMinWidth ) ;
}
1999-07-28 12:09:02 +04:00
// if the max width available is less than the min content width for fixed table, we're done
2000-05-10 04:54:00 +04:00
nscoord minTableWidth = GetTableMinWidth ( ) ;
if ( ! tableIsAutoWidth & & ( maxWidth < minTableWidth ) ) {
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , nsnull ) ;
1998-07-18 01:02:28 +04:00
}
1998-07-17 03:23:31 +04:00
1999-07-28 12:09:02 +04:00
// if the max width available is less than the min content width for auto table
// that had no % cells/cols, we're done
2000-05-10 04:54:00 +04:00
if ( tableIsAutoWidth & & ( maxWidth < minTableWidth ) & & ( 0 = = perAdjTableWidth ) ) {
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , nsnull ) ;
1998-07-27 06:15:37 +04:00
}
1999-07-28 12:09:02 +04:00
PRInt32 cellSpacingTotal ;
1999-11-06 01:36:59 +03:00
// the following are of size NUM_WIDTHS, but only MIN_CON, DES_CON, FIX, FIX_ADJ, PCT
1999-07-28 12:09:02 +04:00
// are used and they account for colspan ADJusted values
PRInt32 totalWidths [ NUM_WIDTHS ] ; // sum of col widths of a particular type
1999-10-04 09:19:32 +04:00
PRInt32 totalAvailWidths [ NUM_WIDTHS ] ;
1999-07-28 12:09:02 +04:00
PRInt32 totalCounts [ NUM_WIDTHS ] ; // num of cols of a particular type
PRInt32 minWidths [ NUM_WIDTHS ] ;
PRInt32 num0Proportional ;
1998-07-17 03:23:31 +04:00
1999-10-04 09:19:32 +04:00
CalculateTotals ( cellSpacingTotal , totalCounts , totalWidths , totalAvailWidths , minWidths , num0Proportional ) ;
1999-07-28 12:09:02 +04:00
// auto width table's adjusted width needs cell spacing
if ( tableIsAutoWidth & & perAdjTableWidth > 0 ) {
perAdjTableWidth = PR_MIN ( perAdjTableWidth + cellSpacingTotal , maxWidth ) ;
}
nscoord totalAllocated = totalWidths [ MIN_CON ] + cellSpacingTotal ;
// allocate and initialize arrays indicating what col gets set
1999-12-14 01:56:31 +03:00
PRInt32 * allocTypes = new PRInt32 [ numCols ] ;
1999-07-28 12:09:02 +04:00
if ( ! allocTypes ) return PR_FALSE ;
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
allocTypes [ colX ] = - 1 ;
}
1999-05-18 09:18:16 +04:00
1999-07-28 12:09:02 +04:00
// allocate percentage cols
if ( totalCounts [ PCT ] > 0 ) {
1999-10-04 09:19:32 +04:00
if ( totalAllocated + totalAvailWidths [ PCT ] - minWidths [ PCT ] < = maxWidth ) {
1999-07-28 12:09:02 +04:00
AllocateFully ( totalAllocated , allocTypes , PCT ) ;
1999-11-15 18:42:20 +03:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-05-18 09:18:16 +04:00
}
1999-07-28 12:09:02 +04:00
else {
2000-09-01 05:29:50 +04:00
AllocateConstrained ( maxWidth - totalAllocated , PCT , PR_FALSE , allocTypes , p2t ) ;
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1999-05-18 09:18:16 +04:00
}
1999-07-28 12:09:02 +04:00
}
// allocate fixed cols
if ( totalAllocated < maxWidth & & totalCounts [ FIX ] > 0 ) {
1999-10-04 09:19:32 +04:00
if ( totalAllocated + totalAvailWidths [ FIX ] - minWidths [ FIX ] < = maxWidth ) {
1999-07-28 12:09:02 +04:00
AllocateFully ( totalAllocated , allocTypes , FIX ) ;
1999-11-15 18:42:20 +03:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-05-18 09:18:16 +04:00
}
1999-07-28 12:09:02 +04:00
else {
2000-09-01 05:29:50 +04:00
AllocateConstrained ( maxWidth - totalAllocated , FIX , PR_TRUE , allocTypes , p2t ) ;
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1999-10-04 09:19:32 +04:00
}
}
// allocate fixed adjusted cols
if ( totalAllocated < maxWidth & & totalCounts [ FIX_ADJ ] > 0 ) {
if ( totalAllocated + totalAvailWidths [ FIX_ADJ ] - minWidths [ FIX_ADJ ] < = maxWidth ) {
AllocateFully ( totalAllocated , allocTypes , FIX_ADJ ) ;
1999-11-15 18:42:20 +03:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-10-04 09:19:32 +04:00
}
else {
2000-09-01 05:29:50 +04:00
AllocateConstrained ( maxWidth - totalAllocated , FIX_ADJ , PR_TRUE , allocTypes , p2t ) ;
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1999-05-18 09:18:16 +04:00
}
}
1999-07-28 12:09:02 +04:00
// allocate proportional cols up to their min proportional value
if ( totalAllocated < maxWidth & & totalCounts [ MIN_PRO ] > 0 ) {
1999-10-04 09:19:32 +04:00
if ( totalAllocated + totalAvailWidths [ MIN_PRO ] - minWidths [ MIN_PRO ] < = maxWidth ) {
1999-07-28 12:09:02 +04:00
AllocateFully ( totalAllocated , allocTypes , MIN_PRO , PR_FALSE ) ;
1999-11-15 18:42:20 +03:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-04-04 03:02:43 +04:00
}
else {
2000-09-01 05:29:50 +04:00
AllocateConstrained ( maxWidth - totalAllocated , MIN_PRO , PR_FALSE , allocTypes , p2t ) ;
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1999-04-04 03:02:43 +04:00
}
1999-07-28 12:09:02 +04:00
}
1998-07-17 03:23:31 +04:00
1999-07-28 12:09:02 +04:00
// allocate auto cols, considering even those that are proportional
if ( totalAllocated < maxWidth & & totalCounts [ DES_CON ] > 0 ) {
1999-10-04 09:19:32 +04:00
if ( totalAllocated + totalAvailWidths [ DES_CON ] - minWidths [ DES_CON ] < = maxWidth ) {
1999-07-28 12:09:02 +04:00
AllocateFully ( totalAllocated , allocTypes , DES_CON ) ;
1999-11-15 18:42:20 +03:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-07-28 12:09:02 +04:00
}
else {
2000-09-01 05:29:50 +04:00
AllocateConstrained ( maxWidth - totalAllocated , DES_CON , PR_TRUE , allocTypes , p2t ) ;
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1998-06-24 03:23:21 +04:00
}
1998-07-17 03:23:31 +04:00
}
1998-06-24 03:23:21 +04:00
1999-10-26 02:49:51 +04:00
// if this is a nested non auto table and pass1 reflow, we are done
if ( ( maxWidth = = NS_UNCONSTRAINEDSIZE ) & & ( ! tableIsAutoWidth ) ) {
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1999-07-28 12:09:02 +04:00
}
1998-11-30 22:06:33 +03:00
1999-07-28 12:09:02 +04:00
// allocate the rest unconstrained
PRBool skip0Proportional = totalCounts [ DES_CON ] > num0Proportional ;
if ( ( tableIsAutoWidth & & ( perAdjTableWidth - totalAllocated > 0 ) ) | |
( ! tableIsAutoWidth & & ( totalAllocated < maxWidth ) ) ) {
1999-12-14 01:56:31 +03:00
if ( totalCounts [ PCT ] ! = numCols ) {
1999-10-04 09:19:32 +04:00
//PRBool onlyAuto = (totalCounts[DES_CON] > 0) && !mIsNavQuirksMode;
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
if ( PCT = = allocTypes [ colX ] ) {
allocTypes [ colX ] = - 1 ;
}
1999-10-04 09:19:32 +04:00
//else if ((FIX == allocTypes[colX]) && onlyAuto) {
// allocTypes[colX] = -1;
//}
1998-07-22 07:53:43 +04:00
}
}
1999-07-28 12:09:02 +04:00
if ( tableIsAutoWidth ) {
2000-09-01 05:29:50 +04:00
AllocateUnconstrained ( perAdjTableWidth - totalAllocated , allocTypes , skip0Proportional , p2t ) ;
1998-07-13 22:11:12 +04:00
}
1999-07-28 12:09:02 +04:00
else {
2000-09-01 05:29:50 +04:00
AllocateUnconstrained ( maxWidth - totalAllocated , allocTypes , skip0Proportional , p2t ) ;
1998-08-01 06:31:55 +04:00
}
}
1999-07-28 12:09:02 +04:00
// give the proportional cols the rest up to the max width in quirks mode
else if ( tableIsAutoWidth & & mIsNavQuirksMode & & ( totalCounts [ MIN_PRO ] > 0 ) ) {
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
if ( DES_CON ! = allocTypes [ colX ] ) {
allocTypes [ colX ] = - 1 ;
1998-07-28 04:23:01 +04:00
}
1998-07-11 04:00:31 +04:00
}
2000-09-01 05:29:50 +04:00
AllocateUnconstrained ( maxWidth - totalAllocated , allocTypes , skip0Proportional , p2t ) ;
1998-07-11 04:00:31 +04:00
}
1998-07-17 03:23:31 +04:00
2000-01-22 04:16:50 +03:00
return BCW_Wrapup ( aPresContext , this , mTableFrame , allocTypes ) ;
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
// Allocate aWidthType values to all cols available in aIsAllocated
void BasicTableLayoutStrategy : : AllocateFully ( nscoord & aTotalAllocated ,
PRInt32 * aAllocTypes ,
PRInt32 aWidthType ,
PRBool aMarkAllocated )
1998-04-30 21:57:09 +04:00
{
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
for ( PRInt32 colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord oldWidth = mTableFrame - > GetColumnWidth ( colX ) ;
nscoord newWidth = colFrame - > GetWidth ( aWidthType ) ;
1999-10-04 09:19:32 +04:00
1999-11-06 01:36:59 +03:00
PRBool useAdj ;
2000-09-01 05:29:50 +04:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame , mIsNavQuirksMode , useAdj ) ) {
1999-11-06 01:36:59 +03:00
if ( - 1 ! = aAllocTypes [ colX ] ) {
1999-10-04 09:19:32 +04:00
continue ;
}
}
1999-07-28 12:09:02 +04:00
// account for col span overrides with DES_CON and FIX
1999-11-06 01:36:59 +03:00
if ( ( DES_CON = = aWidthType ) & & useAdj ) {
1999-07-28 12:09:02 +04:00
newWidth = PR_MAX ( newWidth , colFrame - > GetWidth ( DES_ADJ ) ) ;
}
else if ( PCT = = aWidthType ) {
newWidth = PR_MAX ( newWidth , colFrame - > GetWidth ( PCT_ADJ ) ) ;
1998-05-27 02:03:16 +04:00
}
1999-07-28 12:09:02 +04:00
if ( WIDTH_NOT_SET = = newWidth ) {
continue ;
}
if ( newWidth > oldWidth ) {
mTableFrame - > SetColumnWidth ( colX , newWidth ) ;
aTotalAllocated + = newWidth - oldWidth ;
}
if ( aMarkAllocated ) {
aAllocTypes [ colX ] = aWidthType ;
1998-07-11 04:00:31 +04:00
}
1998-05-27 02:03:16 +04:00
}
1999-07-28 12:09:02 +04:00
}
void BasicTableLayoutStrategy : : AllocateUnconstrained ( PRInt32 aAllocAmount ,
PRInt32 * aAllocTypes ,
2000-09-01 05:29:50 +04:00
PRBool aSkip0Proportional ,
float aPixelToTwips )
1999-07-28 12:09:02 +04:00
{
1999-10-13 18:44:22 +04:00
nscoord divisor = 0 ;
PRInt32 numColsAllocated = 0 ;
PRInt32 totalAllocated = 0 ;
1999-07-28 12:09:02 +04:00
PRInt32 colX ;
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
if ( - 1 ! = aAllocTypes [ colX ] ) {
divisor + = mTableFrame - > GetColumnWidth ( colX ) ;
1999-10-13 18:44:22 +04:00
numColsAllocated + + ;
1999-07-28 12:09:02 +04:00
}
}
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
if ( - 1 ! = aAllocTypes [ colX ] ) {
if ( aSkip0Proportional ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
if ( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) {
continue ;
1998-08-11 22:42:10 +04:00
}
}
1999-07-28 12:09:02 +04:00
nscoord oldWidth = mTableFrame - > GetColumnWidth ( colX ) ;
float percent = ( divisor = = 0 )
1999-10-13 18:44:22 +04:00
? ( 1.0f / ( ( float ) numColsAllocated ) )
1999-07-28 12:09:02 +04:00
: ( ( float ) oldWidth ) / ( ( float ) divisor ) ;
2000-09-01 05:29:50 +04:00
nscoord addition = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) aAllocAmount ) * percent ) , aPixelToTwips ) ;
1999-10-13 18:44:22 +04:00
if ( addition > ( aAllocAmount - totalAllocated ) ) {
mTableFrame - > SetColumnWidth ( colX , oldWidth + ( aAllocAmount - totalAllocated ) ) ;
break ;
}
1999-07-28 12:09:02 +04:00
mTableFrame - > SetColumnWidth ( colX , oldWidth + addition ) ;
1999-10-13 18:44:22 +04:00
totalAllocated + = addition ;
1998-08-11 22:42:10 +04:00
}
1999-07-28 12:09:02 +04:00
}
}
1999-11-06 01:36:59 +03:00
nscoord GetConstrainedWidth ( nsTableColFrame * colFrame ,
PRBool aConsiderPct )
{
nscoord conWidth = WIDTH_NOT_SET ;
if ( aConsiderPct ) {
2000-01-03 03:56:12 +03:00
conWidth = colFrame - > GetPctWidth ( ) ;
1999-11-06 01:36:59 +03:00
}
if ( conWidth < = 0 ) {
conWidth = colFrame - > GetFixWidth ( ) ;
}
return conWidth ;
}
# define LIMIT_DES 0
# define LIMIT_CON 1
# define LIMIT_NONE 2
void
2000-02-12 04:55:40 +03:00
BasicTableLayoutStrategy : : ComputeColspanWidths ( PRInt32 aWidthIndex ,
nsTableCellFrame * aCellFrame ,
PRInt32 aColIndex ,
PRInt32 aColSpan ,
PRBool aConsiderPct ,
2000-09-01 05:29:50 +04:00
nscoord aPercentBase ,
float aPixelToTwips )
1999-11-06 01:36:59 +03:00
{
if ( ! aCellFrame | | ( aColIndex < 0 ) | | ( aColIndex < 0 ) | | ( aColSpan < 0 ) ) {
NS_ASSERTION ( PR_FALSE , " ComputeColspanWidths called incorrectly " ) ;
return ;
}
nscoord cellWidth = 0 ;
if ( MIN_CON = = aWidthIndex ) {
cellWidth = aCellFrame - > GetPass1MaxElementSize ( ) . width ;
}
else if ( DES_CON = = aWidthIndex ) {
1999-12-24 06:46:21 +03:00
cellWidth = aCellFrame - > GetMaximumWidth ( ) ;
1999-11-06 01:36:59 +03:00
}
else { // FIX width
// see if the cell has a style width specified
const nsStylePosition * cellPosition ;
aCellFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
if ( eStyleUnit_Coord = = cellPosition - > mWidth . GetUnit ( ) ) {
// need to add padding into fixed width
2000-02-12 04:55:40 +03:00
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( aPercentBase , 0 ) , aCellFrame ) ;
cellWidth = cellPosition - > mWidth . GetCoordValue ( ) + padding . left + padding . right ;
1999-11-06 01:36:59 +03:00
cellWidth = PR_MAX ( cellWidth , aCellFrame - > GetPass1MaxElementSize ( ) . width ) ;
}
}
if ( 0 > = cellWidth ) {
return ;
}
if ( MIN_CON = = aWidthIndex ) {
// for min width, first allocate fixed cells up to their fixed value, then if
// necessary allocate auto cells up to their auto value, then if necessary
// allocate auto cells.
for ( PRInt32 limitX = LIMIT_CON ; limitX < = LIMIT_NONE ; limitX + + ) {
if ( ComputeColspanWidths ( aWidthIndex , aCellFrame , cellWidth ,
2000-09-01 05:29:50 +04:00
aColIndex , aColSpan , aConsiderPct , limitX , aPixelToTwips ) ) {
1999-11-06 01:36:59 +03:00
return ;
}
}
} else {
// for des width, just allocate auto cells
ComputeColspanWidths ( aWidthIndex , aCellFrame , cellWidth ,
2000-09-01 05:29:50 +04:00
aColIndex , aColSpan , aConsiderPct , LIMIT_NONE , aPixelToTwips ) ;
1999-11-06 01:36:59 +03:00
}
}
PRBool
BasicTableLayoutStrategy : : ComputeColspanWidths ( PRInt32 aWidthIndex ,
nsTableCellFrame * aCellFrame ,
nscoord aCellWidth ,
PRInt32 aColIndex ,
PRInt32 aColSpan ,
PRBool aConsiderPct ,
2000-09-01 05:29:50 +04:00
PRInt32 aLimitType ,
float aPixelToTwips )
1999-11-06 01:36:59 +03:00
{
PRBool result = PR_TRUE ;
// skip DES_CON if there is a FIX since FIX is really the desired size
//if ((DES_CON == widthX) && (cellWidths[FIX] > 0))
nscoord spanCellSpacing = 0 ; // total cell spacing cells being spanned
nscoord spanTotal = 0 ; // total width of type aWidthIndex of spanned cells
nscoord divisorCon = 0 ; // the sum of constrained (fix or pct if specified) widths of spanned cells
nscoord divisorDes = 0 ; // the sum of desired widths
// the following are only used for MIN_CON calculations. Takings differences between
// actual and target values allows target values to be reached and not exceeded. This
// is not as accurate as the method in AllocateConstrained, but it is a lot cheaper.
nscoord divisorConLimit = 0 ; // the sum of differences between constrained width and min width
nscoord divisorDesLimit = 0 ; // the sum of differences between desired width and min width
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 spanX ;
// accumulate the various divisors to be used later
for ( spanX = 0 ; spanX < aColSpan ; spanX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( aColIndex + spanX ) ;
nscoord colWidth = PR_MAX ( colFrame - > GetWidth ( aWidthIndex ) ,
colFrame - > GetWidth ( aWidthIndex + NUM_MAJOR_WIDTHS ) ) ;
colWidth = PR_MAX ( colWidth , 0 ) ;
if ( aWidthIndex = = DES_CON ) {
nscoord conWidth = GetConstrainedWidth ( colFrame , aConsiderPct ) ;
if ( conWidth < = 0 ) {
divisorDes + = colWidth ;
spanTotal + = colWidth ;
}
else {
divisorCon + = conWidth ;
spanTotal + = conWidth ;
}
}
else if ( aWidthIndex = = MIN_CON ) {
nscoord conWidth = GetConstrainedWidth ( colFrame , aConsiderPct ) ;
nscoord desWidth = colFrame - > GetDesWidth ( ) ;
if ( conWidth > 0 ) {
divisorCon + = conWidth ;
divisorConLimit + = PR_MAX ( conWidth - colWidth , 0 ) ;
}
else {
divisorDes + = desWidth ;
divisorDesLimit + = PR_MAX ( desWidth - colWidth , 0 ) ;
}
spanTotal + = colWidth ;
}
else { // FIX width
if ( colWidth > 0 ) {
divisorCon + = colWidth ;
}
else {
divisorDes + = colFrame - > GetDesWidth ( ) ;
}
spanTotal + = colWidth ;
}
if ( ( spanX > 0 ) & & ( mTableFrame - > GetNumCellsOriginatingInCol ( aColIndex + spanX ) > 0 ) ) {
spanCellSpacing + = spacingX ;
}
}
if ( MIN_CON ! = aWidthIndex ) {
aLimitType = LIMIT_NONE ; // just in case we were called incorrectly
}
else {
// this method gets called up to 3 times, first to let fixed cols reach their
// target, 2nd to let auto cols reach their target and 3rd to let auto cols
// fill out the remainder. Below are some optimizations which can skip steps.
// if there are no constrained cols to focus on, focus on auto cols
if ( ( LIMIT_CON = = aLimitType ) & & ( 0 = = divisorConLimit ) ) {
aLimitType = LIMIT_DES ;
}
// if there are no auto cols to focus on, focus on nothing
if ( ( LIMIT_DES = = aLimitType ) & & ( 0 = = divisorDesLimit ) ) {
aLimitType = LIMIT_NONE ;
}
}
nscoord availWidth = aCellWidth - spanTotal - spanCellSpacing ;
// there are 2 cases where the target will not be reached
if ( ( LIMIT_CON = = aLimitType ) & & ( divisorConLimit < availWidth ) ) {
availWidth = divisorConLimit ;
result = PR_FALSE ;
}
if ( ( LIMIT_DES = = aLimitType ) & & ( divisorDesLimit < availWidth ) ) {
availWidth = divisorDesLimit ;
result = PR_FALSE ;
}
if ( availWidth > 0 ) {
// get the correct numerator in a similar fashion to getting the divisor
for ( spanX = 0 ; spanX < aColSpan ; spanX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( aColIndex + spanX ) ;
nscoord colWidth = PR_MAX ( colFrame - > GetWidth ( aWidthIndex ) ,
colFrame - > GetWidth ( aWidthIndex + NUM_MAJOR_WIDTHS ) ) ;
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
colWidth = PR_MAX ( colWidth , 0 ) ;
nscoord numeratorDes = 0 ;
nscoord numeratorCon = 0 ;
nscoord numeratorConLimit = 0 ;
nscoord numeratorDesLimit = 0 ;
if ( aWidthIndex = = DES_CON ) {
nscoord conWidth = GetConstrainedWidth ( colFrame , aConsiderPct ) ;
if ( conWidth < = 0 ) {
numeratorDes = colWidth ;
}
else {
numeratorCon = conWidth ;
}
}
else if ( aWidthIndex = = MIN_CON ) {
nscoord conWidth = GetConstrainedWidth ( colFrame , aConsiderPct ) ;
nscoord desWidth = colFrame - > GetDesWidth ( ) ;
if ( conWidth > 0 ) {
numeratorCon = conWidth ;
numeratorConLimit = PR_MAX ( conWidth - colWidth , 0 ) ;
}
else {
numeratorDes = desWidth ;
numeratorDesLimit = PR_MAX ( desWidth - colWidth , 0 ) ;
}
}
else { // FIX width
if ( colWidth < = 0 ) {
numeratorDes = colFrame - > GetDesWidth ( ) ;
}
else {
numeratorCon = colWidth ;
}
}
nscoord divisor ;
nscoord numerator ;
if ( divisorDes > 0 ) { // there were auto cols
divisor = divisorDes ;
numerator = numeratorDes ;
}
else { // there were only constrained cols
divisor = divisorCon ;
numerator = numeratorCon ;
}
// let constrained cols reach their target
if ( LIMIT_CON = = aLimitType ) {
if ( divisorConLimit > 0 ) {
divisor = divisorConLimit ;
numerator = numeratorConLimit ;
}
}
// let auto cols reach their target
else if ( LIMIT_DES = = aLimitType ) {
if ( divisorDesLimit > 0 ) {
divisor = divisorDesLimit ;
numerator = numeratorDesLimit ;
}
}
// calculate the amount of additional width the col will get
nscoord addition = ( 0 > = divisor )
? NSToCoordRound ( ( ( float ) availWidth ) / ( ( float ) aColSpan ) )
: NSToCoordRound ( ( ( ( float ) numerator ) / ( ( float ) divisor ) ) * availWidth ) ;
if ( addition > 0 ) {
2000-09-01 05:29:50 +04:00
addition = nsTableFrame : : RoundToPixel ( addition , aPixelToTwips ) ;
1999-11-06 01:36:59 +03:00
nscoord newColAdjWidth = colWidth + addition ;
if ( newColAdjWidth > minWidth ) {
if ( FIX = = aWidthIndex ) {
// a colspan cannot fix a column below what a cell desires on its own
nscoord desCon = colFrame - > GetWidth ( DES_CON ) ; // do not consider DES_ADJ
if ( desCon > newColAdjWidth ) {
newColAdjWidth = desCon ;
}
}
colFrame - > SetWidth ( aWidthIndex + NUM_MAJOR_WIDTHS , newColAdjWidth ) ;
colFrame - > SetConstrainingCell ( aCellFrame ) ; // XXX is this right?
}
}
}
}
return result ;
}
2000-02-12 04:55:40 +03:00
// 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.
1999-07-28 12:09:02 +04:00
// Determine min, desired, fixed, and proportional sizes for the cols and
// and calculate min/max table width
2000-02-12 04:55:40 +03:00
PRBool
BasicTableLayoutStrategy : : AssignPreliminaryColumnWidths ( nsIPresContext * aPresContext ,
nscoord aMaxWidth ,
2000-09-01 05:29:50 +04:00
const nsHTMLReflowState & aReflowState ,
float aPixelToTwips )
1999-07-28 12:09:02 +04:00
{
2000-02-02 03:48:30 +03:00
if ( gsDebugAssign ) { printf ( " AssignPrelimColWidths en max=%d count=%d \n " , aMaxWidth , gsDebugCount + + ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
1999-07-28 12:09:02 +04:00
PRBool rv = PR_FALSE ;
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-07-28 12:09:02 +04:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 colX , rowX ;
mCellSpacingTotal = 0 ;
PRInt32 propTotal = 0 ; // total of numbers of the type 1*, 2*, etc
PRInt32 numColsForColsAttr = 0 ; // Nav Quirks cols attribute for equal width cols
if ( NS_STYLE_TABLE_COLS_NONE ! = mCols ) {
1999-12-14 01:56:31 +03:00
numColsForColsAttr = ( NS_STYLE_TABLE_COLS_ALL = = mCols ) ? numCols : mCols ;
1999-07-28 12:09:02 +04:00
}
// For every column, determine it's min and desired width based on cell style
// base on cells which do not span cols. Also, determine mCellSpacingTotal
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nscoord minWidth = 0 ;
nscoord desWidth = 0 ;
nscoord fixWidth = WIDTH_NOT_SET ;
1999-08-21 10:38:07 +04:00
// Get column frame and reset it
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
NS_ASSERTION ( nsnull ! = colFrame , " bad col frame " ) ;
1999-08-21 10:38:07 +04:00
colFrame - > ResetSizingInfo ( ) ;
1999-07-28 12:09:02 +04:00
1999-08-26 01:49:18 +04:00
if ( mTableFrame - > GetNumCellsOriginatingInCol ( colX ) > 0 ) {
1999-07-28 12:09:02 +04:00
mCellSpacingTotal + = spacingX ;
}
// Scan the cells in the col that have colspan = 1 and find the maximum
// min, desired, and fixed cells.
1999-08-19 23:52:37 +04:00
nsTableCellFrame * fixContributor = nsnull ;
1999-10-13 18:44:22 +04:00
nsTableCellFrame * desContributor = nsnull ;
1999-07-28 12:09:02 +04:00
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 12:09:02 +04:00
// skip cells that don't originate at (rowX, colX); colspans are handled in the
// next pass, row spans don't need to be handled
if ( ! cellFrame | | ! originates | | ( colSpan > 1 ) ) {
continue ;
}
// these values include borders and padding
minWidth = PR_MAX ( minWidth , cellFrame - > GetPass1MaxElementSize ( ) . width ) ;
1999-12-24 06:46:21 +03:00
nscoord cellDesWidth = cellFrame - > GetMaximumWidth ( ) ;
1999-10-13 18:44:22 +04:00
if ( cellDesWidth > desWidth ) {
desContributor = cellFrame ;
desWidth = cellDesWidth ;
}
1999-07-28 12:09:02 +04:00
// see if the cell has a style width specified
const nsStylePosition * cellPosition ;
cellFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
if ( eStyleUnit_Coord = = cellPosition - > mWidth . GetUnit ( ) ) {
nscoord coordValue = cellPosition - > mWidth . GetCoordValue ( ) ;
if ( coordValue > 0 ) { // ignore if width == 0
// need to add padding into fixed width
2000-02-12 04:55:40 +03:00
nsSize percentBase ( aReflowState . mComputedWidth , 0 ) ;
nsMargin padding = nsTableFrame : : GetPadding ( percentBase , cellFrame ) ;
nscoord newFixWidth = coordValue + padding . left + padding . right ;
1999-10-13 18:44:22 +04:00
// 2nd part of condition is Nav Quirk like below
if ( ( newFixWidth > fixWidth ) | | ( ( newFixWidth = = fixWidth ) & & ( desContributor = = cellFrame ) ) ) {
1999-08-19 23:52:37 +04:00
fixWidth = newFixWidth ;
fixContributor = cellFrame ;
}
1999-07-28 12:09:02 +04:00
fixWidth = PR_MAX ( fixWidth , minWidth ) ;
1998-08-11 22:42:10 +04:00
}
1999-07-28 12:09:02 +04:00
}
}
desWidth = PR_MAX ( desWidth , minWidth ) ;
1999-10-13 18:44:22 +04:00
// Nav Quirk like above
if ( ( fixWidth > 0 ) & & ( desWidth > fixWidth ) & & ( fixContributor ! = desContributor ) ) {
fixWidth = WIDTH_NOT_SET ;
fixContributor = nsnull ;
}
1999-07-28 12:09:02 +04:00
// cache the computed column info
colFrame - > SetWidth ( MIN_CON , minWidth ) ;
colFrame - > SetWidth ( DES_CON , desWidth ) ;
1999-08-19 23:52:37 +04:00
colFrame - > SetConstrainingCell ( fixContributor ) ;
1999-07-28 12:09:02 +04:00
if ( fixWidth > 0 ) {
colFrame - > SetWidth ( FIX , PR_MAX ( fixWidth , minWidth ) ) ;
}
// determine if there is a proportional column either from html4
// proportional width on a col or Nav Quirks cols attr
if ( fixWidth < = 0 ) {
nscoord proportion = WIDTH_NOT_SET ;
1999-12-14 01:56:31 +03:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Proportional = = colStyleWidth . GetUnit ( ) ) {
proportion = colStyleWidth . GetIntValue ( ) ;
}
else if ( colX < numColsForColsAttr ) {
proportion = 1 ;
if ( ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) & &
( colStyleWidth . GetPercentValue ( ) > 0.0f ) ) {
proportion = WIDTH_NOT_SET ;
}
}
1999-07-28 12:09:02 +04:00
if ( proportion > = 0 ) {
colFrame - > SetWidth ( MIN_PRO , proportion ) ;
if ( proportion > 0 ) {
propTotal + = proportion ;
colFrame - > SetConstraint ( eProportionConstraint ) ;
1998-08-11 22:42:10 +04:00
}
1999-04-04 03:02:43 +04:00
else {
1999-07-28 12:09:02 +04:00
colFrame - > SetConstraint ( e0ProportionConstraint ) ;
// override the desired, proportional widths
1999-08-24 16:01:31 +04:00
nscoord colMinWidth = colFrame - > GetWidth ( MIN_CON ) ;
colFrame - > SetWidth ( DES_CON , colMinWidth ) ;
2000-02-01 06:23:29 +03:00
colFrame - > SetWidth ( MIN_PRO , 0 ) ;
1998-08-11 22:42:10 +04:00
}
}
}
}
1999-07-28 12:09:02 +04:00
if ( mCellSpacingTotal > 0 ) {
mCellSpacingTotal + = spacingX ; // add last cell spacing on right
}
1998-08-11 22:42:10 +04:00
1999-07-28 12:09:02 +04:00
// figure the proportional width for porportional cols
if ( propTotal > 0 ) {
nscoord minPropTotal = 0 ;
nscoord desPropTotal = 0 ;
// figure the totals of all proportional cols which support every min and desired width
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord colProp = colFrame - > GetWidth ( MIN_PRO ) ;
if ( colProp > 0 ) {
nscoord minWidth = colFrame - > GetWidth ( MIN_CON ) ;
nscoord desWidth = colFrame - > GetWidth ( DES_CON ) ;
minPropTotal = PR_MAX ( minPropTotal , NSToCoordRound ( ( ( float ) propTotal * minWidth ) / ( float ) colProp ) ) ;
desPropTotal = PR_MAX ( desPropTotal , NSToCoordRound ( ( ( float ) propTotal * desWidth ) / ( float ) colProp ) ) ;
1998-06-24 03:23:21 +04:00
}
}
1999-07-28 12:09:02 +04:00
// store a ratio to allow going from a min to a desired proportional width
if ( minPropTotal > 0 ) {
mMinToDesProportionRatio = ( ( float ) desPropTotal ) / ( ( float ) minPropTotal ) ;
}
// figure the cols proportional min width based on the new totals
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord colProp = colFrame - > GetWidth ( MIN_PRO ) ;
if ( colProp > 0 ) {
nscoord minProp = NSToCoordRound ( ( ( float ) colProp * minPropTotal ) / ( float ) propTotal ) ;
colFrame - > SetWidth ( MIN_PRO , minProp ) ;
colFrame - > SetWidth ( DES_CON , NSToCoordRound ( ( ( float ) minProp ) * mMinToDesProportionRatio ) ) ;
1998-06-24 03:23:21 +04:00
}
1998-05-30 02:08:19 +04:00
}
}
1998-05-27 02:03:16 +04:00
1999-07-28 12:09:02 +04:00
// For each col, consider the cells originating in it with colspans > 1.
// Adjust the cols that each cell spans if necessary. Iterate backwards
// so that nested and/or overlaping col spans handle the inner ones first,
// ensuring more accurated calculations.
1999-12-14 01:56:31 +03:00
for ( colX = numCols - 1 ; colX > = 0 ; colX - - ) {
1999-10-16 01:18:32 +04:00
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
1999-07-28 12:09:02 +04:00
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 12:09:02 +04:00
if ( ! originates | | ( 1 = = colSpan ) ) {
continue ;
1998-09-30 03:15:01 +04:00
}
1999-08-04 03:16:43 +04:00
// set MIN_ADJ, DES_ADJ, FIX_ADJ
1999-10-04 09:19:32 +04:00
for ( PRInt32 widthX = 0 ; widthX < NUM_MAJOR_WIDTHS ; widthX + + ) {
2000-09-01 05:29:50 +04:00
ComputeColspanWidths ( widthX , cellFrame , colX , colSpan , PR_FALSE ,
aReflowState . mComputedWidth , aPixelToTwips ) ;
1998-09-30 03:15:01 +04:00
}
1998-08-02 00:31:40 +04:00
}
1998-07-24 01:55:45 +04:00
}
1998-06-30 04:37:03 +04:00
1999-07-28 12:09:02 +04:00
// Set the col's fixed width if present
// Set the table col width for each col to the content min.
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord fixColWidth = colFrame - > GetWidth ( FIX ) ;
// use the style width of a col only if the col hasn't gotten a fixed width from any cell
if ( fixColWidth < = 0 ) {
1999-12-14 01:56:31 +03:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Coord = = colStyleWidth . GetUnit ( ) ) {
fixColWidth = colStyleWidth . GetCoordValue ( ) ;
if ( fixColWidth > 0 ) {
colFrame - > SetWidth ( FIX , fixColWidth ) ;
}
}
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
mTableFrame - > SetColumnWidth ( colX , minWidth ) ;
1999-04-04 03:02:43 +04:00
}
1999-07-28 12:09:02 +04:00
2000-01-22 04:16:50 +03:00
if ( gsDebugAssign ) { printf ( " AssignPrelimColWidths ex \n " ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
1999-07-28 12:09:02 +04:00
return rv ;
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
// Determine percentage col widths for each col frame
2000-02-12 04:55:40 +03:00
nscoord
BasicTableLayoutStrategy : : AssignPercentageColumnWidths ( nscoord aBasisIn ,
2000-09-01 05:29:50 +04:00
PRBool aTableIsAutoWidth ,
float aPixelToTwips )
1999-07-28 12:09:02 +04:00
{
1998-07-11 04:00:31 +04:00
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-07-28 12:09:02 +04:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 colX , rowX ;
2000-02-09 17:22:00 +03:00
nscoord basis ; // basis to use for percentage based calculations
if ( ! aTableIsAutoWidth ) {
if ( NS_UNCONSTRAINEDSIZE = = aBasisIn ) {
return 0 ; // don't do the calculations on unconstrained basis
}
basis = aBasisIn ;
}
else {
// For an auto table, determine the potentially new percent adjusted width based
// on percent cells/cols. This probably should only be a NavQuirks thing, since
// a percentage based cell or column on an auto table should force the column to auto
basis = 0 ;
1999-10-25 08:34:28 +04:00
nscoord fixWidthTotal = 0 ; // total of fixed widths of all cols
float perTotal = 0.0f ; // total of percentage constrained cols and/or cells in cols
PRInt32 numPerCols = 0 ; // number of colums that have percentage constraints
1999-11-06 01:36:59 +03:00
nscoord prefWidthTotal = 0 ; // total of des/fix widths of cols that don't have percentage constraints
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord colBasis = - 1 ;
// Scan the cells in the col
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 12:09:02 +04:00
if ( ! originates ) { // skip cells that don't originate in the col
continue ;
}
// see if the cell has a style percent width specified
const nsStylePosition * cellPosition ;
cellFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
if ( eStyleUnit_Percent = = cellPosition - > mWidth . GetUnit ( ) ) {
float percent = cellPosition - > mWidth . GetPercentValue ( ) ;
colBasis = 0 ;
if ( percent > 0.0f ) {
1999-10-22 02:36:21 +04:00
// calculate the preferred width of the cell based on fixWidth and desWidth
nscoord cellDesWidth = 0 ;
for ( PRInt32 spanX = 0 ; spanX < colSpan ; spanX + + ) {
nsTableColFrame * spanFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
cellDesWidth + = spanFrame - > GetDesWidth ( ) ;
}
// figure the basis using the cell's desired width and percent
2000-09-01 05:29:50 +04:00
colBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) cellDesWidth / percent ) , aPixelToTwips ) ;
1999-10-25 08:34:28 +04:00
perTotal + = percent ;
1998-07-22 07:53:43 +04:00
}
1998-07-18 01:02:28 +04:00
}
1999-07-28 12:09:02 +04:00
}
if ( - 1 = = colBasis ) {
// see if the col has a style percent width specified
1999-12-14 01:56:31 +03:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
float percent = colStyleWidth . GetPercentValue ( ) ;
colBasis = 0 ;
if ( percent > 0.0f ) {
nscoord desWidth = colFrame - > GetDesWidth ( ) ;
2000-09-01 05:29:50 +04:00
colBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) desWidth / percent ) , aPixelToTwips ) ;
1999-12-14 01:56:31 +03:00
}
}
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
basis = PR_MAX ( basis , colBasis ) ;
1999-11-06 01:36:59 +03:00
nscoord fixWidth = colFrame - > GetFixWidth ( ) ;
fixWidthTotal + = fixWidth ;
1999-07-28 12:09:02 +04:00
if ( colBasis > = 0 ) {
numPerCols + + ;
}
1999-10-25 08:34:28 +04:00
else {
1999-11-06 01:36:59 +03:00
prefWidthTotal + = ( fixWidth > 0 ) ? fixWidth : colFrame - > GetDesWidth ( ) ;
1999-10-25 08:34:28 +04:00
}
1999-07-28 12:09:02 +04:00
} // end for (colX ..
1999-11-06 01:36:59 +03:00
// If there are no pct cells or cols, there is nothing to do.
if ( 0 = = numPerCols ) {
return 0 ;
}
1999-07-28 12:09:02 +04:00
// If there is only one col and it is % based, it won't affect anything
1999-12-14 01:56:31 +03:00
if ( ( 1 = = numCols ) & & ( numCols = = numPerCols ) ) {
1999-07-28 12:09:02 +04:00
return 0 ;
1998-07-18 01:02:28 +04:00
}
1999-10-25 08:34:28 +04:00
// compute a basis considering total percentages and the desired width of everything else
if ( perTotal < 1.0f ) {
if ( perTotal > 0.0f ) {
2000-09-01 05:29:50 +04:00
nscoord otherBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) prefWidthTotal / ( 1.0f - perTotal ) ) , aPixelToTwips ) ;
1999-10-25 08:34:28 +04:00
basis = PR_MAX ( basis , otherBasis ) ;
}
}
2000-02-09 17:22:00 +03:00
else if ( ( prefWidthTotal > 0 ) & & ( NS_UNCONSTRAINEDSIZE ! = aBasisIn ) ) { // make the basis as big as possible
1999-10-25 08:34:28 +04:00
basis = aBasisIn ;
}
1999-07-28 12:09:02 +04:00
basis = PR_MAX ( basis , fixWidthTotal ) ;
basis = PR_MIN ( basis , aBasisIn ) ;
}
1998-07-18 01:02:28 +04:00
1999-07-28 12:09:02 +04:00
nscoord colPctTotal = 0 ;
// Determine the percentage contribution for cols and for cells with colspan = 1
// Iterate backwards, similarly to the reasoning in AssignPreliminaryColumnWidths
1999-12-14 01:56:31 +03:00
for ( colX = numCols - 1 ; colX > = 0 ; colX - - ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord maxColPctWidth = WIDTH_NOT_SET ;
float maxColPct = 0.0f ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * percentContributor = nsnull ;
1999-07-28 12:09:02 +04:00
// Scan the cells in the col that have colspan = 1; assign PER widths
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 12:09:02 +04:00
// skip cells that don't originate at (rowX, colX); colspans are handled in the
// next pass, row spans don't need to be handled
if ( ! cellFrame | | ! originates | | ( colSpan > 1 ) ) {
continue ;
}
// see if the cell has a style percent width specified
const nsStylePosition * cellPosition ;
cellFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
if ( eStyleUnit_Percent = = cellPosition - > mWidth . GetUnit ( ) ) {
float percent = cellPosition - > mWidth . GetPercentValue ( ) ;
if ( percent > maxColPct ) {
maxColPct = percent ;
maxColPctWidth = NSToCoordRound ( ( ( float ) basis ) * maxColPct ) ;
1999-08-19 23:52:37 +04:00
percentContributor = cellFrame ;
1999-07-28 12:09:02 +04:00
if ( ! mIsNavQuirksMode ) {
2000-02-12 04:55:40 +03:00
// need to add padding
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( basis , 0 ) , cellFrame ) ;
maxColPctWidth + = padding . left + padding . right ;
1998-06-06 02:50:03 +04:00
}
}
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
}
if ( WIDTH_NOT_SET = = maxColPctWidth ) {
// see if the col has a style percent width specified
1999-12-14 01:56:31 +03:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
maxColPct = colStyleWidth . GetPercentValue ( ) ;
2000-09-01 05:29:50 +04:00
maxColPctWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) basis ) * maxColPct ) , aPixelToTwips ) ;
1999-12-14 01:56:31 +03:00
}
1999-07-28 12:09:02 +04:00
}
// conflicting pct/fixed widths are recorded. Nav 4.x may be changing the
// fixed width value if it exceeds the pct value and not recording the pct
// value. This is not being done and IE5 doesn't do it either.
if ( maxColPctWidth > 0 ) {
2000-05-27 01:13:01 +04:00
maxColPctWidth = PR_MAX ( maxColPctWidth , colFrame - > GetMinWidth ( ) ) ;
1999-07-28 12:09:02 +04:00
colFrame - > SetWidth ( PCT , maxColPctWidth ) ;
1999-08-19 23:52:37 +04:00
colFrame - > SetConstrainingCell ( percentContributor ) ;
2000-05-27 01:13:01 +04:00
colPctTotal + = NSToCoordRound ( 100.0f * ( float ) maxColPct ) ;
1999-07-28 12:09:02 +04:00
}
}
1999-10-04 09:19:32 +04:00
1999-07-28 12:09:02 +04:00
// For each col, consider the cells originating in it with colspans > 1.
// Adjust the cols that each cell spans if necessary.
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 23:52:37 +04:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 12:09:02 +04:00
if ( ! originates | | ( 1 = = colSpan ) ) {
continue ;
1998-05-27 02:03:16 +04:00
}
1999-07-28 12:09:02 +04:00
nscoord cellPctWidth = WIDTH_NOT_SET ;
// see if the cell has a style percentage width specified
const nsStylePosition * cellPosition ;
cellFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
float cellPct = 0.0f ;
if ( eStyleUnit_Percent = = cellPosition - > mWidth . GetUnit ( ) ) {
cellPct = cellPosition - > mWidth . GetPercentValue ( ) ;
2000-09-01 05:29:50 +04:00
cellPctWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) basis ) * cellPct ) , aPixelToTwips ) ;
1999-07-28 12:09:02 +04:00
if ( ! mIsNavQuirksMode ) {
// need to add padding
2000-02-12 04:55:40 +03:00
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( basis , 0 ) , cellFrame ) ;
cellPctWidth + = padding . left + padding . right ;
1999-04-04 03:02:43 +04:00
}
1998-05-30 02:08:19 +04:00
}
1999-07-28 12:09:02 +04:00
if ( cellPctWidth > 0 ) {
nscoord spanCellSpacing = 0 ;
nscoord spanTotal = 0 ;
nscoord colPctWidthTotal = 0 ;
// accumulate the spanTotal as the max of MIN, DES, FIX, PCT
1999-08-24 16:01:31 +04:00
PRInt32 spanX ;
for ( spanX = 0 ; spanX < colSpan ; spanX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
nscoord colPctWidth = colFrame - > GetWidth ( PCT ) ;
if ( colPctWidth > 0 ) { // skip pct cols
colPctWidthTotal + = colPctWidth ;
continue ;
1998-06-06 02:50:03 +04:00
}
1999-07-28 12:09:02 +04:00
nscoord colWidth = PR_MAX ( colFrame - > GetMinWidth ( ) , colFrame - > GetFixWidth ( ) ) ;
1999-08-19 23:52:37 +04:00
colWidth = PR_MAX ( colWidth , colFrame - > GetDesWidth ( ) ) ; // XXX check this
1999-07-28 12:09:02 +04:00
//colWidth = PR_MAX(colWidth, colFrame->GetPctWidth());
spanTotal + = colWidth ;
1999-08-26 01:49:18 +04:00
if ( ( spanX > 0 ) & & ( mTableFrame - > GetNumCellsOriginatingInCol ( colX + spanX ) > 0 ) ) {
1999-07-28 12:09:02 +04:00
spanCellSpacing + = spacingX ;
1998-06-06 02:50:03 +04:00
}
1999-07-28 12:09:02 +04:00
}
cellPctWidth + = spanCellSpacing ; // add it back in since it was subtracted from aBasisIn
if ( cellPctWidth < = 0 ) {
continue ;
}
if ( colPctWidthTotal < cellPctWidth ) {
// record the percent contributions for the spanned cols
1999-08-24 16:01:31 +04:00
for ( spanX = 0 ; spanX < colSpan ; spanX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
if ( colFrame - > GetWidth ( PCT ) > 0 ) { // skip pct cols
continue ;
}
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
nscoord colWidth = PR_MAX ( minWidth , colFrame - > GetFixWidth ( ) ) ;
1999-08-19 23:52:37 +04:00
colWidth = PR_MAX ( colWidth , colFrame - > GetDesWidth ( ) ) ; // XXX check this
1999-11-06 01:36:59 +03:00
float avail = ( float ) PR_MAX ( cellPctWidth - colPctWidthTotal , 0 ) ;
1999-07-28 12:09:02 +04:00
float colPctAdj = ( 0 = = spanTotal )
2000-05-27 01:13:01 +04:00
? avail / ( ( float ) colSpan )
: ( avail / ( float ) basis ) * ( ( ( float ) colWidth ) / ( float ) spanTotal ) ;
1999-07-28 12:09:02 +04:00
if ( colPctAdj > 0 ) {
nscoord colPctAdjWidth = colFrame - > GetWidth ( PCT_ADJ ) ;
2000-09-01 05:29:50 +04:00
nscoord newColPctAdjWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( colPctAdj * ( float ) basis ) , aPixelToTwips ) ;
1999-07-28 12:09:02 +04:00
if ( newColPctAdjWidth > colPctAdjWidth ) {
2000-05-27 01:13:01 +04:00
newColPctAdjWidth = PR_MAX ( newColPctAdjWidth , minWidth ) ;
1999-08-19 23:52:37 +04:00
if ( newColPctAdjWidth > colFrame - > GetWidth ( PCT ) ) {
colFrame - > SetWidth ( PCT_ADJ , newColPctAdjWidth ) ;
colFrame - > SetConstrainingCell ( cellFrame ) ;
}
1999-07-28 12:09:02 +04:00
}
1998-06-06 02:50:03 +04:00
}
1998-05-30 02:08:19 +04:00
}
1998-05-27 02:03:16 +04:00
}
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
} // end for (rowX ..
2000-05-27 01:13:01 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
colPctTotal + = NSToCoordRound ( 100.0f * ( float ) colFrame - > GetWidth ( PCT_ADJ ) / ( float ) basis ) ;
1999-07-28 12:09:02 +04:00
} // end for (colX ..
// if the percent total went over 100%, adjustments need to be made to right most cols
if ( colPctTotal > 100 ) {
2000-05-27 01:13:01 +04:00
nscoord excess = NSToCoordRound ( ( ( float ) ( colPctTotal - 100 ) ) * 0.01f * ( float ) basis ) ;
for ( colX = numCols - 1 ; ( colX > = 0 ) & & ( excess > 0 ) ; colX - - ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord pctWidth = colFrame - > GetWidth ( PCT ) ;
nscoord reduction = 0 ;
if ( pctWidth > 0 ) {
reduction = ( excess > pctWidth ) ? pctWidth : excess ;
nscoord newPctWidth = ( reduction = = pctWidth ) ? WIDTH_NOT_SET : pctWidth - reduction ;
colFrame - > SetWidth ( PCT , PR_MAX ( newPctWidth , colFrame - > GetMinWidth ( ) ) ) ;
}
else {
nscoord pctAdjWidth = colFrame - > GetWidth ( PCT_ADJ ) ;
if ( pctAdjWidth > 0 ) {
reduction = ( excess > pctAdjWidth ) ? pctAdjWidth : excess ;
nscoord newPctAdjWidth = ( reduction = = pctAdjWidth ) ? WIDTH_NOT_SET : pctAdjWidth - reduction ;
colFrame - > SetWidth ( PCT_ADJ , PR_MAX ( newPctAdjWidth , colFrame - > GetMinWidth ( ) ) ) ;
1999-07-28 12:09:02 +04:00
}
}
2000-05-27 01:13:01 +04:00
excess - = reduction ;
1998-04-30 21:57:09 +04:00
}
1998-11-04 22:33:27 +03:00
}
1999-07-28 12:09:02 +04:00
return basis ;
}
2000-05-10 04:54:00 +04:00
nscoord BasicTableLayoutStrategy : : GetTableMinWidth ( ) const
1999-07-28 12:09:02 +04:00
{
2000-05-10 04:54:00 +04:00
nscoord minWidth = 0 ;
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
for ( PRInt32 colX = 0 ; colX < numCols ; colX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
minWidth + = PR_MAX ( colFrame - > GetMinWidth ( ) , colFrame - > GetWidth ( MIN_ADJ ) ) ;
2000-05-17 02:55:34 +04:00
if ( mTableFrame - > GetNumCellsOriginatingInCol ( colX ) > 0 ) {
minWidth + = spacingX ;
}
2000-05-10 04:54:00 +04:00
}
// if it is not a degenerate table, add the last spacing on the right
if ( minWidth > 0 ) {
minWidth + = spacingX ;
}
return minWidth ;
}
1999-07-28 12:09:02 +04:00
2000-05-10 04:54:00 +04:00
nscoord BasicTableLayoutStrategy : : GetTableMaxWidth ( ) const
{
1999-07-28 12:09:02 +04:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2000-05-10 04:54:00 +04:00
nscoord maxWidth = 0 ;
1999-12-14 01:56:31 +03:00
for ( PRInt32 colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-05-17 02:55:34 +04:00
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 ;
1999-08-26 01:49:18 +04:00
if ( mTableFrame - > GetNumCellsOriginatingInCol ( colX ) > 0 ) {
2000-05-10 04:54:00 +04:00
maxWidth + = spacingX ;
1999-04-04 03:02:43 +04:00
}
1998-11-04 22:33:27 +03:00
}
1999-07-28 12:09:02 +04:00
// if it is not a degenerate table, add the last spacing on the right
2000-05-10 04:54:00 +04:00
if ( maxWidth > 0 ) {
maxWidth + = spacingX ;
1998-07-17 03:23:31 +04:00
}
2000-05-10 04:54:00 +04:00
return maxWidth ;
1999-07-28 12:09:02 +04:00
}
1998-07-17 03:23:31 +04:00
2000-09-01 05:29:50 +04:00
// calculate totals by width type. The logic here is kept in synch with
// that in CanAllocate.
1999-07-28 12:09:02 +04:00
void BasicTableLayoutStrategy : : CalculateTotals ( PRInt32 & aCellSpacing ,
PRInt32 * aTotalCounts ,
PRInt32 * aTotalWidths ,
1999-10-04 09:19:32 +04:00
PRInt32 * aTotalAvailWidths ,
1999-07-28 12:09:02 +04:00
PRInt32 * aMinWidths ,
PRInt32 & a0ProportionalCount )
{
//mTableFrame->Dump(PR_TRUE, PR_FALSE);
aCellSpacing = 0 ;
for ( PRInt32 widthX = 0 ; widthX < NUM_WIDTHS ; widthX + + ) {
1999-10-04 09:19:32 +04:00
aTotalCounts [ widthX ] = 0 ;
aTotalWidths [ widthX ] = 0 ;
aTotalAvailWidths [ widthX ] = 0 ;
aMinWidths [ widthX ] = 0 ;
1999-07-28 12:09:02 +04:00
}
a0ProportionalCount = 0 ;
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2000-09-01 05:29:50 +04:00
PRInt32 colX ;
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 12:09:02 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
1999-08-26 01:49:18 +04:00
if ( mTableFrame - > GetNumCellsOriginatingInCol ( colX ) > 0 ) {
1999-07-28 12:09:02 +04:00
aCellSpacing + = spacingX ;
}
nscoord minCol = colFrame - > GetMinWidth ( ) ;
aTotalCounts [ MIN_CON ] + + ;
aTotalWidths [ MIN_CON ] + = minCol ;
if ( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) {
a0ProportionalCount + + ;
}
1999-10-04 09:19:32 +04:00
nscoord pct = colFrame - > GetPctWidth ( ) ;
nscoord fix = colFrame - > GetWidth ( FIX ) ;
nscoord fixAdj = colFrame - > GetWidth ( FIX_ADJ ) ;
// if there is a pct width then no others are considered
if ( pct > 0 ) {
1999-07-28 12:09:02 +04:00
aTotalCounts [ PCT ] + + ;
1999-10-04 09:19:32 +04:00
aTotalWidths [ PCT ] + = pct ;
aTotalAvailWidths [ PCT ] + = pct ;
1999-07-28 12:09:02 +04:00
aMinWidths [ PCT ] + = minCol ;
continue ;
}
1999-10-04 09:19:32 +04:00
if ( ( fix > 0 ) | | ( fixAdj > 0 ) ) {
if ( fix > 0 ) {
aTotalCounts [ FIX ] + + ;
aTotalWidths [ FIX ] + = fix ;
aTotalAvailWidths [ FIX ] + = fix ;
aMinWidths [ FIX ] + = minCol ;
}
nscoord desCon = colFrame - > GetWidth ( DES_CON ) ;
if ( fixAdj > 0 ) {
if ( fixAdj > fix ) {
aTotalCounts [ FIX_ADJ ] + + ;
aTotalWidths [ FIX_ADJ ] + = fixAdj ;
aTotalAvailWidths [ FIX_ADJ ] + = fixAdj ;
if ( fix > 0 ) {
aTotalAvailWidths [ FIX_ADJ ] - = fix ;
}
else { // there was no fix
aMinWidths [ FIX_ADJ ] + = minCol ;
}
2000-09-01 05:29:50 +04:00
// include the DES_CON of a FIX_ADJ that has no FIX
if ( mIsNavQuirksMode & & ( desCon > fixAdj ) & & ( fix < = 0 ) ) {
1999-10-04 09:19:32 +04:00
aTotalCounts [ DES_CON ] + + ;
aTotalWidths [ DES_CON ] + = desCon ;
aTotalAvailWidths [ DES_CON ] + = desCon ;
if ( fixAdj > 0 ) {
aTotalAvailWidths [ DES_CON ] - = fixAdj ;
}
}
}
}
1999-07-28 12:09:02 +04:00
continue ;
}
1998-07-17 03:23:31 +04:00
1999-07-28 12:09:02 +04:00
if ( eProportionConstraint = = colFrame - > GetConstraint ( ) ) {
nscoord minProp = colFrame - > GetWidth ( MIN_PRO ) ;
aTotalCounts [ MIN_PRO ] + + ;
aTotalWidths [ MIN_PRO ] + = minProp ;
1999-10-04 09:19:32 +04:00
aTotalAvailWidths [ MIN_PRO ] = aTotalWidths [ MIN_PRO ] ;
1999-07-28 12:09:02 +04:00
aTotalCounts [ DES_CON ] + + ;
aTotalWidths [ DES_CON ] + = NSToCoordRound ( ( ( float ) minProp ) * mMinToDesProportionRatio ) ;
1999-10-04 09:19:32 +04:00
aTotalAvailWidths [ DES_CON ] = aTotalWidths [ DES_CON ] ;
1999-07-28 12:09:02 +04:00
aMinWidths [ MIN_PRO ] + = minCol ;
aMinWidths [ DES_CON ] + = minProp ;
1999-10-04 09:19:32 +04:00
continue ;
1999-07-28 12:09:02 +04:00
}
1999-10-04 09:19:32 +04:00
// desired alone is lowest priority
aTotalCounts [ DES_CON ] + + ;
aTotalWidths [ DES_CON ] + = colFrame - > GetDesWidth ( ) ;
aTotalAvailWidths [ DES_CON ] = aTotalWidths [ DES_CON ] ;
aMinWidths [ DES_CON ] + = minCol ;
1998-05-30 02:08:19 +04:00
}
1999-07-28 12:09:02 +04:00
// if it is not a degenerate table, add the last spacing on the right
1999-12-14 01:56:31 +03:00
if ( numCols > 0 ) {
1999-07-28 12:09:02 +04:00
aCellSpacing + = spacingX ;
1998-07-13 22:11:12 +04:00
}
1998-04-30 21:57:09 +04:00
}
1999-07-28 12:09:02 +04:00
1999-05-10 23:23:09 +04:00
struct nsColInfo {
1999-05-27 02:22:23 +04:00
nsColInfo ( nsTableColFrame * aFrame ,
PRInt32 aIndex ,
PRInt32 aMinWidth ,
PRInt32 aWidth ,
PRInt32 aMaxWidth )
: mFrame ( aFrame ) , mIndex ( aIndex ) , mMinWidth ( aMinWidth ) ,
1999-07-28 12:09:02 +04:00
mWidth ( aWidth ) , mMaxWidth ( aMaxWidth ) , mWeight ( 0 )
1999-05-27 02:22:23 +04:00
{ }
nsTableColFrame * mFrame ;
PRInt32 mIndex ;
PRInt32 mMinWidth ;
PRInt32 mWidth ;
PRInt32 mMaxWidth ;
float mWeight ;
1999-05-10 23:23:09 +04:00
} ;
void
1999-07-28 12:09:02 +04:00
AC_Wrapup ( nsTableFrame * aTableFrame ,
1999-07-28 23:43:37 +04:00
PRInt32 aNumItems ,
nsColInfo * * aColInfo ,
PRBool aAbort = PR_FALSE )
1999-05-10 23:23:09 +04:00
{
1999-07-28 12:09:02 +04:00
if ( aColInfo ) {
for ( PRInt32 i = 0 ; i < aNumItems ; i + + ) {
if ( aColInfo [ i ] ) {
if ( ! aAbort ) {
aTableFrame - > SetColumnWidth ( aColInfo [ i ] - > mIndex , aColInfo [ i ] - > mWidth ) ;
}
delete aColInfo [ i ] ;
}
}
delete [ ] aColInfo ;
1999-05-27 02:22:23 +04:00
}
}
void
1999-07-28 12:09:02 +04:00
AC_Increase ( PRInt32 aNumAutoCols ,
1999-08-23 08:41:30 +04:00
nsColInfo * * aColInfo ,
PRInt32 aDivisor ,
2000-09-01 05:29:50 +04:00
PRInt32 & aAvailWidth ,
float aPixelToTwips )
1999-05-27 02:22:23 +04:00
{
for ( PRInt32 i = 0 ; i < aNumAutoCols ; i + + ) {
if ( ( aAvailWidth < = 0 ) | | ( aDivisor < = 0 ) ) {
break ;
}
2000-02-09 17:22:00 +03:00
// aDivisor represents the sum of unallocated space (diff between max and min values)
float percent = ( ( float ) aColInfo [ i ] - > mMaxWidth - ( float ) aColInfo [ i ] - > mMinWidth ) / ( float ) aDivisor ;
aDivisor - = aColInfo [ i ] - > mMaxWidth - aColInfo [ i ] - > mMinWidth ;
2000-09-01 05:29:50 +04:00
nscoord addition = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) ( aAvailWidth ) ) * percent ) , aPixelToTwips ) ;
1999-08-23 08:41:30 +04:00
// if its the last col, try to give what's left to it
if ( ( i = = aNumAutoCols - 1 ) & & ( addition < aAvailWidth ) ) {
addition = aAvailWidth ;
1999-05-27 02:22:23 +04:00
}
1999-08-23 08:41:30 +04:00
// don't let the addition exceed what is available to add
addition = PR_MIN ( addition , aAvailWidth ) ;
// don't go over the col max
addition = PR_MIN ( addition , aColInfo [ i ] - > mMaxWidth - aColInfo [ i ] - > mWidth ) ;
1999-05-27 02:22:23 +04:00
aColInfo [ i ] - > mWidth + = addition ;
aAvailWidth - = addition ;
}
}
void
1999-07-28 12:09:02 +04:00
AC_Decrease ( PRInt32 aNumAutoCols ,
1999-08-23 08:41:30 +04:00
nsColInfo * * aColInfo ,
PRInt32 aDivisor ,
2000-09-01 05:29:50 +04:00
PRInt32 & aExcess ,
float aPixelToTwips )
1999-05-27 02:22:23 +04:00
{
for ( PRInt32 i = 0 ; i < aNumAutoCols ; i + + ) {
if ( ( aExcess < = 0 ) | | ( aDivisor < = 0 ) ) {
break ;
}
float percent = ( ( float ) aColInfo [ i ] - > mMaxWidth ) / ( float ) aDivisor ;
aDivisor - = aColInfo [ i ] - > mMaxWidth ;
2000-09-01 05:29:50 +04:00
nscoord reduction = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) ( aExcess ) ) * percent ) , aPixelToTwips ) ;
1999-08-23 08:41:30 +04:00
// if its the last col, try to remove the remaining excess from it
if ( ( i = = aNumAutoCols - 1 ) & & ( reduction < aExcess ) ) {
reduction = aExcess ;
1999-05-27 02:22:23 +04:00
}
1999-08-23 08:41:30 +04:00
// don't let the reduction exceed what is available to reduce
reduction = PR_MIN ( reduction , aExcess ) ;
// don't go under the col min
reduction = PR_MIN ( reduction , aColInfo [ i ] - > mWidth - aColInfo [ i ] - > mMinWidth ) ;
1999-05-27 02:22:23 +04:00
aColInfo [ i ] - > mWidth - = reduction ;
aExcess - = reduction ;
}
}
void
1999-07-28 12:09:02 +04:00
AC_Sort ( nsColInfo * * aColInfo , PRInt32 aNumCols )
1999-05-27 02:22:23 +04:00
{
// sort the cols based on the Weight
for ( PRInt32 j = aNumCols - 1 ; j > 0 ; j - - ) {
for ( PRInt32 i = 0 ; i < j ; i + + ) {
if ( aColInfo [ i ] - > mWeight < aColInfo [ i + 1 ] - > mWeight ) { // swap them
nsColInfo * save = aColInfo [ i ] ;
aColInfo [ i ] = aColInfo [ i + 1 ] ;
aColInfo [ i + 1 ] = save ;
}
}
1999-05-10 23:23:09 +04:00
}
}
1999-10-04 09:19:32 +04:00
1999-07-28 12:09:02 +04:00
// this assumes that the table has set the width for each col to be its min
void BasicTableLayoutStrategy : : AllocateConstrained ( PRInt32 aAvailWidth ,
PRInt32 aWidthType ,
PRBool aStartAtMin ,
2000-09-01 05:29:50 +04:00
PRInt32 * aAllocTypes ,
float aPixelToTwips )
1999-05-27 02:22:23 +04:00
{
1999-10-04 09:19:32 +04:00
if ( ( 0 = = aAvailWidth ) | | ( aWidthType < 0 ) | | ( aWidthType > = NUM_WIDTHS ) ) {
1999-07-28 12:09:02 +04:00
NS_ASSERTION ( PR_TRUE , " invalid args to AllocateConstrained " ) ;
1999-05-27 02:22:23 +04:00
return ;
}
1999-12-14 01:56:31 +03:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-10-04 09:19:32 +04:00
PRInt32 numConstrainedCols = 0 ;
nscoord sumMaxConstraints = 0 ;
2000-02-09 17:22:00 +03:00
nscoord sumMinConstraints = 0 ;
1999-11-06 01:36:59 +03:00
PRBool useAdj = PR_TRUE ;
1999-10-04 09:19:32 +04:00
PRInt32 colX ;
2000-02-09 17:22:00 +03:00
// find out how many constrained cols there are
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 09:19:32 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-09-01 05:29:50 +04:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame , mIsNavQuirksMode , useAdj ) ) {
1999-11-06 01:36:59 +03:00
if ( - 1 ! = aAllocTypes [ colX ] ) {
1999-10-04 09:19:32 +04:00
continue ;
}
}
numConstrainedCols + + ;
nscoord width = colFrame - > GetWidth ( aWidthType ) ;
1999-11-06 01:36:59 +03:00
if ( ( DES_CON = = aWidthType ) & & useAdj ) {
1999-10-04 09:19:32 +04:00
width = PR_MAX ( width , colFrame - > GetWidth ( DES_ADJ ) ) ;
}
else if ( PCT = = aWidthType ) {
width = PR_MAX ( width , colFrame - > GetWidth ( PCT_ADJ ) ) ;
}
}
2000-02-09 17:22:00 +03:00
// allocate storage for the constrained cols. Only they get adjusted.
1999-10-04 09:19:32 +04:00
nsColInfo * * colInfo = new nsColInfo * [ numConstrainedCols ] ;
1999-07-28 23:43:37 +04:00
if ( ! colInfo ) return ;
1999-10-04 09:19:32 +04:00
memset ( colInfo , 0 , numConstrainedCols * sizeof ( nsColInfo * ) ) ;
1999-07-28 23:43:37 +04:00
1999-07-28 12:09:02 +04:00
PRInt32 maxMinDiff = 0 ;
PRInt32 constrColX = 0 ;
// set the col info entries for each constrained col
1999-12-14 01:56:31 +03:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 09:19:32 +04:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-09-01 05:29:50 +04:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame , mIsNavQuirksMode , useAdj ) ) {
1999-11-06 01:36:59 +03:00
if ( - 1 ! = aAllocTypes [ colX ] ) {
1999-10-04 09:19:32 +04:00
continue ;
}
1999-07-28 12:09:02 +04:00
}
nscoord minWidth = mTableFrame - > GetColumnWidth ( colX ) ;
nscoord maxWidth = colFrame - > GetWidth ( aWidthType ) ;
1999-11-06 01:36:59 +03:00
if ( ( DES_CON = = aWidthType ) & & useAdj ) {
1999-07-28 12:09:02 +04:00
maxWidth = PR_MAX ( maxWidth , colFrame - > GetWidth ( DES_ADJ ) ) ;
}
else if ( PCT = = aWidthType ) {
maxWidth = PR_MAX ( maxWidth , colFrame - > GetWidth ( PCT_ADJ ) ) ;
}
if ( maxWidth < = 0 ) {
continue ;
}
2000-02-09 17:22:00 +03:00
sumMaxConstraints + = maxWidth ;
sumMinConstraints + = minWidth ;
1999-10-04 09:19:32 +04:00
1999-07-28 12:09:02 +04:00
maxWidth = PR_MAX ( maxWidth , minWidth ) ;
maxMinDiff + = maxWidth - minWidth ;
nscoord startWidth = ( aStartAtMin ) ? minWidth : maxWidth ;
1999-07-28 23:43:37 +04:00
colInfo [ constrColX ] = new nsColInfo ( colFrame , colX , minWidth , startWidth , maxWidth ) ;
1999-07-28 12:09:02 +04:00
if ( ! colInfo [ constrColX ] ) {
1999-10-04 09:19:32 +04:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo , PR_TRUE ) ;
1999-07-28 12:09:02 +04:00
return ;
}
aAllocTypes [ colX ] = aWidthType ;
1999-07-28 23:43:37 +04:00
constrColX + + ;
1999-05-27 02:22:23 +04:00
}
1999-10-04 09:19:32 +04:00
if ( constrColX < numConstrainedCols ) {
1999-07-28 12:09:02 +04:00
// some of the constrainted cols might have been 0 and skipped
1999-10-04 09:19:32 +04:00
numConstrainedCols = constrColX ;
1999-07-28 12:09:02 +04:00
}
1999-10-04 09:19:32 +04:00
1999-07-28 12:09:02 +04:00
PRInt32 i ;
if ( aStartAtMin ) { // allocate extra space
nscoord availWidth = aAvailWidth ;
1999-10-04 09:19:32 +04:00
for ( i = 0 ; i < numConstrainedCols ; i + + ) {
1999-07-28 12:09:02 +04:00
// the weight here is a relative metric for determining when cols reach their max constraint.
1999-05-27 02:22:23 +04:00
// A col with a larger weight will reach its max before one with a smaller value.
nscoord delta = colInfo [ i ] - > mMaxWidth - colInfo [ i ] - > mWidth ;
colInfo [ i ] - > mWeight = ( delta < = 0 )
? 1000000 // cols which have already reached their max get a large value
: ( ( float ) colInfo [ i ] - > mMaxWidth ) / ( ( float ) delta ) ;
}
// sort the cols based on the weight so that in one pass cols with higher
// weights will get their max earlier than ones with lower weights
// This is an innefficient bubble sort, but unless there are an unlikely
// large number of cols, it is not an issue.
1999-10-04 09:19:32 +04:00
AC_Sort ( colInfo , numConstrainedCols ) ;
1999-05-27 02:22:23 +04:00
// compute the proportion to be added to each column, don't go beyond the col's
// max. This algorithm assumes that the Weight works as stated above
2000-09-01 05:29:50 +04:00
AC_Increase ( numConstrainedCols , colInfo , sumMaxConstraints - sumMinConstraints ,
availWidth , aPixelToTwips ) ;
1999-05-27 02:22:23 +04:00
}
1999-07-28 12:09:02 +04:00
else { // reduce each col width
nscoord reduceWidth = maxMinDiff - aAvailWidth ;
if ( reduceWidth < 0 ) {
NS_ASSERTION ( PR_TRUE , " AllocateConstrained called incorrectly " ) ;
1999-10-04 09:19:32 +04:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo ) ;
1999-07-28 12:09:02 +04:00
return ;
}
1999-10-04 09:19:32 +04:00
for ( i = 0 ; i < numConstrainedCols ; i + + ) {
1999-05-27 02:22:23 +04:00
// the weight here is a relative metric for determining when cols reach their min.
// A col with a larger weight will reach its min before one with a smaller value.
nscoord delta = colInfo [ i ] - > mWidth - colInfo [ i ] - > mMinWidth ;
colInfo [ i ] - > mWeight = ( delta < = 0 )
? 1000000 // cols which have already reached their min get a large value
: ( ( float ) colInfo [ i ] - > mWidth ) / ( ( float ) delta ) ;
}
// sort the cols based on the Weight
1999-10-04 09:19:32 +04:00
AC_Sort ( colInfo , numConstrainedCols ) ;
1999-05-27 02:22:23 +04:00
// compute the proportion to be subtracted from each column, don't go beyond
// the col's min. This algorithm assumes that the Weight works as stated above
2000-09-01 05:29:50 +04:00
AC_Decrease ( numConstrainedCols , colInfo , sumMaxConstraints , reduceWidth , aPixelToTwips ) ;
1999-05-10 23:23:09 +04:00
}
1999-10-04 09:19:32 +04:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo ) ;
1998-07-17 03:23:31 +04:00
}
1999-08-19 23:52:37 +04:00
// XXX this function will be improved after the colspan algorithms have been extracted
// from AssignPreliminarColumnWidths and AssignPercentageColumnWidths. For now, pessimistic
// assumptions are made
PRBool BasicTableLayoutStrategy : : ColumnsCanBeInvalidatedBy ( nsStyleCoord * aPrevStyleWidth ,
1999-08-21 03:27:54 +04:00
const nsTableCellFrame & aCellFrame ) const
1999-08-19 23:52:37 +04:00
{
1999-08-21 03:27:54 +04:00
if ( ! mTableFrame )
1999-08-19 23:52:37 +04:00
return PR_TRUE ;
1998-07-25 03:26:23 +04:00
1999-08-19 23:52:37 +04:00
const nsStylePosition * cellPosition ;
aCellFrame . GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) cellPosition ) ;
const nsStyleCoord & styleWidth = cellPosition - > mWidth ;
PRInt32 colIndex ;
aCellFrame . GetColIndex ( colIndex ) ;
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colIndex ) ;
2000-01-15 23:10:00 +03:00
nscoord colSpan = mTableFrame - > GetEffectiveColSpan ( aCellFrame ) ;
1999-08-19 23:52:37 +04:00
if ( aPrevStyleWidth ) {
nsTableColFrame * colSpanFrame = colFrame ;
// see if this cell is responsible for setting a fixed or percentage based col
for ( PRInt32 span = 1 ; span < = colSpan ; span + + ) {
if ( & aCellFrame = = colSpanFrame - > GetConstrainingCell ( ) )
return PR_TRUE ; // assume that the style change will affect cols
if ( span < colSpan )
colSpanFrame = mTableFrame - > GetColFrame ( colIndex + span ) ;
}
// if we get here, the cell was not responsible for a fixed or percentage col
switch ( aPrevStyleWidth - > GetUnit ( ) ) {
case eStyleUnit_Percent :
if ( eStyleUnit_Percent = = styleWidth . GetUnit ( ) ) {
// PCT to PCT
if ( aPrevStyleWidth - > GetPercentValue ( ) < styleWidth . GetPercentValue ( ) )
return PR_TRUE ; // XXX see comments above
}
// PCT to FIX and PCT to AUTO changes have no effect since PCT allocations
// are the highest priority and the cell's previous PCT value did not
// cause it to be responsible for setting any cells PCT_ADJ
case eStyleUnit_Coord :
if ( eStyleUnit_Percent = = styleWidth . GetUnit ( ) ) {
// FIX to PCT
return PR_TRUE ; // XXX see comments above
}
else if ( eStyleUnit_Coord = = styleWidth . GetUnit ( ) ) {
// FIX to FIX
nscoord newWidth = styleWidth . GetCoordValue ( ) ;
if ( aPrevStyleWidth - > GetCoordValue ( ) < newWidth ) {
if ( colSpan > 1 )
return PR_TRUE ; // XXX see comments above
if ( newWidth > colFrame - > GetFixWidth ( ) )
return PR_TRUE ; // XXX see comments above
}
}
// FIX to AUTO results in no column changes here
case eStyleUnit_Auto :
if ( eStyleUnit_Percent = = styleWidth . GetUnit ( ) ) {
// AUTO to PCT
return PR_TRUE ; // XXX see comments above
}
else if ( eStyleUnit_Coord = = styleWidth . GetUnit ( ) ) {
// AUTO to FIX
return PR_TRUE ; // XXX see comments above
}
// AUTO to AUTO is not a style change
1999-08-24 16:01:31 +04:00
default :
break ;
1999-08-19 23:52:37 +04:00
}
}
return PR_FALSE ;
}
// XXX this function will be improved after the colspan algorithms have been extracted
// from AssignPreliminarColumnWidths and AssignPercentageColumnWidths. For now, pessimistic
// assumptions are made
PRBool BasicTableLayoutStrategy : : ColumnsCanBeInvalidatedBy ( const nsTableCellFrame & aCellFrame ,
PRBool aConsiderMinWidth ) const
{
if ( aConsiderMinWidth | | ! mTableFrame )
return PR_TRUE ;
PRInt32 colIndex ;
aCellFrame . GetColIndex ( colIndex ) ;
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colIndex ) ;
2000-01-15 23:10:00 +03:00
nscoord colSpan = mTableFrame - > GetEffectiveColSpan ( aCellFrame ) ;
1999-08-19 23:52:37 +04:00
// check to see if DES_CON can affect columns
nsTableColFrame * spanFrame = colFrame ;
for ( PRInt32 span = 0 ; span < colSpan ; span + + ) {
// see if the column width is constrained
if ( ( spanFrame - > GetPctWidth ( ) > 0 ) | | ( spanFrame - > GetFixWidth ( ) > 0 ) | |
( spanFrame - > GetWidth ( MIN_PRO ) > 0 ) ) {
if ( ( spanFrame - > GetWidth ( PCT_ADJ ) > 0 ) & & ( spanFrame - > GetWidth ( PCT ) < = 0 ) ) {
return PR_TRUE ;
}
if ( ( spanFrame - > GetWidth ( FIX_ADJ ) > 0 ) & & ( spanFrame - > GetWidth ( FIX ) < = 0 ) ) {
return PR_TRUE ; // its unfortunate that the balancing algorithms cause this
}
}
else {
return PR_TRUE ; // XXX need to add cases if table has coord width specified
}
if ( span < colSpan - 1 )
spanFrame = mTableFrame - > GetColFrame ( colIndex + span + 1 ) ;
}
return PR_FALSE ;
}
PRBool BasicTableLayoutStrategy : : ColumnsAreValidFor ( const nsTableCellFrame & aCellFrame ,
nscoord aPrevCellMin ,
nscoord aPrevCellDes ) const
{
PRInt32 colIndex ;
aCellFrame . GetColIndex ( colIndex ) ;
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colIndex ) ;
2000-01-15 23:10:00 +03:00
nscoord colSpan = mTableFrame - > GetEffectiveColSpan ( aCellFrame ) ;
1999-08-19 23:52:37 +04:00
nscoord cellMin = aCellFrame . GetPass1MaxElementSize ( ) . width ;
1999-12-24 06:46:21 +03:00
nscoord cellDes = aCellFrame . GetMaximumWidth ( ) ;
1999-08-19 23:52:37 +04:00
nscoord colMin = colFrame - > GetMinWidth ( ) ;
nscoord colDes = colFrame - > GetDesWidth ( ) ;
PRBool minChanged = PR_TRUE ;
if ( ( ( cellMin > aPrevCellMin ) & & ( cellMin < = colMin ) ) | |
( ( cellMin < = aPrevCellMin ) & & ( aPrevCellMin < = colMin ) ) ) {
minChanged = PR_FALSE ;
}
if ( minChanged ) {
1999-08-21 03:27:54 +04:00
return PR_FALSE ; // XXX add cases where table has coord width and cell is constrained
1999-08-19 23:52:37 +04:00
}
1999-08-22 06:36:00 +04:00
PRBool desChanged = PR_TRUE ;
2000-05-26 02:40:21 +04:00
if ( ( ( cellDes > aPrevCellDes ) & & ( cellDes < = colDes ) ) | |
( cellDes = = aPrevCellDes ) ) {
2000-01-13 00:53:55 +03:00
// XXX This next check causes a problem if the cell's desired width shrinks,
// because the comparison (aPresCellDes <= colDes) will always be TRUE and
// so we always end up setting desChanged to PR_FALSE. That means the column
// won't shrink like it should
#if 0
2000-05-26 02:40:21 +04:00
| | ( ( cellDes < aPrevCellDes ) & & ( aPrevCellDes < = colDes ) ) ) {
2000-01-13 00:53:55 +03:00
# endif
1999-08-19 23:52:37 +04:00
desChanged = PR_FALSE ;
}
if ( 1 = = colSpan ) {
// see if the column width is constrained
if ( ( colFrame - > GetPctWidth ( ) > 0 ) | | ( colFrame - > GetFixWidth ( ) > 0 ) | |
( colFrame - > GetWidth ( MIN_PRO ) > 0 ) ) {
if ( ( colFrame - > GetWidth ( PCT_ADJ ) > 0 ) & & ( colFrame - > GetWidth ( PCT ) < = 0 ) ) {
if ( desChanged ) {
1999-08-21 03:27:54 +04:00
return PR_FALSE ; // XXX add cases where table has coord width
1999-08-19 23:52:37 +04:00
}
}
if ( ( colFrame - > GetWidth ( FIX_ADJ ) > 0 ) & & ( colFrame - > GetWidth ( FIX ) < = 0 ) ) {
if ( desChanged ) {
1999-08-21 03:27:54 +04:00
return PR_FALSE ; // its unfortunate that the balancing algorithms cause this
1999-08-19 23:52:37 +04:00
// XXX add cases where table has coord width
}
}
}
else { // the column width is not constrained
if ( desChanged ) {
1999-08-21 03:27:54 +04:00
return PR_FALSE ;
1999-08-19 23:52:37 +04:00
}
}
}
else {
1999-08-21 03:27:54 +04:00
return PR_FALSE ; // XXX this needs a lot of cases
1999-08-19 23:52:37 +04:00
}
1999-08-21 03:27:54 +04:00
return PR_TRUE ;
1999-08-19 23:52:37 +04:00
}
1998-07-24 01:55:45 +04:00
PRBool BasicTableLayoutStrategy : : IsColumnInList ( const PRInt32 colIndex ,
1999-04-04 03:02:43 +04:00
PRInt32 * colIndexes ,
PRInt32 aNumFixedColumns )
1998-07-24 01:55:45 +04:00
{
PRBool result = PR_FALSE ;
1999-04-04 03:02:43 +04:00
for ( PRInt32 i = 0 ; i < aNumFixedColumns ; i + + ) {
if ( colIndex = = colIndexes [ i ] ) {
1998-07-24 01:55:45 +04:00
result = PR_TRUE ;
break ;
}
1999-04-04 03:02:43 +04:00
else if ( colIndex < colIndexes [ i ] ) {
1998-07-24 01:55:45 +04:00
break ;
1999-04-04 03:02:43 +04:00
}
1998-07-24 01:55:45 +04:00
}
return result ;
}
1998-07-17 03:23:31 +04:00
1998-08-14 20:16:43 +04:00
PRBool BasicTableLayoutStrategy : : ColIsSpecifiedAsMinimumWidth ( PRInt32 aColIndex )
{
PRBool result = PR_FALSE ;
nsTableColFrame * colFrame ;
mTableFrame - > GetColumnFrame ( aColIndex , colFrame ) ;
1999-12-14 01:56:31 +03:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
switch ( colStyleWidth . GetUnit ( ) ) {
1998-08-14 20:16:43 +04:00
case eStyleUnit_Coord :
1999-12-14 01:56:31 +03:00
if ( 0 = = colStyleWidth . GetCoordValue ( ) ) {
1998-08-14 20:16:43 +04:00
result = PR_TRUE ;
1999-04-04 03:02:43 +04:00
}
1998-08-14 20:16:43 +04:00
break ;
case eStyleUnit_Percent :
{
// total hack for now for 0% and 1% specifications
// should compare percent to available parent width and see that it is below minimum
// for this column
1999-12-14 01:56:31 +03:00
float percent = colStyleWidth . GetPercentValue ( ) ;
1999-04-04 03:02:43 +04:00
if ( 0.0f = = percent | | 0.01f = = percent ) {
1998-08-14 20:16:43 +04:00
result = PR_TRUE ;
1999-04-04 03:02:43 +04:00
}
1998-08-14 20:16:43 +04:00
break ;
}
case eStyleUnit_Proportional :
1999-12-14 01:56:31 +03:00
if ( 0 = = colStyleWidth . GetIntValue ( ) ) {
1999-04-04 03:02:43 +04:00
result = PR_TRUE ;
}
1999-02-12 20:45:58 +03:00
default :
break ;
1998-08-14 20:16:43 +04:00
}
return result ;
}
1999-07-28 12:09:02 +04:00
void BasicTableLayoutStrategy : : Dump ( PRInt32 aIndent )
1998-10-03 00:34:11 +04:00
{
1999-07-28 12:09:02 +04:00
char * indent = new char [ aIndent + 1 ] ;
for ( PRInt32 i = 0 ; i < aIndent + 1 ; i + + ) {
indent [ i ] = ' ' ;
}
indent [ aIndent ] = 0 ;
1999-12-14 01:56:31 +03:00
printf ( " %s**START BASIC STRATEGY DUMP** table=%p cols=%X " ,
indent , mTableFrame , mCols ) ;
2000-05-10 04:54:00 +04:00
printf ( " \n %s cellSpacing=%d propRatio=%.2f navQuirks=%d " ,
indent , mCellSpacingTotal , mMinToDesProportionRatio , mIsNavQuirksMode ) ;
1999-07-28 12:09:02 +04:00
printf ( " **END BASIC STRATEGY DUMP** \n " ) ;
delete [ ] indent ;
1998-10-03 00:34:11 +04:00
}
1998-08-14 20:16:43 +04:00