Issue #146 - Part 3: Create nsDisplayTableBackgroundImage to avoid

display list collisions when processing the background image of a table.
This commit is contained in:
wolfbeast 2019-11-03 17:25:37 +01:00 committed by Roy Tam
commit a96ec7b886
2 changed files with 75 additions and 7 deletions

View file

@ -2751,9 +2751,19 @@ nsDisplayBackgroundImage::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuil
}
nsDisplayList thisItemList;
nsDisplayBackgroundImage* bgItem =
new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgOriginRect, bg);
nsDisplayBackgroundImage* bgItem;
if (aSecondaryReferenceFrame) {
bgItem =
new (aBuilder) nsDisplayTableBackgroundImage(aBuilder,
aFrame,
i,
bgOriginRect,
bg,
aSecondaryReferenceFrame);
} else {
bgItem =
new (aBuilder) nsDisplayBackgroundImage(aBuilder, aFrame, i, bgOriginRect, bg);
}
if (bgItem->ShouldFixToViewport(aBuilder)) {
if (aSecondaryReferenceFrame) {
thisItemList.AppendNewToTop(
@ -2906,7 +2916,7 @@ nsDisplayBackgroundImage::ImageLayerization
nsDisplayBackgroundImage::ShouldCreateOwnLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager)
{
nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(mFrame);
nsIFrame* backgroundStyleFrame = nsCSSRendering::FindBackgroundStyleFrame(StyleFrame());
if (ActiveLayerTracker::IsBackgroundPositionAnimated(aBuilder,
backgroundStyleFrame)) {
return WHENEVER_POSSIBLE;
@ -3161,16 +3171,16 @@ nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
StyleGeometryBox clip = mBackgroundStyle->mImage.mLayers[mLayer].mClip;
if (clip == StyleGeometryBox::Text) {
if (!GenerateAndPushTextMask(mFrame, aCtx, mBackgroundRect, aBuilder)) {
if (!GenerateAndPushTextMask(StyleFrame(), aCtx, mBackgroundRect, aBuilder)) {
return;
}
}
nsCSSRendering::PaintBGParams params =
nsCSSRendering::PaintBGParams::ForSingleLayer(*mFrame->PresContext(),
nsCSSRendering::PaintBGParams::ForSingleLayer(*StyleFrame()->PresContext(),
*aCtx,
aBounds, mBackgroundRect,
mFrame, flags, mLayer,
StyleFrame(), flags, mLayer,
CompositionOp::OP_OVER);
params.bgClipRect = aClipRect;
image::DrawResult result =
@ -3272,6 +3282,27 @@ nsDisplayBackgroundImage::GetPerFrameKey()
nsDisplayItem::GetPerFrameKey();
}
nsDisplayTableBackgroundImage::nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
uint32_t aLayer,
const nsRect& aBackgroundRect,
const nsStyleBackground* aBackgroundStyle,
nsIFrame* aCellFrame)
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aBackgroundRect, aBackgroundStyle)
, mStyleFrame(aFrame)
, mTableType(GetTableTypeFromFrame(mStyleFrame))
{
mFrame = aCellFrame;
}
bool
nsDisplayTableBackgroundImage::IsInvalid(nsRect& aRect)
{
bool result = mStyleFrame ? mStyleFrame->IsInvalid(aRect) : false;
aRect += ToReferenceFrame();
return result;
}
nsDisplayThemedBackground::nsDisplayThemedBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
const nsRect& aBackgroundRect)

View file

@ -2814,6 +2814,8 @@ protected:
void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
const nsRect& aBounds, nsRect* aClipRect);
virtual nsIFrame* StyleFrame() { return mFrame; }
// Determine whether we want to be separated into our own layer, independent
// of whether this item can actually be layerized.
enum ImageLayerization {
@ -2859,6 +2861,41 @@ static_assert(
"TableType cannot fit with TableTypeBits::COUNT");
TableType GetTableTypeFromFrame(nsIFrame* aFrame);
/**
* A display item to paint background image for table. For table parts, such
* as row, row group, col, col group, when drawing its background, we'll
* create separate background image display item for its containning cell.
* Those background image display items will reference to same DisplayItemData
* if we keep the mFrame point to cell's ancestor frame. We don't want to this
* happened bacause share same DisplatItemData will cause many bugs. So that
* we let mFrame point to cell frame and store the table type of the ancestor
* frame. And use mFrame and table type as key to generate DisplayItemData to
* avoid sharing DisplayItemData.
*
* Also store ancestor frame as mStyleFrame for all rendering informations.
*/
class nsDisplayTableBackgroundImage : public nsDisplayBackgroundImage {
public:
nsDisplayTableBackgroundImage(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame,
uint32_t aLayer,
const nsRect& aBackgroundRect,
const nsStyleBackground* aBackgroundStyle,
nsIFrame* aCellFrame);
virtual uint32_t GetPerFrameKey() override {
return (static_cast<uint8_t>(mTableType) << nsDisplayItem::TYPE_BITS) |
nsDisplayItem::GetPerFrameKey();
}
virtual bool IsInvalid(nsRect& aRect) override;
protected:
virtual nsIFrame* StyleFrame() override { return mStyleFrame; }
nsIFrame* mStyleFrame;
TableType mTableType;
};
/**
* A display item to paint the native theme background for a frame.
*/