diff --git a/mozilla/layout/html/table/src/nsTableCellFrame.cpp b/mozilla/layout/html/table/src/nsTableCellFrame.cpp index 06ca717b3bd..025cb287f97 100644 --- a/mozilla/layout/html/table/src/nsTableCellFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableCellFrame.cpp @@ -400,6 +400,9 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { return NS_OK; } + nsTableFrame* tableFrame = nsnull; + nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(rv); + const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); const nsStyleVisibility* vis = @@ -407,7 +410,6 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { if (vis->IsVisibleOrCollapsed()) { - const nsStyleBackground* myColor = (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background); #ifdef OLD_TABLE_SELECTION myColor = GetColorStyleFromSelection(myColor); @@ -423,27 +425,24 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)cellTableStyle)); nsRect rect(0, 0, mRect.width, mRect.height); - // draw the background except when the cell is empty and 'empty-cells: hide' is set - if (!GetContentEmpty() || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND == cellTableStyle->mEmptyCells) { + // Draw the background for collapsed borders only during pass1. Draw the backgrounds + // when the cell is not empty or when showing empty cells or backgrounds + if ((!tableFrame->IsBorderCollapse() || + !(aFlags & BORDER_COLLAPSE_BACKGROUNDS)) && // unset bit indicates pass1 + (!GetContentEmpty() || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND == cellTableStyle->mEmptyCells)) { + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, 0, 0, PR_TRUE); } - // draw the border except when the cell is empty and 'empty-cells: hide || -moz-show-background' is set - if (!GetContentEmpty() || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells) { + // draw the border only for separate borders and only when there is content or showing empty cells + if (!tableFrame->IsBorderCollapse() && + (!GetContentEmpty() || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells)) { PRIntn skipSides = GetSkipSides(); - nsTableFrame* tableFrame = nsnull; // I should be checking my own style context, but border-collapse isn't inheriting correctly - nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); - if ((NS_SUCCEEDED(rv)) && tableFrame) { - const nsStyleTableBorder* tableStyle; - tableFrame->GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)tableStyle)); - if (!tableFrame->IsBorderCollapse()) { - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, mStyleContext, skipSides); - } - } + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *myBorder, mStyleContext, skipSides); } #ifndef OLD_TABLE_SELECTION DecorateForSelection(aPresContext, aRenderingContext,myColor); //ignore return value @@ -459,31 +458,38 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, } #endif - // if the cell originates in a row and/or col that is collapsed, the - // bottom and/or right portion of the cell is painted by translating - // the rendering context. - PRBool clipState; - nsPoint offset; - GetCollapseOffset(aPresContext, offset); - if ((0 != offset.x) || (0 != offset.y)) { - aRenderingContext.PushState(); - aRenderingContext.Translate(offset.x, offset.y); - aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height), - nsClipCombine_kIntersect, clipState); - } - else{ - if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + // paint the children unless its the background layer, there are collapsed border, and it's pass1 + if ( !((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && + tableFrame->IsBorderCollapse() && + !(aFlags & BORDER_COLLAPSE_BACKGROUNDS)) ) { + // if the cell originates in a row and/or col that is collapsed, the + // bottom and/or right portion of the cell is painted by translating + // the rendering context. + PRBool clipState; + nsPoint offset; + GetCollapseOffset(aPresContext, offset); + if ((0 != offset.x) || (0 != offset.y)) { aRenderingContext.PushState(); - SetOverflowClipRect(aRenderingContext); - } - } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - if ((0 != offset.x) || (0 != offset.y)) { - aRenderingContext.PopState(clipState); - } - else { - if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { - aRenderingContext.PopState(clipState); + aRenderingContext.Translate(offset.x, offset.y); + aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height), + nsClipCombine_kIntersect, clipState); + } + else { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); + + if ((0 != offset.x) || (0 != offset.y)) { + aRenderingContext.PopState(clipState); + } + else { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + aRenderingContext.PopState(clipState); + } } } diff --git a/mozilla/layout/html/table/src/nsTableFrame.cpp b/mozilla/layout/html/table/src/nsTableFrame.cpp index 952d9a34812..6268fe7c0a6 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableFrame.cpp @@ -1437,7 +1437,34 @@ nsTableFrame::GetAdditionalChildListName(PRInt32 aIndex, return NS_OK; } -/* SEC: TODO: adjust the rect for captions */ +void +nsTableFrame::PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer, + PRUint32 aFlags) + +{ + const nsStyleDisplay* disp = (const nsStyleDisplay*) + mStyleContext->GetStyleData(eStyleStruct_Display); + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + + nsHTMLContainerFrame::PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); + + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + PRBool clipState; + aRenderingContext.PopState(clipState); + } +} + +// table paint code is concerned primarily with borders and bg color +// SEC: TODO: adjust the rect for captions NS_METHOD nsTableFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -1445,37 +1472,41 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { - // table paint code is concerned primarily with borders and bg color if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { const nsStyleVisibility* vis = (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility); - if (vis->IsVisibleOrCollapsed()) { + if (vis && vis->IsVisibleOrCollapsed()) { const nsStyleBorder* border = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); - nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, 0, 0, PR_TRUE); - // paint the column groups and columns - nsIFrame* colGroupFrame = mColGroups.FirstChild(); - while (nsnull != colGroupFrame) { - PaintChild(aPresContext, aRenderingContext, aDirtyRect, colGroupFrame, aWhichLayer); - colGroupFrame->GetNextSibling(&colGroupFrame); - } - - PRIntn skipSides = GetSkipSides(); - if (IsBorderCollapse()) { - PaintBCBorders(aPresContext, aRenderingContext, aDirtyRect); - } - else { + // paint the border here only for separate borders + if (!IsBorderCollapse()) { + PRIntn skipSides = GetSkipSides(); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); } } } + // for collapsed borders paint the backgrounds of cells, but not their contents (that happens below) + PRUint32 flags = aFlags; + if ((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && IsBorderCollapse()) { + flags &= ~BORDER_COLLAPSE_BACKGROUNDS; // set bit to 0 + } + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, flags); + + if ((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && IsBorderCollapse()) { + // for collapsed borders, paint the borders and then the backgrounds of cell + // contents but not the backgrounds of the cells + PaintBCBorders(aPresContext, aRenderingContext, aDirtyRect); + flags |= BORDER_COLLAPSE_BACKGROUNDS; // set bit to 1 + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, flags); + } + #ifdef DEBUG // for debug... if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { @@ -1483,22 +1514,7 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); } #endif - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children don't - // leak out of us. Note that because overflow'-clip' only applies to - // the content area we do this after painting the border and background - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetOverflowClipRect(aRenderingContext); - } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - PRBool clipState; - aRenderingContext.PopState(clipState); - } DO_GLOBAL_REFLOW_COUNT_DSP_J("nsTableFrame", &aRenderingContext, NS_RGB(255,128,255)); return NS_OK; /*nsFrame::Paint(aPresContext, diff --git a/mozilla/layout/html/table/src/nsTableFrame.h b/mozilla/layout/html/table/src/nsTableFrame.h index 7dc64be49b4..5087b4bbf7b 100644 --- a/mozilla/layout/html/table/src/nsTableFrame.h +++ b/mozilla/layout/html/table/src/nsTableFrame.h @@ -61,6 +61,10 @@ struct nsStylePosition; enum nsPixelRound {eAlwaysRoundUp=0, eAlwaysRoundDown, eRoundUpIfHalfOrMore}; +// flags for Paint, PaintChild, PaintChildren are currently only used by tables. +// use low order bit of flags to distinguish between pass1(0) and pass2(1) border collapse backgrounds +#define BORDER_COLLAPSE_BACKGROUNDS 0x00000001 + #ifdef DEBUG_TABLE_REFLOW_TIMING #ifdef WIN32 #include @@ -304,6 +308,12 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + virtual void PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer, + PRUint32 aFlags = 0); + nsMargin* GetBCBorder(nsIPresContext& aPresContext, PRBool aInnerBorderOnly, nsMargin& aBorder) const; diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.cpp b/mozilla/layout/html/table/src/nsTableRowFrame.cpp index e9fd8b52757..8c3a2f35e7a 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowFrame.cpp @@ -600,7 +600,7 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PushState(); SetOverflowClipRect(aRenderingContext); } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (disp && (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow)) { PRBool clipState; aRenderingContext.PopState(clipState); @@ -650,7 +650,7 @@ void nsTableRowFrame::PaintChildren(nsIPresContext* aPresContext, aRenderingContext.PushState(); aRenderingContext.Translate(kidRect.x, kidRect.y); kid->Paint(aPresContext, aRenderingContext, kidDamageArea, - aWhichLayer); + aWhichLayer, aFlags); #ifdef DEBUG if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { diff --git a/mozilla/layout/html/table/src/nsTableRowFrame.h b/mozilla/layout/html/table/src/nsTableRowFrame.h index d05dc5eab6a..36a92ee5979 100644 --- a/mozilla/layout/html/table/src/nsTableRowFrame.h +++ b/mozilla/layout/html/table/src/nsTableRowFrame.h @@ -51,8 +51,6 @@ class nsReflowTimer; #define NS_ROW_NEED_SPECIAL_REFLOW 0x20000000 #define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000 -#define NS_ROW_FRAME_PAINT_SKIP_ROW 0x00000001 -#define NS_ROW_FRAME_PAINT_SKIP_CELLS 0x00000002 /** * nsTableRowFrame is the frame that maps table rows * (HTML tag TR). This class cannot be reused diff --git a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp index 3271ec020a9..06d1690273e 100644 --- a/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/html/table/src/nsTableRowGroupFrame.cpp @@ -235,7 +235,7 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PushState(); SetOverflowClipRect(aRenderingContext); } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (disp && (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow)) { PRBool clipState; aRenderingContext.PopState(clipState); @@ -284,7 +284,7 @@ void nsTableRowGroupFrame::PaintChildren(nsIPresContext* aPresContext, damageArea.width, damageArea.height); aRenderingContext.PushState(); aRenderingContext.Translate(kidRect.x, kidRect.y); - kid->Paint(aPresContext, aRenderingContext, kidDamageArea, aWhichLayer); + kid->Paint(aPresContext, aRenderingContext, kidDamageArea, aWhichLayer, aFlags); #ifdef DEBUG if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { diff --git a/mozilla/layout/html/tests/table/collapsing_borders/bug127040.html b/mozilla/layout/html/tests/table/collapsing_borders/bug127040.html new file mode 100644 index 00000000000..46bd9a1ed6d --- /dev/null +++ b/mozilla/layout/html/tests/table/collapsing_borders/bug127040.html @@ -0,0 +1,36 @@ + + + + + +testcase for bug 127040 + + + + + + + + + + + + + + + + + + + +
asdfqwer
fdsarewq
zxcvuiop
+ + + + + + diff --git a/mozilla/layout/tables/nsTableCellFrame.cpp b/mozilla/layout/tables/nsTableCellFrame.cpp index 06ca717b3bd..025cb287f97 100644 --- a/mozilla/layout/tables/nsTableCellFrame.cpp +++ b/mozilla/layout/tables/nsTableCellFrame.cpp @@ -400,6 +400,9 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_SUCCEEDED(IsVisibleForPainting(aPresContext, aRenderingContext, PR_FALSE, &isVisible)) && !isVisible) { return NS_OK; } + nsTableFrame* tableFrame = nsnull; + nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); if (!tableFrame) ABORT1(rv); + const nsStyleDisplay* disp = (const nsStyleDisplay*)mStyleContext->GetStyleData(eStyleStruct_Display); const nsStyleVisibility* vis = @@ -407,7 +410,6 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { if (vis->IsVisibleOrCollapsed()) { - const nsStyleBackground* myColor = (const nsStyleBackground*)mStyleContext->GetStyleData(eStyleStruct_Background); #ifdef OLD_TABLE_SELECTION myColor = GetColorStyleFromSelection(myColor); @@ -423,27 +425,24 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)cellTableStyle)); nsRect rect(0, 0, mRect.width, mRect.height); - // draw the background except when the cell is empty and 'empty-cells: hide' is set - if (!GetContentEmpty() || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND == cellTableStyle->mEmptyCells) { + // Draw the background for collapsed borders only during pass1. Draw the backgrounds + // when the cell is not empty or when showing empty cells or backgrounds + if ((!tableFrame->IsBorderCollapse() || + !(aFlags & BORDER_COLLAPSE_BACKGROUNDS)) && // unset bit indicates pass1 + (!GetContentEmpty() || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW_BACKGROUND == cellTableStyle->mEmptyCells)) { + nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *myBorder, 0, 0, PR_TRUE); } - // draw the border except when the cell is empty and 'empty-cells: hide || -moz-show-background' is set - if (!GetContentEmpty() || - NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells) { + // draw the border only for separate borders and only when there is content or showing empty cells + if (!tableFrame->IsBorderCollapse() && + (!GetContentEmpty() || + NS_STYLE_TABLE_EMPTY_CELLS_SHOW == cellTableStyle->mEmptyCells)) { PRIntn skipSides = GetSkipSides(); - nsTableFrame* tableFrame = nsnull; // I should be checking my own style context, but border-collapse isn't inheriting correctly - nsresult rv = nsTableFrame::GetTableFrame(this, tableFrame); - if ((NS_SUCCEEDED(rv)) && tableFrame) { - const nsStyleTableBorder* tableStyle; - tableFrame->GetStyleData(eStyleStruct_TableBorder, ((const nsStyleStruct *&)tableStyle)); - if (!tableFrame->IsBorderCollapse()) { - nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, - aDirtyRect, rect, *myBorder, mStyleContext, skipSides); - } - } + nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, + aDirtyRect, rect, *myBorder, mStyleContext, skipSides); } #ifndef OLD_TABLE_SELECTION DecorateForSelection(aPresContext, aRenderingContext,myColor); //ignore return value @@ -459,31 +458,38 @@ nsTableCellFrame::Paint(nsIPresContext* aPresContext, } #endif - // if the cell originates in a row and/or col that is collapsed, the - // bottom and/or right portion of the cell is painted by translating - // the rendering context. - PRBool clipState; - nsPoint offset; - GetCollapseOffset(aPresContext, offset); - if ((0 != offset.x) || (0 != offset.y)) { - aRenderingContext.PushState(); - aRenderingContext.Translate(offset.x, offset.y); - aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height), - nsClipCombine_kIntersect, clipState); - } - else{ - if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + // paint the children unless its the background layer, there are collapsed border, and it's pass1 + if ( !((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && + tableFrame->IsBorderCollapse() && + !(aFlags & BORDER_COLLAPSE_BACKGROUNDS)) ) { + // if the cell originates in a row and/or col that is collapsed, the + // bottom and/or right portion of the cell is painted by translating + // the rendering context. + PRBool clipState; + nsPoint offset; + GetCollapseOffset(aPresContext, offset); + if ((0 != offset.x) || (0 != offset.y)) { aRenderingContext.PushState(); - SetOverflowClipRect(aRenderingContext); - } - } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - if ((0 != offset.x) || (0 != offset.y)) { - aRenderingContext.PopState(clipState); - } - else { - if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { - aRenderingContext.PopState(clipState); + aRenderingContext.Translate(offset.x, offset.y); + aRenderingContext.SetClipRect(nsRect(-offset.x, -offset.y, mRect.width, mRect.height), + nsClipCombine_kIntersect, clipState); + } + else { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + } + + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); + + if ((0 != offset.x) || (0 != offset.y)) { + aRenderingContext.PopState(clipState); + } + else { + if ((NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) || HasPctOverHeight()) { + aRenderingContext.PopState(clipState); + } } } diff --git a/mozilla/layout/tables/nsTableFrame.cpp b/mozilla/layout/tables/nsTableFrame.cpp index 952d9a34812..6268fe7c0a6 100644 --- a/mozilla/layout/tables/nsTableFrame.cpp +++ b/mozilla/layout/tables/nsTableFrame.cpp @@ -1437,7 +1437,34 @@ nsTableFrame::GetAdditionalChildListName(PRInt32 aIndex, return NS_OK; } -/* SEC: TODO: adjust the rect for captions */ +void +nsTableFrame::PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer, + PRUint32 aFlags) + +{ + const nsStyleDisplay* disp = (const nsStyleDisplay*) + mStyleContext->GetStyleData(eStyleStruct_Display); + // If overflow is hidden then set the clip rect so that children don't + // leak out of us. Note that because overflow'-clip' only applies to + // the content area we do this after painting the border and background + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + aRenderingContext.PushState(); + SetOverflowClipRect(aRenderingContext); + } + + nsHTMLContainerFrame::PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); + + if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { + PRBool clipState; + aRenderingContext.PopState(clipState); + } +} + +// table paint code is concerned primarily with borders and bg color +// SEC: TODO: adjust the rect for captions NS_METHOD nsTableFrame::Paint(nsIPresContext* aPresContext, nsIRenderingContext& aRenderingContext, @@ -1445,37 +1472,41 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, nsFramePaintLayer aWhichLayer, PRUint32 aFlags) { - // table paint code is concerned primarily with borders and bg color if (NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) { const nsStyleVisibility* vis = (const nsStyleVisibility*)mStyleContext->GetStyleData(eStyleStruct_Visibility); - if (vis->IsVisibleOrCollapsed()) { + if (vis && vis->IsVisibleOrCollapsed()) { const nsStyleBorder* border = (const nsStyleBorder*)mStyleContext->GetStyleData(eStyleStruct_Border); - nsRect rect(0, 0, mRect.width, mRect.height); nsCSSRendering::PaintBackground(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, 0, 0, PR_TRUE); - // paint the column groups and columns - nsIFrame* colGroupFrame = mColGroups.FirstChild(); - while (nsnull != colGroupFrame) { - PaintChild(aPresContext, aRenderingContext, aDirtyRect, colGroupFrame, aWhichLayer); - colGroupFrame->GetNextSibling(&colGroupFrame); - } - - PRIntn skipSides = GetSkipSides(); - if (IsBorderCollapse()) { - PaintBCBorders(aPresContext, aRenderingContext, aDirtyRect); - } - else { + // paint the border here only for separate borders + if (!IsBorderCollapse()) { + PRIntn skipSides = GetSkipSides(); nsCSSRendering::PaintBorder(aPresContext, aRenderingContext, this, aDirtyRect, rect, *border, mStyleContext, skipSides); } } } + // for collapsed borders paint the backgrounds of cells, but not their contents (that happens below) + PRUint32 flags = aFlags; + if ((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && IsBorderCollapse()) { + flags &= ~BORDER_COLLAPSE_BACKGROUNDS; // set bit to 0 + } + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, flags); + + if ((NS_FRAME_PAINT_LAYER_BACKGROUND == aWhichLayer) && IsBorderCollapse()) { + // for collapsed borders, paint the borders and then the backgrounds of cell + // contents but not the backgrounds of the cells + PaintBCBorders(aPresContext, aRenderingContext, aDirtyRect); + flags |= BORDER_COLLAPSE_BACKGROUNDS; // set bit to 1 + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, flags); + } + #ifdef DEBUG // for debug... if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { @@ -1483,22 +1514,7 @@ nsTableFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.DrawRect(0, 0, mRect.width, mRect.height); } #endif - const nsStyleDisplay* disp = (const nsStyleDisplay*) - mStyleContext->GetStyleData(eStyleStruct_Display); - // If overflow is hidden then set the clip rect so that children don't - // leak out of us. Note that because overflow'-clip' only applies to - // the content area we do this after painting the border and background - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - aRenderingContext.PushState(); - SetOverflowClipRect(aRenderingContext); - } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); - - if (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow) { - PRBool clipState; - aRenderingContext.PopState(clipState); - } DO_GLOBAL_REFLOW_COUNT_DSP_J("nsTableFrame", &aRenderingContext, NS_RGB(255,128,255)); return NS_OK; /*nsFrame::Paint(aPresContext, diff --git a/mozilla/layout/tables/nsTableFrame.h b/mozilla/layout/tables/nsTableFrame.h index 7dc64be49b4..5087b4bbf7b 100644 --- a/mozilla/layout/tables/nsTableFrame.h +++ b/mozilla/layout/tables/nsTableFrame.h @@ -61,6 +61,10 @@ struct nsStylePosition; enum nsPixelRound {eAlwaysRoundUp=0, eAlwaysRoundDown, eRoundUpIfHalfOrMore}; +// flags for Paint, PaintChild, PaintChildren are currently only used by tables. +// use low order bit of flags to distinguish between pass1(0) and pass2(1) border collapse backgrounds +#define BORDER_COLLAPSE_BACKGROUNDS 0x00000001 + #ifdef DEBUG_TABLE_REFLOW_TIMING #ifdef WIN32 #include @@ -304,6 +308,12 @@ public: nsFramePaintLayer aWhichLayer, PRUint32 aFlags = 0); + virtual void PaintChildren(nsIPresContext* aPresContext, + nsIRenderingContext& aRenderingContext, + const nsRect& aDirtyRect, + nsFramePaintLayer aWhichLayer, + PRUint32 aFlags = 0); + nsMargin* GetBCBorder(nsIPresContext& aPresContext, PRBool aInnerBorderOnly, nsMargin& aBorder) const; diff --git a/mozilla/layout/tables/nsTableRowFrame.cpp b/mozilla/layout/tables/nsTableRowFrame.cpp index e9fd8b52757..8c3a2f35e7a 100644 --- a/mozilla/layout/tables/nsTableRowFrame.cpp +++ b/mozilla/layout/tables/nsTableRowFrame.cpp @@ -600,7 +600,7 @@ NS_METHOD nsTableRowFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PushState(); SetOverflowClipRect(aRenderingContext); } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (disp && (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow)) { PRBool clipState; aRenderingContext.PopState(clipState); @@ -650,7 +650,7 @@ void nsTableRowFrame::PaintChildren(nsIPresContext* aPresContext, aRenderingContext.PushState(); aRenderingContext.Translate(kidRect.x, kidRect.y); kid->Paint(aPresContext, aRenderingContext, kidDamageArea, - aWhichLayer); + aWhichLayer, aFlags); #ifdef DEBUG if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) { diff --git a/mozilla/layout/tables/nsTableRowFrame.h b/mozilla/layout/tables/nsTableRowFrame.h index d05dc5eab6a..36a92ee5979 100644 --- a/mozilla/layout/tables/nsTableRowFrame.h +++ b/mozilla/layout/tables/nsTableRowFrame.h @@ -51,8 +51,6 @@ class nsReflowTimer; #define NS_ROW_NEED_SPECIAL_REFLOW 0x20000000 #define NS_TABLE_ROW_HAS_UNPAGINATED_HEIGHT 0x40000000 -#define NS_ROW_FRAME_PAINT_SKIP_ROW 0x00000001 -#define NS_ROW_FRAME_PAINT_SKIP_CELLS 0x00000002 /** * nsTableRowFrame is the frame that maps table rows * (HTML tag TR). This class cannot be reused diff --git a/mozilla/layout/tables/nsTableRowGroupFrame.cpp b/mozilla/layout/tables/nsTableRowGroupFrame.cpp index 3271ec020a9..06d1690273e 100644 --- a/mozilla/layout/tables/nsTableRowGroupFrame.cpp +++ b/mozilla/layout/tables/nsTableRowGroupFrame.cpp @@ -235,7 +235,7 @@ NS_METHOD nsTableRowGroupFrame::Paint(nsIPresContext* aPresContext, aRenderingContext.PushState(); SetOverflowClipRect(aRenderingContext); } - PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); + PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer, aFlags); if (disp && (NS_STYLE_OVERFLOW_HIDDEN == disp->mOverflow)) { PRBool clipState; aRenderingContext.PopState(clipState); @@ -284,7 +284,7 @@ void nsTableRowGroupFrame::PaintChildren(nsIPresContext* aPresContext, damageArea.width, damageArea.height); aRenderingContext.PushState(); aRenderingContext.Translate(kidRect.x, kidRect.y); - kid->Paint(aPresContext, aRenderingContext, kidDamageArea, aWhichLayer); + kid->Paint(aPresContext, aRenderingContext, kidDamageArea, aWhichLayer, aFlags); #ifdef DEBUG if ((NS_FRAME_PAINT_LAYER_DEBUG == aWhichLayer) && GetShowFrameBorders()) {