Back to index

lightning-sunbird  0.9+nobinonly
nsTableFrame.h
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 #ifndef nsTableFrame_h__
00038 #define nsTableFrame_h__
00039 
00040 #include "nscore.h"
00041 #include "nsVoidArray.h"
00042 #include "nsHTMLContainerFrame.h"
00043 #include "nsStyleCoord.h"
00044 #include "nsStyleConsts.h"
00045 #include "nsITableLayout.h"
00046 #include "nsTableColFrame.h"
00047 #include "nsTableColGroupFrame.h"
00048 
00049 class nsCellMap;
00050 class nsTableCellMap;
00051 class nsTableCellFrame;
00052 class nsTableColFrame;
00053 class nsTableRowGroupFrame;
00054 class nsTableRowFrame;
00055 class nsTableColGroupFrame;
00056 class nsITableLayoutStrategy;
00057 class nsStyleContext;
00058 
00059 struct nsTableReflowState;
00060 struct nsStylePosition;
00061 
00062 enum nsPixelRound {eAlwaysRoundUp=0, eAlwaysRoundDown, eRoundUpIfHalfOrMore};
00063 
00064 #ifdef DEBUG_TABLE_REFLOW_TIMING
00065 #ifdef WIN32
00066 #include <windows.h>
00067 #endif
00068 class nsReflowTimer
00069 {
00070 public:
00071   nsReflowTimer(nsIFrame* aFrame) {
00072     mFrame = aFrame;
00073     mNextSibling = nsnull;
00074     mFrameType = aFrame->GetType();
00075     NS_IF_ADDREF(mFrameType);
00076     mReflowType = -1;
00077               Reset();
00078        }
00079 
00080   void Destroy() {
00081     PRInt32 numChildren = mChildren.Count();
00082     for (PRInt32 childX = 0; childX < numChildren; childX++) {
00083       ((nsReflowTimer*)mChildren.ElementAt(childX))->Destroy();
00084     }
00085     NS_IF_RELEASE(mFrameType);
00086     if (mNextSibling) { // table frames have 3 auxillary timers
00087       delete mNextSibling->mNextSibling->mNextSibling;
00088       delete mNextSibling->mNextSibling;
00089       delete mNextSibling;
00090     }
00091     delete this;
00092   }
00093 
00094   void Print(PRUint32 aIndent,
00095              char*    aHeader = 0)  {
00096               if (aHeader) {
00097            printf("%s", aHeader);
00098               }
00099     printf(" elapsed=%d numStarts=%d \n", Elapsed(), mNumStarts);       
00100   }
00101 
00102   PRUint32 Elapsed() {
00103     return mTotalTime;
00104        }
00105 
00106   void Reset() {
00107               mTotalTime = mNumStarts = 0;
00108     mStarted = PR_FALSE;
00109        }
00110 
00111   void Start() {
00112     NS_ASSERTION(!mStarted, "started timer without stopping");
00113 #ifdef WIN32
00114     mStartTime = GetTickCount();
00115 #else
00116     mStartTime = 0;
00117 #endif
00118     mStarted = PR_TRUE;
00119     mNumStarts++;
00120        }
00121 
00122   void Stop() {
00123     NS_ASSERTION(mStarted, "stopped timer without starting");
00124               mTotalTime += GetTickCount() - mStartTime;
00125     mStarted = PR_FALSE;
00126        }
00127   PRUint32        mTotalTime;
00128   PRUint32        mStartTime;
00129   PRUint32        mNumStarts;
00130   PRBool          mStarted;
00131   const nsIFrame* mFrame;
00132   nsIAtom*        mFrameType; // needed for frame summary timer
00133   nsReflowReason  mReason;
00134   nsVoidArray     mChildren;
00135   PRInt32         mCount;
00136   // reflow state/reflow metrics data
00137   nscoord         mAvailWidth;
00138   nscoord         mComputedWidth;
00139   nscoord         mComputedHeight;
00140   nscoord         mMaxElementWidth;
00141   nscoord         mMaxWidth; // preferred width
00142   nscoord         mDesiredWidth;
00143   nscoord         mDesiredHeight;        
00144   nsReflowStatus  mStatus;
00145   nsReflowTimer*  mNextSibling;
00146   PRInt32         mReflowType;
00147 
00148 private:
00149   ~nsReflowTimer() {}
00150 
00151 };
00152 
00153 #endif
00154 
00159 #define NS_TABLE_FRAME_COLGROUP_LIST_INDEX 0
00160 #define NS_TABLE_FRAME_OVERFLOW_LIST_INDEX 1
00161 #define NS_TABLE_FRAME_LAST_LIST_INDEX    NS_TABLE_FRAME_OVERFLOW_LIST_INDEX
00162 
00163 /* ============================================================================ */
00164 
00175 class nsTableFrame : public nsHTMLContainerFrame, public nsITableLayout
00176 {
00177 public:
00178 
00179   // nsISupports
00180   NS_DECL_ISUPPORTS_INHERITED
00181 
00183   friend class nsTableOuterFrame;
00184 
00192   friend nsresult 
00193   NS_NewTableFrame(nsIPresShell* aPresShell, nsIFrame** aResult);
00194 
00198   NS_IMETHOD Init(nsPresContext*  aPresContext,
00199                   nsIContent*      aContent,
00200                   nsIFrame*        aParent,
00201                   nsStyleContext*  aContext,
00202                   nsIFrame*        aPrevInFlow);
00203 
00204 
00205   static void* GetProperty(nsIFrame*            aFrame,
00206                            nsIAtom*             aPropertyName,
00207                            PRBool               aCreateIfNecessary = PR_FALSE);
00208 
00209   static float GetTwipsToPixels(nsPresContext* aPresContext);
00210 
00211   static nscoord RoundToPixel(nscoord      aValue,
00212                               float        aPixelToTwips,
00213                               nsPixelRound aRound= eAlwaysRoundUp);
00214 
00215   // See if a special height reflow will occur due to having a pct height when
00216   // the pct height basis may not yet be valid.
00217   static void CheckRequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
00218 
00219   // Notify the frame and its ancestors (up to the containing table) that a special
00220   // height reflow will occur. 
00221   static void RequestSpecialHeightReflow(const nsHTMLReflowState& aReflowState);
00222 
00223   // Return true (and set aMetrics's desiredSize to aRect) if the special height reflow
00224   // was not initiated by aReflowState.frame's containing table.
00225   static PRBool IsPrematureSpecialHeightReflow(const nsHTMLReflowState& aReflowState,
00226                                                const nsRect&            aRect,
00227                                                PRBool                   aNeedSpecialHeightReflow,
00228                                                nsHTMLReflowMetrics&     aMetrics);
00229 
00230   virtual PRBool IsContainingBlock() const;
00231 
00232   static nsresult AppendDirtyReflowCommand(nsIFrame* aFrame);
00233 
00234   static void RePositionViews(nsIFrame* aFrame);
00235 
00236   static PRBool PageBreakAfter(nsIFrame& aSourceFrame,
00237                                nsIFrame* aNextFrame);
00238 
00239   nsPoint GetFirstSectionOrigin(const nsHTMLReflowState& aReflowState) const;
00240   /*
00241    * Notification that aAttribute has changed for content inside a table (cell, row, etc)
00242    */
00243   void AttributeChangedFor(nsIFrame*       aFrame,
00244                            nsIContent*     aContent, 
00245                            nsIAtom*        aAttribute); 
00246 
00248   NS_IMETHOD Destroy(nsPresContext* aPresContext);
00249 
00250   NS_IMETHOD AppendFrames(nsIAtom*        aListName,
00251                           nsIFrame*       aFrameList);
00252   NS_IMETHOD InsertFrames(nsIAtom*        aListName,
00253                           nsIFrame*       aPrevFrame,
00254                           nsIFrame*       aFrameList);
00255   NS_IMETHOD RemoveFrame(nsIAtom*        aListName,
00256                          nsIFrame*       aOldFrame);
00257 
00258   // Get the offset from the border box to the area where the row groups fit
00259   nsMargin GetChildAreaOffset(const nsHTMLReflowState* aReflowState) const;
00260 
00261   // Get the offset from the border box to the area where the content fits
00262   nsMargin GetContentAreaOffset(const nsHTMLReflowState* aReflowState) const;
00263 
00265   // TODO: today, this depends on display types.  This should be changed to rely
00266   // on stronger criteria, like an inner table frame atom
00267   static NS_METHOD GetTableFrame(nsIFrame*      aSourceFrame, 
00268                                  nsTableFrame*& aTableFrame);
00269 
00270   // Return the closest sibling of aPriorChildFrame (including aPriroChildFrame)
00271   // of type aChildType.
00272   static nsIFrame* GetFrameAtOrBefore(nsIFrame*       aParentFrame,
00273                                       nsIFrame*       aPriorChildFrame,
00274                                       nsIAtom*        aChildType);
00275   PRBool IsAutoWidth(PRBool* aIsPctWidth = nsnull);
00276   PRBool IsAutoHeight();
00277   static PRBool IsPctHeight(nsStyleContext* aStyleContext);
00278   
00282   PRBool IsRowGroup(PRInt32 aDisplayType) const;
00283 
00287   NS_IMETHOD SetInitialChildList(nsPresContext* aPresContext,
00288                                  nsIAtom*        aListName,
00289                                  nsIFrame*       aChildList);
00290 
00294   virtual nsIFrame* GetFirstChild(nsIAtom* aListName) const;
00295 
00297   virtual nsIAtom* GetAdditionalChildListName(PRInt32 aIndex) const;
00298 
00300   NS_IMETHOD Paint(nsPresContext*      aPresContext,
00301                    nsIRenderingContext& aRenderingContext,
00302                    const nsRect&        aDirtyRect,
00303                    nsFramePaintLayer    aWhichLayer,
00304                    PRUint32             aFlags = 0);
00305 
00306   virtual void PaintChildren(nsPresContext*      aPresContext,
00307                              nsIRenderingContext& aRenderingContext,
00308                              const nsRect&        aDirtyRect,
00309                              nsFramePaintLayer    aWhichLayer,
00310                              PRUint32             aFlags = 0);
00311 
00312   nsMargin GetBCBorder() const;
00313 
00314   // get the area that the border leak out from the inner table frame into
00315   // the surrounding margin space
00316   nsMargin GetBCMargin() const;
00317 
00324   nscoord GetContinuousLeftBCBorderWidth(float aPixelsToTwips) const;
00325 
00326   void SetBCDamageArea(const nsRect& aValue);
00327 
00328   void PaintBCBorders(nsIRenderingContext& aRenderingContext,
00329                       const nsRect&        aDirtyRect);
00330 
00331   NS_IMETHOD GetFrameForPoint(const nsPoint& aPoint, 
00332                               nsFramePaintLayer aWhichLayer,
00333                               nsIFrame**     aFrame);
00334 
00337   NS_IMETHOD SetSelected(nsPresContext* aPresContext,
00338                          nsIDOMRange *aRange,
00339                          PRBool aSelected,
00340                          nsSpread aSpread);
00341 
00359   NS_IMETHOD Reflow(nsPresContext*          aPresContext,
00360                     nsHTMLReflowMetrics&     aDesiredSize,
00361                     const nsHTMLReflowState& aReflowState,
00362                     nsReflowStatus&          aStatus);
00363 
00364   nsresult ReflowTable(nsHTMLReflowMetrics&     aDesiredSize,
00365                        const nsHTMLReflowState& aReflowState,
00366                        nscoord                  aAvailHeight,
00367                        nsReflowReason           aReason,
00368                        nsIFrame*&               aLastChildReflowed,
00369                        PRBool&                  aDidBalance,
00370                        nsReflowStatus&          aStatus);
00371 
00372   static nsMargin GetBorderPadding(const nsHTMLReflowState& aReflowState,
00373                                    float                    aPixelToTwips,
00374                                    const nsTableCellFrame*  aCellFrame);
00375 
00376   static nsMargin GetBorderPadding(const nsSize&           aBasis,
00377                                    float                   aPixelToTwips,
00378                                    const nsTableCellFrame* aCellFrame);
00379 
00380   nsFrameList& GetColGroups();
00381 
00382   NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext,
00383                                         nsIFrame**      aProviderFrame,
00384                                         PRBool*         aIsChild);
00385 
00391   virtual nsIAtom* GetType() const;
00392 
00393 #ifdef DEBUG
00394 
00395   NS_IMETHOD GetFrameName(nsAString& aResult) const;
00396 #endif
00397 
00399   virtual PRInt32 GetColumnWidth(PRInt32 aColIndex);
00400 
00402   virtual void SetColumnWidth(PRInt32 aColIndex, nscoord aWidth);
00403 
00405   virtual nscoord GetCellSpacingX();
00406 
00408   virtual nscoord GetCellSpacingY();
00409  
00421   virtual PRInt32  GetEffectiveRowSpan(PRInt32                 aStartRowIndex,
00422                                        const nsTableCellFrame& aCell) const;
00423   virtual PRInt32  GetEffectiveRowSpan(const nsTableCellFrame& aCell,
00424                                        nsCellMap*              aCellMap = nsnull);
00425 
00434   virtual PRInt32  GetEffectiveColSpan(const nsTableCellFrame& aCell,
00435                                        nsCellMap*              aCellMap = nsnull) const;
00436 
00440   PRBool HasMoreThanOneCell(PRInt32 aRowIndex) const;
00441 
00445   PRInt32 GetEffectiveCOLSAttribute();
00446 
00451   nsTableColFrame* GetColFrame(PRInt32 aColIndex) const;
00452 
00458   void InsertCol(nsTableColFrame& aColFrame,
00459                  PRInt32          aColIndex);
00460 
00461   nsTableColGroupFrame* CreateAnonymousColGroupFrame(nsTableColGroupType aType);
00462 
00463   PRInt32 DestroyAnonymousColFrames(PRInt32 aNumFrames);
00464 
00465   void CreateAnonymousColFrames(PRInt32         aNumColsToAdd,
00466                                 nsTableColType  aColType,
00467                                 PRBool          aDoAppend,
00468                                 nsIFrame*       aPrevCol = nsnull);
00469 
00470   void CreateAnonymousColFrames(nsTableColGroupFrame* aColGroupFrame,
00471                                 PRInt32               aNumColsToAdd,
00472                                 nsTableColType        aColType,
00473                                 PRBool                aAddToColGroupAndTable,
00474                                 nsIFrame*             aPrevCol,
00475                                 nsIFrame**            aFirstNewFrame);
00476 
00477   void MatchCellMapToColCache(nsTableCellMap* aCellMap);
00479   void ClearColCache();
00480 
00481   virtual void AppendCell(nsTableCellFrame& aCellFrame,
00482                           PRInt32           aRowIndex);
00483 
00484   virtual void InsertCells(nsVoidArray&    aCellFrames, 
00485                            PRInt32         aRowIndex, 
00486                            PRInt32         aColIndexBefore);
00487 
00488   virtual void RemoveCell(nsTableCellFrame* aCellFrame,
00489                           PRInt32           aRowIndex);
00490 
00491   void AppendRows(nsTableRowGroupFrame& aRowGroupFrame,
00492                   PRInt32               aRowIndex,
00493                   nsVoidArray&          aRowFrames);
00494 
00495   PRInt32 InsertRow(nsTableRowGroupFrame& aRowGroupFrame,
00496                     nsIFrame&             aFrame,
00497                     PRInt32               aRowIndex,
00498                     PRBool                aConsiderSpans);
00499 
00500   PRInt32 InsertRows(nsTableRowGroupFrame& aRowGroupFrame,
00501                      nsVoidArray&          aFrames,
00502                      PRInt32               aRowIndex,
00503                      PRBool                aConsiderSpans);
00504 
00505   virtual void RemoveRows(nsTableRowFrame& aFirstRowFrame,
00506                           PRInt32          aNumRowsToRemove,
00507                           PRBool           aConsiderSpans);
00508 
00513   void AppendRowGroups(nsIFrame* aFirstRowGroupFrame);
00514 
00520   void InsertRowGroups(nsIFrame*       aFirstRowGroupFrame,
00521                        nsIFrame*       aLastRowGroupFrame);
00522 
00523   void InsertColGroups(PRInt32         aColIndex,
00524                        nsIFrame*       aFirstFrame,
00525                        nsIFrame*       aLastFrame = nsnull);
00526 
00527   virtual void RemoveCol(nsTableColGroupFrame* aColGroupFrame,
00528                          PRInt32               aColIndex,
00529                          PRBool                aRemoveFromCache,
00530                          PRBool                aRemoveFromCellMap);
00531 
00532   nsTableCellFrame* GetCellInfoAt(PRInt32            aRowX, 
00533                                   PRInt32            aColX, 
00534                                   PRBool*            aOriginates = nsnull, 
00535                                   PRInt32*           aColSpan = nsnull);
00536 
00537   PRInt32 GetNumCellsOriginatingInCol(PRInt32 aColIndex) const;
00538   PRInt32 GetNumCellsOriginatingInRow(PRInt32 aRowIndex) const;
00539 
00540   PRBool HasPctCol() const;
00541   void SetHasPctCol(PRBool aValue);
00542 
00543   PRBool HasCellSpanningPctCol() const;
00544   void SetHasCellSpanningPctCol(PRBool aValue);
00545 
00546   PRBool NeedSpecialReflow() const;
00547   void   SetNeedSpecialReflow(PRBool aValue);
00548 
00549   PRBool NeedToInitiateSpecialReflow() const;
00550   void   SetNeedToInitiateSpecialReflow(PRBool aValue);
00551 
00552   PRBool InitiatedSpecialReflow() const;
00553   void   SetInitiatedSpecialReflow(PRBool aValue);
00554 
00555 protected:
00556 
00560   nsTableFrame();
00561 
00563   virtual ~nsTableFrame();
00564 
00565   void InitChildReflowState(nsHTMLReflowState& aReflowState);
00566 
00568   virtual PRIntn GetSkipSides() const;
00569 
00570   virtual PRBool ParentDisablesSelection() const; //override default behavior
00571 
00572 public:
00586   virtual PRBool NeedsReflow(const nsHTMLReflowState& aReflowState);
00587 
00588   PRBool IsRowInserted() const;
00589   void   SetRowInserted(PRBool aValue);
00590 
00591 protected:
00592 
00593   NS_METHOD ReflowChildren(nsTableReflowState&  aReflowState,
00594                            PRBool               aDoColGroups,
00595                            PRBool               aDirtyOnly,
00596                            nsReflowStatus&      aStatus,
00597                            nsIFrame*&           aLastChildReflowed,
00598                            nsRect&              aOverflowArea,
00599                            PRBool*              aReflowedAtLeastOne = nsnull);
00600 // begin incremental reflow methods
00601   
00610   NS_IMETHOD IncrementalReflow(const nsHTMLReflowState& aReflowState,
00611                                nsReflowStatus&          aStatus);
00612 
00617   NS_IMETHOD IR_TargetIsChild(nsTableReflowState&   aReflowStatet,
00618                               nsReflowStatus&       aStatus,
00619                               nsIFrame*             aNextFrame);
00620 
00624   NS_IMETHOD IR_TargetIsMe(nsTableReflowState&  aReflowState,
00625                            nsReflowStatus&      aStatus);
00626 
00631   NS_IMETHOD IR_StyleChanged(nsTableReflowState&  aReflowState,
00632                              nsReflowStatus&      aStatus);
00633   
00634   NS_IMETHOD AdjustSiblingsAfterReflow(nsTableReflowState& aReflowState,
00635                                        nsIFrame*           aKidFrame,
00636                                        nscoord             aDeltaY);
00637   
00638   nsresult RecoverState(nsTableReflowState& aReflowState,
00639                         nsIFrame*           aKidFrame);
00640 
00641   NS_METHOD CollapseRowGroupIfNecessary(nsIFrame* aRowGroupFrame,
00642                                         const nscoord& aYTotalOffset,
00643                                         nscoord& aYGroupOffset, PRInt32& aRowX);
00644 
00645   NS_METHOD AdjustForCollapsingRows(nsHTMLReflowMetrics&  aDesiredSize);
00646 
00647   NS_METHOD AdjustForCollapsingCols(nsHTMLReflowMetrics&  aDesiredSize);
00648   // end incremental reflow methods
00649 
00650 
00651   // WIDTH AND HEIGHT CALCULATION
00652 
00653 public:
00654 
00655   // calculate the computed width of aFrame including its border and padding given 
00656   // its reflow state.
00657   nscoord CalcBorderBoxWidth(const nsHTMLReflowState& aReflowState);
00658 
00659   // calculate the computed height of aFrame including its border and padding given 
00660   // its reflow state.
00661   nscoord CalcBorderBoxHeight(const nsHTMLReflowState& aReflowState);
00662   // calculate the minimum width to layout aFrame and its desired width 
00663   // including border and padding given its reflow state and column width information 
00664   void CalcMinAndPreferredWidths(const nsHTMLReflowState& aReflowState,
00665                                  PRBool                   aCalcPrefWidthIfAutoWithPctCol,
00666                                  nscoord&                 aMinWidth,
00667                                  nscoord&                 aPreferredWidth);
00668 protected:
00669 
00670   // calcs the width of the table according to the computed widths of each column.
00671   virtual PRInt32 CalcDesiredWidth(const nsHTMLReflowState& aReflowState);
00672 
00673   // update the  desired height of this table taking into account the current
00674   // reflow state, the table attributes and the content driven rowgroup heights
00675   // this function can change the overflow area
00676   void CalcDesiredHeight(const nsHTMLReflowState& aReflowState, nsHTMLReflowMetrics& aDesiredSize);
00677 
00678   // The following is a helper for CalcDesiredHeight 
00679  
00680   void DistributeHeightToRows(const nsHTMLReflowState& aReflowState,
00681                               nscoord                  aAmount);
00682 
00683   void PlaceChild(nsTableReflowState&  aReflowState,
00684                   nsIFrame*            aKidFrame,
00685                   nsHTMLReflowMetrics& aKidDesiredSize);
00686 
00693   virtual void BalanceColumnWidths(const nsHTMLReflowState& aReflowState);
00694 
00695 
00696   nsIFrame* GetFirstBodyRowGroupFrame();
00697   PRBool MoveOverflowToChildList(nsPresContext* aPresContext);
00703   void PushChildren(const nsAutoVoidArray& aFrames, PRInt32 aPushFrom);
00704 
00705 public:
00706   // put the children frames in the display order (e.g. thead before tbody before tfoot)
00707   // and put the non row group frames at the end. Also return the number of row group frames.
00708   void OrderRowGroups(nsVoidArray&           aChildren,
00709                       PRUint32&              aNumRowGroups,
00710                       nsIFrame**             aFirstBody = nsnull,
00711                       nsTableRowGroupFrame** aHead      = nsnull,
00712                       nsTableRowGroupFrame** aFoot      = nsnull) const;
00713 
00714   // Returns PR_TRUE if there are any cells above the row at
00715   // aRowIndex and spanning into the row at aRowIndex     
00716   PRBool RowIsSpannedInto(PRInt32 aRowIndex);
00717 
00718   // Returns PR_TRUE if there is a cell originating in aRowIndex
00719   // which spans into the next row
00720   PRBool RowHasSpanningCells(PRInt32 aRowIndex);
00721 
00722   // Returns PR_TRUE if there are any cells to the left of the column at
00723   // aColIndex and spanning into the column at aColIndex     
00724   PRBool ColIsSpannedInto(PRInt32 aColIndex);
00725 
00726   // Returns PR_TRUE if there is a cell originating in aColIndex
00727   // which spans into the next col
00728   PRBool ColHasSpanningCells(PRInt32 aColIndex);
00729 
00730   // Allows rows to notify the table of additions or changes to a cell's width
00731   // The table uses this to update the appropriate column widths and to decide 
00732   // whether to reinitialize (and then rebalance) or rebalance the table. If the 
00733   // most extreme measure results (e.g. reinitialize) then PR_TRUE is returned 
00734   // indicating that further calls are not going to accomplish anyting.
00735   PRBool CellChangedWidth(const nsTableCellFrame& aCellFrame,
00736                           nscoord                 aPrevMinWidth,
00737                           nscoord                 aPrevMaxWidth,
00738                           PRBool                  aCellWasDestroyed = PR_FALSE);
00739  
00740 protected:
00741 
00742   PRBool HaveReflowedColGroups() const;
00743   void   SetHaveReflowedColGroups(PRBool aValue);
00744 
00745   PRBool DidResizeReflow() const;
00746   void   SetResizeReflow(PRBool aValue);
00747 
00748 public:
00749   PRBool NeedStrategyInit() const;
00750   void SetNeedStrategyInit(PRBool aValue);
00751 
00752   PRBool NeedStrategyBalance() const;
00753   void SetNeedStrategyBalance(PRBool aValue);
00754 
00755   PRBool IsBorderCollapse() const;
00756 
00757   PRBool NeedToCalcBCBorders() const;
00758   void SetNeedToCalcBCBorders(PRBool aValue);
00759   
00760   PRBool NeedToCollapseRows() const;
00761   void SetNeedToCollapseRows(PRBool aValue);
00762   
00763   PRBool NeedToCollapseColumns() const;
00764   void SetNeedToCollapseColumns(PRBool aValue);
00765 
00769   virtual nsTableCellMap* GetCellMap() const;
00770 
00776   void AdjustRowIndices(PRInt32 aRowIndex,
00777                         PRInt32 aAdjustment);
00778 
00787   void ResetRowIndices(nsIFrame* aFirstRowGroupFrame = nsnull,
00788                        nsIFrame* aLastRowGroupFrame = nsnull);
00789 
00790   nsVoidArray& GetColCache();
00791 
00794   static nsTableRowGroupFrame* GetRowGroupFrame(nsIFrame* aFrame,
00795                                                 nsIAtom*  aFrameTypeIn = nsnull);
00796 
00797 protected:
00798 
00799   void SetBorderCollapse(PRBool aValue);
00800 
00801   void CalcBCBorders();
00802 
00803   void ExpandBCDamageArea(nsRect& aRect) const;
00804 
00805   PRBool HadInitialReflow() const;
00806   void SetHadInitialReflow(PRBool aValue);
00807 
00808   void SetColumnDimensions(nscoord         aHeight,
00809                            const nsMargin& aReflowState);
00810 
00811   PRInt32 CollectRows(nsIFrame*       aFrame,
00812                       nsVoidArray&    aCollection);
00813 
00814 public: /* ----- Cell Map public methods ----- */
00815 
00816   PRInt32 GetStartRowIndex(nsTableRowGroupFrame& aRowGroupFrame);
00817 
00822   virtual PRInt32 GetRowCount() const;
00823 
00826   virtual PRInt32 GetEffectiveColCount() const;
00827   virtual PRInt32 GetColCount() const;
00828 
00829   // return the last col index which isn't of type eColAnonymousCell
00830   PRInt32 GetIndexOfLastRealCol();
00831 
00836   nsTableCellFrame * GetCellFrameAt(PRInt32 aRowIndex, PRInt32 aColIndex);
00837 
00839   nscoord GetMinCaptionWidth();
00840 
00842   virtual PRBool IsAutoLayout();
00843 
00844   nscoord GetMinWidth() const;
00845   void    SetMinWidth(nscoord aWidth);
00846   
00847   nscoord GetDesiredWidth() const;
00848   void    SetDesiredWidth(nscoord aWidth);
00849 
00850   nscoord GetPreferredWidth() const;
00851   void    SetPreferredWidth(nscoord aWidth); 
00852   
00853   /*---------------- nsITableLayout methods ------------------------*/
00854   
00856   NS_IMETHOD GetCellDataAt(PRInt32 aRowIndex, PRInt32 aColIndex, 
00857                            nsIDOMElement* &aCell,   //out params
00858                            PRInt32& aStartRowIndex, PRInt32& aStartColIndex, 
00859                            PRInt32& aRowSpan, PRInt32& aColSpan,
00860                            PRInt32& aActualRowSpan, PRInt32& aActualColSpan,
00861                            PRBool& aIsSelected);
00862 
00867   NS_IMETHOD GetTableSize(PRInt32& aRowCount, PRInt32& aColCount);
00868 
00869   /*------------end of nsITableLayout methods -----------------------*/
00870 
00871 public:
00872  
00873 #ifdef DEBUG
00874   void Dump(PRBool          aDumpRows,
00875             PRBool          aDumpCols, 
00876             PRBool          aDumpCellMap);
00877   static void DumpTableFrames(nsIFrame* aFrame);
00878 #endif
00879 
00880 protected:
00881 #ifdef DEBUG
00882   void DumpRowGroup(nsIFrame* aChildFrame);
00883 #endif
00884   // DATA MEMBERS
00885   nsAutoVoidArray mColFrames;  
00886 
00887   struct TableBits {
00888     PRUint32 mHadInitialReflow:1;      // has intial reflow happened
00889     PRUint32 mHaveReflowedColGroups:1; // have the col groups gotten their initial reflow
00890     PRUint32 mNeedStrategyBalance:1;   // does the strategy needs to balance the table
00891     PRUint32 mNeedStrategyInit:1;      // does the strategy needs to be initialized and then balance the table
00892     PRUint32 mHasPctCol:1;             // does any cell or col have a pct width
00893     PRUint32 mCellSpansPctCol:1;       // does any cell span a col with a pct width (or containing a cell with a pct width)
00894     PRUint32 mDidResizeReflow:1;       // did a resize reflow happen (indicating pass 2)
00895     PRUint32 mIsBorderCollapse:1;      // border collapsing model vs. separate model
00896     PRUint32 mRowInserted:1;
00897     PRUint32 mNeedSpecialReflow:1;
00898     PRUint32 mNeedToInitiateSpecialReflow:1;
00899     PRUint32 mInitiatedSpecialReflow:1;
00900     PRUint32 mNeedToCalcBCBorders:1;
00901     PRUint32 mLeftContBCBorder:8;
00902     PRUint32 mNeedToCollapseRows:1;    // rows that have visibility need to be collapse
00903     PRUint32 mNeedToCollapseColumns:1; // colums that have visibility need to be collapsed
00904     PRUint32 :9;                       // unused
00905   } mBits;
00906 
00907   nsTableCellMap*         mCellMap;            // maintains the relationships between rows, cols, and cells
00908   nsITableLayoutStrategy* mTableLayoutStrategy;// the layout strategy for this frame
00909   nsFrameList             mColGroups;          // the list of colgroup frames
00910   nscoord                 mMinWidth;       // XXX could store as PRUint16 with pixels
00911   nscoord                 mDesiredWidth;   // XXX could store as PRUint16 with pixels
00912   nscoord                 mPreferredWidth; // XXX could store as PRUint16 with pixels
00913 
00914 
00915   // DEBUG REFLOW 
00916 #if defined DEBUG_TABLE_REFLOW_TIMING
00917 public:
00918   static void DebugReflow(nsIFrame*            aFrame, 
00919                           nsHTMLReflowState&   aReflowState, 
00920                           nsHTMLReflowMetrics* aMetrics = nsnull,
00921                           nsReflowStatus       aStatus  = NS_FRAME_COMPLETE);
00922 
00923   static void DebugReflowDone(nsIFrame* aFrame);
00924 
00925   enum nsMethod {eInit=0, eBalanceCols, eNonPctCols, eNonPctColspans, ePctCols};
00926   static void DebugTimeMethod(nsMethod           aMethod,
00927                               nsTableFrame&      aFrame,
00928                               nsHTMLReflowState& aReflowState,
00929                               PRBool             aStart);
00930   nsReflowTimer* mTimer;
00931 #endif
00932 };
00933 
00934 
00935 inline PRBool nsTableFrame::IsRowGroup(PRInt32 aDisplayType) const
00936 {
00937   return PRBool((NS_STYLE_DISPLAY_TABLE_HEADER_GROUP == aDisplayType) ||
00938                 (NS_STYLE_DISPLAY_TABLE_FOOTER_GROUP == aDisplayType) ||
00939                 (NS_STYLE_DISPLAY_TABLE_ROW_GROUP    == aDisplayType));
00940 }
00941 
00942 inline void nsTableFrame::SetHadInitialReflow(PRBool aValue)
00943 {
00944   mBits.mHadInitialReflow = aValue;
00945 }
00946 
00947 inline PRBool nsTableFrame::HadInitialReflow() const
00948 {
00949   return (PRBool)mBits.mHadInitialReflow;
00950 }
00951 
00952 inline void nsTableFrame::SetHaveReflowedColGroups(PRBool aValue)
00953 {
00954   mBits.mHaveReflowedColGroups = aValue;
00955 }
00956 
00957 inline PRBool nsTableFrame::HaveReflowedColGroups() const
00958 {
00959   return (PRBool)mBits.mHaveReflowedColGroups;
00960 }
00961 
00962 inline PRBool nsTableFrame::HasPctCol() const
00963 {
00964   return (PRBool)mBits.mHasPctCol;
00965 }
00966 
00967 inline void nsTableFrame::SetHasPctCol(PRBool aValue)
00968 {
00969   mBits.mHasPctCol = (unsigned)aValue;
00970 }
00971 
00972 inline PRBool nsTableFrame::HasCellSpanningPctCol() const
00973 {
00974   return (PRBool)mBits.mCellSpansPctCol;
00975 }
00976 
00977 inline void nsTableFrame::SetHasCellSpanningPctCol(PRBool aValue)
00978 {
00979   mBits.mCellSpansPctCol = (unsigned)aValue;
00980 }
00981 
00982 inline PRBool nsTableFrame::NeedSpecialReflow() const
00983 {
00984   return (PRBool)mBits.mNeedSpecialReflow;
00985 }
00986 
00987 inline void nsTableFrame::SetNeedSpecialReflow(PRBool aValue)
00988 {
00989   mBits.mNeedSpecialReflow = (unsigned)aValue;
00990 }
00991 
00992 inline PRBool nsTableFrame::NeedToInitiateSpecialReflow() const
00993 {
00994   return (PRBool)mBits.mNeedToInitiateSpecialReflow;
00995 }
00996 
00997 inline void nsTableFrame::SetNeedToInitiateSpecialReflow(PRBool aValue)
00998 {
00999   mBits.mNeedToInitiateSpecialReflow = (unsigned)aValue;
01000 }
01001 
01002 inline PRBool nsTableFrame::InitiatedSpecialReflow() const
01003 {
01004   return (PRBool)mBits.mInitiatedSpecialReflow;
01005 }
01006 
01007 inline void nsTableFrame::SetInitiatedSpecialReflow(PRBool aValue)
01008 {
01009   mBits.mInitiatedSpecialReflow = (unsigned)aValue;
01010 }
01011 
01012 inline PRBool nsTableFrame::IsRowInserted() const
01013 {
01014   return (PRBool)mBits.mRowInserted;
01015 }
01016 
01017 inline void nsTableFrame::SetRowInserted(PRBool aValue)
01018 {
01019   mBits.mRowInserted = (unsigned)aValue;
01020 }
01021 
01022 inline void nsTableFrame::SetNeedToCollapseRows(PRBool aValue)
01023 {
01024   mBits.mNeedToCollapseRows = (unsigned)aValue;
01025 }
01026 
01027 inline PRBool nsTableFrame::NeedToCollapseRows() const
01028 {
01029   return (PRBool)mBits.mNeedToCollapseRows;
01030 }
01031 
01032 inline void nsTableFrame::SetNeedToCollapseColumns(PRBool aValue)
01033 {
01034   mBits.mNeedToCollapseColumns = (unsigned)aValue;
01035 }
01036 
01037 inline PRBool nsTableFrame::NeedToCollapseColumns() const
01038 {
01039   return (PRBool)mBits.mNeedToCollapseColumns;
01040 }
01041 
01042 inline nsFrameList& nsTableFrame::GetColGroups()
01043 {
01044   return NS_STATIC_CAST(nsTableFrame*, GetFirstInFlow())->mColGroups;
01045 }
01046 
01047 inline nsVoidArray& nsTableFrame::GetColCache()
01048 {
01049   return mColFrames;
01050 }
01051 
01052 inline void nsTableFrame::SetMinWidth(nscoord aWidth)
01053 {
01054   mMinWidth = aWidth;
01055 }
01056 
01057 inline void nsTableFrame::SetDesiredWidth(nscoord aWidth)
01058 {
01059   mDesiredWidth = aWidth;
01060 }
01061 
01062 inline void nsTableFrame::SetPreferredWidth(nscoord aWidth)
01063 {
01064   mPreferredWidth = aWidth;
01065 }
01066 
01067 inline PRBool nsTableFrame::IsBorderCollapse() const
01068 {
01069   return (PRBool)mBits.mIsBorderCollapse;
01070 }
01071 
01072 inline void nsTableFrame::SetBorderCollapse(PRBool aValue) 
01073 {
01074   mBits.mIsBorderCollapse = aValue;
01075 }
01076 
01077 inline PRBool nsTableFrame::NeedToCalcBCBorders() const
01078 {
01079   return (PRBool)mBits.mNeedToCalcBCBorders;
01080 }
01081 
01082 inline void nsTableFrame::SetNeedToCalcBCBorders(PRBool aValue)
01083 {
01084   mBits.mNeedToCalcBCBorders = (unsigned)aValue;
01085 }
01086 
01087 inline nscoord
01088 nsTableFrame::GetContinuousLeftBCBorderWidth(float aPixelsToTwips) const
01089 {
01090   return BC_BORDER_RIGHT_HALF_COORD(aPixelsToTwips, mBits.mLeftContBCBorder);
01091 }
01092 
01093 enum nsTableIteration {
01094   eTableLTR = 0,
01095   eTableRTL = 1,
01096   eTableDIR = 2
01097 };
01098 
01099 class nsTableIterator
01100 {
01101 public:
01102   nsTableIterator(nsIFrame&        aSource,
01103                   nsTableIteration aType);
01104   nsTableIterator(nsFrameList&     aSource,
01105                   nsTableIteration aType);
01106   nsIFrame* First();
01107   nsIFrame* Next();
01108   PRBool    IsLeftToRight();
01109   PRInt32   Count();
01110 
01111 protected:
01112   void Init(nsIFrame*        aFirstChild,
01113             nsTableIteration aType);
01114   PRBool    mLeftToRight;
01115   nsIFrame* mFirstListChild;
01116   nsIFrame* mFirstChild;
01117   nsIFrame* mCurrentChild;
01118   PRInt32   mCount;
01119 };
01120 
01121 #define ABORT0() \
01122 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
01123 return;}
01124 
01125 #define ABORT1(aReturn) \
01126 {NS_ASSERTION(PR_FALSE, "CellIterator program error"); \
01127 return aReturn;} 
01128 
01129 #define GET_PIXELS_TO_TWIPS(presContext,var) \
01130   float var = (presContext)->ScaledPixelsToTwips();
01131 
01132 #define GET_TWIPS_TO_PIXELS(presContext,var) \
01133   float var = (presContext)->ScaledPixelsToTwips(); \
01134   var = 1.0f / var;
01135 
01136 #endif