Bug 505184. When 'deflation' of the background area is not required, paint table backgrounds using a dedicated nsDisplayBackground instead of the multipurpose nsDisplayTableBorderBackground. r=fantasai

This commit is contained in:
Robert O'Callahan 2009-07-22 12:44:52 +12:00
parent 53a0bb6bba
commit bec635e65d
5 changed files with 62 additions and 40 deletions

View File

@ -104,6 +104,8 @@ struct nsMargin {
right -= aMargin.right; right -= aMargin.right;
bottom -= aMargin.bottom; bottom -= aMargin.bottom;
return *this;} return *this;}
PRBool IsZero() { return !left && !top && !right && !bottom; }
}; };
struct nsIntMargin { struct nsIntMargin {
@ -138,6 +140,8 @@ struct nsIntMargin {
return nsIntMargin(left + aMargin.left, top + aMargin.top, return nsIntMargin(left + aMargin.left, top + aMargin.top,
right + aMargin.right, bottom + aMargin.bottom); right + aMargin.right, bottom + aMargin.bottom);
} }
PRBool IsZero() { return !left && !top && !right && !bottom; }
}; };
#endif /* NSMARGIN_H */ #endif /* NSMARGIN_H */

View File

@ -1409,9 +1409,21 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255)); DO_GLOBAL_REFLOW_COUNT_DSP_COLOR("nsTableFrame", NS_RGB(255,128,255));
if (GetStyleVisibility()->IsVisible()) {
nsMargin deflate = GetDeflationForBackground(PresContext());
// If 'deflate' is (0,0,0,0) then we can paint the table background
// in its own display item, so do that to take advantage of
// opacity and visibility optimizations
if (deflate.IsZero()) {
nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
}
}
// This background is created regardless of whether this frame is // This background is created regardless of whether this frame is
// visible or not. Visibility decisions are delegated to the // visible or not. Visibility decisions are delegated to the
// table background painter. // table background painter. This handles borders and backgrounds
// for the table.
nsDisplayTableItem* item = new (aBuilder) nsDisplayTableBorderBackground(this); nsDisplayTableItem* item = new (aBuilder) nsDisplayTableBorderBackground(this);
nsresult rv = aLists.BorderBackground()->AppendNewToTop(item); nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@ -1419,6 +1431,16 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
return DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item); return DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item);
} }
nsMargin
nsTableFrame::GetDeflationForBackground(nsPresContext* aPresContext) const
{
if (eCompatibility_NavQuirks != aPresContext->CompatibilityMode() ||
!IsBorderCollapse())
return nsMargin(0,0,0,0);
return GetOuterBCBorder();
}
// XXX We don't put the borders and backgrounds in tree order like we should. // XXX We don't put the borders and backgrounds in tree order like we should.
// That requires some major surgery which we aren't going to do right now. // That requires some major surgery which we aren't going to do right now.
void void
@ -1431,30 +1453,11 @@ nsTableFrame::PaintTableBorderBackground(nsIRenderingContext& aRenderingContext,
TableBackgroundPainter painter(this, TableBackgroundPainter::eOrigin_Table, TableBackgroundPainter painter(this, TableBackgroundPainter::eOrigin_Table,
presContext, aRenderingContext, presContext, aRenderingContext,
aDirtyRect, aPt); aDirtyRect, aPt);
nsresult rv; nsMargin deflate = GetDeflationForBackground(presContext);
// If 'deflate' is (0,0,0,0) then we'll paint the table background
if (eCompatibility_NavQuirks == presContext->CompatibilityMode()) { // in a separate display item, so don't do it here.
nsMargin deflate(0,0,0,0); nsresult rv = painter.PaintTable(this, deflate, !deflate.IsZero());
if (IsBorderCollapse()) { if (NS_FAILED(rv)) return;
PRInt32 p2t = nsPresContext::AppUnitsPerCSSPixel();
BCPropertyData* propData =
(BCPropertyData*)nsTableFrame::GetProperty((nsIFrame*)this,
nsGkAtoms::tableBCProperty,
PR_FALSE);
if (propData) {
deflate.top = BC_BORDER_TOP_HALF_COORD(p2t, propData->mTopBorderWidth);
deflate.right = BC_BORDER_RIGHT_HALF_COORD(p2t, propData->mRightBorderWidth);
deflate.bottom = BC_BORDER_BOTTOM_HALF_COORD(p2t, propData->mBottomBorderWidth);
deflate.left = BC_BORDER_LEFT_HALF_COORD(p2t, propData->mLeftBorderWidth);
}
}
rv = painter.PaintTable(this, &deflate);
if (NS_FAILED(rv)) return;
}
else {
rv = painter.PaintTable(this, nsnull);
if (NS_FAILED(rv)) return;
}
if (GetStyleVisibility()->IsVisible()) { if (GetStyleVisibility()->IsVisible()) {
const nsStyleBorder* border = GetStyleBorder(); const nsStyleBorder* border = GetStyleBorder();
@ -2593,6 +2596,7 @@ nsTableFrame::GetExcludedOuterBCBorder() const
{ {
return GetOuterBCBorder() - GetIncludedOuterBCBorder(); return GetOuterBCBorder() - GetIncludedOuterBCBorder();
} }
static static
void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState, void GetSeparateModelBorderPadding(const nsHTMLReflowState* aReflowState,
nsStyleContext& aStyleContext, nsStyleContext& aStyleContext,

View File

@ -298,6 +298,12 @@ public:
*/ */
nsMargin GetExcludedOuterBCBorder() const; nsMargin GetExcludedOuterBCBorder() const;
/**
* In quirks mode, the size of the table background is reduced
* by the outer BC border. Compute the reduction needed.
*/
nsMargin GetDeflationForBackground(nsPresContext* aPresContext) const;
/** Get width of table + colgroup + col collapse: elements that /** Get width of table + colgroup + col collapse: elements that
* continue along the length of the whole left side. * continue along the length of the whole left side.
* see nsTablePainter about continuous borders * see nsTablePainter about continuous borders

View File

@ -282,15 +282,13 @@ nsresult
TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame, TableBackgroundPainter::PaintTableFrame(nsTableFrame* aTableFrame,
nsTableRowGroupFrame* aFirstRowGroup, nsTableRowGroupFrame* aFirstRowGroup,
nsTableRowGroupFrame* aLastRowGroup, nsTableRowGroupFrame* aLastRowGroup,
nsMargin* aDeflate) const nsMargin& aDeflate)
{ {
NS_PRECONDITION(aTableFrame, "null frame"); NS_PRECONDITION(aTableFrame, "null frame");
TableBackgroundData tableData; TableBackgroundData tableData;
tableData.SetFull(aTableFrame); tableData.SetFull(aTableFrame);
tableData.mRect.MoveTo(0,0); //using table's coords tableData.mRect.MoveTo(0,0); //using table's coords
if (aDeflate) { tableData.mRect.Deflate(aDeflate);
tableData.mRect.Deflate(*aDeflate);
}
if (mIsBorderCollapse && tableData.ShouldSetBCBorder()) { if (mIsBorderCollapse && tableData.ShouldSetBCBorder()) {
if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) { if (aFirstRowGroup && aLastRowGroup && mNumCols > 0) {
//only handle non-degenerate tables; we need a more robust BC model //only handle non-degenerate tables; we need a more robust BC model
@ -354,8 +352,9 @@ TableBackgroundPainter::TranslateContext(nscoord aDX,
} }
nsresult nsresult
TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame, TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
nsMargin* aDeflate) const nsMargin& aDeflate,
PRBool aPaintTableBackground)
{ {
NS_PRECONDITION(aTableFrame, "null table frame"); NS_PRECONDITION(aTableFrame, "null table frame");
@ -363,13 +362,17 @@ TableBackgroundPainter::PaintTable(nsTableFrame* aTableFrame,
aTableFrame->OrderRowGroups(rowGroups); aTableFrame->OrderRowGroups(rowGroups);
if (rowGroups.Length() < 1) { //degenerate case if (rowGroups.Length() < 1) { //degenerate case
PaintTableFrame(aTableFrame, nsnull, nsnull, nsnull); if (aPaintTableBackground) {
PaintTableFrame(aTableFrame, nsnull, nsnull, nsMargin(0,0,0,0));
}
/* No cells; nothing else to paint */ /* No cells; nothing else to paint */
return NS_OK; return NS_OK;
} }
PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1], if (aPaintTableBackground) {
aDeflate); PaintTableFrame(aTableFrame, rowGroups[0], rowGroups[rowGroups.Length() - 1],
aDeflate);
}
/*Set up column background/border data*/ /*Set up column background/border data*/
if (mNumCols > 0) { if (mNumCols > 0) {

View File

@ -93,21 +93,26 @@ class TableBackgroundPainter
/* ~*~ Using nsTablePainter Background Painting ~*~ /* ~*~ Using nsTablePainter Background Painting ~*~
A call to PaintTable will normally paint all of the table's A call to PaintTable will normally paint all of the table's
elements (except the cells in non-BC). Elements with views elements (except for the table background, if aPaintTableBackground
however, will be skipped and must create their own painter is false).
to call the appropriate paint function in their ::Paint Elements with views however, will be skipped and must create their
own painter to call the appropriate paint function in their ::Paint
method (e.g. painter.PaintRow in nsTableRow::Paint) method (e.g. painter.PaintRow in nsTableRow::Paint)
*/ */
/** Paint background for the table frame and its children down through cells /** Paint background for the table frame (if requested) and its children
* down through cells.
* (Cells themselves will only be painted in border collapse) * (Cells themselves will only be painted in border collapse)
* Table must do a flagged TABLE_BG_PAINT ::Paint call on its * Table must do a flagged TABLE_BG_PAINT ::Paint call on its
* children afterwards * children afterwards
* @param aTableFrame - the table frame * @param aTableFrame - the table frame
* @param aDeflate - deflation needed to bring table's mRect * @param aDeflate - deflation needed to bring table's mRect
* to the outer grid lines in border-collapse * to the outer grid lines in border-collapse
* @param aPaintTableBackground - if true, the table background
* is included, otherwise it isn't
*/ */
nsresult PaintTable(nsTableFrame* aTableFrame, nsMargin* aDeflate); nsresult PaintTable(nsTableFrame* aTableFrame, const nsMargin& aDeflate,
PRBool aPaintTableBackground);
/** Paint background for the row group and its children down through cells /** Paint background for the row group and its children down through cells
* (Cells themselves will only be painted in border collapse) * (Cells themselves will only be painted in border collapse)
@ -143,7 +148,7 @@ class TableBackgroundPainter
nsresult PaintTableFrame(nsTableFrame* aTableFrame, nsresult PaintTableFrame(nsTableFrame* aTableFrame,
nsTableRowGroupFrame* aFirstRowGroup, nsTableRowGroupFrame* aFirstRowGroup,
nsTableRowGroupFrame* aLastRowGroup, nsTableRowGroupFrame* aLastRowGroup,
nsMargin* aDeflate = nsnull); const nsMargin& aDeflate);
/* aPassThrough params indicate whether to paint the element or to just /* aPassThrough params indicate whether to paint the element or to just
* pass through and paint underlying layers only * pass through and paint underlying layers only