1998-04-30 17:57:09 +00:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
1999-11-06 03:40:37 +00: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 17:57:09 +00:00
*
1999-11-06 03:40:37 +00: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 17:57:09 +00:00
*
1999-11-06 03:40:37 +00:00
* The Original Code is mozilla . org code .
*
* The Initial Developer of the Original Code is Netscape
1998-04-30 17:57:09 +00:00
* Communications Corporation . Portions created by Netscape are
1999-11-06 03:40:37 +00:00
* Copyright ( C ) 1998 Netscape Communications Corporation . All
* Rights Reserved .
*
* Contributor ( s ) :
1998-04-30 17:57:09 +00:00
*/
# include "BasicTableLayoutStrategy.h"
2000-09-01 01:29:50 +00:00
# include "nsIPresContext.h"
1998-04-30 17:57:09 +00:00
# include "nsTableFrame.h"
1998-05-29 22:08:19 +00:00
# include "nsTableColFrame.h"
1998-04-30 17:57:09 +00:00
# include "nsTableCellFrame.h"
# include "nsIStyleContext.h"
# include "nsStyleConsts.h"
1998-07-11 00:00:31 +00:00
# include "nsVoidArray.h"
1998-05-30 21:21:51 +00:00
# include "nsHTMLIIDs.h"
1998-04-30 17:57:09 +00:00
1999-10-18 13:48:19 +00:00
# if 1
1999-08-21 06:38:07 +00:00
static PRBool gsDebugAssign = PR_FALSE ;
static PRBool gsDebugBalance = PR_FALSE ;
1999-10-18 13:48:19 +00:00
# else
static PRBool gsDebugAssign = PR_TRUE ;
static PRBool gsDebugBalance = PR_TRUE ;
# endif
2000-02-02 00:48:30 +00:00
static PRInt32 gsDebugCount = 0 ;
1999-08-21 06:38:07 +00:00
2000-09-09 01:46:44 +00:00
// The priority of allocations for columns is as follows
// 1) max(MIN, MIN_ADJ)
// 2) max (PCT, PCT_ADJ)
// 3) FIX
// 4) FIX_ADJ
2001-01-12 23:07:54 +00:00
// 5) max(DES_CON, DES_ADJ), but use MIN_PRO if present
// 6) for a fixed width table, the column may get more
2000-09-09 01:46:44 +00:00
// space if the sum of the col allocations is insufficient
2000-09-01 01:29:50 +00:00
// the logic here is kept in synch with that in CalculateTotals.
2000-12-19 20:29:46 +00:00
PRBool CanAllocate ( PRInt32 aType ,
PRInt32 aPrevType ,
nsTableColFrame * aColFrame )
1999-10-04 05:19:32 +00:00
{
2000-12-19 20:29:46 +00:00
switch ( aType ) {
case PCT :
case FIX :
case DES_CON :
return ( WIDTH_NOT_SET = = aPrevType ) ;
case FIX_ADJ :
return ( WIDTH_NOT_SET = = aPrevType ) | | ( FIX = = aPrevType ) ;
default :
NS_ASSERTION ( PR_FALSE , " invalid call " ) ;
1999-10-04 05:19:32 +00:00
}
return PR_FALSE ;
}
2001-03-13 06:38:59 +00:00
// this doesn't work for a col frame which might get its width from a col
PRBool
HasPctValue ( nsIFrame * aFrame )
{
const nsStylePosition * position ;
aFrame - > GetStyleData ( eStyleStruct_Position , ( const nsStyleStruct * & ) position ) ;
if ( eStyleUnit_Percent = = position - > mWidth . GetUnit ( ) ) {
float percent = position - > mWidth . GetPercentValue ( ) ;
if ( percent > 0.0f ) {
return PR_TRUE ;
}
}
return PR_FALSE ;
}
1998-05-29 22:08:19 +00:00
/* ---------- BasicTableLayoutStrategy ---------- */
2001-01-27 23:06:33 +00:00
MOZ_DECL_CTOR_COUNTER ( BasicTableLayoutStrategy )
1999-10-08 20:41:19 +00:00
1998-05-26 22:03:16 +00:00
1999-05-26 22:22:23 +00:00
BasicTableLayoutStrategy : : BasicTableLayoutStrategy ( nsTableFrame * aFrame , PRBool aIsNavQuirks )
1998-04-30 17:57:09 +00:00
{
1999-10-08 20:41:19 +00:00
MOZ_COUNT_CTOR ( BasicTableLayoutStrategy ) ;
1999-04-03 23:02:43 +00:00
NS_ASSERTION ( nsnull ! = aFrame , " bad frame arg " ) ;
1998-06-23 23:23:21 +00:00
1999-07-28 08:09:02 +00:00
mTableFrame = aFrame ;
mCellSpacingTotal = 0 ;
mIsNavQuirksMode = aIsNavQuirks ;
1998-04-30 17:57:09 +00:00
}
BasicTableLayoutStrategy : : ~ BasicTableLayoutStrategy ( )
{
1999-10-08 20:41:19 +00:00
MOZ_COUNT_DTOR ( BasicTableLayoutStrategy ) ;
1998-04-30 17:57:09 +00:00
}
2000-02-12 01:55:40 +00:00
PRBool BasicTableLayoutStrategy : : Initialize ( nsIPresContext * aPresContext ,
const nsHTMLReflowState & aReflowState )
1998-04-30 17:57:09 +00:00
{
2001-03-13 06:38:59 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eInit , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_TRUE ) ;
# endif
1999-07-28 08:09:02 +00:00
ContinuingFrameCheck ( ) ;
1998-07-16 23:23:31 +00:00
1998-04-30 17:57:09 +00:00
PRBool result = PR_TRUE ;
1998-05-26 22:03:16 +00:00
1998-07-22 18:22:12 +00:00
// re-init instance variables
2001-03-13 06:38:59 +00:00
mCellSpacingTotal = 0 ;
mCols = mTableFrame - > GetEffectiveCOLSAttribute ( ) ;
2000-09-01 01:29:50 +00:00
float p2t ;
aPresContext - > GetScaledPixelsToTwips ( & p2t ) ;
1998-04-30 17:57:09 +00:00
2001-03-13 06:38:59 +00:00
mTableFrame - > SetHasPctCol ( PR_FALSE ) ;
1998-10-09 19:59:45 +00:00
2001-03-13 06:38:59 +00:00
nscoord boxWidth = mTableFrame - > CalcBorderBoxWidth ( aReflowState ) ;
PRBool hasPctCol = AssignNonPctColumnWidths ( aPresContext , boxWidth , aReflowState , p2t ) ;
1998-10-09 19:59:45 +00:00
2001-03-13 06:38:59 +00:00
mTableFrame - > SetHasPctCol ( hasPctCol ) ;
// calc the min, desired, preferred widths from what we know so far
nscoord minWidth , prefWidth ;
mTableFrame - > CalcMinAndPreferredWidths ( aReflowState , minWidth , prefWidth ) ;
if ( hasPctCol & & mTableFrame - > IsAutoWidth ( ) ) {
prefWidth = CalcPctAdjTableWidth ( aReflowState , boxWidth , p2t ) ;
1998-04-30 17:57:09 +00:00
}
2001-03-13 06:38:59 +00:00
// calc the desired width, considering if there is a specified width.
// don't use nsTableFrame::CalcDesiredWidth because it is based on table column widths.
nscoord desWidth = ( mTableFrame - > IsAutoWidth ( ) ) ? PR_MIN ( prefWidth , aReflowState . availableWidth )
: prefWidth ;
desWidth = PR_MAX ( desWidth , minWidth ) ;
mTableFrame - > SetMinWidth ( minWidth ) ;
mTableFrame - > SetDesiredWidth ( desWidth ) ;
mTableFrame - > SetPreferredWidth ( prefWidth ) ;
mTableFrame - > SetNeedStrategyInit ( PR_FALSE ) ;
# ifdef DEBUG_TABLE_REFLOW_TIMING
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eInit , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_FALSE ) ;
# endif
# ifdef DEBUG_TABLE_REFLOW
printf ( " Initialized min=%d des=%d pref=%d \n " , minWidth , desWidth , prefWidth ) ;
# endif
return result ;
1998-04-30 17:57:09 +00:00
}
1999-07-28 08:09:02 +00:00
void BasicTableLayoutStrategy : : ContinuingFrameCheck ( )
1998-04-30 17:57:09 +00:00
{
1998-09-22 23:36:06 +00:00
# ifdef NS_DEBUG
1999-07-28 08:09:02 +00:00
nsIFrame * tablePIF = nsnull ;
1999-02-24 04:48:08 +00:00
mTableFrame - > GetPrevInFlow ( & tablePIF ) ;
1999-07-28 08:09:02 +00:00
NS_ASSERTION ( ! tablePIF , " never ever call me on a continuing frame! " ) ;
1998-04-30 17:57:09 +00:00
# endif
1999-07-28 08:09:02 +00:00
}
1998-04-30 17:57:09 +00:00
2000-01-22 01:16:50 +00:00
PRBool BCW_Wrapup ( nsIPresContext * aPresContext ,
2001-03-13 06:38:59 +00:00
const nsHTMLReflowState & aReflowState ,
2000-01-22 01:16:50 +00:00
BasicTableLayoutStrategy * aStrategy ,
1999-08-21 06:38:07 +00:00
nsTableFrame * aTableFrame ,
PRInt32 * aAllocTypes )
1999-07-28 08:09:02 +00:00
{
1999-08-21 06:38:07 +00:00
if ( aAllocTypes )
delete [ ] aAllocTypes ;
2000-10-28 22:17:53 +00:00
if ( gsDebugBalance ) { printf ( " BalanceColumnWidths ex \n " ) ; aTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
2001-03-13 06:38:59 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eBalanceCols , * aTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_FALSE ) ;
# endif
1999-07-28 08:09:02 +00:00
return PR_TRUE ;
}
1998-07-16 23:23:31 +00:00
2000-12-19 20:29:46 +00:00
void
ResetPctValues ( nsTableFrame * aTableFrame ,
PRInt32 aNumCols )
{
// initialize the col percent and cell percent values to 0.
PRInt32 colX ;
for ( colX = 0 ; colX < aNumCols ; colX + + ) {
nsTableColFrame * colFrame = aTableFrame - > GetColFrame ( colX ) ;
if ( colFrame ) {
colFrame - > SetWidth ( PCT , WIDTH_NOT_SET ) ;
colFrame - > SetWidth ( PCT_ADJ , WIDTH_NOT_SET ) ;
}
}
}
1999-07-28 08:09:02 +00:00
PRBool
2000-01-22 01:16:50 +00:00
BasicTableLayoutStrategy : : BalanceColumnWidths ( nsIPresContext * aPresContext ,
2001-03-13 06:38:59 +00:00
const nsHTMLReflowState & aReflowState )
1999-07-28 08:09:02 +00:00
{
2001-03-13 06:38:59 +00:00
if ( gsDebugBalance ) { printf ( " BalanceColumnWidths en count=%d \n " , gsDebugCount + + ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
# ifdef DEBUG_TABLE_REFLOW_TIMING
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eBalanceCols , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_TRUE ) ;
# endif
2000-09-01 01:29:50 +00:00
float p2t ;
aPresContext - > GetScaledPixelsToTwips ( & p2t ) ;
1999-08-21 06:38:07 +00:00
1999-07-28 08:09:02 +00:00
ContinuingFrameCheck ( ) ;
1998-07-16 23:23:31 +00:00
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2001-03-13 06:38:59 +00:00
PRBool tableIsAutoWidth = mTableFrame - > IsAutoWidth ( ) ;
nscoord horBorderPadding = aReflowState . mComputedBorderPadding . left +
aReflowState . mComputedBorderPadding . right ;
1999-12-13 22:56:31 +00:00
1999-07-28 08:09:02 +00:00
// determine if the table is auto/fixed and get the fixed width if available
2001-03-13 06:38:59 +00:00
nscoord maxWidth = mTableFrame - > CalcBorderBoxWidth ( aReflowState ) ;
2001-03-24 23:15:49 +00:00
if ( NS_UNCONSTRAINEDSIZE = = maxWidth ) {
maxWidth = PR_MIN ( maxWidth , aReflowState . availableWidth ) ;
NS_ASSERTION ( NS_UNCONSTRAINEDSIZE ! = maxWidth , " cannot balance with an unconstrained width " ) ;
2001-03-13 06:38:59 +00:00
return PR_FALSE ;
1999-07-28 08:09:02 +00:00
}
// initialize the col percent and cell percent values to 0.
2000-12-19 20:29:46 +00:00
ResetPctValues ( mTableFrame , numCols ) ;
2001-03-13 06:38:59 +00:00
// An auto table returns a new table width based on percent cells/cols if they exist
1999-10-25 22:49:51 +00:00
nscoord perAdjTableWidth = 0 ;
2001-03-13 06:38:59 +00:00
if ( mTableFrame - > HasPctCol ( ) ) {
perAdjTableWidth = AssignPctColumnWidths ( aReflowState , maxWidth , tableIsAutoWidth , p2t ) ;
perAdjTableWidth = PR_MIN ( perAdjTableWidth , maxWidth ) ;
perAdjTableWidth - = horBorderPadding ;
perAdjTableWidth = PR_MAX ( perAdjTableWidth , 0 ) ;
1999-10-25 22:49:51 +00:00
}
1999-10-04 05:19:32 +00:00
2001-03-13 06:38:59 +00:00
// reduce the maxWidth by border and padding, since we will be dealing with content width
maxWidth - = horBorderPadding ;
maxWidth = PR_MAX ( 0 , maxWidth ) ;
1999-10-04 05:19:32 +00:00
// set the table's columns to the min width
2001-03-13 06:38:59 +00:00
nscoord minTableWidth = 0 ;
2000-12-19 20:29:46 +00:00
PRInt32 colX ;
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 05:19:32 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-10-04 05:19:32 +00:00
nscoord colMinWidth = colFrame - > GetMinWidth ( ) ;
mTableFrame - > SetColumnWidth ( colX , colMinWidth ) ;
2001-03-13 06:38:59 +00:00
minTableWidth + = colMinWidth ;
2000-12-19 20:29:46 +00:00
}
2001-03-13 06:38:59 +00:00
minTableWidth + = mCellSpacingTotal ;
1999-07-28 08:09:02 +00:00
// if the max width available is less than the min content width for fixed table, we're done
2000-05-10 00:54:00 +00:00
if ( ! tableIsAutoWidth & & ( maxWidth < minTableWidth ) ) {
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , nsnull ) ;
1998-07-17 21:02:28 +00:00
}
1998-07-16 23:23:31 +00:00
1999-07-28 08:09:02 +00: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 00:54:00 +00:00
if ( tableIsAutoWidth & & ( maxWidth < minTableWidth ) & & ( 0 = = perAdjTableWidth ) ) {
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , nsnull ) ;
1998-07-27 02:15:37 +00:00
}
1999-11-05 22:36:59 +00:00
// the following are of size NUM_WIDTHS, but only MIN_CON, DES_CON, FIX, FIX_ADJ, PCT
1999-07-28 08:09:02 +00:00
// are used and they account for colspan ADJusted values
PRInt32 totalWidths [ NUM_WIDTHS ] ; // sum of col widths of a particular type
PRInt32 totalCounts [ NUM_WIDTHS ] ; // num of cols of a particular type
2000-12-19 20:29:46 +00:00
PRInt32 dupedWidths [ NUM_WIDTHS ] ;
1999-07-28 08:09:02 +00:00
PRInt32 num0Proportional ;
1998-07-16 23:23:31 +00:00
2001-03-13 06:38:59 +00:00
CalculateTotals ( totalCounts , totalWidths , dupedWidths , num0Proportional ) ;
1999-07-28 08:09:02 +00:00
// auto width table's adjusted width needs cell spacing
if ( tableIsAutoWidth & & perAdjTableWidth > 0 ) {
2000-12-19 20:29:46 +00:00
maxWidth = perAdjTableWidth ;
1999-07-28 08:09:02 +00:00
}
2001-03-13 06:38:59 +00:00
nscoord totalAllocated = totalWidths [ MIN_CON ] + mCellSpacingTotal ;
1999-07-28 08:09:02 +00:00
// allocate and initialize arrays indicating what col gets set
1999-12-13 22:56:31 +00:00
PRInt32 * allocTypes = new PRInt32 [ numCols ] ;
1999-07-28 08:09:02 +00:00
if ( ! allocTypes ) return PR_FALSE ;
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
allocTypes [ colX ] = - 1 ;
}
1999-05-18 05:18:16 +00:00
2000-12-19 20:29:46 +00:00
// allocate PCT/PCT_ADJ cols
1999-07-28 08:09:02 +00:00
if ( totalCounts [ PCT ] > 0 ) {
2000-12-19 20:29:46 +00:00
if ( totalAllocated + totalWidths [ PCT ] - dupedWidths [ PCT ] < = maxWidth ) {
1999-07-28 08:09:02 +00:00
AllocateFully ( totalAllocated , allocTypes , PCT ) ;
1999-11-15 15:42:20 +00:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-05-18 05:18:16 +00:00
}
1999-07-28 08:09:02 +00:00
else {
2000-09-01 01:29:50 +00:00
AllocateConstrained ( maxWidth - totalAllocated , PCT , PR_FALSE , allocTypes , p2t ) ;
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1999-05-18 05:18:16 +00:00
}
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
// allocate FIX cols
if ( ( totalAllocated < maxWidth ) & & ( totalCounts [ FIX ] > 0 ) ) {
if ( totalAllocated + totalWidths [ FIX ] - dupedWidths [ FIX ] < = maxWidth ) {
1999-07-28 08:09:02 +00:00
AllocateFully ( totalAllocated , allocTypes , FIX ) ;
1999-11-15 15:42:20 +00:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-05-18 05:18:16 +00:00
}
1999-07-28 08:09:02 +00:00
else {
2000-09-01 01:29:50 +00:00
AllocateConstrained ( maxWidth - totalAllocated , FIX , PR_TRUE , allocTypes , p2t ) ;
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1999-10-04 05:19:32 +00:00
}
}
// allocate fixed adjusted cols
2000-12-19 20:29:46 +00:00
if ( ( totalAllocated < maxWidth ) & & ( totalCounts [ FIX_ADJ ] > 0 ) ) {
if ( totalAllocated + totalWidths [ FIX_ADJ ] - dupedWidths [ FIX_ADJ ] < = maxWidth ) {
1999-10-04 05:19:32 +00:00
AllocateFully ( totalAllocated , allocTypes , FIX_ADJ ) ;
1999-11-15 15:42:20 +00:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-10-04 05:19:32 +00:00
}
else {
2000-09-01 01:29:50 +00:00
AllocateConstrained ( maxWidth - totalAllocated , FIX_ADJ , PR_TRUE , allocTypes , p2t ) ;
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1999-05-18 05:18:16 +00:00
}
}
1998-07-16 23:23:31 +00:00
2001-01-12 23:07:54 +00:00
// allocate proportional and auto cols together
if ( ( totalAllocated < maxWidth ) & & ( totalCounts [ MIN_PRO ] + totalCounts [ DES_CON ] > 0 ) ) {
if ( totalAllocated + totalWidths [ MIN_PRO ] - dupedWidths [ MIN_PRO ] +
totalWidths [ DES_CON ] - dupedWidths [ DES_CON ] < = maxWidth ) {
1999-07-28 08:09:02 +00:00
AllocateFully ( totalAllocated , allocTypes , DES_CON ) ;
1999-11-15 15:42:20 +00:00
//NS_WARN_IF_FALSE(totalAllocated <= maxWidth, "over allocated");
1999-07-28 08:09:02 +00:00
}
else {
2000-09-01 01:29:50 +00:00
AllocateConstrained ( maxWidth - totalAllocated , DES_CON , PR_TRUE , allocTypes , p2t ) ;
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1998-06-23 23:23:21 +00:00
}
1998-07-16 23:23:31 +00:00
}
1998-06-23 23:23:21 +00:00
1999-10-25 22:49:51 +00:00
// if this is a nested non auto table and pass1 reflow, we are done
if ( ( maxWidth = = NS_UNCONSTRAINEDSIZE ) & & ( ! tableIsAutoWidth ) ) {
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1999-07-28 08:09:02 +00:00
}
1998-11-30 19:06:33 +00:00
2000-12-19 20:29:46 +00:00
// allocate the rest to auto columns, with some exceptions
1999-07-28 08:09:02 +00:00
if ( ( tableIsAutoWidth & & ( perAdjTableWidth - totalAllocated > 0 ) ) | |
( ! tableIsAutoWidth & & ( totalAllocated < maxWidth ) ) ) {
2001-03-21 06:02:21 +00:00
PRInt32 numEffCols = mTableFrame - > GetEffectiveColCount ( ) ;
2001-03-13 05:10:17 +00:00
PRBool excludePct = ( totalCounts [ PCT ] ! = numEffCols ) ;
2001-03-21 06:02:21 +00:00
PRBool excludeFix = ( totalCounts [ PCT ] + totalCounts [ FIX ] + totalCounts [ FIX_ADJ ] < numEffCols ) ;
2000-12-19 20:29:46 +00:00
PRBool excludePro = ( totalCounts [ DES_CON ] > 0 ) ;
PRBool exclude0Pro = ( totalCounts [ MIN_PRO ] ! = num0Proportional ) ;
1999-07-28 08:09:02 +00:00
if ( tableIsAutoWidth ) {
2000-12-19 20:29:46 +00:00
AllocateUnconstrained ( perAdjTableWidth - totalAllocated , allocTypes , excludePct ,
excludeFix , excludePro , exclude0Pro , p2t ) ;
1998-07-13 18:11:12 +00:00
}
1999-07-28 08:09:02 +00:00
else {
2000-12-19 20:29:46 +00:00
AllocateUnconstrained ( maxWidth - totalAllocated , allocTypes , excludePct ,
excludeFix , excludePro , exclude0Pro , p2t ) ;
1998-07-11 00:00:31 +00:00
}
}
2001-03-13 06:38:59 +00:00
return BCW_Wrapup ( aPresContext , aReflowState , this , mTableFrame , allocTypes ) ;
1998-04-30 17:57:09 +00:00
}
2000-12-19 20:29:46 +00:00
nscoord GetColWidth ( nsTableColFrame * aColFrame ,
PRInt32 aWidthType )
{
switch ( aWidthType ) {
case DES_CON :
return aColFrame - > GetDesWidth ( ) ;
case FIX :
case FIX_ADJ :
return aColFrame - > GetWidth ( aWidthType ) ;
case PCT :
return aColFrame - > GetPctWidth ( ) ;
default :
NS_ASSERTION ( PR_FALSE , " invalid call " ) ;
return WIDTH_NOT_SET ;
}
}
1998-04-30 17:57:09 +00:00
1999-07-28 08:09:02 +00:00
// Allocate aWidthType values to all cols available in aIsAllocated
2000-12-19 20:29:46 +00:00
void BasicTableLayoutStrategy : : AllocateFully ( nscoord & aTotalAllocated ,
PRInt32 * aAllocTypes ,
PRInt32 aWidthType )
1998-04-30 17:57:09 +00:00
{
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-12-13 22:56:31 +00:00
for ( PRInt32 colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame ) ) {
1999-07-28 08:09:02 +00:00
continue ;
}
2000-12-19 20:29:46 +00:00
nscoord oldWidth = mTableFrame - > GetColumnWidth ( colX ) ;
nscoord newWidth = GetColWidth ( colFrame , aWidthType ) ;
2001-01-12 23:07:54 +00:00
// proportional and desired widths are handled together
PRBool haveProWidth = PR_FALSE ;
if ( DES_CON = = aWidthType ) {
nscoord proWidth = colFrame - > GetWidth ( MIN_PRO ) ;
if ( proWidth > = 0 ) {
haveProWidth = PR_TRUE ;
newWidth = proWidth ;
}
}
2000-12-19 20:29:46 +00:00
if ( WIDTH_NOT_SET = = newWidth ) continue ;
1999-07-28 08:09:02 +00:00
if ( newWidth > oldWidth ) {
mTableFrame - > SetColumnWidth ( colX , newWidth ) ;
aTotalAllocated + = newWidth - oldWidth ;
}
2001-01-12 23:07:54 +00:00
aAllocTypes [ colX ] = ( haveProWidth ) ? MIN_PRO : aWidthType ;
1998-05-26 22:03:16 +00:00
}
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
// This method is the last allocation method to get called, but just in case
// code gets added later after, set the allocated cols to some final value.
# define FINISHED 99
1999-07-28 08:09:02 +00:00
void BasicTableLayoutStrategy : : AllocateUnconstrained ( PRInt32 aAllocAmount ,
PRInt32 * aAllocTypes ,
2000-12-19 20:29:46 +00:00
PRBool aExcludePct ,
PRBool aExcludeFix ,
PRBool aExcludePro ,
PRBool aExclude0Pro ,
2000-09-01 01:29:50 +00:00
float aPixelToTwips )
1999-07-28 08:09:02 +00:00
{
2000-12-19 20:29:46 +00:00
// set up allocTypes to exclude anything but auto cols if possible
PRInt32 colX ;
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2000-12-19 20:29:46 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
if ( aExcludePct & & ( PCT = = aAllocTypes [ colX ] ) ) {
aAllocTypes [ colX ] = FINISHED ;
}
else if ( aExcludeFix & & ( ( FIX = = aAllocTypes [ colX ] ) | | ( FIX_ADJ = = aAllocTypes [ colX ] ) ) ) {
aAllocTypes [ colX ] = FINISHED ;
}
else if ( MIN_PRO = = aAllocTypes [ colX ] ) {
if ( aExcludePro ) {
aAllocTypes [ colX ] = FINISHED ;
}
else {
if ( aExclude0Pro ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
if ( colFrame - > GetConstraint ( ) = = e0ProportionConstraint ) {
aAllocTypes [ colX ] = FINISHED ;
}
}
}
}
}
1999-10-13 14:44:22 +00:00
nscoord divisor = 0 ;
PRInt32 numColsAllocated = 0 ;
PRInt32 totalAllocated = 0 ;
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
2000-11-30 21:44:59 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-12-19 20:29:46 +00:00
PRBool skipColumn = aExclude0Pro & & ( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) ;
if ( FINISHED ! = aAllocTypes [ colX ] & & ! skipColumn ) {
1999-07-28 08:09:02 +00:00
divisor + = mTableFrame - > GetColumnWidth ( colX ) ;
1999-10-13 14:44:22 +00:00
numColsAllocated + + ;
1999-07-28 08:09:02 +00:00
}
}
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
2000-12-19 20:29:46 +00:00
if ( FINISHED ! = aAllocTypes [ colX ] ) {
if ( aExclude0Pro ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( colFrame & & ( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) ) {
1999-07-28 08:09:02 +00:00
continue ;
1998-08-11 18:42:10 +00:00
}
}
1999-07-28 08:09:02 +00:00
nscoord oldWidth = mTableFrame - > GetColumnWidth ( colX ) ;
float percent = ( divisor = = 0 )
1999-10-13 14:44:22 +00:00
? ( 1.0f / ( ( float ) numColsAllocated ) )
1999-07-28 08:09:02 +00:00
: ( ( float ) oldWidth ) / ( ( float ) divisor ) ;
2000-09-01 01:29:50 +00:00
nscoord addition = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) aAllocAmount ) * percent ) , aPixelToTwips ) ;
1999-10-13 14:44:22 +00:00
if ( addition > ( aAllocAmount - totalAllocated ) ) {
mTableFrame - > SetColumnWidth ( colX , oldWidth + ( aAllocAmount - totalAllocated ) ) ;
break ;
}
1999-07-28 08:09:02 +00:00
mTableFrame - > SetColumnWidth ( colX , oldWidth + addition ) ;
1999-10-13 14:44:22 +00:00
totalAllocated + = addition ;
1998-08-11 18:42:10 +00:00
}
1999-07-28 08:09:02 +00:00
}
}
1999-11-05 22:36:59 +00:00
nscoord GetConstrainedWidth ( nsTableColFrame * colFrame ,
PRBool aConsiderPct )
{
nscoord conWidth = WIDTH_NOT_SET ;
if ( aConsiderPct ) {
2000-01-03 00:56:12 +00:00
conWidth = colFrame - > GetPctWidth ( ) ;
1999-11-05 22:36:59 +00:00
}
if ( conWidth < = 0 ) {
conWidth = colFrame - > GetFixWidth ( ) ;
}
return conWidth ;
}
2000-12-19 20:29:46 +00:00
# define LIMIT_PCT 0 // retrict allocations to only the pct width cols
# define LIMIT_FIX 1 // retrict allocations to only the fix width cols
# define LIMIT_DES 2 // retrict allocations to only the auto width cols
# define LIMIT_NONE 3 // retrict allocations to only the auto widths unless there are none
// and then restrict fix or pct.
1999-11-05 22:36:59 +00:00
void
2000-09-09 01:46:44 +00:00
BasicTableLayoutStrategy : : ComputeNonPctColspanWidths ( const nsHTMLReflowState & aReflowState ,
PRBool aConsiderPct ,
2001-03-13 06:38:59 +00:00
float aPixelToTwips ,
PRBool * aHasPctCol )
1999-11-05 22:36:59 +00:00
{
2001-02-01 02:29:14 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eNonPctColspans , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_TRUE ) ;
2001-02-01 02:29:14 +00:00
# endif
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2000-09-09 01:46:44 +00:00
// zero out prior ADJ values
1999-11-05 22:36:59 +00:00
2000-09-09 01:46:44 +00:00
PRInt32 colX ;
for ( colX = numCols - 1 ; colX > = 0 ; colX - - ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-09-09 01:46:44 +00:00
colFrame - > SetWidth ( MIN_ADJ , WIDTH_NOT_SET ) ;
colFrame - > SetWidth ( FIX_ADJ , WIDTH_NOT_SET ) ;
colFrame - > SetWidth ( DES_ADJ , WIDTH_NOT_SET ) ;
1999-11-05 22:36:59 +00:00
}
2000-09-09 01:46:44 +00: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.
2001-04-17 04:32:32 +00:00
//if more than one colspan originate in one column, resort the access to
//the rows so that the inner colspans are handled first
2000-09-09 01:46:44 +00:00
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
2001-04-17 04:32:32 +00:00
PRInt32 * numColSpans = new PRInt32 [ numRows ] ;
if ( ! numColSpans )
return ;
PRInt32 * rowIndices = new PRInt32 [ numRows ] ;
if ( ! rowIndices ) {
2001-04-19 19:11:17 +00:00
delete [ ] numColSpans ;
2001-04-17 04:32:32 +00:00
return ;
}
2000-09-09 01:46:44 +00:00
for ( colX = numCols - 1 ; colX > = 0 ; colX - - ) {
2001-04-17 05:34:10 +00:00
PRInt32 rowX ;
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
2001-04-17 04:32:32 +00:00
numColSpans [ rowX ] = 0 ;
rowIndices [ rowX ] = 0 ;
}
PRInt32 biggestColspan = 0 ;
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
if ( ! originates | | ( 1 = = colSpan ) ) {
continue ;
}
numColSpans [ rowX ] = colSpan ;
if ( colSpan > biggestColspan )
biggestColspan = colSpan ;
}
PRInt32 index = 0 ;
for ( PRInt32 j = 2 ; j < = biggestColspan ; j + + ) {
for ( PRInt32 k = 0 ; k < numRows ; k + + ) {
if ( numColSpans [ k ] = = j ) {
rowIndices [ index ] = k ;
index + + ;
}
}
}
for ( PRInt32 i = 0 ; i < index ; i + + ) {
2000-09-09 01:46:44 +00:00
PRBool originates ;
PRInt32 colSpan ;
2001-04-17 04:32:32 +00:00
PRInt32 rowX = rowIndices [ i ] ;
2000-09-09 01:46:44 +00:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
if ( ! originates | | ( 1 = = colSpan ) ) {
continue ;
}
// set MIN_ADJ, DES_ADJ, FIX_ADJ
for ( PRInt32 widthX = 0 ; widthX < NUM_MAJOR_WIDTHS ; widthX + + ) {
nscoord cellWidth = 0 ;
if ( MIN_CON = = widthX ) {
cellWidth = cellFrame - > GetPass1MaxElementSize ( ) . width ;
}
else if ( DES_CON = = widthX ) {
cellWidth = cellFrame - > GetMaximumWidth ( ) ;
}
else { // FIX width
// 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 ( ) ) {
// need to add padding into fixed width
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( aReflowState . mComputedWidth , 0 ) , cellFrame ) ;
cellWidth = cellPosition - > mWidth . GetCoordValue ( ) + padding . left + padding . right ;
cellWidth = PR_MAX ( cellWidth , cellFrame - > GetPass1MaxElementSize ( ) . width ) ;
}
}
1999-11-05 22:36:59 +00:00
2000-09-09 01:46:44 +00:00
if ( 0 > = cellWidth ) continue ;
2000-12-19 20:29:46 +00:00
// first allocate pct cells up to their value if aConsiderPct, then
// allocate fixed cells up to their value, then allocate auto cells
// up to their value, then allocate auto cells proportionally.
PRInt32 limit = ( aConsiderPct ) ? LIMIT_PCT : LIMIT_FIX ;
if ( MIN_CON ! = widthX ) { // FIX and DES only need to allocate NONE
limit = LIMIT_NONE ;
}
while ( limit < = LIMIT_NONE ) {
if ( ComputeNonPctColspanWidths ( widthX , cellFrame , cellWidth , colX , colSpan ,
limit , aPixelToTwips ) ) {
break ;
2000-09-09 01:46:44 +00:00
}
2000-12-19 20:29:46 +00:00
limit + + ;
2000-09-09 01:46:44 +00:00
}
1999-11-05 22:36:59 +00:00
}
2001-03-13 06:38:59 +00:00
// determine if there is a pct col if we are requested to do so
if ( aHasPctCol & & ! * aHasPctCol ) {
* aHasPctCol = HasPctValue ( cellFrame ) ;
}
1999-11-05 22:36:59 +00:00
}
}
2001-04-19 19:11:17 +00:00
delete [ ] numColSpans ;
delete [ ] rowIndices ;
2001-02-01 02:29:14 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eNonPctColspans , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_FALSE ) ;
2001-02-01 02:29:14 +00:00
# endif
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
# ifdef DEBUG
static char * widths [ ] = { " MIN " , " DES " , " FIX " } ;
static char * limits [ ] = { " PCT " , " FIX " , " DES " , " NONE " } ;
static PRInt32 dumpCount = 0 ;
void DumpColWidths ( nsTableFrame & aTableFrame ,
char * aMessage ,
nsTableCellFrame * aCellFrame ,
PRInt32 aColIndex ,
PRInt32 aWidthType ,
PRInt32 aLimitType )
{
PRInt32 rowIndex ;
aCellFrame - > GetRowIndex ( rowIndex ) ;
printf ( " %s (row,col)=(%d,%d) width=%s limit=%s count=%d \n " , aMessage , rowIndex , aColIndex ,
widths [ aWidthType ] , limits [ aLimitType ] , dumpCount + + ) ;
2001-01-12 23:07:54 +00:00
for ( PRInt32 i = 0 ; i < aTableFrame . GetColCount ( ) ; i + + ) {
2000-12-19 20:29:46 +00:00
printf ( " col %d = " , i ) ;
nsTableColFrame * colFrame = aTableFrame . GetColFrame ( i ) ;
for ( PRInt32 j = 0 ; j < NUM_WIDTHS ; j + + ) {
printf ( " %d " , colFrame - > GetWidth ( j ) ) ;
}
printf ( " \n " ) ;
}
}
# endif
1999-11-05 22:36:59 +00:00
2000-12-19 20:29:46 +00:00
// (aWidthIndex == MIN_CON) is called with:
// (aLimitType == LIMIT_PCT) to give MIN_ADJ to PCT cols (up to their PCT value)
// (aLimitType == LIMIT_FIX) to give MIN_ADJ to FIX cols (up to their FIX value)
// (aLimitType == LIMIT_DES) to give MIN_ADJ to auto cols (up to their preferred value)
// (aLimitType == LIMIT_NONE) to give MIN_ADJ to auto cols
// (aWidthIndex == FIX), (aWidthIndex == DES) is called with:
// (aLimitType == LIMIT_NONE) to give FIX_ADJ to auto cols
1999-11-05 22:36:59 +00:00
PRBool
2000-09-09 01:46:44 +00:00
BasicTableLayoutStrategy : : ComputeNonPctColspanWidths ( PRInt32 aWidthIndex ,
nsTableCellFrame * aCellFrame ,
nscoord aCellWidth ,
PRInt32 aColIndex ,
PRInt32 aColSpan ,
PRInt32 & aLimitType ,
float aPixelToTwips )
1999-11-05 22:36:59 +00:00
{
2000-12-19 20:29:46 +00:00
//DumpColWidths(*mTableFrame, "enter ComputeNonPctColspanWidths", aCellFrame, aColIndex, aWidthIndex, aLimitType);
1999-11-05 22:36:59 +00:00
PRBool result = PR_TRUE ;
2000-09-09 01:46:44 +00:00
2000-12-19 20:29:46 +00:00
nscoord spanCellSpacing = 0 ; // total cell spacing cells being spanned
nscoord minTotal = 0 ; // the sum of min widths of spanned cells.
nscoord autoMinTotal = 0 ; // the sum of min widths of spanned auto cells.
nscoord fixMinTotal = 0 ; // the sum of min widths of spanned fix cells.
nscoord pctMinTotal = 0 ; // the sum of min widths of spanned pct cells.
nscoord pctTotal = 0 ; // the sum of pct widths of spanned cells.
nscoord fixTotal = 0 ; // the sum of fix widths of spanned cells
nscoord autoDesTotal = 0 ; // the sum of desired widths of spanned cells which are auto
nscoord pctLimitTotal = 0 ; // the sum of pct widths not exceeding aCellWidth
nscoord fixLimitTotal = 0 ; // the sum of fix widths not exceeding aCellWidth
nscoord desLimitTotal = 0 ; // the sum of des widths not exceeding aCellWidth
PRInt32 numAutoCols = 0 ;
1999-11-05 22:36:59 +00:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
2000-12-19 21:16:41 +00:00
PRInt32 spanX ;
1999-11-05 22:36:59 +00:00
// accumulate the various divisors to be used later
2000-12-19 21:16:41 +00:00
for ( spanX = 0 ; spanX < aColSpan ; spanX + + ) {
1999-11-05 22:36:59 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( aColIndex + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
nscoord minWidth = PR_MAX ( colFrame - > GetMinWidth ( ) , 0 ) ;
nscoord pctWidth = PR_MAX ( colFrame - > GetPctWidth ( ) , 0 ) ;
nscoord fixWidth = PR_MAX ( colFrame - > GetFixWidth ( ) , 0 ) ;
nscoord desWidth = PR_MAX ( colFrame - > GetDesWidth ( ) , minWidth ) ;
minTotal + = minWidth ;
if ( pctWidth > 0 ) {
pctTotal + = pctWidth ;
pctMinTotal + = minWidth ;
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
else if ( fixWidth > 0 ) {
fixTotal + = fixWidth ;
fixMinTotal + = minWidth ;
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
if ( colFrame - > GetWidth ( PCT ) + colFrame - > GetWidth ( FIX ) < = 0 ) {
autoDesTotal + = desWidth ;
autoMinTotal + = minWidth ;
numAutoCols + + ;
1999-11-05 22:36:59 +00:00
}
if ( ( spanX > 0 ) & & ( mTableFrame - > GetNumCellsOriginatingInCol ( aColIndex + spanX ) > 0 ) ) {
spanCellSpacing + = spacingX ;
}
}
2000-12-19 20:29:46 +00:00
nscoord availWidth = aCellWidth - spanCellSpacing ;
2000-09-09 01:46:44 +00:00
if ( MIN_CON = = aWidthIndex ) {
2000-12-19 20:29:46 +00:00
// MIN widths (unlike the others) are added to existing values, so subtract out the min total
availWidth - = minTotal ;
pctLimitTotal = ( ( pctTotal - pctMinTotal ) < availWidth ) ? pctTotal - pctMinTotal : availWidth ;
fixLimitTotal = ( ( fixTotal - fixMinTotal ) < availWidth ) ? fixTotal - fixMinTotal : availWidth ;
desLimitTotal = ( ( autoDesTotal - autoMinTotal ) < availWidth ) ? autoDesTotal - autoMinTotal : availWidth ;
}
2001-04-15 17:08:04 +00:00
else { // FIX or DES_CON with LIMIT_NONE
if ( FIX = = aWidthIndex ) {
2001-04-15 20:49:09 +00:00
if ( autoDesTotal > 0 ) {
availWidth - = pctTotal + fixTotal ;
}
else if ( fixTotal > 0 ) {
availWidth - = pctTotal ;
}
2000-12-19 20:29:46 +00:00
}
2001-04-15 17:08:04 +00:00
else if ( DES_CON = = aWidthIndex ) {
availWidth - = pctTotal + fixTotal ;
2000-12-19 20:29:46 +00:00
}
}
1999-11-05 22:36:59 +00:00
2000-12-19 20:29:46 +00:00
// Below are some optimizations which can skip steps.
if ( LIMIT_PCT = = aLimitType ) {
NS_ASSERTION ( MIN_CON = = aWidthIndex , " invalid call to ComputeNonPctColspanWidths " ) ;
// if there are no pct cols, limit fix cols
if ( 0 = = pctTotal ) {
2000-09-09 01:46:44 +00:00
aLimitType = LIMIT_FIX ;
}
2000-12-19 20:29:46 +00:00
}
if ( LIMIT_FIX = = aLimitType ) {
NS_ASSERTION ( MIN_CON = = aWidthIndex , " invalid call to ComputeNonPctColspanWidths " ) ;
// if there are no fix cols, limit des
if ( 0 = = fixTotal ) {
1999-11-05 22:36:59 +00:00
aLimitType = LIMIT_DES ;
}
2000-12-19 20:29:46 +00:00
}
if ( LIMIT_DES = = aLimitType ) {
NS_ASSERTION ( MIN_CON = = aWidthIndex , " invalid call to ComputeNonPctColspanWidths " ) ;
// if there are no auto cols, limit none
if ( 0 = = autoDesTotal ) {
1999-11-05 22:36:59 +00:00
aLimitType = LIMIT_NONE ;
}
}
2000-12-19 20:29:46 +00:00
// there are some cases where allocating up to aCellWidth will not be satisfied
switch ( aLimitType ) {
case LIMIT_PCT :
if ( pctLimitTotal < availWidth ) {
// the pct cols won't satisfy the request alone
availWidth = pctLimitTotal ;
result = PR_FALSE ;
}
break ;
case LIMIT_FIX :
if ( fixLimitTotal < availWidth ) {
// the fix cols won't satisfy the request alone
availWidth = fixLimitTotal ;
result = PR_FALSE ;
}
break ;
case LIMIT_DES :
if ( desLimitTotal < availWidth ) {
// the auto cols won't satisfy the request alone
availWidth = desLimitTotal ;
result = PR_FALSE ;
}
break ;
default : // LIMIT_NONE
break ;
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
1999-11-05 22:36:59 +00:00
if ( availWidth > 0 ) {
2001-01-12 23:07:54 +00:00
nscoord usedWidth = 0 ;
1999-11-05 22:36:59 +00:00
// get the correct numerator in a similar fashion to getting the divisor
for ( spanX = 0 ; spanX < aColSpan ; spanX + + ) {
2001-01-30 05:00:44 +00:00
if ( usedWidth > = availWidth ) break ;
1999-11-05 22:36:59 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( aColIndex + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
nscoord pctWidth = PR_MAX ( colFrame - > GetPctWidth ( ) , 0 ) ;
nscoord fixWidth = PR_MAX ( colFrame - > GetFixWidth ( ) , 0 ) ;
nscoord desWidth = PR_MAX ( colFrame - > GetDesWidth ( ) , minWidth ) ;
1999-11-05 22:36:59 +00:00
nscoord colWidth = PR_MAX ( colFrame - > GetWidth ( aWidthIndex ) ,
colFrame - > GetWidth ( aWidthIndex + NUM_MAJOR_WIDTHS ) ) ;
2000-12-19 20:29:46 +00:00
colWidth = PR_MAX ( colWidth , minWidth ) ;
1999-11-05 22:36:59 +00:00
2000-12-19 20:29:46 +00:00
nscoord numeratorPct = 0 ;
nscoord numeratorFix = 0 ;
nscoord numeratorAutoDes = 0 ;
if ( pctWidth > 0 ) {
numeratorPct = pctWidth ;
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
else if ( fixWidth > 0 ) {
numeratorFix = fixWidth ;
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
if ( colFrame - > GetWidth ( PCT ) + colFrame - > GetWidth ( FIX ) < = 0 ) {
numeratorAutoDes = desWidth ;
1999-11-05 22:36:59 +00:00
}
nscoord divisor ;
nscoord numerator ;
2000-12-19 20:29:46 +00:00
2000-09-09 01:46:44 +00:00
// let pct cols reach their target
if ( LIMIT_PCT = = aLimitType ) {
2000-12-19 20:29:46 +00:00
if ( pctLimitTotal > 0 ) {
divisor = pctTotal - pctMinTotal ;
2001-01-30 05:00:44 +00:00
numerator = PR_MAX ( numeratorPct - minWidth , 0 ) ;
2000-09-09 01:46:44 +00:00
}
1999-11-05 22:36:59 +00:00
}
2000-12-19 20:29:46 +00:00
// let fix cols reach their target
else if ( LIMIT_FIX = = aLimitType ) {
if ( fixLimitTotal > 0 ) {
divisor = fixTotal - fixMinTotal ;
2001-01-30 05:00:44 +00:00
numerator = PR_MAX ( numeratorFix - minWidth , 0 ) ;
1999-11-05 22:36:59 +00:00
}
}
// let auto cols reach their target
else if ( LIMIT_DES = = aLimitType ) {
2000-12-19 20:29:46 +00:00
if ( desLimitTotal > 0 ) {
if ( autoDesTotal > 0 ) { // there were auto cols
divisor = autoDesTotal - autoMinTotal ;
2001-01-30 05:00:44 +00:00
numerator = PR_MAX ( numeratorAutoDes - minWidth , 0 ) ;
2000-12-19 20:29:46 +00:00
}
else if ( fixTotal > 0 ) { // there were fix cols but no auto
divisor = fixTotal - fixMinTotal ;
2001-01-30 05:00:44 +00:00
numerator = PR_MAX ( numeratorFix - minWidth , 0 ) ;
2000-12-19 20:29:46 +00:00
}
else if ( pctTotal > 0 ) { // there were only pct cols
divisor = pctTotal - pctMinTotal ;
2001-01-30 05:00:44 +00:00
numerator = PR_MAX ( numeratorPct - minWidth , 0 ) ;
2000-12-19 20:29:46 +00:00
}
else continue ;
1999-11-05 22:36:59 +00:00
}
}
2000-12-19 20:29:46 +00:00
else if ( LIMIT_NONE = = aLimitType ) {
if ( ( MIN_CON = = aWidthIndex ) & & ( 0 = = minTotal ) ) {
2001-01-12 23:07:54 +00:00
// divide evenly among the spanned cols
divisor = aColSpan ;
numerator = 1 ;
2000-12-19 20:29:46 +00:00
}
else {
if ( autoDesTotal > 0 ) { // there were auto cols
divisor = autoDesTotal ;
numerator = numeratorAutoDes ;
}
else if ( fixTotal > 0 ) { // there were fix cols but no auto
divisor = fixTotal ;
numerator = numeratorFix ;
}
else if ( pctTotal > 0 ) { // there were only pct cols
divisor = pctTotal ;
numerator = numeratorPct ;
}
else continue ;
1999-11-05 22:36:59 +00:00
2000-12-19 20:29:46 +00:00
}
}
// calculate the adj col width
nscoord newColAdjWidth = ( 0 > = divisor )
1999-11-05 22:36:59 +00:00
? NSToCoordRound ( ( ( float ) availWidth ) / ( ( float ) aColSpan ) )
: NSToCoordRound ( ( ( ( float ) numerator ) / ( ( float ) divisor ) ) * availWidth ) ;
2000-12-19 20:29:46 +00:00
newColAdjWidth = nsTableFrame : : RoundToPixel ( newColAdjWidth , aPixelToTwips ) ;
2001-01-12 23:07:54 +00:00
// don't let the new allocation exceed the avail total
newColAdjWidth = PR_MIN ( newColAdjWidth , availWidth - usedWidth ) ;
// put the remainder of the avail total in the last spanned col
if ( spanX = = aColSpan - 1 ) {
newColAdjWidth = availWidth - usedWidth ;
}
usedWidth + = newColAdjWidth ;
2000-12-19 20:29:46 +00:00
// MIN_CON gets added to what is there, the others don't
if ( MIN_CON = = aWidthIndex ) {
newColAdjWidth + = colWidth ;
}
if ( newColAdjWidth > colWidth ) {
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 ;
1999-11-05 22:36:59 +00:00
}
}
2000-12-19 20:29:46 +00:00
colFrame - > SetWidth ( aWidthIndex + NUM_MAJOR_WIDTHS , newColAdjWidth ) ;
colFrame - > SetConstrainingCell ( aCellFrame ) ; // XXX is this right?
1999-11-05 22:36:59 +00:00
}
2001-03-21 06:02:21 +00:00
else {
if ( ( newColAdjWidth > 0 ) & & ( FIX = = aWidthIndex ) ) {
if ( colFrame - > GetWidth ( FIX ) < 0 ) {
nscoord desCon = colFrame - > GetWidth ( DES_CON ) ;
if ( desCon > newColAdjWidth ) {
newColAdjWidth = desCon ;
}
}
if ( colFrame - > GetWidth ( FIX_ADJ ) < newColAdjWidth ) {
colFrame - > SetWidth ( FIX_ADJ , PR_MAX ( colWidth , newColAdjWidth ) ) ;
}
}
}
1999-11-05 22:36:59 +00:00
}
}
2000-12-19 20:29:46 +00:00
//DumpColWidths(*mTableFrame, "exit ComputeNonPctColspanWidths", aCellFrame, aColIndex, aWidthIndex, aLimitType);
1999-11-05 22:36:59 +00:00
return result ;
}
2001-03-13 06:38:59 +00:00
2000-02-12 01:55:40 +00: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 08:09:02 +00:00
// Determine min, desired, fixed, and proportional sizes for the cols and
2001-03-13 06:38:59 +00:00
// and calculate min/max table width. Return true if there is at least one pct cell or col
2000-02-12 01:55:40 +00:00
PRBool
2000-09-09 01:46:44 +00:00
BasicTableLayoutStrategy : : AssignNonPctColumnWidths ( nsIPresContext * aPresContext ,
nscoord aMaxWidth ,
const nsHTMLReflowState & aReflowState ,
float aPixelToTwips )
1999-07-28 08:09:02 +00:00
{
2001-02-01 02:29:14 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eNonPctCols , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_TRUE ) ;
2001-02-01 02:29:14 +00:00
# endif
2000-10-28 22:17:53 +00:00
if ( gsDebugAssign ) { printf ( " AssignNonPctColWidths en max=%d count=%d \n " , aMaxWidth , gsDebugCount + + ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
1999-07-28 08:09:02 +00:00
PRBool rv = PR_FALSE ;
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-07-28 08:09:02 +00:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 colX , rowX ;
mCellSpacingTotal = 0 ;
2001-03-13 06:38:59 +00:00
PRBool hasPctCol = PR_FALSE ; // return value
1999-07-28 08:09:02 +00:00
2000-12-19 20:29:46 +00:00
PRInt32 rawPropTotal = - 1 ; // total of numbers of the type 1*, 2*, etc
1999-07-28 08:09:02 +00:00
PRInt32 numColsForColsAttr = 0 ; // Nav Quirks cols attribute for equal width cols
if ( NS_STYLE_TABLE_COLS_NONE ! = mCols ) {
1999-12-13 22:56:31 +00:00
numColsForColsAttr = ( NS_STYLE_TABLE_COLS_ALL = = mCols ) ? numCols : mCols ;
1999-07-28 08:09:02 +00: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-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nscoord minWidth = 0 ;
nscoord desWidth = 0 ;
nscoord fixWidth = WIDTH_NOT_SET ;
1999-08-21 06:38:07 +00:00
// Get column frame and reset it
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
NS_ASSERTION ( nsnull ! = colFrame , " bad col frame " ) ;
1999-08-21 06:38:07 +00:00
colFrame - > ResetSizingInfo ( ) ;
1999-07-28 08:09:02 +00:00
1999-08-25 21:49:18 +00:00
if ( mTableFrame - > GetNumCellsOriginatingInCol ( colX ) > 0 ) {
1999-07-28 08:09:02 +00: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 19:52:37 +00:00
nsTableCellFrame * fixContributor = nsnull ;
1999-10-13 14:44:22 +00:00
nsTableCellFrame * desContributor = nsnull ;
1999-07-28 08:09:02 +00:00
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 19:52:37 +00:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 08:09:02 +00: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 03:46:21 +00:00
nscoord cellDesWidth = cellFrame - > GetMaximumWidth ( ) ;
1999-10-13 14:44:22 +00:00
if ( cellDesWidth > desWidth ) {
desContributor = cellFrame ;
desWidth = cellDesWidth ;
}
1999-07-28 08:09:02 +00: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 01:55:40 +00:00
nsSize percentBase ( aReflowState . mComputedWidth , 0 ) ;
nsMargin padding = nsTableFrame : : GetPadding ( percentBase , cellFrame ) ;
nscoord newFixWidth = coordValue + padding . left + padding . right ;
2000-09-07 20:55:03 +00:00
// 2nd part of condition is Nav/IE Quirk like below
1999-10-13 14:44:22 +00:00
if ( ( newFixWidth > fixWidth ) | | ( ( newFixWidth = = fixWidth ) & & ( desContributor = = cellFrame ) ) ) {
1999-08-19 19:52:37 +00:00
fixWidth = newFixWidth ;
fixContributor = cellFrame ;
}
1998-08-11 18:42:10 +00:00
}
1999-07-28 08:09:02 +00:00
}
2001-03-13 06:38:59 +00:00
if ( ! hasPctCol & & HasPctValue ( cellFrame ) ) { // see if there is a pct cell
hasPctCol = PR_TRUE ;
}
1999-07-28 08:09:02 +00:00
}
2000-09-07 20:55:03 +00:00
// Nav/IE Quirk like above
if ( fixWidth > 0 ) {
2000-12-19 20:29:46 +00:00
if ( mIsNavQuirksMode & & ( desWidth > fixWidth ) & & ( fixContributor ! = desContributor ) ) {
2000-09-07 20:55:03 +00:00
fixWidth = WIDTH_NOT_SET ;
fixContributor = nsnull ;
}
else {
fixWidth = PR_MAX ( fixWidth , minWidth ) ;
}
1999-10-13 14:44:22 +00:00
}
2000-09-07 20:55:03 +00:00
desWidth = PR_MAX ( desWidth , minWidth ) ;
1999-10-13 14:44:22 +00:00
1999-07-28 08:09:02 +00:00
// cache the computed column info
colFrame - > SetWidth ( MIN_CON , minWidth ) ;
colFrame - > SetWidth ( DES_CON , desWidth ) ;
1999-08-19 19:52:37 +00:00
colFrame - > SetConstrainingCell ( fixContributor ) ;
1999-07-28 08:09:02 +00:00
if ( fixWidth > 0 ) {
colFrame - > SetWidth ( FIX , PR_MAX ( fixWidth , minWidth ) ) ;
}
2001-03-13 06:38:59 +00:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
1999-07-28 08:09:02 +00:00
// 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-13 22:56:31 +00:00
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 08:09:02 +00:00
if ( proportion > = 0 ) {
2000-12-19 20:29:46 +00:00
rawPropTotal = PR_MAX ( rawPropTotal , 0 ) ; // it was initialized to -1
1999-07-28 08:09:02 +00:00
colFrame - > SetWidth ( MIN_PRO , proportion ) ;
2000-12-19 20:29:46 +00:00
nsColConstraint colConstraint = ( 0 = = proportion )
? e0ProportionConstraint : eProportionConstraint ;
rawPropTotal + = proportion ;
colFrame - > SetConstraint ( colConstraint ) ;
1998-08-11 18:42:10 +00:00
}
}
2001-03-13 06:38:59 +00:00
if ( ! hasPctCol ) { // see if there is a pct col
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
float percent = colStyleWidth . GetPercentValue ( ) ;
if ( percent > 0.0f ) {
hasPctCol = PR_TRUE ;
}
}
}
1998-08-11 18:42:10 +00:00
}
1999-07-28 08:09:02 +00:00
if ( mCellSpacingTotal > 0 ) {
mCellSpacingTotal + = spacingX ; // add last cell spacing on right
}
1998-08-11 18:42:10 +00:00
2001-03-13 06:38:59 +00:00
PRBool * pctRequest = ( hasPctCol ) ? nsnull : & hasPctCol ;
ComputeNonPctColspanWidths ( aReflowState , PR_FALSE , aPixelToTwips , pctRequest ) ;
2001-01-12 23:07:54 +00:00
2000-12-19 20:29:46 +00:00
// figure the proportional widths for porportional cols
if ( rawPropTotal > 0 ) {
// get the total desired widths
nscoord desTotal = 0 ;
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
// consider 1*, 2*, etc cols, but ignore 0* cols
if ( colFrame - > GetWidth ( MIN_PRO ) > 0 ) {
desTotal + = colFrame - > GetDesWidth ( ) ;
1998-06-23 23:23:21 +00:00
}
}
2000-12-19 20:29:46 +00:00
// find the largest combined prop size considering each prop col and
// its desired size
nscoord maxPropTotal = 0 ;
for ( colX = 0 ; colX < numCols ; colX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord rawProp = colFrame - > GetWidth ( MIN_PRO ) ;
if ( rawProp > 0 ) {
nscoord desWidth = colFrame - > GetDesWidth ( ) ;
nscoord propTotal = NSToCoordRound ( ( ( float ) desWidth ) * ( ( float ) rawPropTotal ) / ( float ) rawProp ) ;
nsTableFrame : : RoundToPixel ( propTotal , aPixelToTwips ) ;
maxPropTotal = PR_MAX ( maxPropTotal , propTotal ) ;
}
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
// set MIN_PRO widths based on the maxPropTotal
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
nscoord rawProp = colFrame - > GetWidth ( MIN_PRO ) ;
if ( 0 = = rawProp ) {
// a 0* col gets only the min width
colFrame - > SetWidth ( MIN_PRO , colFrame - > GetMinWidth ( ) ) ;
}
else if ( ( rawProp > 0 ) & & ( rawPropTotal > 0 ) ) {
nscoord propWidth = NSToCoordRound ( ( ( float ) maxPropTotal ) * ( ( float ) rawProp ) / ( float ) rawPropTotal ) ;
propWidth = nsTableFrame : : RoundToPixel ( propWidth , aPixelToTwips ) ;
colFrame - > SetWidth ( MIN_PRO , PR_MAX ( propWidth , colFrame - > GetMinWidth ( ) ) ) ;
1998-06-23 23:23:21 +00:00
}
1998-05-29 22:08:19 +00:00
}
}
1998-05-26 22:03:16 +00:00
1999-07-28 08:09:02 +00:00
// Set the col's fixed width if present
// Set the table col width for each col to the content min.
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
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-13 22:56:31 +00:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Coord = = colStyleWidth . GetUnit ( ) ) {
fixColWidth = colStyleWidth . GetCoordValue ( ) ;
if ( fixColWidth > 0 ) {
colFrame - > SetWidth ( FIX , fixColWidth ) ;
}
}
1998-04-30 17:57:09 +00:00
}
1999-07-28 08:09:02 +00:00
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
mTableFrame - > SetColumnWidth ( colX , minWidth ) ;
1999-04-03 23:02:43 +00:00
}
1999-07-28 08:09:02 +00:00
2000-10-28 22:17:53 +00:00
if ( gsDebugAssign ) { printf ( " AssignNonPctColWidths ex \n " ) ; mTableFrame - > Dump ( aPresContext , PR_FALSE , PR_TRUE , PR_FALSE ) ; }
2001-02-01 02:29:14 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : eNonPctCols , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_FALSE ) ;
2001-02-01 02:29:14 +00:00
# endif
2001-03-13 06:38:59 +00:00
return hasPctCol ;
1998-04-30 17:57:09 +00:00
}
2000-09-09 01:46:44 +00:00
void
BasicTableLayoutStrategy : : ReduceOverSpecifiedPctCols ( nscoord aExcess )
{
2001-01-12 23:07:54 +00:00
nscoord numCols = mTableFrame - > GetColCount ( ) ;
2000-09-09 01:46:44 +00:00
for ( PRInt32 colX = numCols - 1 ; ( colX > = 0 ) & & ( aExcess > 0 ) ; colX - - ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-09-09 01:46:44 +00:00
nscoord pctWidth = colFrame - > GetWidth ( PCT ) ;
nscoord reduction = 0 ;
if ( pctWidth > 0 ) {
reduction = ( aExcess > pctWidth ) ? pctWidth : aExcess ;
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 = ( aExcess > pctAdjWidth ) ? pctAdjWidth : aExcess ;
nscoord newPctAdjWidth = ( reduction = = pctAdjWidth ) ? WIDTH_NOT_SET : pctAdjWidth - reduction ;
colFrame - > SetWidth ( PCT_ADJ , PR_MAX ( newPctAdjWidth , colFrame - > GetMinWidth ( ) ) ) ;
}
}
aExcess - = reduction ;
}
}
2001-02-07 04:31:38 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
nscoord WrapupAssignPctColumnWidths ( nsTableFrame * aTableFrame ,
const nsHTMLReflowState & aReflowState ,
nscoord aValue )
{
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : ePctCols , * aTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_FALSE ) ;
2001-02-07 04:31:38 +00:00
return aValue ;
}
# else
inline nscoord WrapupAssignPctColumnWidths ( nsTableFrame * aTableFrame ,
const nsHTMLReflowState & aReflowState ,
nscoord aValue )
{
return aValue ;
}
# endif
2001-03-13 06:38:59 +00:00
nscoord
BasicTableLayoutStrategy : : CalcPctAdjTableWidth ( const nsHTMLReflowState & aReflowState ,
nscoord aAvailWidthIn ,
float aPixelToTwips )
{
NS_ASSERTION ( mTableFrame - > IsAutoWidth ( ) & & mTableFrame - > HasPctCol ( ) , " invalid call " ) ;
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
PRInt32 numCols = mTableFrame - > GetColCount ( ) ; // consider cols at end without orig cells
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 colX , rowX ;
// 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
nscoord basis = 0 ;
float * rawPctValues = new float [ numCols ] ; // store the raw pct values, allow for spans past the effective numCols
if ( ! rawPctValues ) return NS_ERROR_OUT_OF_MEMORY ;
for ( colX = 0 ; colX < numCols ; colX + + ) {
rawPctValues [ colX ] = 0.0f ;
}
nsMargin borderPadding = mTableFrame - > GetBorderPadding ( aReflowState ) ;
nscoord availWidth = aAvailWidthIn ;
if ( NS_UNCONSTRAINEDSIZE ! = availWidth ) {
// adjust the avail width to exclude table border, padding and cell spacing
availWidth - = borderPadding . left + borderPadding . right + mCellSpacingTotal ;
}
for ( colX = 0 ; colX < numCols ; colX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
if ( ! colFrame ) continue ;
nscoord maxColBasis = - 1 ;
// Scan the cells in the col
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
if ( ! originates ) continue ; // skip cells that don't originate in the col
// 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 > 0.0f ) {
// calculate the preferred width of the cell based on fixWidth and desWidth
nscoord cellDesWidth = 0 ;
float spanPct = percent / float ( colSpan ) ;
for ( PRInt32 spanX = 0 ; spanX < colSpan ; spanX + + ) {
nsTableColFrame * spanFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
if ( ! spanFrame ) continue ;
cellDesWidth + = spanFrame - > GetWidth ( DES_CON ) ; // don't consider DES_ADJ
rawPctValues [ colX + spanX ] = PR_MAX ( rawPctValues [ colX + spanX ] , spanPct ) ;
}
// figure the basis using the cell's desired width and percent
nscoord colBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) cellDesWidth / percent ) , aPixelToTwips ) ;
maxColBasis = PR_MAX ( maxColBasis , colBasis ) ;
}
}
}
if ( - 1 = = maxColBasis ) {
// see if the col has a style percent width specified
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
float percent = colStyleWidth . GetPercentValue ( ) ;
maxColBasis = 0 ;
if ( percent > 0.0f ) {
rawPctValues [ colX ] = PR_MAX ( rawPctValues [ colX ] , percent ) ;
nscoord desWidth = colFrame - > GetWidth ( DES_CON ) ; // don't consider DES_ADJ
maxColBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) desWidth / percent ) , aPixelToTwips ) ;
}
}
}
basis = PR_MAX ( basis , maxColBasis ) ;
} // end for (colX ..
float perTotal = 0.0f ; // total of percentage constrained cols and/or cells in cols
nscoord fixWidthTotal = 0 ; // total of fixed widths of all cols
PRInt32 numPerCols = 0 ; // number of colums that have percentage constraints
nscoord fixDesTotal = 0 ; // total of fix or des widths of cols
nscoord fixDesTotalNoPct = 0 ; // total of fix or des widths of cols without pct
for ( colX = 0 ; colX < numCols ; colX + + ) {
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
nscoord fixWidth = colFrame - > GetFixWidth ( ) ;
nscoord fixDesWidth = ( fixWidth > 0 ) ? fixWidth : colFrame - > GetDesWidth ( ) ;
fixDesTotal + = fixDesWidth ;
if ( rawPctValues [ colX ] + perTotal > 1.0f ) {
rawPctValues [ colX ] = PR_MAX ( 1.0f - perTotal , 0.0f ) ;
}
if ( rawPctValues [ colX ] > 0.0f ) {
numPerCols + + ;
perTotal + = rawPctValues [ colX ] ;
}
else {
fixDesTotalNoPct + = fixDesWidth ;
}
}
delete [ ] rawPctValues ; // destroy the raw pct values
// If there are no pct cells or cols, there is nothing to do.
if ( ( 0 = = numPerCols ) | | ( 0.0f = = perTotal ) ) {
NS_ASSERTION ( PR_FALSE , " invalid call " ) ;
return 0 ;
}
// If there is only one col and it is % based, it won't affect anything
if ( ( 1 = = numCols ) & & ( numCols = = numPerCols ) ) {
return 0 ;
}
// compute a basis considering total percentages and the desired width of everything else
if ( ( perTotal > 0.0f ) & & ( perTotal < 1.0f ) ) {
nscoord otherBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) fixDesTotalNoPct / ( 1.0f - perTotal ) ) , aPixelToTwips ) ;
basis = PR_MAX ( basis , otherBasis ) ;
}
else if ( ( fixDesTotalNoPct > 0 ) & & ( NS_UNCONSTRAINEDSIZE ! = availWidth ) ) { // make the basis as big as possible
basis = availWidth ; // the 100% cols force as big a width as possible
}
basis = PR_MAX ( basis , fixDesTotal ) ;
basis = PR_MIN ( basis , availWidth ) ; // don't exceed the max we were given
if ( NS_UNCONSTRAINEDSIZE ! = availWidth ) {
// add back the table border, padding and cell spacing
basis + = borderPadding . left + borderPadding . right + mCellSpacingTotal ;
}
return basis ;
}
1999-07-28 08:09:02 +00:00
// Determine percentage col widths for each col frame
2000-02-12 01:55:40 +00:00
nscoord
2001-02-07 04:31:38 +00:00
BasicTableLayoutStrategy : : AssignPctColumnWidths ( const nsHTMLReflowState & aReflowState ,
2001-03-13 06:38:59 +00:00
nscoord aAvailWidth ,
2001-02-07 04:31:38 +00:00
PRBool aTableIsAutoWidth ,
float aPixelToTwips )
1999-07-28 08:09:02 +00:00
{
2001-02-01 02:29:14 +00:00
# ifdef DEBUG_TABLE_REFLOW_TIMING
2001-03-13 06:38:59 +00:00
nsTableFrame : : DebugTimeMethod ( nsTableFrame : : ePctCols , * mTableFrame , ( nsHTMLReflowState & ) aReflowState , PR_TRUE ) ;
2001-02-01 02:29:14 +00:00
# endif
2000-09-09 01:46:44 +00:00
mTableFrame - > SetHasCellSpanningPctCol ( PR_FALSE ) ; // this gets refigured below
1998-07-11 00:00:31 +00:00
PRInt32 numRows = mTableFrame - > GetRowCount ( ) ;
2001-01-13 00:26:01 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ; // consider cols at end without orig cells
2001-03-13 05:10:17 +00:00
PRInt32 numEffCols = mTableFrame - > GetEffectiveColCount ( ) ;
1999-07-28 08:09:02 +00:00
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
PRInt32 colX , rowX ;
2000-12-19 20:29:46 +00:00
2000-02-09 14:22:00 +00:00
nscoord basis ; // basis to use for percentage based calculations
2001-03-13 06:38:59 +00:00
if ( aTableIsAutoWidth ) {
basis = CalcPctAdjTableWidth ( aReflowState , aAvailWidth , aPixelToTwips ) ;
2000-02-09 14:22:00 +00:00
}
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 ;
2001-01-13 00:26:01 +00:00
float * rawPctValues = new float [ numCols ] ; // store the raw pct values, allow for spans past the effective numCols
2000-12-21 23:06:44 +00:00
if ( ! rawPctValues ) return NS_ERROR_OUT_OF_MEMORY ;
2001-01-13 00:26:01 +00:00
//XXX not sure if this really sets each element to 0.0f
//memset(rawPctValues, 0.0f, numCols * sizeof(float));
2001-03-13 05:10:17 +00:00
for ( colX = 0 ; colX < numEffCols ; colX + + ) {
2001-01-13 00:26:01 +00:00
rawPctValues [ colX ] = 0.0f ;
}
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-11-29 21:48:56 +00:00
nscoord maxColBasis = - 1 ;
1999-07-28 08:09:02 +00:00
// Scan the cells in the col
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 19:52:37 +00:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 08:09:02 +00: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 ( ) ;
if ( percent > 0.0f ) {
1999-10-21 22:36:21 +00:00
// calculate the preferred width of the cell based on fixWidth and desWidth
nscoord cellDesWidth = 0 ;
2000-12-19 20:29:46 +00:00
float spanPct = percent / float ( colSpan ) ;
1999-10-21 22:36:21 +00:00
for ( PRInt32 spanX = 0 ; spanX < colSpan ; spanX + + ) {
nsTableColFrame * spanFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! spanFrame ) continue ;
2000-12-19 20:29:46 +00:00
cellDesWidth + = spanFrame - > GetWidth ( DES_CON ) ; // don't consider DES_ADJ
rawPctValues [ colX + spanX ] = PR_MAX ( rawPctValues [ colX + spanX ] , spanPct ) ;
1999-10-21 22:36:21 +00:00
}
// figure the basis using the cell's desired width and percent
2000-11-29 21:48:56 +00:00
nscoord colBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) cellDesWidth / percent ) , aPixelToTwips ) ;
maxColBasis = PR_MAX ( maxColBasis , colBasis ) ;
1998-07-22 03:53:43 +00:00
}
1998-07-17 21:02:28 +00:00
}
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
if ( - 1 = = maxColBasis ) {
1999-07-28 08:09:02 +00:00
// see if the col has a style percent width specified
1999-12-13 22:56:31 +00:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
float percent = colStyleWidth . GetPercentValue ( ) ;
2000-11-29 21:48:56 +00:00
maxColBasis = 0 ;
1999-12-13 22:56:31 +00:00
if ( percent > 0.0f ) {
2000-12-19 20:29:46 +00:00
rawPctValues [ colX ] = PR_MAX ( rawPctValues [ colX ] , percent ) ;
nscoord desWidth = colFrame - > GetWidth ( DES_CON ) ; // don't consider DES_ADJ
2000-11-29 21:48:56 +00:00
maxColBasis = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( float ) desWidth / percent ) , aPixelToTwips ) ;
1999-12-13 22:56:31 +00:00
}
}
1998-04-30 17:57:09 +00:00
}
2000-11-29 21:48:56 +00:00
basis = PR_MAX ( basis , maxColBasis ) ;
2000-12-19 20:29:46 +00:00
} // end for (colX ..
float perTotal = 0.0f ; // total of percentage constrained cols and/or cells in cols
PRInt32 numPerCols = 0 ; // number of colums that have percentage constraints
nscoord fixDesTotal = 0 ; // total of fix or des widths of cols
nscoord fixDesTotalNoPct = 0 ; // total of fix or des widths of cols without pct
2001-03-13 05:10:17 +00:00
for ( colX = 0 ; colX < numEffCols ; colX + + ) {
2000-12-19 20:29:46 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
1999-11-05 22:36:59 +00:00
nscoord fixWidth = colFrame - > GetFixWidth ( ) ;
2000-12-19 20:29:46 +00:00
nscoord fixDesWidth = ( fixWidth > 0 ) ? fixWidth : colFrame - > GetDesWidth ( ) ;
fixDesTotal + = fixDesWidth ;
if ( rawPctValues [ colX ] + perTotal > 1.0f ) {
rawPctValues [ colX ] = PR_MAX ( 1.0f - perTotal , 0.0f ) ;
}
if ( rawPctValues [ colX ] > 0.0f ) {
1999-07-28 08:09:02 +00:00
numPerCols + + ;
2000-12-19 20:29:46 +00:00
perTotal + = rawPctValues [ colX ] ;
1999-07-28 08:09:02 +00:00
}
1999-10-25 04:34:28 +00:00
else {
2000-12-19 20:29:46 +00:00
fixDesTotalNoPct + = fixDesWidth ;
1999-10-25 04:34:28 +00:00
}
2000-12-19 20:29:46 +00:00
}
delete [ ] rawPctValues ; // destroy the raw pct values
1999-11-05 22:36:59 +00:00
// If there are no pct cells or cols, there is nothing to do.
2000-12-19 20:29:46 +00:00
if ( ( 0 = = numPerCols ) | | ( 0.0f = = perTotal ) ) {
2001-02-07 04:31:38 +00:00
return WrapupAssignPctColumnWidths ( mTableFrame , aReflowState , 0 ) ;
1999-11-05 22:36:59 +00:00
}
1999-07-28 08:09:02 +00:00
// If there is only one col and it is % based, it won't affect anything
1999-12-13 22:56:31 +00:00
if ( ( 1 = = numCols ) & & ( numCols = = numPerCols ) ) {
2001-02-07 04:31:38 +00:00
return WrapupAssignPctColumnWidths ( mTableFrame , aReflowState , 0 ) ;
1998-07-17 21:02:28 +00:00
}
2001-03-13 06:38:59 +00:00
basis = aAvailWidth ;
1999-07-28 08:09:02 +00:00
}
2001-03-13 06:38:59 +00:00
// adjust the basis to exclude table border, padding and cell spacing
nsMargin borderPadding = mTableFrame - > GetBorderPadding ( aReflowState ) ;
basis - = borderPadding . left + borderPadding . right + mCellSpacingTotal ;
1998-07-17 21:02:28 +00:00
1999-07-28 08:09:02 +00:00
nscoord colPctTotal = 0 ;
// Determine the percentage contribution for cols and for cells with colspan = 1
2000-09-09 01:46:44 +00:00
// Iterate backwards, similarly to the reasoning in AssignNonPctColumnWidths
1999-12-13 22:56:31 +00:00
for ( colX = numCols - 1 ; colX > = 0 ; colX - - ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
nscoord maxColPctWidth = WIDTH_NOT_SET ;
float maxColPct = 0.0f ;
1999-08-19 19:52:37 +00:00
nsTableCellFrame * percentContributor = nsnull ;
1999-07-28 08:09:02 +00: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 19:52:37 +00:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 08:09:02 +00: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 19:52:37 +00:00
percentContributor = cellFrame ;
1999-07-28 08:09:02 +00:00
if ( ! mIsNavQuirksMode ) {
2000-02-12 01:55:40 +00:00
// need to add padding
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( basis , 0 ) , cellFrame ) ;
maxColPctWidth + = padding . left + padding . right ;
1998-06-05 22:50:03 +00:00
}
}
1998-04-30 17:57:09 +00:00
}
1999-07-28 08:09:02 +00:00
}
if ( WIDTH_NOT_SET = = maxColPctWidth ) {
// see if the col has a style percent width specified
1999-12-13 22:56:31 +00:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
if ( eStyleUnit_Percent = = colStyleWidth . GetUnit ( ) ) {
maxColPct = colStyleWidth . GetPercentValue ( ) ;
2000-09-01 01:29:50 +00:00
maxColPctWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) basis ) * maxColPct ) , aPixelToTwips ) ;
1999-12-13 22:56:31 +00:00
}
1999-07-28 08:09:02 +00: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-09-09 01:46:44 +00:00
maxColPctWidth = PR_MAX ( maxColPctWidth , colFrame - > GetWidth ( MIN_CON ) ) ;
1999-07-28 08:09:02 +00:00
colFrame - > SetWidth ( PCT , maxColPctWidth ) ;
1999-08-19 19:52:37 +00:00
colFrame - > SetConstrainingCell ( percentContributor ) ;
2000-05-26 21:13:01 +00:00
colPctTotal + = NSToCoordRound ( 100.0f * ( float ) maxColPct ) ;
1999-07-28 08:09:02 +00:00
}
}
2000-09-09 01:46:44 +00:00
// if the percent total went over 100%, adjustments need to be made to right most cols
if ( colPctTotal > 100 ) {
ReduceOverSpecifiedPctCols ( NSToCoordRound ( ( ( float ) ( colPctTotal - 100 ) ) * 0.01f * ( float ) basis ) ) ;
colPctTotal = 100 ;
}
// check to see if a cell spans a percentage col. This will cause the MIN_ADJ,
// FIX_ADJ, and DES_ADJ values to be recomputed
2001-02-01 02:29:14 +00:00
PRBool done = PR_FALSE ;
for ( colX = 0 ; ( colX < numCols ) & & ! done ; colX + + ) {
for ( rowX = 0 ; ( rowX < numRows ) & & ! done ; rowX + + ) {
2000-09-09 01:46:44 +00:00
PRBool originates ;
PRInt32 colSpan ;
2001-03-21 05:32:22 +00:00
mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
if ( ! originates | | 1 = = colSpan ) {
2000-09-09 01:46:44 +00:00
continue ;
}
// determine if the cell spans cols which have a pct value
2001-02-01 02:29:14 +00:00
for ( PRInt32 spanX = 0 ; ( spanX < colSpan ) & & ! done ; spanX + + ) {
2000-09-09 01:46:44 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-09-09 01:46:44 +00:00
if ( colFrame - > GetWidth ( PCT ) > 0 ) {
mTableFrame - > SetHasCellSpanningPctCol ( PR_TRUE ) ;
// recompute the MIN_ADJ, FIX_ADJ, and DES_ADJ values
2001-03-13 06:38:59 +00:00
ComputeNonPctColspanWidths ( aReflowState , PR_TRUE , aPixelToTwips , nsnull ) ;
2001-02-01 02:29:14 +00:00
done = PR_TRUE ;
2000-09-09 01:46:44 +00:00
break ;
}
}
}
}
1999-07-28 08:09:02 +00:00
// For each col, consider the cells originating in it with colspans > 1.
// Adjust the cols that each cell spans if necessary.
2001-03-13 05:10:17 +00:00
for ( colX = 0 ; colX < numEffCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
for ( rowX = 0 ; rowX < numRows ; rowX + + ) {
PRBool originates ;
PRInt32 colSpan ;
1999-08-19 19:52:37 +00:00
nsTableCellFrame * cellFrame = mTableFrame - > GetCellInfoAt ( rowX , colX , & originates , & colSpan ) ;
1999-07-28 08:09:02 +00:00
if ( ! originates | | ( 1 = = colSpan ) ) {
continue ;
1998-05-26 22:03:16 +00:00
}
2001-03-13 05:10:17 +00:00
colSpan = PR_MIN ( colSpan , numEffCols - colX ) ;
nscoord cellPctWidth = WIDTH_NOT_SET ;
1999-07-28 08:09:02 +00:00
// 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 01:29:50 +00:00
cellPctWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) basis ) * cellPct ) , aPixelToTwips ) ;
1999-07-28 08:09:02 +00:00
if ( ! mIsNavQuirksMode ) {
// need to add padding
2000-02-12 01:55:40 +00:00
nsMargin padding = nsTableFrame : : GetPadding ( nsSize ( basis , 0 ) , cellFrame ) ;
cellPctWidth + = padding . left + padding . right ;
1999-04-03 23:02:43 +00:00
}
1998-05-29 22:08:19 +00:00
}
1999-07-28 08:09:02 +00: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 12:01:31 +00:00
PRInt32 spanX ;
for ( spanX = 0 ; spanX < colSpan ; spanX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
nscoord colPctWidth = colFrame - > GetWidth ( PCT ) ;
if ( colPctWidth > 0 ) { // skip pct cols
colPctWidthTotal + = colPctWidth ;
continue ;
1998-06-05 22:50:03 +00:00
}
1999-07-28 08:09:02 +00:00
nscoord colWidth = PR_MAX ( colFrame - > GetMinWidth ( ) , colFrame - > GetFixWidth ( ) ) ;
1999-08-19 19:52:37 +00:00
colWidth = PR_MAX ( colWidth , colFrame - > GetDesWidth ( ) ) ; // XXX check this
1999-07-28 08:09:02 +00:00
//colWidth = PR_MAX(colWidth, colFrame->GetPctWidth());
spanTotal + = colWidth ;
1999-08-25 21:49:18 +00:00
if ( ( spanX > 0 ) & & ( mTableFrame - > GetNumCellsOriginatingInCol ( colX + spanX ) > 0 ) ) {
1999-07-28 08:09:02 +00:00
spanCellSpacing + = spacingX ;
1998-06-05 22:50:03 +00:00
}
1999-07-28 08:09:02 +00: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 12:01:31 +00:00
for ( spanX = 0 ; spanX < colSpan ; spanX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX + spanX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
if ( colFrame - > GetWidth ( PCT ) > 0 ) { // skip pct cols
continue ;
}
nscoord minWidth = colFrame - > GetMinWidth ( ) ;
nscoord colWidth = PR_MAX ( minWidth , colFrame - > GetFixWidth ( ) ) ;
1999-08-19 19:52:37 +00:00
colWidth = PR_MAX ( colWidth , colFrame - > GetDesWidth ( ) ) ; // XXX check this
1999-11-05 22:36:59 +00:00
float avail = ( float ) PR_MAX ( cellPctWidth - colPctWidthTotal , 0 ) ;
1999-07-28 08:09:02 +00:00
float colPctAdj = ( 0 = = spanTotal )
2001-01-12 23:07:54 +00:00
? avail / ( ( float ) colSpan ) / ( ( float ) basis )
2000-05-26 21:13:01 +00:00
: ( avail / ( float ) basis ) * ( ( ( float ) colWidth ) / ( float ) spanTotal ) ;
1999-07-28 08:09:02 +00:00
if ( colPctAdj > 0 ) {
nscoord colPctAdjWidth = colFrame - > GetWidth ( PCT_ADJ ) ;
2000-09-01 01:29:50 +00:00
nscoord newColPctAdjWidth = nsTableFrame : : RoundToPixel ( NSToCoordRound ( colPctAdj * ( float ) basis ) , aPixelToTwips ) ;
1999-07-28 08:09:02 +00:00
if ( newColPctAdjWidth > colPctAdjWidth ) {
2000-05-26 21:13:01 +00:00
newColPctAdjWidth = PR_MAX ( newColPctAdjWidth , minWidth ) ;
1999-08-19 19:52:37 +00:00
if ( newColPctAdjWidth > colFrame - > GetWidth ( PCT ) ) {
colFrame - > SetWidth ( PCT_ADJ , newColPctAdjWidth ) ;
colFrame - > SetConstrainingCell ( cellFrame ) ;
}
1999-07-28 08:09:02 +00:00
}
1998-06-05 22:50:03 +00:00
}
1998-05-29 22:08:19 +00:00
}
1998-05-26 22:03:16 +00:00
}
1998-04-30 17:57:09 +00:00
}
1999-07-28 08:09:02 +00:00
} // end for (rowX ..
2000-05-26 21:13:01 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-05-26 21:13:01 +00:00
colPctTotal + = NSToCoordRound ( 100.0f * ( float ) colFrame - > GetWidth ( PCT_ADJ ) / ( float ) basis ) ;
1999-07-28 08:09:02 +00:00
} // end for (colX ..
// if the percent total went over 100%, adjustments need to be made to right most cols
if ( colPctTotal > 100 ) {
2000-09-09 01:46:44 +00:00
ReduceOverSpecifiedPctCols ( NSToCoordRound ( ( ( float ) ( colPctTotal - 100 ) ) * 0.01f * ( float ) basis ) ) ;
1998-11-04 19:33:27 +00:00
}
1999-07-28 08:09:02 +00:00
2001-03-13 06:38:59 +00:00
// adjust the basis to include table border, padding and cell spacing
basis + = borderPadding . left + borderPadding . right + mCellSpacingTotal ;
2001-02-07 04:31:38 +00:00
return WrapupAssignPctColumnWidths ( mTableFrame , aReflowState , basis ) ;
1999-07-28 08:09:02 +00:00
}
1998-07-16 23:23:31 +00:00
2000-09-01 01:29:50 +00:00
// calculate totals by width type. The logic here is kept in synch with
2000-12-19 20:29:46 +00:00
// that in CanAllocate. aDupedWidths (duplicatd) are widths that will be
// allocated in BalanceColumnWidths before aTotalsWidths (e.g. aTotalWidths[PCT]
// will have aDuplicatedWidths[PCT] consisting of the MIN widths of cols which
// have a PCT width).
2001-03-13 06:38:59 +00:00
void BasicTableLayoutStrategy : : CalculateTotals ( PRInt32 * aTotalCounts ,
1999-07-28 08:09:02 +00:00
PRInt32 * aTotalWidths ,
2000-12-19 20:29:46 +00:00
PRInt32 * aDupedWidths ,
1999-07-28 08:09:02 +00:00
PRInt32 & a0ProportionalCount )
{
//mTableFrame->Dump(PR_TRUE, PR_FALSE);
for ( PRInt32 widthX = 0 ; widthX < NUM_WIDTHS ; widthX + + ) {
1999-10-04 05:19:32 +00:00
aTotalCounts [ widthX ] = 0 ;
aTotalWidths [ widthX ] = 0 ;
2000-12-19 20:29:46 +00:00
aDupedWidths [ widthX ] = 0 ;
1999-07-28 08:09:02 +00:00
}
a0ProportionalCount = 0 ;
nscoord spacingX = mTableFrame - > GetCellSpacingX ( ) ;
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
2000-09-01 01:29:50 +00:00
PRInt32 colX ;
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-07-28 08:09:02 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
1999-07-28 08:09:02 +00:00
nscoord minCol = colFrame - > GetMinWidth ( ) ;
aTotalCounts [ MIN_CON ] + + ;
aTotalWidths [ MIN_CON ] + = minCol ;
if ( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) {
a0ProportionalCount + + ;
}
1999-10-04 05:19:32 +00: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 08:09:02 +00:00
aTotalCounts [ PCT ] + + ;
2000-12-19 20:29:46 +00:00
aTotalWidths [ PCT ] + = PR_MAX ( pct , minCol ) ;
aDupedWidths [ PCT ] + = minCol ;
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
else if ( ( fix > 0 ) | | ( fixAdj > 0 ) ) {
1999-10-04 05:19:32 +00:00
if ( fix > 0 ) {
aTotalCounts [ FIX ] + + ;
2000-12-19 20:29:46 +00:00
aTotalWidths [ FIX ] + = PR_MAX ( fix , minCol ) ;
aDupedWidths [ FIX ] + = minCol ;
1999-10-04 05:19:32 +00:00
}
if ( fixAdj > 0 ) {
if ( fixAdj > fix ) {
aTotalCounts [ FIX_ADJ ] + + ;
2000-12-19 20:29:46 +00:00
aTotalWidths [ FIX_ADJ ] + = PR_MAX ( fixAdj , minCol ) ;
1999-10-04 05:19:32 +00:00
if ( fix > 0 ) {
2000-12-19 20:29:46 +00:00
aDupedWidths [ FIX_ADJ ] + = fix ;
1999-10-04 05:19:32 +00:00
}
else { // there was no fix
2000-12-19 20:29:46 +00:00
aDupedWidths [ FIX_ADJ ] + = minCol ;
1999-10-04 05:19:32 +00:00
}
}
}
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
else if ( ( eProportionConstraint = = colFrame - > GetConstraint ( ) ) | |
( e0ProportionConstraint = = colFrame - > GetConstraint ( ) ) ) {
1999-07-28 08:09:02 +00:00
aTotalCounts [ MIN_PRO ] + + ;
2000-12-19 20:29:46 +00:00
aTotalWidths [ MIN_PRO ] + = PR_MAX ( colFrame - > GetWidth ( MIN_PRO ) , minCol ) ;
aDupedWidths [ MIN_PRO ] + = minCol ;
1999-07-28 08:09:02 +00:00
}
2000-12-19 20:29:46 +00:00
else {
// desired alone is lowest priority
aTotalCounts [ DES_CON ] + + ;
aTotalWidths [ DES_CON ] + = PR_MAX ( colFrame - > GetDesWidth ( ) , minCol ) ;
aDupedWidths [ DES_CON ] + = minCol ;
2000-10-13 01:57:02 +00:00
}
1998-05-29 22:08:19 +00:00
}
1998-04-30 17:57:09 +00:00
}
1999-07-28 08:09:02 +00:00
1999-05-10 19:23:09 +00:00
struct nsColInfo {
1999-05-26 22:22:23 +00:00
nsColInfo ( nsTableColFrame * aFrame ,
PRInt32 aIndex ,
PRInt32 aMinWidth ,
PRInt32 aWidth ,
PRInt32 aMaxWidth )
: mFrame ( aFrame ) , mIndex ( aIndex ) , mMinWidth ( aMinWidth ) ,
1999-07-28 08:09:02 +00:00
mWidth ( aWidth ) , mMaxWidth ( aMaxWidth ) , mWeight ( 0 )
1999-05-26 22:22:23 +00:00
{ }
nsTableColFrame * mFrame ;
PRInt32 mIndex ;
PRInt32 mMinWidth ;
PRInt32 mWidth ;
PRInt32 mMaxWidth ;
float mWeight ;
1999-05-10 19:23:09 +00:00
} ;
void
1999-07-28 08:09:02 +00:00
AC_Wrapup ( nsTableFrame * aTableFrame ,
1999-07-28 19:43:37 +00:00
PRInt32 aNumItems ,
nsColInfo * * aColInfo ,
PRBool aAbort = PR_FALSE )
1999-05-10 19:23:09 +00:00
{
1999-07-28 08:09:02 +00: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-26 22:22:23 +00:00
}
}
void
1999-07-28 08:09:02 +00:00
AC_Increase ( PRInt32 aNumAutoCols ,
1999-08-23 04:41:30 +00:00
nsColInfo * * aColInfo ,
PRInt32 aDivisor ,
2000-09-01 01:29:50 +00:00
PRInt32 & aAvailWidth ,
float aPixelToTwips )
1999-05-26 22:22:23 +00:00
{
for ( PRInt32 i = 0 ; i < aNumAutoCols ; i + + ) {
if ( ( aAvailWidth < = 0 ) | | ( aDivisor < = 0 ) ) {
break ;
}
2000-02-09 14:22:00 +00: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 01:29:50 +00:00
nscoord addition = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) ( aAvailWidth ) ) * percent ) , aPixelToTwips ) ;
1999-08-23 04:41:30 +00:00
// if its the last col, try to give what's left to it
if ( ( i = = aNumAutoCols - 1 ) & & ( addition < aAvailWidth ) ) {
addition = aAvailWidth ;
1999-05-26 22:22:23 +00:00
}
1999-08-23 04:41:30 +00: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-26 22:22:23 +00:00
aColInfo [ i ] - > mWidth + = addition ;
aAvailWidth - = addition ;
}
}
void
1999-07-28 08:09:02 +00:00
AC_Decrease ( PRInt32 aNumAutoCols ,
1999-08-23 04:41:30 +00:00
nsColInfo * * aColInfo ,
PRInt32 aDivisor ,
2000-09-01 01:29:50 +00:00
PRInt32 & aExcess ,
float aPixelToTwips )
1999-05-26 22:22:23 +00: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 01:29:50 +00:00
nscoord reduction = nsTableFrame : : RoundToPixel ( NSToCoordRound ( ( ( float ) ( aExcess ) ) * percent ) , aPixelToTwips ) ;
1999-08-23 04:41:30 +00:00
// if its the last col, try to remove the remaining excess from it
if ( ( i = = aNumAutoCols - 1 ) & & ( reduction < aExcess ) ) {
reduction = aExcess ;
1999-05-26 22:22:23 +00:00
}
1999-08-23 04:41:30 +00: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-26 22:22:23 +00:00
aColInfo [ i ] - > mWidth - = reduction ;
aExcess - = reduction ;
}
}
void
1999-07-28 08:09:02 +00:00
AC_Sort ( nsColInfo * * aColInfo , PRInt32 aNumCols )
1999-05-26 22:22:23 +00: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 19:23:09 +00:00
}
}
1999-10-04 05:19:32 +00:00
1999-07-28 08:09:02 +00: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 01:29:50 +00:00
PRInt32 * aAllocTypes ,
float aPixelToTwips )
1999-05-26 22:22:23 +00:00
{
1999-10-04 05:19:32 +00:00
if ( ( 0 = = aAvailWidth ) | | ( aWidthType < 0 ) | | ( aWidthType > = NUM_WIDTHS ) ) {
1999-07-28 08:09:02 +00:00
NS_ASSERTION ( PR_TRUE , " invalid args to AllocateConstrained " ) ;
1999-05-26 22:22:23 +00:00
return ;
}
2001-01-12 23:07:54 +00:00
PRInt32 numCols = mTableFrame - > GetColCount ( ) ;
1999-10-04 05:19:32 +00:00
PRInt32 numConstrainedCols = 0 ;
nscoord sumMaxConstraints = 0 ;
2000-02-09 14:22:00 +00:00
nscoord sumMinConstraints = 0 ;
1999-10-04 05:19:32 +00:00
PRInt32 colX ;
2000-02-09 14:22:00 +00:00
// find out how many constrained cols there are
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 05:19:32 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame ) ) {
continue ;
1999-10-04 05:19:32 +00:00
}
numConstrainedCols + + ;
}
2000-02-09 14:22:00 +00:00
// allocate storage for the constrained cols. Only they get adjusted.
1999-10-04 05:19:32 +00:00
nsColInfo * * colInfo = new nsColInfo * [ numConstrainedCols ] ;
1999-07-28 19:43:37 +00:00
if ( ! colInfo ) return ;
1999-10-04 05:19:32 +00:00
memset ( colInfo , 0 , numConstrainedCols * sizeof ( nsColInfo * ) ) ;
1999-07-28 19:43:37 +00:00
1999-07-28 08:09:02 +00:00
PRInt32 maxMinDiff = 0 ;
PRInt32 constrColX = 0 ;
// set the col info entries for each constrained col
1999-12-13 22:56:31 +00:00
for ( colX = 0 ; colX < numCols ; colX + + ) {
1999-10-04 05:19:32 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( colX ) ;
2000-10-06 01:04:13 +00:00
if ( ! colFrame ) continue ;
2000-12-19 20:29:46 +00:00
if ( ! CanAllocate ( aWidthType , aAllocTypes [ colX ] , colFrame ) ) {
1999-07-28 08:09:02 +00:00
continue ;
}
2000-12-19 20:29:46 +00:00
nscoord minWidth = mTableFrame - > GetColumnWidth ( colX ) ;
nscoord maxWidth = GetColWidth ( colFrame , aWidthType ) ;
2001-01-12 23:07:54 +00:00
// proportional and desired widths are handled together
PRBool haveProWidth = PR_FALSE ;
if ( DES_CON = = aWidthType ) {
nscoord proWidth = colFrame - > GetWidth ( MIN_PRO ) ;
if ( proWidth > = 0 ) {
haveProWidth = PR_TRUE ;
maxWidth = proWidth ;
}
}
2000-12-19 20:29:46 +00:00
if ( maxWidth < = 0 ) continue ;
2000-02-09 14:22:00 +00:00
sumMaxConstraints + = maxWidth ;
sumMinConstraints + = minWidth ;
1999-10-04 05:19:32 +00:00
1999-07-28 08:09:02 +00:00
maxWidth = PR_MAX ( maxWidth , minWidth ) ;
maxMinDiff + = maxWidth - minWidth ;
nscoord startWidth = ( aStartAtMin ) ? minWidth : maxWidth ;
1999-07-28 19:43:37 +00:00
colInfo [ constrColX ] = new nsColInfo ( colFrame , colX , minWidth , startWidth , maxWidth ) ;
1999-07-28 08:09:02 +00:00
if ( ! colInfo [ constrColX ] ) {
1999-10-04 05:19:32 +00:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo , PR_TRUE ) ;
1999-07-28 08:09:02 +00:00
return ;
}
2001-01-12 23:07:54 +00:00
aAllocTypes [ colX ] = ( haveProWidth ) ? MIN_PRO : aWidthType ;
1999-07-28 19:43:37 +00:00
constrColX + + ;
1999-05-26 22:22:23 +00:00
}
1999-10-04 05:19:32 +00:00
if ( constrColX < numConstrainedCols ) {
1999-07-28 08:09:02 +00:00
// some of the constrainted cols might have been 0 and skipped
1999-10-04 05:19:32 +00:00
numConstrainedCols = constrColX ;
1999-07-28 08:09:02 +00:00
}
1999-10-04 05:19:32 +00:00
1999-07-28 08:09:02 +00:00
PRInt32 i ;
if ( aStartAtMin ) { // allocate extra space
nscoord availWidth = aAvailWidth ;
1999-10-04 05:19:32 +00:00
for ( i = 0 ; i < numConstrainedCols ; i + + ) {
1999-07-28 08:09:02 +00:00
// the weight here is a relative metric for determining when cols reach their max constraint.
1999-05-26 22:22:23 +00: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 05:19:32 +00:00
AC_Sort ( colInfo , numConstrainedCols ) ;
1999-05-26 22:22:23 +00: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 01:29:50 +00:00
AC_Increase ( numConstrainedCols , colInfo , sumMaxConstraints - sumMinConstraints ,
availWidth , aPixelToTwips ) ;
1999-05-26 22:22:23 +00:00
}
1999-07-28 08:09:02 +00:00
else { // reduce each col width
nscoord reduceWidth = maxMinDiff - aAvailWidth ;
if ( reduceWidth < 0 ) {
NS_ASSERTION ( PR_TRUE , " AllocateConstrained called incorrectly " ) ;
1999-10-04 05:19:32 +00:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo ) ;
1999-07-28 08:09:02 +00:00
return ;
}
1999-10-04 05:19:32 +00:00
for ( i = 0 ; i < numConstrainedCols ; i + + ) {
1999-05-26 22:22:23 +00: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 05:19:32 +00:00
AC_Sort ( colInfo , numConstrainedCols ) ;
1999-05-26 22:22:23 +00: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 01:29:50 +00:00
AC_Decrease ( numConstrainedCols , colInfo , sumMaxConstraints , reduceWidth , aPixelToTwips ) ;
1999-05-10 19:23:09 +00:00
}
1999-10-04 05:19:32 +00:00
AC_Wrapup ( mTableFrame , numConstrainedCols , colInfo ) ;
1998-07-16 23:23:31 +00:00
}
1999-08-19 19:52:37 +00:00
1998-07-23 21:55:45 +00:00
PRBool BasicTableLayoutStrategy : : IsColumnInList ( const PRInt32 colIndex ,
1999-04-03 23:02:43 +00:00
PRInt32 * colIndexes ,
PRInt32 aNumFixedColumns )
1998-07-23 21:55:45 +00:00
{
PRBool result = PR_FALSE ;
1999-04-03 23:02:43 +00:00
for ( PRInt32 i = 0 ; i < aNumFixedColumns ; i + + ) {
if ( colIndex = = colIndexes [ i ] ) {
1998-07-23 21:55:45 +00:00
result = PR_TRUE ;
break ;
}
1999-04-03 23:02:43 +00:00
else if ( colIndex < colIndexes [ i ] ) {
1998-07-23 21:55:45 +00:00
break ;
1999-04-03 23:02:43 +00:00
}
1998-07-23 21:55:45 +00:00
}
return result ;
}
1998-07-16 23:23:31 +00:00
1998-08-14 16:16:43 +00:00
PRBool BasicTableLayoutStrategy : : ColIsSpecifiedAsMinimumWidth ( PRInt32 aColIndex )
{
PRBool result = PR_FALSE ;
2001-03-13 06:38:59 +00:00
nsTableColFrame * colFrame = mTableFrame - > GetColFrame ( aColIndex ) ;
1999-12-13 22:56:31 +00:00
nsStyleCoord colStyleWidth = colFrame - > GetStyleWidth ( ) ;
switch ( colStyleWidth . GetUnit ( ) ) {
1998-08-14 16:16:43 +00:00
case eStyleUnit_Coord :
1999-12-13 22:56:31 +00:00
if ( 0 = = colStyleWidth . GetCoordValue ( ) ) {
1998-08-14 16:16:43 +00:00
result = PR_TRUE ;
1999-04-03 23:02:43 +00:00
}
1998-08-14 16:16:43 +00: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-13 22:56:31 +00:00
float percent = colStyleWidth . GetPercentValue ( ) ;
1999-04-03 23:02:43 +00:00
if ( 0.0f = = percent | | 0.01f = = percent ) {
1998-08-14 16:16:43 +00:00
result = PR_TRUE ;
1999-04-03 23:02:43 +00:00
}
1998-08-14 16:16:43 +00:00
break ;
}
case eStyleUnit_Proportional :
1999-12-13 22:56:31 +00:00
if ( 0 = = colStyleWidth . GetIntValue ( ) ) {
1999-04-03 23:02:43 +00:00
result = PR_TRUE ;
}
1999-02-12 17:45:58 +00:00
default :
break ;
1998-08-14 16:16:43 +00:00
}
return result ;
}
1999-07-28 08:09:02 +00:00
void BasicTableLayoutStrategy : : Dump ( PRInt32 aIndent )
1998-10-02 20:34:11 +00:00
{
1999-07-28 08:09:02 +00:00
char * indent = new char [ aIndent + 1 ] ;
2000-11-30 15:53:55 +00:00
if ( ! indent ) return ;
1999-07-28 08:09:02 +00:00
for ( PRInt32 i = 0 ; i < aIndent + 1 ; i + + ) {
indent [ i ] = ' ' ;
}
indent [ aIndent ] = 0 ;
2000-10-28 22:17:53 +00:00
printf ( " %s**START BASIC STRATEGY DUMP** table=%p cols=%X " ,
1999-12-13 22:56:31 +00:00
indent , mTableFrame , mCols ) ;
2000-10-28 22:17:53 +00:00
printf ( " \n %s cellSpacing=%d propRatio=%.2f navQuirks=%d " ,
indent , mCellSpacingTotal , mMinToDesProportionRatio , mIsNavQuirksMode ) ;
printf ( " **END BASIC STRATEGY DUMP** \n " ) ;
1999-07-28 08:09:02 +00:00
delete [ ] indent ;
1998-10-02 20:34:11 +00:00
}
1998-08-14 16:16:43 +00:00