Back to index

lightning-sunbird  0.9+nobinonly
nsTableColGroupFrame.cpp
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 #include "nsTableColGroupFrame.h"
00038 #include "nsTableColFrame.h"
00039 #include "nsTableFrame.h"
00040 #include "nsIDOMHTMLTableColElement.h"
00041 #include "nsReflowPath.h"
00042 #include "nsStyleContext.h"
00043 #include "nsStyleConsts.h"
00044 #include "nsPresContext.h"
00045 #include "nsHTMLParts.h"
00046 #include "nsHTMLAtoms.h"
00047 #include "nsCOMPtr.h"
00048 #include "nsCSSRendering.h"
00049 #include "nsIPresShell.h"
00050 #include "nsLayoutAtoms.h"
00051 
00052 #define COL_GROUP_TYPE_BITS          0xC0000000 // uses bits 31-32 from mState
00053 #define COL_GROUP_TYPE_OFFSET        30
00054 
00055 nsTableColGroupType 
00056 nsTableColGroupFrame::GetColType() const 
00057 {
00058   return (nsTableColGroupType)((mState & COL_GROUP_TYPE_BITS) >> COL_GROUP_TYPE_OFFSET);
00059 }
00060 
00061 void nsTableColGroupFrame::SetColType(nsTableColGroupType aType) 
00062 {
00063   PRUint32 type = aType - eColGroupContent;
00064   mState |= (type << COL_GROUP_TYPE_OFFSET);
00065 }
00066 
00067 void nsTableColGroupFrame::ResetColIndices(nsIFrame*       aFirstColGroup,
00068                                            PRInt32         aFirstColIndex,
00069                                            nsIFrame*       aStartColFrame)
00070 {
00071   nsTableColGroupFrame* colGroupFrame = (nsTableColGroupFrame*)aFirstColGroup;
00072   PRInt32 colIndex = aFirstColIndex;
00073   while (colGroupFrame) {
00074     if (nsLayoutAtoms::tableColGroupFrame == colGroupFrame->GetType()) {
00075        // reset the starting col index for the first cg only if we should reset
00076       // the whole colgroup (aStartColFrame defaults to nsnull) or if
00077       // aFirstColIndex is smaller than the existing starting col index
00078       if ((colIndex != aFirstColIndex) ||
00079           (colIndex < colGroupFrame->GetStartColumnIndex()) ||
00080           !aStartColFrame) {
00081         colGroupFrame->SetStartColumnIndex(colIndex);
00082       }
00083       nsIFrame* colFrame = aStartColFrame; 
00084       if (!colFrame || (colIndex != aFirstColIndex)) {
00085         colFrame = colGroupFrame->GetFirstChild(nsnull);
00086       }
00087       while (colFrame) {
00088         if (nsLayoutAtoms::tableColFrame == colFrame->GetType()) {
00089           ((nsTableColFrame*)colFrame)->SetColIndex(colIndex);
00090           colIndex++;
00091         }
00092         colFrame = colFrame->GetNextSibling();
00093       }
00094     }
00095     colGroupFrame = NS_STATIC_CAST(nsTableColGroupFrame*,
00096                                    colGroupFrame->GetNextSibling());
00097   }
00098 }
00099 
00100 
00101 nsresult
00102 nsTableColGroupFrame::AddColsToTable(PRInt32          aFirstColIndex,
00103                                      PRBool           aResetSubsequentColIndices,
00104                                      nsIFrame*        aFirstFrame,
00105                                      nsIFrame*        aLastFrame)
00106 {
00107   nsresult rv = NS_OK;
00108   nsTableFrame* tableFrame = nsnull;
00109   rv = nsTableFrame::GetTableFrame(this, tableFrame);
00110   if (!tableFrame || !aFirstFrame) return NS_ERROR_NULL_POINTER;
00111 
00112   // set the col indices of the col frames and and add col info to the table
00113   PRInt32 colIndex = aFirstColIndex;
00114   nsIFrame* kidFrame = aFirstFrame;
00115   PRBool foundLastFrame = PR_FALSE;
00116   while (kidFrame) {
00117     if (nsLayoutAtoms::tableColFrame == kidFrame->GetType()) {
00118       ((nsTableColFrame*)kidFrame)->SetColIndex(colIndex);
00119       if (!foundLastFrame) {
00120         mColCount++;
00121         tableFrame->InsertCol((nsTableColFrame &)*kidFrame, colIndex);
00122       }
00123       colIndex++;
00124     }
00125     if (kidFrame == aLastFrame) {
00126       foundLastFrame = PR_TRUE;
00127     }
00128     kidFrame = kidFrame->GetNextSibling(); 
00129   }
00130   // We have already set the colindex for all the colframes in this
00131   // colgroup that come after the first inserted colframe, but there could
00132   // be other colgroups following this one and their colframes need
00133   // correct colindices too.
00134   if (aResetSubsequentColIndices && GetNextSibling()) {
00135     ResetColIndices(GetNextSibling(), colIndex);
00136   }
00137 
00138   return rv;
00139 }
00140 
00141 
00142 PRBool
00143 nsTableColGroupFrame::GetLastRealColGroup(nsTableFrame* aTableFrame, 
00144                                           nsIFrame**    aLastColGroup)
00145 {
00146   *aLastColGroup = nsnull;
00147   nsFrameList colGroups = aTableFrame->GetColGroups();
00148 
00149   nsIFrame* nextToLastColGroup = nsnull;
00150   nsIFrame* lastColGroup       = colGroups.FirstChild();
00151   while(lastColGroup) {
00152     nsIFrame* next = lastColGroup->GetNextSibling();
00153     if (next) {
00154       nextToLastColGroup = lastColGroup;
00155       lastColGroup = next;
00156     }
00157     else {
00158       break;
00159     }
00160   }
00161 
00162   if (!lastColGroup) return PR_TRUE; // there are no col group frames
00163  
00164   nsTableColGroupType lastColGroupType =
00165     ((nsTableColGroupFrame *)lastColGroup)->GetColType();
00166   if (eColGroupAnonymousCell == lastColGroupType) {
00167     *aLastColGroup = nextToLastColGroup;
00168     return PR_FALSE;
00169   }
00170   else {
00171     *aLastColGroup = lastColGroup;
00172     return PR_TRUE;
00173   }
00174 }
00175 
00176 // don't set mColCount here, it is done in AddColsToTable
00177 NS_IMETHODIMP
00178 nsTableColGroupFrame::SetInitialChildList(nsPresContext* aPresContext,
00179                                           nsIAtom*        aListName,
00180                                           nsIFrame*       aChildList)
00181 {
00182   nsTableFrame* tableFrame;
00183   nsTableFrame::GetTableFrame(this, tableFrame);
00184   if (!tableFrame) return NS_ERROR_NULL_POINTER;
00185 
00186   if (!aChildList) {
00187     nsIFrame* firstChild;
00188     tableFrame->CreateAnonymousColFrames(this, GetSpan(), eColAnonymousColGroup, 
00189                                          PR_FALSE, nsnull, &firstChild);
00190     if (firstChild) {
00191       SetInitialChildList(aPresContext, aListName, firstChild);
00192     }
00193     return NS_OK; 
00194   }
00195 
00196   mFrames.AppendFrames(this, aChildList);
00197   return NS_OK;
00198 }
00199 
00200 NS_IMETHODIMP
00201 nsTableColGroupFrame::AppendFrames(nsIAtom*        aListName,
00202                                    nsIFrame*       aFrameList)
00203 {
00204   nsTableColFrame* col = GetFirstColumn();
00205   nsTableColFrame* nextCol;
00206   while (col && col->GetColType() == eColAnonymousColGroup) {
00207     // this colgroup spans one or more columns but now that there is a
00208     // real column below, spanned anonymous columns should be removed
00209     nextCol = col->GetNextCol();
00210     RemoveFrame(nsnull, col);
00211     col = nextCol;
00212   }
00213 
00214   mFrames.AppendFrames(this, aFrameList);
00215   InsertColsReflow(GetStartColumnIndex() + mColCount, aFrameList);
00216   return NS_OK;
00217 }
00218 
00219 NS_IMETHODIMP
00220 nsTableColGroupFrame::InsertFrames(nsIAtom*        aListName,
00221                                    nsIFrame*       aPrevFrameIn,
00222                                    nsIFrame*       aFrameList)
00223 {
00224   nsFrameList frames(aFrameList); // convience for getting last frame
00225   nsIFrame* lastFrame = frames.LastChild();
00226 
00227   nsTableColFrame* col = GetFirstColumn();
00228   nsTableColFrame* nextCol;
00229   while (col && col->GetColType() == eColAnonymousColGroup) {
00230     // this colgroup spans one or more columns but now that there is 
00231     // real column below, spanned anonymous columns should be removed
00232     nextCol = col->GetNextCol();
00233     RemoveFrame(nsnull, col);
00234     col = nextCol;
00235   }
00236 
00237   mFrames.InsertFrames(this, aPrevFrameIn, aFrameList);
00238   nsIFrame* prevFrame = nsTableFrame::GetFrameAtOrBefore(this, aPrevFrameIn,
00239                                                          nsLayoutAtoms::tableColFrame);
00240 
00241   PRInt32 colIndex = (prevFrame) ? ((nsTableColFrame*)prevFrame)->GetColIndex() + 1 : GetStartColumnIndex();
00242   InsertColsReflow(colIndex, aFrameList, lastFrame);
00243 
00244   return NS_OK;
00245 }
00246 
00247 void
00248 nsTableColGroupFrame::InsertColsReflow(PRInt32         aColIndex,
00249                                        nsIFrame*       aFirstFrame,
00250                                        nsIFrame*       aLastFrame)
00251 {
00252   AddColsToTable(aColIndex, PR_TRUE, aFirstFrame, aLastFrame);
00253 
00254   nsTableFrame* tableFrame;
00255   nsTableFrame::GetTableFrame(this, tableFrame);
00256   if (!tableFrame) return;
00257 
00258   // XXX this could be optimized with much effort
00259   tableFrame->SetNeedStrategyInit(PR_TRUE);
00260 
00261   // Generate a reflow command so we reflow the table
00262   nsTableFrame::AppendDirtyReflowCommand(tableFrame);
00263 }
00264 
00265 void
00266 nsTableColGroupFrame::RemoveChild(nsTableColFrame& aChild,
00267                                   PRBool           aResetSubsequentColIndices)
00268 {
00269   PRInt32 colIndex = 0;
00270   nsIFrame* nextChild = nsnull;
00271   if (aResetSubsequentColIndices) {
00272     colIndex = aChild.GetColIndex();
00273     nextChild = aChild.GetNextSibling();
00274   }
00275   if (mFrames.DestroyFrame(GetPresContext(), (nsIFrame*)&aChild)) {
00276     mColCount--;
00277     if (aResetSubsequentColIndices) {
00278       if (nextChild) { // reset inside this and all following colgroups
00279         ResetColIndices(this, colIndex, nextChild);
00280       }
00281       else {
00282         nsIFrame* nextGroup = GetNextSibling();
00283         if (nextGroup) // reset next and all following colgroups
00284           ResetColIndices(nextGroup, colIndex);
00285       }
00286     }
00287   }
00288   nsTableFrame* tableFrame;
00289   nsTableFrame::GetTableFrame(this, tableFrame);
00290   if (!tableFrame) return;
00291 
00292   // XXX this could be optimized with much effort
00293   tableFrame->SetNeedStrategyInit(PR_TRUE);
00294   // Generate a reflow command so we reflow the table
00295   nsTableFrame::AppendDirtyReflowCommand(tableFrame);
00296 }
00297 
00298 NS_IMETHODIMP
00299 nsTableColGroupFrame::RemoveFrame(nsIAtom*        aListName,
00300                                   nsIFrame*       aOldFrame)
00301 {
00302   if (!aOldFrame) return NS_OK;
00303 
00304   if (nsLayoutAtoms::tableColFrame == aOldFrame->GetType()) {
00305     nsTableColFrame* colFrame = (nsTableColFrame*)aOldFrame;
00306     PRInt32 colIndex = colFrame->GetColIndex();
00307     RemoveChild(*colFrame, PR_TRUE);
00308     
00309     nsTableFrame* tableFrame;
00310     nsTableFrame::GetTableFrame(this, tableFrame);
00311     if (!tableFrame) return NS_ERROR_NULL_POINTER;
00312 
00313     tableFrame->RemoveCol(this, colIndex, PR_TRUE, PR_TRUE);
00314 
00315     // XXX This could probably be optimized with much effort
00316     tableFrame->SetNeedStrategyInit(PR_TRUE);
00317     // Generate a reflow command so we reflow the table
00318     nsTableFrame::AppendDirtyReflowCommand(tableFrame);
00319   }
00320   else {
00321     mFrames.DestroyFrame(GetPresContext(), aOldFrame);
00322   }
00323 
00324   return NS_OK;
00325 }
00326 
00327 NS_METHOD 
00328 nsTableColGroupFrame::Paint(nsPresContext*      aPresContext,
00329                             nsIRenderingContext& aRenderingContext,
00330                             const nsRect&        aDirtyRect,
00331                             nsFramePaintLayer    aWhichLayer,
00332                             PRUint32             aFlags)
00333 {
00334   PRBool isVisible;
00335   if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) {
00336     return NS_OK;
00337   }
00338 
00339   PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
00340   return NS_OK;
00341 }
00342 
00343 PRIntn
00344 nsTableColGroupFrame::GetSkipSides() const
00345 {
00346   PRIntn skip = 0;
00347   if (nsnull != mPrevInFlow) {
00348     skip |= 1 << NS_SIDE_TOP;
00349   }
00350   if (nsnull != mNextInFlow) {
00351     skip |= 1 << NS_SIDE_BOTTOM;
00352   }
00353   return skip;
00354 }
00355 
00356 NS_IMETHODIMP
00357 nsTableColGroupFrame::GetFrameForPoint(const nsPoint& aPoint, 
00358                                    nsFramePaintLayer aWhichLayer,
00359                                    nsIFrame**     aFrame)
00360 {
00361   // this should act like a block, so we need to override
00362   return GetFrameForPointUsing(aPoint, nsnull, aWhichLayer, PR_FALSE, aFrame);
00363 }
00364 
00365 NS_METHOD nsTableColGroupFrame::Reflow(nsPresContext*          aPresContext,
00366                                        nsHTMLReflowMetrics&     aDesiredSize,
00367                                        const nsHTMLReflowState& aReflowState,
00368                                        nsReflowStatus&          aStatus)
00369 {
00370   DO_GLOBAL_REFLOW_COUNT("nsTableColGroupFrame", aReflowState.reason);
00371   DISPLAY_REFLOW(aPresContext, this, aReflowState, aDesiredSize, aStatus);
00372   NS_ASSERTION(nsnull!=mContent, "bad state -- null content for frame");
00373   nsresult rv=NS_OK;
00374   
00375   const nsStyleVisibility* groupVis = GetStyleVisibility();
00376   PRBool collapseGroup = (NS_STYLE_VISIBILITY_COLLAPSE == groupVis->mVisible);
00377   if (collapseGroup) {
00378     nsTableFrame* tableFrame = nsnull;
00379     nsTableFrame::GetTableFrame(this, tableFrame);
00380     if (tableFrame)  {
00381       tableFrame->SetNeedToCollapseColumns(PR_TRUE);
00382     }
00383   }
00384   // for every content child that (is a column thingy and does not already have a frame)
00385   // create a frame and adjust it's style
00386   nsIFrame* kidFrame = nsnull;
00387   
00388   
00389   if (eReflowReason_Incremental == aReflowState.reason) {
00390     rv = IncrementalReflow(aDesiredSize, aReflowState, aStatus);
00391   }
00392 
00393   for (kidFrame = mFrames.FirstChild(); kidFrame;
00394        kidFrame = kidFrame->GetNextSibling()) {
00395     // Give the child frame a chance to reflow, even though we know it'll have 0 size
00396     nsHTMLReflowMetrics kidSize(nsnull);
00397     // XXX Use a valid reason...
00398     nsHTMLReflowState kidReflowState(aPresContext, aReflowState, kidFrame,
00399                                      nsSize(0,0), eReflowReason_Initial);
00400 
00401     nsReflowStatus status;
00402     ReflowChild(kidFrame, aPresContext, kidSize, kidReflowState, 0, 0, 0, status);
00403     FinishReflowChild(kidFrame, aPresContext, nsnull, kidSize, 0, 0, 0);
00404   }
00405 
00406   aDesiredSize.width=0;
00407   aDesiredSize.height=0;
00408   aDesiredSize.ascent=aDesiredSize.height;
00409   aDesiredSize.descent=0;
00410   if (aDesiredSize.mComputeMEW)
00411   {
00412     aDesiredSize.mMaxElementWidth=0;
00413   }
00414   aStatus = NS_FRAME_COMPLETE;
00415   NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aDesiredSize);
00416   return rv;
00417 }
00418 
00419 NS_METHOD nsTableColGroupFrame::IncrementalReflow(nsHTMLReflowMetrics&     aDesiredSize,
00420                                                   const nsHTMLReflowState& aReflowState,
00421                                                   nsReflowStatus&          aStatus)
00422 {
00423 
00424   // the col group is a target if its path has a reflow command
00425   nsHTMLReflowCommand* command = aReflowState.path->mReflowCommand;
00426   if (command)
00427     IR_TargetIsMe(aDesiredSize, aReflowState, aStatus);
00428 
00429   // see if the chidren are targets as well
00430   nsReflowPath::iterator iter = aReflowState.path->FirstChild();
00431   nsReflowPath::iterator end  = aReflowState.path->EndChildren();
00432   for (; iter != end; ++iter)
00433     IR_TargetIsChild(aDesiredSize, aReflowState, aStatus, *iter);
00434 
00435   return NS_OK;
00436 }
00437 
00438 NS_METHOD nsTableColGroupFrame::IR_TargetIsMe(nsHTMLReflowMetrics&     aDesiredSize,
00439                                               const nsHTMLReflowState& aReflowState,
00440                                               nsReflowStatus&          aStatus)
00441 {
00442   nsresult rv = NS_OK;
00443   aStatus = NS_FRAME_COMPLETE;
00444   switch (aReflowState.path->mReflowCommand->Type())
00445   {
00446   case eReflowType_StyleChanged :
00447     rv = IR_StyleChanged(aDesiredSize, aReflowState, aStatus);
00448     break;
00449 
00450   case eReflowType_ContentChanged :
00451     NS_ASSERTION(PR_FALSE, "illegal reflow type: ContentChanged");
00452     rv = NS_ERROR_ILLEGAL_VALUE;
00453     break;
00454   
00455   default:
00456     NS_NOTYETIMPLEMENTED("unexpected reflow command type");
00457     rv = NS_ERROR_NOT_IMPLEMENTED;
00458     break;
00459   }
00460 
00461   return rv;
00462 }
00463 
00464 NS_METHOD nsTableColGroupFrame::IR_StyleChanged(nsHTMLReflowMetrics&     aDesiredSize,
00465                                                 const nsHTMLReflowState& aReflowState,
00466                                                 nsReflowStatus&          aStatus)
00467 {
00468   nsresult rv = NS_OK;
00469   // we presume that all the easy optimizations were done in the nsHTMLStyleSheet before we were called here
00470   // XXX: we can optimize this when we know which style attribute changed
00471   nsTableFrame* tableFrame = nsnull;
00472   rv = nsTableFrame::GetTableFrame(this, tableFrame);
00473   if (tableFrame)  {
00474     tableFrame->SetNeedStrategyInit(PR_TRUE);
00475   }
00476   return rv;
00477 }
00478 
00479 NS_METHOD nsTableColGroupFrame::IR_TargetIsChild(nsHTMLReflowMetrics&     aDesiredSize,
00480                                                  const nsHTMLReflowState& aReflowState,
00481                                                  nsReflowStatus&          aStatus,
00482                                                  nsIFrame *               aNextFrame)
00483 {
00484   nsresult rv;
00485  
00486   // Pass along the reflow command
00487   nsHTMLReflowMetrics desiredSize(nsnull);
00488   nsPresContext* presContext = GetPresContext();
00489   nsHTMLReflowState kidReflowState(presContext, aReflowState, aNextFrame,
00490                                    nsSize(aReflowState.availableWidth,
00491                                           aReflowState.availableHeight));
00492   rv = ReflowChild(aNextFrame, presContext, desiredSize, kidReflowState, 0, 0, 0, aStatus);
00493   aNextFrame->DidReflow(presContext, nsnull, NS_FRAME_REFLOW_FINISHED);
00494   if (NS_FAILED(rv))
00495     return rv;
00496 
00497   nsTableFrame *tableFrame=nsnull;
00498   rv = nsTableFrame::GetTableFrame(this, tableFrame);
00499   if (tableFrame) {
00500     // compare the new col count to the old col count.  
00501     // If they are the same, we just need to rebalance column widths
00502     // If they differ, we need to fix up other column groups and the column cache
00503     // XXX for now assume the worse
00504     tableFrame->SetNeedStrategyInit(PR_TRUE);
00505   }
00506   return rv;
00507 }
00508 
00509 nsTableColFrame * nsTableColGroupFrame::GetFirstColumn()
00510 {
00511   return GetNextColumn(nsnull);
00512 }
00513 
00514 nsTableColFrame * nsTableColGroupFrame::GetNextColumn(nsIFrame *aChildFrame)
00515 {
00516   nsTableColFrame *result = nsnull;
00517   nsIFrame *childFrame = aChildFrame;
00518   if (nsnull==childFrame)
00519     childFrame = mFrames.FirstChild();
00520   while (nsnull!=childFrame)
00521   {
00522     if (NS_STYLE_DISPLAY_TABLE_COLUMN ==
00523         childFrame->GetStyleDisplay()->mDisplay)
00524     {
00525       result = (nsTableColFrame *)childFrame;
00526       break;
00527     }
00528     childFrame = childFrame->GetNextSibling();
00529   }
00530   return result;
00531 }
00532 
00533 PRInt32 nsTableColGroupFrame::GetSpan()
00534 {
00535   PRInt32 span = 1;
00536   nsIContent* iContent = GetContent();
00537   if (!iContent) return NS_OK;
00538 
00539   // col group element derives from col element
00540   nsIDOMHTMLTableColElement* cgContent = nsnull;
00541   nsresult rv = iContent->QueryInterface(NS_GET_IID(nsIDOMHTMLTableColElement), 
00542                                          (void **)&cgContent);
00543   if (cgContent && NS_SUCCEEDED(rv)) { 
00544     cgContent->GetSpan(&span);
00545     // XXX why does this work!!
00546     if (span == -1) {
00547       span = 1;
00548     }
00549     NS_RELEASE(cgContent);
00550   }
00551   return span;
00552 }
00553 
00554 void nsTableColGroupFrame::SetContinuousBCBorderWidth(PRUint8     aForSide,
00555                                                       BCPixelSize aPixelValue)
00556 {
00557   switch (aForSide) {
00558     case NS_SIDE_TOP:
00559       mTopContBorderWidth = aPixelValue;
00560       return;
00561     case NS_SIDE_BOTTOM:
00562       mBottomContBorderWidth = aPixelValue;
00563       return;
00564     default:
00565       NS_ERROR("invalid side arg");
00566   }
00567 }
00568 
00569 void nsTableColGroupFrame::GetContinuousBCBorderWidth(float     aPixelsToTwips,
00570                                                       nsMargin& aBorder)
00571 {
00572   nsTableFrame* table;
00573   nsTableFrame::GetTableFrame(this, table);
00574   nsTableColFrame* col = table->GetColFrame(mStartColIndex + mColCount - 1);
00575   col->GetContinuousBCBorderWidth(aPixelsToTwips, aBorder);
00576   aBorder.top = BC_BORDER_BOTTOM_HALF_COORD(aPixelsToTwips,
00577                                             mTopContBorderWidth);
00578   aBorder.bottom = BC_BORDER_TOP_HALF_COORD(aPixelsToTwips,
00579                                             mBottomContBorderWidth);
00580   return;
00581 }
00582 
00583 /* ----- global methods ----- */
00584 
00585 nsresult 
00586 NS_NewTableColGroupFrame(nsIPresShell* aPresShell, nsIFrame** aNewFrame)
00587 {
00588   NS_PRECONDITION(aNewFrame, "null OUT ptr");
00589   if (nsnull == aNewFrame) {
00590     return NS_ERROR_NULL_POINTER;
00591   }
00592   nsTableColGroupFrame* it = new (aPresShell) nsTableColGroupFrame;
00593   if (nsnull == it) {
00594     return NS_ERROR_OUT_OF_MEMORY;
00595   }
00596   *aNewFrame = it;
00597   return NS_OK;
00598 }
00599 
00600 NS_IMETHODIMP
00601 nsTableColGroupFrame::Init(nsPresContext*  aPresContext,
00602                            nsIContent*      aContent,
00603                            nsIFrame*        aParent,
00604                            nsStyleContext*  aContext,
00605                            nsIFrame*        aPrevInFlow)
00606 {
00607   nsresult  rv;
00608 
00609   // Let the base class do its processing
00610   rv = nsHTMLContainerFrame::Init(aPresContext, aContent, aParent, aContext,
00611                                   aPrevInFlow);
00612 
00613   // record that children that are ignorable whitespace should be excluded 
00614   mState |= NS_FRAME_EXCLUDE_IGNORABLE_WHITESPACE;
00615 
00616   return rv;
00617 }
00618 
00619 nsIAtom*
00620 nsTableColGroupFrame::GetType() const
00621 {
00622   return nsLayoutAtoms::tableColGroupFrame;
00623 }
00624 
00625 #ifdef DEBUG
00626 NS_IMETHODIMP
00627 nsTableColGroupFrame::GetFrameName(nsAString& aResult) const
00628 {
00629   return MakeFrameName(NS_LITERAL_STRING("TableColGroup"), aResult);
00630 }
00631 
00632 void nsTableColGroupFrame::Dump(PRInt32 aIndent)
00633 {
00634   char* indent = new char[aIndent + 1];
00635   if (!indent) return;
00636   for (PRInt32 i = 0; i < aIndent + 1; i++) {
00637     indent[i] = ' ';
00638   }
00639   indent[aIndent] = 0;
00640 
00641   printf("%s**START COLGROUP DUMP**\n%s startcolIndex=%d  colcount=%d span=%d coltype=",
00642     indent, indent, GetStartColumnIndex(),  GetColCount(), GetSpan());
00643   nsTableColGroupType colType = GetColType();
00644   switch (colType) {
00645   case eColGroupContent:
00646     printf(" content ");
00647     break;
00648   case eColGroupAnonymousCol: 
00649     printf(" anonymous-column  ");
00650     break;
00651   case eColGroupAnonymousCell: 
00652     printf(" anonymous-cell ");
00653     break;
00654   }
00655   // verify the colindices
00656   PRInt32 j = GetStartColumnIndex();
00657   nsTableColFrame* col = GetFirstColumn();
00658   while (col) {
00659     NS_ASSERTION(j == col->GetColIndex(), "wrong colindex on col frame");
00660     col = col->GetNextCol();
00661     j++;
00662   }
00663   NS_ASSERTION((j - GetStartColumnIndex()) == GetColCount(),
00664                "number of cols out of sync");
00665   printf("\n%s**END COLGROUP DUMP** ", indent);
00666   delete [] indent;
00667 }
00668 #endif