Bug 530686. Only create an nsDisplayTableBorderBackground when it's going to have something to paint, since having one can disable some scrolling optimizations. r=dbaron

This commit is contained in:
Robert O'Callahan 2009-12-12 10:50:30 -08:00
Родитель 3d48c9aac2
Коммит 5c87a2d633
6 изменённых файлов: 45 добавлений и 23 удалений

Просмотреть файл

@ -121,6 +121,13 @@ iframe {
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<div id="testTableNoBackground" class="testcase">
<table style="position:fixed; width:200px; height:200px;">
<tr><td></td></tr>
</table>
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
</div>
<script>
var testcases = document.querySelectorAll("div.testcase");
var tests = [];
@ -295,6 +302,13 @@ function testHiddenTable(blitRegion, paintRegion) {
"Should repaint area that was scrolled into view: " + paintRegion.toString());
}
function testTableNoBackground(blitRegion, paintRegion) {
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
"Should blit everything that was already visible: " + blitRegion.toString());
ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
"Should repaint area that was scrolled into view: " + paintRegion.toString());
}
function clientRectToRect(cr)
{
return [cr.left, cr.top, cr.right, cr.bottom];

Просмотреть файл

@ -927,15 +927,6 @@ nsIFrame::DisplayCaret(nsDisplayListBuilder* aBuilder,
new (aBuilder) nsDisplayCaret(this, aBuilder->GetCaret()));
}
PRBool
nsFrame::HasBorder() const
{
// Border images contribute to the background of the content area
// even if there's no border proper.
return (GetUsedBorder() != nsMargin(0,0,0,0) ||
GetStyleBorder()->IsBorderImageLoaded());
}
nsresult
nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
const nsDisplayListSet& aLists,

Просмотреть файл

@ -540,11 +540,6 @@ protected:
nsFrame(nsStyleContext* aContext);
virtual ~nsFrame();
/**
* @return PR_FALSE if this frame definitely has no borders at all
*/
PRBool HasBorder() const;
/**
* To be called by |BuildDisplayLists| of this class or derived classes to add
* a translucent overlay if this frame's content is selected.

Просмотреть файл

@ -725,6 +725,17 @@ public:
// -moz-appearance and is not chrome
nsCSSShadowArray* GetEffectiveBoxShadows();
/**
* @return PR_FALSE if this frame definitely has no borders at all
*/
PRBool HasBorder() const
{
// Border images contribute to the background of the content area
// even if there's no border proper.
return (GetUsedBorder() != nsMargin(0,0,0,0) ||
GetStyleBorder()->IsBorderImageLoaded());
}
/**
* Accessor functions for geometric parent
*/

Просмотреть файл

@ -448,8 +448,9 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
PRBool isRoot = aBuilder->IsAtRootOfPseudoStackingContext();
if (!isRoot) {
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
NS_ASSERTION(currentItem, "No current table item???");
currentItem->UpdateForFrameBackground(this);
if (currentItem) {
currentItem->UpdateForFrameBackground(this);
}
}
// display outset box-shadows if we need to.

Просмотреть файл

@ -1269,9 +1269,12 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
if (aFrame->IsVisibleForPainting(aBuilder)) {
nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
NS_ASSERTION(currentItem, "No current table item!");
currentItem->UpdateForFrameBackground(aFrame);
// currentItem may be null, when none of the table parts have a
// background or border
if (currentItem) {
currentItem->UpdateForFrameBackground(aFrame);
}
// Paint the outset box-shadows for the table frames
PRBool hasBoxShadow = aFrame->GetStyleBorder()->mBoxShadow != nsnull;
if (hasBoxShadow) {
@ -1326,19 +1329,26 @@ IsFrameAllowedInTable(nsIAtom* aType)
#endif
static PRBool
AnyTablePartVisible(nsIFrame* aFrame)
AnyTablePartHasBorderOrBackground(nsIFrame* aFrame)
{
NS_ASSERTION(IsFrameAllowedInTable(aFrame->GetType()), "unexpected frame type");
if (aFrame->GetStyleVisibility()->IsVisible())
if (aFrame->GetStyleVisibility()->IsVisible() &&
(!aFrame->GetStyleBackground()->IsTransparent() ||
aFrame->GetStyleDisplay()->mAppearance ||
aFrame->HasBorder()))
return PR_TRUE;
nsTableCellFrame *cellFrame = do_QueryFrame(aFrame);
if (cellFrame)
return PR_FALSE;
nsFrameList children = aFrame->GetChildList(nsnull);
for (nsIFrame* f = children.FirstChild(); f; f = f->GetNextSibling()) {
if (AnyTablePartVisible(f))
if (AnyTablePartHasBorderOrBackground(f))
return PR_TRUE;
}
return PR_FALSE;
}
@ -1369,7 +1379,7 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// This background is created if any of the table parts are visible.
// Specific visibility decisions are delegated to the table background
// painter, which handles borders and backgrounds for the table.
if (AnyTablePartVisible(this)) {
if (AnyTablePartHasBorderOrBackground(this)) {
item = new (aBuilder) nsDisplayTableBorderBackground(this);
nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
NS_ENSURE_SUCCESS(rv, rv);