diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-03 17:25:37 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-11-03 17:25:37 +0100 |
commit | ee663e2930650d181be1f7792952dfc32baf0bf0 (patch) | |
tree | abdd19afea50c19264680e566dcb6ef46810fcdf | |
parent | db98e3efff6087b690805358e6f4fda118ec9627 (diff) | |
download | UXP-ee663e2930650d181be1f7792952dfc32baf0bf0.tar UXP-ee663e2930650d181be1f7792952dfc32baf0bf0.tar.gz UXP-ee663e2930650d181be1f7792952dfc32baf0bf0.tar.lz UXP-ee663e2930650d181be1f7792952dfc32baf0bf0.tar.xz UXP-ee663e2930650d181be1f7792952dfc32baf0bf0.zip |
Issue #146 - Part 3: Create nsDisplayTableBackgroundImage to avoid
display list collisions when processing the background image of a table.
-rw-r--r-- | layout/base/nsDisplayList.cpp | 45 | ||||
-rw-r--r-- | layout/base/nsDisplayList.h | 37 |
2 files changed, 75 insertions, 7 deletions
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index 6b792a779..1579e6970 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -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) diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index 69d13ded9..e9047b113 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -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 { @@ -2860,6 +2862,41 @@ static_assert( 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. */ class nsDisplayThemedBackground : public nsDisplayItem { |