Bug 454376 imgLoader.cpp does not compile with Sun Studio 12 on Solaris r=joedraw...
[wine-gecko.git] / layout / tables / nsTablePainter.cpp
blob766b2b7edcbdda83fb1a2f4a53138f78fd889f38
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is TableBackgroundPainter implementation.
17 * The Initial Developer of the Original Code is
18 * Elika J. Etemad ("fantasai") <fantasai@inkedblade.net>.
19 * Portions created by the Initial Developer are Copyright (C) 2004
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsTableFrame.h"
39 #include "nsTableRowGroupFrame.h"
40 #include "nsTableRowFrame.h"
41 #include "nsTableColGroupFrame.h"
42 #include "nsTableColFrame.h"
43 #include "nsTableCellFrame.h"
44 #include "nsTablePainter.h"
45 #include "nsCSSRendering.h"
46 #include "nsDisplayList.h"
48 /* ~*~ Table Background Painting ~*~
50 Mozilla's Table Background painting follows CSS2.1:17.5.1
51 That section does not, however, describe the effect of
52 borders on background image positioning. What we do is:
54 - in separate borders, the borders are passed in so that
55 their width figures in image positioning, even for rows/cols, which
56 don't have visible borders. This is done to allow authors
57 to position row backgrounds by, for example, aligning the
58 top left corner with the top left padding corner of the
59 top left table cell in the row in cases where all cells
60 have consistent border widths. If we didn't honor these
61 invisible borders, there would be no way to align
62 backgrounds with the padding edges, and designs would be
63 lost underneath the border.
65 - in collapsing borders, because the borders collapse, we
66 use the -continuous border- width to synthesize a border
67 style and pass that in instead of using the element's
68 assigned style directly.
70 The continuous border on a given edge of an element is
71 the collapse of all borders guaranteed to be continuous
72 along that edge. Cell borders are ignored (because, for
73 example, setting a thick border on the leftmost cell
74 should not shift the row background over; this way a
75 striped background set on <tr> will line up across rows
76 even if the cells are assigned arbitrary border widths.
78 For example, the continuous border on the top edge of a
79 row group is the collapse of any row group, row, and
80 table borders involved. (The first row group's top would
81 be [table-top + row group top + first row top]. It's bottom
82 would be [row group bottom + last row bottom + next row
83 top + next row group top].)
84 The top edge of a column group likewise includes the
85 table top, row group top, and first row top borders. However,
86 it *also* includes its own top border, since that is guaranteed
87 to be continuous. It does not include column borders because
88 those are not guaranteed to be continuous: there may be two
89 columns with different borders in a single column group.
91 An alternative would be to define the continuous border as
92 [table? + row group + row] for horizontal
93 [table? + col group + col] for vertical
94 This makes it easier to line up backgrounds across elements
95 despite varying border widths, but it does not give much
96 flexibility in aligning /to/ those border widths.
100 /* ~*~ TableBackgroundPainter ~*~
102 The TableBackgroundPainter is created and destroyed in one painting call.
103 Its principal function is PaintTable, which paints all table element
104 backgrounds. The initial code in that method sets up an array of column
105 data that caches the background styles and the border sizes for the
106 columns and colgroups in TableBackgroundData structs in mCols. Data for
107 BC borders are calculated and stashed in a synthesized border style struct
108 in the data struct since collapsed borders aren't the same width as style-
109 assigned borders. The data struct optimizes by only doing this if there's
110 an image background; otherwise we don't care. //XXX should also check background-origin
111 The class then loops through the row groups, rows, and cells. It uses
112 the mRowGroup and mRow TableBackgroundData structs to cache data for
113 the current frame in the loop. At the cell level, it paints the backgrounds,
114 one over the other, inside the cell rect.
116 The exception to this pattern is when a table element creates a (pseudo)
117 stacking context. Elements with stacking contexts (e.g., 'opacity' applied)
118 are <dfn>passed through</dfn>, which means their data (and their
119 descendants' data) are not cached. The full loop is still executed, however,
120 so that underlying layers can get painted at the cell level.
122 The TableBackgroundPainter is then destroyed.
124 Elements with stacking contexts set up their own painter to finish the
125 painting process, since they were skipped. They call the appropriate
126 sub-part of the loop (e.g. PaintRow) which will paint the frame and
127 descendants. Note that it is permissible according to CSS2.1 to ignore'
128 'position:relative' (and implicitly, 'opacity') on table parts so that
129 table parts can never create stacking contexts; if we want to, we can
130 implement that, and then we won't have to deal with TableBackgroundPainter
131 being used anywhere but from the nsTableFrame.
133 XXX views are going
136 TableBackgroundPainter::TableBackgroundData::TableBackgroundData()
137 : mFrame(nsnull),
138 mBackground(nsnull),
139 mBorder(nsnull),
140 mSynthBorder(nsnull)
142 MOZ_COUNT_CTOR(TableBackgroundData);
145 TableBackgroundPainter::TableBackgroundData::~TableBackgroundData()
147 NS_ASSERTION(!mSynthBorder, "must call Destroy before dtor");
148 MOZ_COUNT_DTOR(TableBackgroundData);
151 void
152 TableBackgroundPainter::TableBackgroundData::Destroy(nsPresContext* aPresContext)
154 NS_PRECONDITION(aPresContext, "null prescontext");
155 if (mSynthBorder) {
156 mSynthBorder->Destroy(aPresContext);
157 mSynthBorder = nsnull;
161 void
162 TableBackgroundPainter::TableBackgroundData::Clear()
164 mRect.Empty();
165 mFrame = nsnull;
166 mBorder = nsnull;
167 mBackground = nsnull;
170 void
171 TableBackgroundPainter::TableBackgroundData::SetFrame(nsIFrame* aFrame)
173 NS_PRECONDITION(aFrame, "null frame");
174 mFrame = aFrame;
175 mRect = aFrame->GetRect();
178 void
179 TableBackgroundPainter::TableBackgroundData::SetData()
181 NS_PRECONDITION(mFrame, "null frame");
182 if (mFrame->IsVisibleForPainting()) {
183 mBackground = mFrame->GetStyleBackground();
184 mBorder = mFrame->GetStyleBorder();
188 void
189 TableBackgroundPainter::TableBackgroundData::SetFull(nsIFrame* aFrame)
191 NS_PRECONDITION(aFrame, "null frame");
192 SetFrame(aFrame);
193 SetData();
196 inline PRBool
197 TableBackgroundPainter::TableBackgroundData::ShouldSetBCBorder()
199 /* we only need accurate border data when positioning background images*/
200 return mBackground && !(mBackground->mBackgroundFlags & NS_STYLE_BG_IMAGE_NONE);
203 nsresult
204 TableBackgroundPainter::TableBackgroundData::SetBCBorder(nsMargin& aBorder,
205 TableBackgroundPainter* aPainter)
207 NS_PRECONDITION(aPainter, "null painter");
208 if (!mSynthBorder) {
209 mSynthBorder = new (aPainter->mPresContext)
210 nsStyleBorder(aPainter->mZeroBorder);
211 if (!mSynthBorder) return NS_ERROR_OUT_OF_MEMORY;
214 NS_FOR_CSS_SIDES(side) {
215 mSynthBorder->SetBorderWidth(side, aBorder.side(side));
218 mBorder = mSynthBorder;
219 return NS_OK;
222 TableBackgroundPainter::TableBackgroundPainter(nsTableFrame* aTableFrame,
223 Origin aOrigin,
224 nsPresContext* aPresContext,
225 nsIRenderingContext& aRenderingContext,
226 const nsRect& aDirtyRect,
227 const nsPoint& aRenderPt)
228 : mPresContext(aPresContext),
229 mRenderingContext(aRenderingContext),
230 mRenderPt(aRenderPt),
231 mDirtyRect(aDirtyRect),
232 mOrigin(aOrigin),
233 mCols(nsnull),
234 mZeroBorder(aPresContext)
236 MOZ_COUNT_CTOR(TableBackgroundPainter);
238 NS_FOR_CSS_SIDES(side) {
239 mZeroBorder.SetBorderStyle(side, NS_STYLE_BORDER_STYLE_SOLID);
240 mZeroBorder.SetBorderWidth(side, 0);
243 mZeroPadding.RecalcData();
245 mIsBorderCollapse = aTableFrame->IsBorderCollapse();
246 #ifdef DEBUG
247 mCompatMode = mPresContext->CompatibilityMode();
248 #endif
249 mNumCols = aTableFrame->GetColCount();
252 TableBackgroundPainter::~TableBackgroundPainter()
254 if (mCols) {
255 TableBackgroundData* lastColGroup = nsnull;
256 for (PRUint32 i = 0; i < mNumCols; i++) {
257 if (mCols[i].mColGroup != lastColGroup) {
258 lastColGroup = mCols[i].mColGroup;
259 NS_ASSERTION(mCols[i].mColGroup, "colgroup data should not be null - bug 237421");
260 // we need to wallpaper a over zero pointer deref, bug 237421 will have the real fix
261 if(lastColGroup)
262 lastColGroup->Destroy(mPresContext);
263 delete lastColGroup;
265 mCols[i].mColGroup = nsnull;
266 mCols[i].mCol.Destroy(mPresContext);
268 delete [] mCols;
270 mRowGroup.Destroy(mPresContext);
271 mRow.Destroy(mPresContext);
272 MOZ_COUNT_DTOR(TableBackgroundPainter);
275 nsresult
276 TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame,
277 nsTableRowGroupFrame* aFirstRowGroup,
278 nsTableRowGroupFrame* aLastRowGroup,
279 nsMargin* aDeflate)
281 NS_PRECONDITION(aTableFrame, "null frame");
282 TableBackgroundData tableData;
283 tableData.SetFull(aTableFrame);
284 tableData.mRect.MoveTo(0,0); //using table's coords
285 if (aDeflate) {
286 tableData.mRect.Deflate(*aDeflate);
288 if (mIsBorderCollapse && tableData.ShouldSetBCBorder()) {
289 if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) {
290 //only handle non-degenerate tables; we need a more robust BC model
291 //to make degenerate tables' borders reasonable to deal with
292 nsMargin border, tempBorder;
293 nsTableColFrame* colFrame = aTableFrame->GetColFrame(mNumCols - 1);
294 if (colFrame) {
295 colFrame->GetContinuousBCBorderWidth(tempBorder);
297 border.right = tempBorder.right;
299 aLastRowGroup->GetContinuousBCBorderWidth(tempBorder);
300 border.bottom = tempBorder.bottom;
302 nsTableRowFrame* rowFrame = aFirstRowGroup->GetFirstRow();
303 if (rowFrame) {
304 rowFrame->GetContinuousBCBorderWidth(tempBorder);
305 border.top = tempBorder.top;
308 border.left = aTableFrame->GetContinuousLeftBCBorderWidth();
310 nsresult rv = tableData.SetBCBorder(border, this);
311 if (NS_FAILED(rv)) {
312 tableData.Destroy(mPresContext);
313 return rv;
317 if (tableData.IsVisible()) {
318 nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
319 tableData.mFrame, mDirtyRect,
320 tableData.mRect + mRenderPt,
321 *tableData.mBackground,
322 *tableData.mBorder,
323 mZeroPadding, PR_TRUE);
325 tableData.Destroy(mPresContext);
326 return NS_OK;
329 void
330 TableBackgroundPainter::TranslateContext(nscoord aDX,
331 nscoord aDY)
333 mRenderPt += nsPoint(aDX, aDY);
334 if (mCols) {
335 TableBackgroundData* lastColGroup = nsnull;
336 for (PRUint32 i = 0; i < mNumCols; i++) {
337 mCols[i].mCol.mRect.MoveBy(-aDX, -aDY);
338 if (lastColGroup != mCols[i].mColGroup) {
339 NS_ASSERTION(mCols[i].mColGroup, "colgroup data should not be null - bug 237421");
340 // we need to wallpaper a over zero pointer deref, bug 237421 will have the real fix
341 if (!mCols[i].mColGroup)
342 return;
343 mCols[i].mColGroup->mRect.MoveBy(-aDX, -aDY);
344 lastColGroup = mCols[i].mColGroup;
350 nsresult
351 TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
352 nsMargin* aDeflate)
354 NS_PRECONDITION(aTableFrame, "null table frame");
356 nsTableFrame::RowGroupArray rowGroups;
357 aTableFrame->OrderRowGroups(rowGroups);
359 if (rowGroups.Length() < 1) { //degenerate case
360 PaintTableFrame(aTableFrame, nsnull, nsnull, nsnull);
361 /* No cells; nothing else to paint */
362 return NS_OK;
365 PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
366 aDeflate);
368 /*Set up column background/border data*/
369 if (mNumCols > 0) {
370 nsFrameList& colGroupList = aTableFrame->GetColGroups();
371 NS_ASSERTION(colGroupList.FirstChild(), "table should have at least one colgroup");
373 mCols = new ColData[mNumCols];
374 if (!mCols) return NS_ERROR_OUT_OF_MEMORY;
376 TableBackgroundData* cgData = nsnull;
377 nsMargin border;
378 /* BC left borders aren't stored on cols, but the previous column's
379 right border is the next one's left border.*/
380 //Start with table's left border.
381 nscoord lastLeftBorder = aTableFrame->GetContinuousLeftBCBorderWidth();
382 for (nsTableColGroupFrame* cgFrame = static_cast<nsTableColGroupFrame*>(colGroupList.FirstChild());
383 cgFrame; cgFrame = static_cast<nsTableColGroupFrame*>(cgFrame->GetNextSibling())) {
385 if (cgFrame->GetColCount() < 1) {
386 //No columns, no cells, so no need for data
387 continue;
390 /*Create data struct for column group*/
391 cgData = new TableBackgroundData;
392 if (!cgData) return NS_ERROR_OUT_OF_MEMORY;
393 cgData->SetFull(cgFrame);
394 if (mIsBorderCollapse && cgData->ShouldSetBCBorder()) {
395 border.left = lastLeftBorder;
396 cgFrame->GetContinuousBCBorderWidth(border);
397 nsresult rv = cgData->SetBCBorder(border, this);
398 if (NS_FAILED(rv)) {
399 cgData->Destroy(mPresContext);
400 delete cgData;
401 return rv;
405 // Boolean that indicates whether mCols took ownership of cgData
406 PRBool cgDataOwnershipTaken = PR_FALSE;
408 /*Loop over columns in this colgroup*/
409 for (nsTableColFrame* col = cgFrame->GetFirstColumn(); col;
410 col = static_cast<nsTableColFrame*>(col->GetNextSibling())) {
411 /*Create data struct for column*/
412 PRUint32 colIndex = col->GetColIndex();
413 NS_ASSERTION(colIndex < mNumCols, "prevent array boundary violation");
414 if (mNumCols <= colIndex)
415 break;
416 mCols[colIndex].mCol.SetFull(col);
417 //Bring column mRect into table's coord system
418 mCols[colIndex].mCol.mRect.MoveBy(cgData->mRect.x, cgData->mRect.y);
419 //link to parent colgroup's data
420 mCols[colIndex].mColGroup = cgData;
421 cgDataOwnershipTaken = PR_TRUE;
422 if (mIsBorderCollapse) {
423 border.left = lastLeftBorder;
424 lastLeftBorder = col->GetContinuousBCBorderWidth(border);
425 if (mCols[colIndex].mCol.ShouldSetBCBorder()) {
426 nsresult rv = mCols[colIndex].mCol.SetBCBorder(border, this);
427 if (NS_FAILED(rv)) return rv;
432 if (!cgDataOwnershipTaken) {
433 cgData->Destroy(mPresContext);
434 delete cgData;
439 for (PRUint32 i = 0; i < rowGroups.Length(); i++) {
440 nsTableRowGroupFrame* rg = rowGroups[i];
441 mRowGroup.SetFrame(rg);
442 // Need to compute the right rect via GetOffsetTo, since the row
443 // group may not be a child of the table.
444 mRowGroup.mRect.MoveTo(rg->GetOffsetTo(aTableFrame));
445 if (mRowGroup.mRect.Intersects(mDirtyRect - mRenderPt)) {
446 nsresult rv = PaintRowGroup(rg,
447 rg->IsPseudoStackingContextFromStyle() || rg->IsScrolled());
448 if (NS_FAILED(rv)) return rv;
451 return NS_OK;
454 nsresult
455 TableBackgroundPainter::PaintRowGroup(nsTableRowGroupFrame* aFrame,
456 PRBool aPassThrough)
458 NS_PRECONDITION(aFrame, "null frame");
460 if (!mRowGroup.mFrame) {
461 mRowGroup.SetFrame(aFrame);
464 nsTableRowFrame* firstRow = aFrame->GetFirstRow();
466 /* Load row group data */
467 if (!aPassThrough) {
468 mRowGroup.SetData();
469 if (mIsBorderCollapse && mRowGroup.ShouldSetBCBorder()) {
470 nsMargin border;
471 if (firstRow) {
472 //pick up first row's top border (= rg top border)
473 firstRow->GetContinuousBCBorderWidth(border);
474 /* (row group doesn't store its top border) */
476 //overwrite sides+bottom borders with rg's own
477 aFrame->GetContinuousBCBorderWidth(border);
478 nsresult res = mRowGroup.SetBCBorder(border, this);
479 if (!NS_SUCCEEDED(res)) {
480 return res;
483 aPassThrough = !mRowGroup.IsVisible();
486 /* translate everything into row group coord system*/
487 if (eOrigin_TableRowGroup != mOrigin) {
488 TranslateContext(mRowGroup.mRect.x, mRowGroup.mRect.y);
490 nsRect rgRect = mRowGroup.mRect;
491 mRowGroup.mRect.MoveTo(0, 0);
493 /* Find the right row to start with */
494 nscoord ignored; // We don't care about overflow above, since what we really
495 // care about are backgrounds and overflow above doesn't
496 // correspond to backgrounds, since cells can't span up from
497 // their originating row. We do care about overflow below,
498 // however, since that can be due to rowspans.
500 // Note that mDirtyRect - mRenderPt is guaranteed to be in the row
501 // group's coordinate system here, so passing its .y to
502 // GetFirstRowContaining is ok.
503 nsIFrame* cursor = aFrame->GetFirstRowContaining(mDirtyRect.y - mRenderPt.y, &ignored);
505 // Sadly, it seems like there may be non-row frames in there... or something?
506 // There are certainly null-checks in GetFirstRow() and GetNextRow(). :(
507 while (cursor && cursor->GetType() != nsGkAtoms::tableRowFrame) {
508 cursor = cursor->GetNextSibling();
511 // It's OK if cursor is null here.
512 nsTableRowFrame* row = static_cast<nsTableRowFrame*>(cursor);
513 if (!row) {
514 // No useful cursor; just start at the top. Don't bother to set up a
515 // cursor; if we've gotten this far then we've already built the display
516 // list for the rowgroup, so not having a cursor means that there's some
517 // good reason we don't have a cursor and we shouldn't create one here.
518 row = firstRow;
521 /* Finally paint */
522 for (; row; row = row->GetNextRow()) {
523 mRow.SetFrame(row);
524 if (mDirtyRect.YMost() - mRenderPt.y < mRow.mRect.y) { // Intersect wouldn't handle
525 // rowspans.
527 // All done; cells originating in later rows can't intersect mDirtyRect.
528 break;
531 nsresult rv = PaintRow(row, aPassThrough || row->IsPseudoStackingContextFromStyle());
532 if (NS_FAILED(rv)) return rv;
535 /* translate back into table coord system */
536 if (eOrigin_TableRowGroup != mOrigin) {
537 TranslateContext(-rgRect.x, -rgRect.y);
540 /* unload rg data */
541 mRowGroup.Clear();
543 return NS_OK;
546 nsresult
547 TableBackgroundPainter::PaintRow(nsTableRowFrame* aFrame,
548 PRBool aPassThrough)
550 NS_PRECONDITION(aFrame, "null frame");
552 if (!mRow.mFrame) {
553 mRow.SetFrame(aFrame);
556 /* Load row data */
557 if (!aPassThrough) {
558 mRow.SetData();
559 if (mIsBorderCollapse && mRow.ShouldSetBCBorder()) {
560 nsMargin border;
561 nsTableRowFrame* nextRow = aFrame->GetNextRow();
562 if (nextRow) { //outer top below us is inner bottom for us
563 border.bottom = nextRow->GetOuterTopContBCBorderWidth();
565 else { //acquire rg's bottom border
566 nsTableRowGroupFrame* rowGroup = static_cast<nsTableRowGroupFrame*>(aFrame->GetParent());
567 rowGroup->GetContinuousBCBorderWidth(border);
569 //get the rest of the borders; will overwrite all but bottom
570 aFrame->GetContinuousBCBorderWidth(border);
572 nsresult res = mRow.SetBCBorder(border, this);
573 if (!NS_SUCCEEDED(res)) {
574 return res;
577 aPassThrough = !mRow.IsVisible();
580 /* Translate */
581 if (eOrigin_TableRow == mOrigin) {
582 /* If we originate from the row, then make the row the origin. */
583 mRow.mRect.MoveTo(0, 0);
585 //else: Use row group's coord system -> no translation necessary
587 for (nsTableCellFrame* cell = aFrame->GetFirstCell(); cell; cell = cell->GetNextCell()) {
588 //Translate to use the same coord system as mRow.
589 mCellRect = cell->GetRect() + mRow.mRect.TopLeft() + mRenderPt;
590 if (mCellRect.Intersects(mDirtyRect)) {
591 nsresult rv = PaintCell(cell, aPassThrough || cell->IsPseudoStackingContextFromStyle());
592 if (NS_FAILED(rv)) return rv;
596 /* Unload row data */
597 mRow.Clear();
598 return NS_OK;
601 nsresult
602 TableBackgroundPainter::PaintCell(nsTableCellFrame* aCell,
603 PRBool aPassSelf)
605 NS_PRECONDITION(aCell, "null frame");
607 const nsStyleTableBorder* cellTableStyle;
608 cellTableStyle = aCell->GetStyleTableBorder();
609 if (!(NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells ||
610 NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND == cellTableStyle->mEmptyCells)
611 && aCell->GetContentEmpty() && !mIsBorderCollapse) {
612 return NS_OK;
615 PRInt32 colIndex;
616 aCell->GetColIndex(colIndex);
617 NS_ASSERTION(colIndex < mNumCols, "prevent array boundary violation");
618 if (mNumCols <= colIndex)
619 return NS_OK;
621 //Paint column group background
622 if (mCols && mCols[colIndex].mColGroup && mCols[colIndex].mColGroup->IsVisible()) {
623 nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
624 mCols[colIndex].mColGroup->mFrame, mDirtyRect,
625 mCols[colIndex].mColGroup->mRect + mRenderPt,
626 *mCols[colIndex].mColGroup->mBackground,
627 *mCols[colIndex].mColGroup->mBorder,
628 mZeroPadding, PR_TRUE, &mCellRect);
631 //Paint column background
632 if (mCols && mCols[colIndex].mCol.IsVisible()) {
633 nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
634 mCols[colIndex].mCol.mFrame, mDirtyRect,
635 mCols[colIndex].mCol.mRect + mRenderPt,
636 *mCols[colIndex].mCol.mBackground,
637 *mCols[colIndex].mCol.mBorder,
638 mZeroPadding, PR_TRUE, &mCellRect);
641 //Paint row group background
642 if (mRowGroup.IsVisible()) {
643 nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
644 mRowGroup.mFrame, mDirtyRect,
645 mRowGroup.mRect + mRenderPt,
646 *mRowGroup.mBackground, *mRowGroup.mBorder,
647 mZeroPadding, PR_TRUE, &mCellRect);
650 //Paint row background
651 if (mRow.IsVisible()) {
652 nsCSSRendering::PaintBackgroundWithSC(mPresContext, mRenderingContext,
653 mRow.mFrame, mDirtyRect,
654 mRow.mRect + mRenderPt,
655 *mRow.mBackground, *mRow.mBorder,
656 mZeroPadding, PR_TRUE, &mCellRect);
659 //Paint cell background in border-collapse unless we're just passing
660 if (mIsBorderCollapse && !aPassSelf) {
661 aCell->PaintCellBackground(mRenderingContext, mDirtyRect,
662 mCellRect.TopLeft());
665 return NS_OK;