Bug 1082249. Invalidate background-attachment:fixed table-part backgrounds when scrolled. r=mattwoodrow

This commit is contained in:
Robert O'Callahan 2015-03-05 00:02:14 +13:00
parent 3f3f8fa14e
commit e92d7a866c
10 changed files with 135 additions and 116 deletions

View File

@ -121,3 +121,11 @@ nsCharClipGeometry::nsCharClipGeometry(nsCharClipDisplayItem* aItem, nsDisplayLi
, mLeftEdge(aItem->mLeftEdge)
, mRightEdge(aItem->mRightEdge)
{}
nsDisplayTableItemGeometry::nsDisplayTableItemGeometry(nsDisplayTableItem* aItem,
nsDisplayListBuilder* aBuilder,
const nsPoint& aFrameOffsetToViewport)
: nsDisplayItemGenericGeometry(aItem, aBuilder)
, nsImageGeometryMixin(aItem, aBuilder)
, mFrameOffsetToViewport(aFrameOffsetToViewport)
{}

View File

@ -13,12 +13,13 @@
#include "nsColor.h"
#include "gfxRect.h"
class nsDisplayBackgroundImage;
class nsCharClipDisplayItem;
class nsDisplayItem;
class nsDisplayListBuilder;
class nsDisplayBackgroundImage;
class nsDisplayThemedBackground;
class nsDisplaySVGEffects;
class nsDisplayTableItem;
class nsDisplayThemedBackground;
/**
* This stores the geometry of an nsDisplayItem, and the area
@ -257,4 +258,16 @@ public:
nscoord mRightEdge;
};
class nsDisplayTableItemGeometry
: public nsDisplayItemGenericGeometry
, public nsImageGeometryMixin<nsDisplayTableItemGeometry>
{
public:
nsDisplayTableItemGeometry(nsDisplayTableItem* aItem,
nsDisplayListBuilder* aBuilder,
const nsPoint& aFrameOffsetToViewport);
nsPoint mFrameOffsetToViewport;
};
#endif /*NSDISPLAYLISTINVALIDATION_H_*/

View File

@ -595,6 +595,9 @@ FRAME_STATE_BIT(TableRowGroup, 30, NS_ROWGROUP_HAS_STYLE_HEIGHT)
// thead or tfoot should be repeated on every printed page
FRAME_STATE_BIT(TableRowGroup, 31, NS_ROWGROUP_REPEATABLE)
FRAME_STATE_GROUP(Table, nsTableFrame)
FRAME_STATE_BIT(Table, 28, NS_TABLE_PART_HAS_FIXED_BACKGROUND)
#ifdef DEFINED_FRAME_STATE_GROUP
#undef DEFINED_FRAME_STATE_GROUP

View File

@ -0,0 +1,48 @@
<!-- This needs to be quirks mode -->
<html>
<style>
table { display:inline-table; caption-side:bottom; border-collapse:collapse; border:2px solid black; }
td { width:100px; height:100px; }
</style>
<body style="height:2000px; overflow:hidden" class="scrollTop">
<script src="scrolling.js"></script>
<p><table style="background:url(repeatable-diagonal-gradient.png) fixed;">
<td>&nbsp;
</table>
<table>
<tbody style="background:url(repeatable-diagonal-gradient.png) fixed;"><td>&nbsp;
</table>
<table>
<tr style="background:url(repeatable-diagonal-gradient.png) fixed;"><td>&nbsp;
</table>
<table>
<td style="background:url(repeatable-diagonal-gradient.png) fixed;">&nbsp;
</table>
<p><table>
<colgroup style="background:url(repeatable-diagonal-gradient.png) fixed;"></colgroup>
<td>&nbsp;
</table>
<table>
<col style="background:url(repeatable-diagonal-gradient.png) fixed;"></col>
<td>&nbsp;
</table>
<table>
<td>&nbsp;
<caption style="background:url(repeatable-diagonal-gradient.png) fixed;">&nbsp;</caption>
</table>
<p><table>
<tbody style="opacity:0.5; background:url(repeatable-diagonal-gradient.png) fixed;"><td>&nbsp;
</table>
<table>
<tr style="opacity:0.5; background:url(repeatable-diagonal-gradient.png) fixed;"><td>&nbsp;
</table>
<table>
<td style="opacity:0.5; background:url(repeatable-diagonal-gradient.png) fixed;">&nbsp;
</table>
<p><table>
<td>&nbsp;
<caption style="opacity:0.5; background:url(repeatable-diagonal-gradient.png) fixed;">&nbsp;</caption>
</table>
</body>
</html>

View File

@ -1,6 +1,7 @@
skip-if(B2G&&browserIsRemote) HTTP == deferred-anchor.xhtml#d deferred-anchor-ref.xhtml#d
== deferred-anchor2.xhtml deferred-anchor-ref.xhtml#d
HTTP == fixed-1.html fixed-1.html?ref
HTTP == fixed-table-1.html fixed-table-1.html?ref
HTTP == fixed-opacity-1.html fixed-opacity-1.html?ref
skip-if(B2G) HTTP == fixed-opacity-2.html fixed-opacity-2.html?ref
skip-if(B2G) random-if(gtk2Widget) fuzzy-if(Android,3,60) HTTP == fixed-text-1.html fixed-text-1.html?ref

View File

@ -428,11 +428,6 @@ public:
nsRenderingContext* aCtx) MOZ_OVERRIDE;
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap) MOZ_OVERRIDE;
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("TableCellBackground", TYPE_TABLE_CELL_BACKGROUND)
};
@ -443,7 +438,7 @@ void nsDisplayTableCellBackground::Paint(nsDisplayListBuilder* aBuilder,
PaintBackground(*aCtx, mVisibleRect, ToReferenceFrame(),
aBuilder->GetBackgroundPaintFlags());
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
}
nsRect
@ -455,29 +450,6 @@ nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder,
return nsDisplayItem::GetBounds(aBuilder, aSnap);
}
nsDisplayItemGeometry*
nsDisplayTableCellBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayTableCellBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayTableItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void nsTableCellFrame::InvalidateFrame(uint32_t aDisplayItemKey)
{
nsIFrame::InvalidateFrame(aDisplayItemKey);

View File

@ -1083,7 +1083,7 @@ nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
/* static */ void
void
nsDisplayTableItem::UpdateForFrameBackground(nsIFrame* aFrame)
{
nsStyleContext *bgSC;
@ -1095,6 +1095,39 @@ nsDisplayTableItem::UpdateForFrameBackground(nsIFrame* aFrame)
mPartHasFixedBackground = true;
}
nsDisplayItemGeometry*
nsDisplayTableItem::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayTableItemGeometry(this, aBuilder,
mFrame->GetOffsetTo(mFrame->PresContext()->PresShell()->GetRootFrame()));
}
void
nsDisplayTableItem::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayTableItemGeometry*>(aGeometry);
bool invalidateForAttachmentFixed = false;
if (mPartHasFixedBackground) {
nsPoint frameOffsetToViewport = mFrame->GetOffsetTo(
mFrame->PresContext()->PresShell()->GetRootFrame());
invalidateForAttachmentFixed =
frameOffsetToViewport != geometry->mFrameOffsetToViewport;
}
if (invalidateForAttachmentFixed ||
(aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages())) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
class nsDisplayTableBorderBackground : public nsDisplayTableItem {
public:
nsDisplayTableBorderBackground(nsDisplayListBuilder* aBuilder,
@ -1108,10 +1141,6 @@ public:
}
#endif
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("TableBorderBackground", TYPE_TABLE_BORDER_BACKGROUND)
@ -1131,29 +1160,6 @@ IsFrameAllowedInTable(nsIAtom* aType)
}
#endif
nsDisplayItemGeometry*
nsDisplayTableBorderBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayTableBorderBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayTableItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void
nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
@ -1163,7 +1169,7 @@ nsDisplayTableBorderBackground::Paint(nsDisplayListBuilder* aBuilder,
ToReferenceFrame(),
aBuilder->GetBackgroundPaintFlags());
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
}
static int32_t GetTablePartRank(nsDisplayItem* aItem)
@ -1286,6 +1292,19 @@ AnyTablePartHasBorderOrBackground(nsIFrame* aStart, nsIFrame* aEnd)
return false;
}
static void
UpdateItemForColGroupBackgrounds(nsDisplayTableItem* item,
const nsFrameList& aFrames) {
for (nsFrameList::Enumerator e(aFrames); !e.AtEnd(); e.Next()) {
nsTableColGroupFrame* cg = static_cast<nsTableColGroupFrame*>(e.get());
item->UpdateForFrameBackground(cg);
for (nsTableColFrame* colFrame = cg->GetFirstColumn(); colFrame;
colFrame = colFrame->GetNextCol()) {
item->UpdateForFrameBackground(colFrame);
}
}
}
// table paint code is concerned primarily with borders and bg color
// SEC: TODO: adjust the rect for captions
void
@ -1320,6 +1339,9 @@ nsTableFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item);
if (item) {
UpdateItemForColGroupBackgrounds(item, mColGroups);
}
}
nsMargin

View File

@ -57,6 +57,11 @@ public:
// cells extending outside them.
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE;
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
void UpdateForFrameBackground(nsIFrame* aFrame);
private:
@ -110,6 +115,7 @@ class nsTableFrame : public nsContainerFrame
typedef mozilla::image::DrawResult DrawResult;
public:
NS_DECL_QUERYFRAME_TARGET(nsTableFrame)
NS_DECL_FRAMEARENA_HELPERS
NS_DECLARE_FRAME_PROPERTY(PositionedTablePartArray,

View File

@ -535,38 +535,11 @@ public:
}
#endif
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("TableRowBackground", TYPE_TABLE_ROW_BACKGROUND)
};
nsDisplayItemGeometry*
nsDisplayTableRowBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayTableRowBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayTableItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void
nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
@ -581,7 +554,7 @@ nsDisplayTableRowBackground::Paint(nsDisplayListBuilder* aBuilder,
DrawResult result =
painter.PaintRow(static_cast<nsTableRowFrame*>(mFrame));
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
}
void

View File

@ -147,39 +147,12 @@ public:
}
#endif
virtual nsDisplayItemGeometry* AllocateGeometry(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE;
virtual void ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion) MOZ_OVERRIDE;
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx) MOZ_OVERRIDE;
NS_DISPLAY_DECL_NAME("TableRowGroupBackground", TYPE_TABLE_ROW_GROUP_BACKGROUND)
};
nsDisplayItemGeometry*
nsDisplayTableRowGroupBackground::AllocateGeometry(nsDisplayListBuilder* aBuilder)
{
return new nsDisplayItemGenericImageGeometry(this, aBuilder);
}
void
nsDisplayTableRowGroupBackground::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
const nsDisplayItemGeometry* aGeometry,
nsRegion *aInvalidRegion)
{
auto geometry =
static_cast<const nsDisplayItemGenericImageGeometry*>(aGeometry);
if (aBuilder->ShouldSyncDecodeImages() &&
geometry->ShouldInvalidateToSyncDecodeImages()) {
bool snap;
aInvalidRegion->Or(*aInvalidRegion, GetBounds(aBuilder, &snap));
}
nsDisplayTableItem::ComputeInvalidationRegion(aBuilder, aGeometry, aInvalidRegion);
}
void
nsDisplayTableRowGroupBackground::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
@ -194,7 +167,7 @@ nsDisplayTableRowGroupBackground::Paint(nsDisplayListBuilder* aBuilder,
DrawResult result =
painter.PaintRowGroup(static_cast<nsTableRowGroupFrame*>(mFrame));
nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result);
nsDisplayTableItemGeometry::UpdateDrawResult(this, result);
}
// Handle the child-traversal part of DisplayGenericTablePart