mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 786502 - Separate background layers into separate items. r=roc
Separate out background layers into separate display-list items, so that backgrounds that are a mix of fixed and non-fixed layers will be treated individually.
This commit is contained in:
parent
959da9d526
commit
bb16d413e7
@ -1482,7 +1482,8 @@ nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
|
|||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsRect* aBGClipRect)
|
nsRect* aBGClipRect,
|
||||||
|
int32_t aLayer)
|
||||||
{
|
{
|
||||||
SAMPLE_LABEL("nsCSSRendering", "PaintBackground");
|
SAMPLE_LABEL("nsCSSRendering", "PaintBackground");
|
||||||
NS_PRECONDITION(aForFrame,
|
NS_PRECONDITION(aForFrame,
|
||||||
@ -1510,7 +1511,7 @@ nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
|
|||||||
PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
|
PaintBackgroundWithSC(aPresContext, aRenderingContext, aForFrame,
|
||||||
aDirtyRect, aBorderArea, sc,
|
aDirtyRect, aBorderArea, sc,
|
||||||
*aForFrame->GetStyleBorder(), aFlags,
|
*aForFrame->GetStyleBorder(), aFlags,
|
||||||
aBGClipRect);
|
aBGClipRect, aLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -2328,7 +2329,8 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||||||
nsStyleContext* aBackgroundSC,
|
nsStyleContext* aBackgroundSC,
|
||||||
const nsStyleBorder& aBorder,
|
const nsStyleBorder& aBorder,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsRect* aBGClipRect)
|
nsRect* aBGClipRect,
|
||||||
|
int32_t aLayer)
|
||||||
{
|
{
|
||||||
NS_PRECONDITION(aForFrame,
|
NS_PRECONDITION(aForFrame,
|
||||||
"Frame is expected to be provided to PaintBackground");
|
"Frame is expected to be provided to PaintBackground");
|
||||||
@ -2372,6 +2374,13 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||||||
drawBackgroundImage,
|
drawBackgroundImage,
|
||||||
drawBackgroundColor);
|
drawBackgroundColor);
|
||||||
|
|
||||||
|
// If we're not drawing the back-most layer, we don't want to draw the
|
||||||
|
// background color.
|
||||||
|
const nsStyleBackground *bg = aBackgroundSC->GetStyleBackground();
|
||||||
|
if (drawBackgroundColor && aLayer >= 0 && aLayer != bg->mImageCount - 1) {
|
||||||
|
drawBackgroundColor = false;
|
||||||
|
}
|
||||||
|
|
||||||
// At this point, drawBackgroundImage and drawBackgroundColor are
|
// At this point, drawBackgroundImage and drawBackgroundColor are
|
||||||
// true if and only if we are actually supposed to paint an image or
|
// true if and only if we are actually supposed to paint an image or
|
||||||
// color into aDirtyRect, respectively.
|
// color into aDirtyRect, respectively.
|
||||||
@ -2406,7 +2415,6 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||||||
// SetupCurrentBackgroundClip. (Arguably it should be the
|
// SetupCurrentBackgroundClip. (Arguably it should be the
|
||||||
// intersection, but that breaks the table painter -- in particular,
|
// intersection, but that breaks the table painter -- in particular,
|
||||||
// taking the intersection breaks reftests/bugs/403249-1[ab].)
|
// taking the intersection breaks reftests/bugs/403249-1[ab].)
|
||||||
const nsStyleBackground *bg = aBackgroundSC->GetStyleBackground();
|
|
||||||
BackgroundClipState clipState;
|
BackgroundClipState clipState;
|
||||||
uint8_t currentBackgroundClip;
|
uint8_t currentBackgroundClip;
|
||||||
bool isSolidBorder;
|
bool isSolidBorder;
|
||||||
@ -2456,13 +2464,27 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bg->mImageCount < 1) {
|
||||||
|
// Return if there are no background layers, all work from this point
|
||||||
|
// onwards happens iteratively on these.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the layer range before we start iterating.
|
||||||
|
int32_t startLayer = aLayer;
|
||||||
|
int32_t nLayers = 1;
|
||||||
|
if (startLayer < 0) {
|
||||||
|
startLayer = (int32_t)bg->mImageCount - 1;
|
||||||
|
nLayers = bg->mImageCount;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure we get invalidated for loads of the image. We need to do
|
// Ensure we get invalidated for loads of the image. We need to do
|
||||||
// this here because this might be the only code that knows about the
|
// this here because this might be the only code that knows about the
|
||||||
// association of the style data with the frame.
|
// association of the style data with the frame.
|
||||||
if (aBackgroundSC != aForFrame->GetStyleContext()) {
|
if (aBackgroundSC != aForFrame->GetStyleContext()) {
|
||||||
ImageLoader* loader = aPresContext->Document()->StyleImageLoader();
|
ImageLoader* loader = aPresContext->Document()->StyleImageLoader();
|
||||||
|
|
||||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, bg, startLayer, nLayers) {
|
||||||
if (bg->mLayers[i].mImage.GetType() == eStyleImageType_Image) {
|
if (bg->mLayers[i].mImage.GetType() == eStyleImageType_Image) {
|
||||||
imgIRequest *image = bg->mLayers[i].mImage.GetImageData();
|
imgIRequest *image = bg->mLayers[i].mImage.GetImageData();
|
||||||
|
|
||||||
@ -2479,7 +2501,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||||||
|
|
||||||
if (drawBackgroundImage) {
|
if (drawBackgroundImage) {
|
||||||
bool clipSet = false;
|
bool clipSet = false;
|
||||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(i, bg, startLayer, nLayers) {
|
||||||
const nsStyleBackground::Layer &layer = bg->mLayers[i];
|
const nsStyleBackground::Layer &layer = bg->mLayers[i];
|
||||||
if (!aBGClipRect) {
|
if (!aBGClipRect) {
|
||||||
uint8_t newBackgroundClip = layer.mClip;
|
uint8_t newBackgroundClip = layer.mClip;
|
||||||
|
@ -335,12 +335,17 @@ struct nsCSSRendering {
|
|||||||
const nsRect& aDirtyRect,
|
const nsRect& aDirtyRect,
|
||||||
const nsRect& aBorderArea,
|
const nsRect& aBorderArea,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsRect* aBGClipRect = nullptr);
|
nsRect* aBGClipRect = nullptr,
|
||||||
|
int32_t aLayer = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as |PaintBackground|, except using the provided style structs.
|
* Same as |PaintBackground|, except using the provided style structs.
|
||||||
* This short-circuits the code that ensures that the root element's
|
* This short-circuits the code that ensures that the root element's
|
||||||
* background is drawn on the canvas.
|
* background is drawn on the canvas.
|
||||||
|
* The aLayer parameter allows you to paint a single layer of the background.
|
||||||
|
* The default value for aLayer, -1, means that all layers will be painted.
|
||||||
|
* The background color will only be painted if the back-most layer is also
|
||||||
|
* being painted.
|
||||||
*/
|
*/
|
||||||
static void PaintBackgroundWithSC(nsPresContext* aPresContext,
|
static void PaintBackgroundWithSC(nsPresContext* aPresContext,
|
||||||
nsRenderingContext& aRenderingContext,
|
nsRenderingContext& aRenderingContext,
|
||||||
@ -350,7 +355,8 @@ struct nsCSSRendering {
|
|||||||
nsStyleContext *aStyleContext,
|
nsStyleContext *aStyleContext,
|
||||||
const nsStyleBorder& aBorder,
|
const nsStyleBorder& aBorder,
|
||||||
uint32_t aFlags,
|
uint32_t aFlags,
|
||||||
nsRect* aBGClipRect = nullptr);
|
nsRect* aBGClipRect = nullptr,
|
||||||
|
int32_t aLayer = -1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the rectangle covered by the given background layer image, taking
|
* Returns the rectangle covered by the given background layer image, taking
|
||||||
|
@ -1362,8 +1362,11 @@ RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
|
nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
|
||||||
nsIFrame* aFrame)
|
nsIFrame* aFrame,
|
||||||
|
uint32_t aLayer)
|
||||||
: nsDisplayItem(aBuilder, aFrame)
|
: nsDisplayItem(aBuilder, aFrame)
|
||||||
|
, mIsBottommostLayer(true)
|
||||||
|
, mLayer(aLayer)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(nsDisplayBackground);
|
MOZ_COUNT_CTOR(nsDisplayBackground);
|
||||||
const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
|
const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
|
||||||
@ -1383,8 +1386,17 @@ nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
|
|||||||
nsPresContext* presContext = mFrame->PresContext();
|
nsPresContext* presContext = mFrame->PresContext();
|
||||||
nsStyleContext* bgSC;
|
nsStyleContext* bgSC;
|
||||||
bool hasBG = nsCSSRendering::FindBackground(presContext, mFrame, &bgSC);
|
bool hasBG = nsCSSRendering::FindBackground(presContext, mFrame, &bgSC);
|
||||||
if (hasBG && bgSC->GetStyleBackground()->HasFixedBackground()) {
|
if (hasBG) {
|
||||||
aBuilder->SetHasFixedItems();
|
const nsStyleBackground* bg = bgSC->GetStyleBackground();
|
||||||
|
if (mLayer != bg->mImageCount - 1) {
|
||||||
|
mIsBottommostLayer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this background layer is attachment-fixed
|
||||||
|
if (!bg->mLayers[mLayer].mImage.IsEmpty() &&
|
||||||
|
bg->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED) {
|
||||||
|
aBuilder->SetHasFixedItems();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1396,6 +1408,39 @@ nsDisplayBackground::~nsDisplayBackground()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*static*/ nsresult
|
||||||
|
nsDisplayBackground::AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
nsDisplayList* aList,
|
||||||
|
nsDisplayBackground** aBackground)
|
||||||
|
{
|
||||||
|
nsStyleContext* bgSC;
|
||||||
|
const nsStyleBackground* bg = nullptr;
|
||||||
|
nsPresContext* presContext = aFrame->PresContext();
|
||||||
|
if (!aFrame->IsThemed() &&
|
||||||
|
nsCSSRendering::FindBackground(presContext, aFrame, &bgSC)) {
|
||||||
|
bg = bgSC->GetStyleBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Passing bg == nullptr in this macro will result in one iteration with
|
||||||
|
// i = 0.
|
||||||
|
bool backgroundSet = !aBackground;
|
||||||
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
||||||
|
nsDisplayBackground* bgItem =
|
||||||
|
new (aBuilder) nsDisplayBackground(aBuilder, aFrame, i);
|
||||||
|
nsresult rv = aList->AppendNewToTop(bgItem);
|
||||||
|
if (rv != NS_OK) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
if (!backgroundSet) {
|
||||||
|
*aBackground = bgItem;
|
||||||
|
backgroundSet = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper for RoundedRectIntersectsRect.
|
// Helper for RoundedRectIntersectsRect.
|
||||||
static bool
|
static bool
|
||||||
CheckCorner(nscoord aXOffset, nscoord aYOffset,
|
CheckCorner(nscoord aXOffset, nscoord aYOffset,
|
||||||
@ -1574,16 +1619,11 @@ nsDisplayBackground::TryOptimizeToImageLayer(nsDisplayListBuilder* aBuilder)
|
|||||||
|
|
||||||
const nsStyleBackground *bg = bgSC->GetStyleBackground();
|
const nsStyleBackground *bg = bgSC->GetStyleBackground();
|
||||||
|
|
||||||
// We could pretty easily support multiple image layers, but for now we
|
|
||||||
// just punt here.
|
|
||||||
if (bg->mLayers.Length() != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
||||||
nsPoint offset = ToReferenceFrame();
|
nsPoint offset = ToReferenceFrame();
|
||||||
nsRect borderArea = nsRect(offset, mFrame->GetSize());
|
nsRect borderArea = nsRect(offset, mFrame->GetSize());
|
||||||
|
|
||||||
const nsStyleBackground::Layer &layer = bg->mLayers[0];
|
const nsStyleBackground::Layer &layer = bg->mLayers[mLayer];
|
||||||
|
|
||||||
nsBackgroundLayerState state =
|
nsBackgroundLayerState state =
|
||||||
nsCSSRendering::PrepareBackgroundLayer(presContext,
|
nsCSSRendering::PrepareBackgroundLayer(presContext,
|
||||||
@ -1784,7 +1824,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||||||
*aSnap = true;
|
*aSnap = true;
|
||||||
|
|
||||||
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||||
if (NS_GET_A(bg->mBackgroundColor) == 255 &&
|
if (mIsBottommostLayer && NS_GET_A(bg->mBackgroundColor) == 255 &&
|
||||||
!nsCSSRendering::IsCanvasFrame(mFrame)) {
|
!nsCSSRendering::IsCanvasFrame(mFrame)) {
|
||||||
result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox, aSnap);
|
result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox, aSnap);
|
||||||
}
|
}
|
||||||
@ -1796,13 +1836,11 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
|||||||
// Of course, if there's only one frame in the flow, it doesn't matter.
|
// Of course, if there's only one frame in the flow, it doesn't matter.
|
||||||
if (bg->mBackgroundInlinePolicy == NS_STYLE_BG_INLINE_POLICY_EACH_BOX ||
|
if (bg->mBackgroundInlinePolicy == NS_STYLE_BG_INLINE_POLICY_EACH_BOX ||
|
||||||
(!mFrame->GetPrevContinuation() && !mFrame->GetNextContinuation())) {
|
(!mFrame->GetPrevContinuation() && !mFrame->GetNextContinuation())) {
|
||||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
const nsStyleBackground::Layer& layer = bg->mLayers[mLayer];
|
||||||
const nsStyleBackground::Layer& layer = bg->mLayers[i];
|
if (layer.mImage.IsOpaque()) {
|
||||||
if (layer.mImage.IsOpaque()) {
|
nsRect r = nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
|
||||||
nsRect r = nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
|
borderBox, *bg, layer);
|
||||||
borderBox, *bg, layer);
|
result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r, aSnap));
|
||||||
result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r, aSnap));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1887,15 +1925,13 @@ nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
|
|||||||
if (!bg->HasFixedBackground())
|
if (!bg->HasFixedBackground())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
const nsStyleBackground::Layer& layer = bg->mLayers[mLayer];
|
||||||
const nsStyleBackground::Layer& layer = bg->mLayers[i];
|
if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED &&
|
||||||
if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED &&
|
!layer.mImage.IsEmpty()) {
|
||||||
!layer.mImage.IsEmpty()) {
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (layer.mClip != NS_STYLE_BG_CLIP_BORDER)
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
if (layer.mClip != NS_STYLE_BG_CLIP_BORDER)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
|
if (nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
|
||||||
return false;
|
return false;
|
||||||
@ -1925,7 +1961,7 @@ nsDisplayBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
|
nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
|
||||||
mVisibleRect,
|
mVisibleRect,
|
||||||
nsRect(offset, mFrame->GetSize()),
|
nsRect(offset, mFrame->GetSize()),
|
||||||
flags);
|
flags, nullptr, mLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
@ -1943,6 +1979,13 @@ nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
|||||||
return r + ToReferenceFrame();
|
return r + ToReferenceFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
nsDisplayBackground::GetPerFrameKey()
|
||||||
|
{
|
||||||
|
return (mLayer << nsDisplayItem::TYPE_BITS) |
|
||||||
|
nsDisplayItem::GetPerFrameKey();
|
||||||
|
}
|
||||||
|
|
||||||
nsRect
|
nsRect
|
||||||
nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
|
||||||
*aSnap = false;
|
*aSnap = false;
|
||||||
|
@ -1604,9 +1604,19 @@ private:
|
|||||||
*/
|
*/
|
||||||
class nsDisplayBackground : public nsDisplayItem {
|
class nsDisplayBackground : public nsDisplayItem {
|
||||||
public:
|
public:
|
||||||
nsDisplayBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame);
|
// aLayer signifies which background layer this item represents
|
||||||
|
nsDisplayBackground(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||||
|
uint32_t aLayer);
|
||||||
virtual ~nsDisplayBackground();
|
virtual ~nsDisplayBackground();
|
||||||
|
|
||||||
|
// This will create and append new items for all the layers of the
|
||||||
|
// background. If given, aBackground will be set with the address of the
|
||||||
|
// bottom-most background item.
|
||||||
|
static nsresult AppendBackgroundItemsToTop(nsDisplayListBuilder* aBuilder,
|
||||||
|
nsIFrame* aFrame,
|
||||||
|
nsDisplayList* aList,
|
||||||
|
nsDisplayBackground** aBackground = nullptr);
|
||||||
|
|
||||||
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||||
LayerManager* aManager,
|
LayerManager* aManager,
|
||||||
const ContainerParameters& aParameters);
|
const ContainerParameters& aParameters);
|
||||||
@ -1628,6 +1638,7 @@ public:
|
|||||||
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder);
|
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder);
|
||||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
|
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
|
||||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
|
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
|
||||||
|
virtual uint32_t GetPerFrameKey();
|
||||||
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
|
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
|
||||||
// Returns the value of GetUnderlyingFrame()->IsThemed(), but cached
|
// Returns the value of GetUnderlyingFrame()->IsThemed(), but cached
|
||||||
bool IsThemed() { return mIsThemed; }
|
bool IsThemed() { return mIsThemed; }
|
||||||
@ -1645,11 +1656,14 @@ protected:
|
|||||||
|
|
||||||
/* Used to cache mFrame->IsThemed() since it isn't a cheap call */
|
/* Used to cache mFrame->IsThemed() since it isn't a cheap call */
|
||||||
bool mIsThemed;
|
bool mIsThemed;
|
||||||
|
/* true if this item represents the bottom-most background layer */
|
||||||
|
bool mIsBottommostLayer;
|
||||||
nsITheme::Transparency mThemeTransparency;
|
nsITheme::Transparency mThemeTransparency;
|
||||||
|
|
||||||
/* If this background can be a simple image layer, we store the format here. */
|
/* If this background can be a simple image layer, we store the format here. */
|
||||||
nsRefPtr<ImageContainer> mImageContainer;
|
nsRefPtr<ImageContainer> mImageContainer;
|
||||||
gfxRect mDestRect;
|
gfxRect mDestRect;
|
||||||
|
uint32_t mLayer;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -202,7 +202,7 @@ nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
||||||
nsPoint offset = ToReferenceFrame();
|
nsPoint offset = ToReferenceFrame();
|
||||||
nsRect bgClipRect = frame->CanvasArea() + offset;
|
nsRect bgClipRect = frame->CanvasArea() + offset;
|
||||||
if (NS_GET_A(mExtraBackgroundColor) > 0) {
|
if (mIsBottommostLayer && NS_GET_A(mExtraBackgroundColor) > 0) {
|
||||||
aCtx->SetColor(mExtraBackgroundColor);
|
aCtx->SetColor(mExtraBackgroundColor);
|
||||||
aCtx->FillRect(bgClipRect);
|
aCtx->FillRect(bgClipRect);
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
|
|||||||
surf ? bounds : mVisibleRect,
|
surf ? bounds : mVisibleRect,
|
||||||
nsRect(offset, mFrame->GetSize()),
|
nsRect(offset, mFrame->GetSize()),
|
||||||
aBuilder->GetBackgroundPaintFlags(),
|
aBuilder->GetBackgroundPaintFlags(),
|
||||||
&bgClipRect);
|
&bgClipRect, mLayer);
|
||||||
if (surf) {
|
if (surf) {
|
||||||
BlitSurface(dest, mDestRect, surf);
|
BlitSurface(dest, mDestRect, surf);
|
||||||
|
|
||||||
@ -295,10 +295,19 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||||||
// We don't have any border or outline, and our background draws over
|
// We don't have any border or outline, and our background draws over
|
||||||
// the overflow area, so just add nsDisplayCanvasBackground instead of
|
// the overflow area, so just add nsDisplayCanvasBackground instead of
|
||||||
// calling DisplayBorderBackgroundOutline.
|
// calling DisplayBorderBackgroundOutline.
|
||||||
if (IsVisibleForPainting(aBuilder)) {
|
if (IsVisibleForPainting(aBuilder)) {
|
||||||
rv = aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
|
nsStyleContext* bgSC;
|
||||||
nsDisplayCanvasBackground(aBuilder, this));
|
const nsStyleBackground* bg = nullptr;
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
if (!IsThemed() &&
|
||||||
|
nsCSSRendering::FindBackground(PresContext(), this, &bgSC)) {
|
||||||
|
bg = bgSC->GetStyleBackground();
|
||||||
|
}
|
||||||
|
// Create separate items for each background layer.
|
||||||
|
NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(i, bg) {
|
||||||
|
rv = aLists.BorderBackground()->AppendNewToTop(
|
||||||
|
new (aBuilder) nsDisplayCanvasBackground(aBuilder, this, i));
|
||||||
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIFrame* kid;
|
nsIFrame* kid;
|
||||||
|
@ -123,8 +123,8 @@ protected:
|
|||||||
*/
|
*/
|
||||||
class nsDisplayCanvasBackground : public nsDisplayBackground {
|
class nsDisplayCanvasBackground : public nsDisplayBackground {
|
||||||
public:
|
public:
|
||||||
nsDisplayCanvasBackground(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame)
|
nsDisplayCanvasBackground(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame, uint32_t aLayer)
|
||||||
: nsDisplayBackground(aBuilder, aFrame)
|
: nsDisplayBackground(aBuilder, aFrame, aLayer)
|
||||||
{
|
{
|
||||||
mExtraBackgroundColor = NS_RGBA(0,0,0,0);
|
mExtraBackgroundColor = NS_RGBA(0,0,0,0);
|
||||||
}
|
}
|
||||||
|
@ -1457,16 +1457,18 @@ nsFrame::DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
|||||||
bool aForceBackground,
|
bool aForceBackground,
|
||||||
nsDisplayBackground** aBackground)
|
nsDisplayBackground** aBackground)
|
||||||
{
|
{
|
||||||
|
*aBackground = nullptr;
|
||||||
|
|
||||||
// Here we don't try to detect background propagation. Frames that might
|
// Here we don't try to detect background propagation. Frames that might
|
||||||
// receive a propagated background should just set aForceBackground to
|
// receive a propagated background should just set aForceBackground to
|
||||||
// true.
|
// true.
|
||||||
if (aBuilder->IsForEventDelivery() || aForceBackground ||
|
if (aBuilder->IsForEventDelivery() || aForceBackground ||
|
||||||
!GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance) {
|
!GetStyleBackground()->IsTransparent() || GetStyleDisplay()->mAppearance) {
|
||||||
nsDisplayBackground* bg = new (aBuilder) nsDisplayBackground(aBuilder, this);
|
return nsDisplayBackground::AppendBackgroundItemsToTop(aBuilder, this,
|
||||||
*aBackground = bg;
|
aLists.BorderBackground(),
|
||||||
return aLists.BorderBackground()->AppendNewToTop(bg);
|
aBackground);
|
||||||
}
|
}
|
||||||
*aBackground = nullptr;
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -498,14 +498,14 @@ public:
|
|||||||
static void ShutdownLayerActivityTimer();
|
static void ShutdownLayerActivityTimer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds display item for standard CSS background if necessary.
|
* Adds display items for standard CSS background if necessary.
|
||||||
* Does not check IsVisibleForPainting.
|
* Does not check IsVisibleForPainting.
|
||||||
* @param aForceBackground draw the background even if the frame
|
* @param aForceBackground draw the background even if the frame
|
||||||
* background style appears to have no background --- this is useful
|
* background style appears to have no background --- this is useful
|
||||||
* for frames that might receive a propagated background via
|
* for frames that might receive a propagated background via
|
||||||
* nsCSSRendering::FindBackground
|
* nsCSSRendering::FindBackground
|
||||||
* @param aBackground *aBackground is set to the new nsDisplayBackground item,
|
* @param aBackground *aBackground is set to the bottom-most
|
||||||
* if one is created, otherwise null.
|
* nsDisplayBackground item, if any are created, otherwise null.
|
||||||
*/
|
*/
|
||||||
nsresult DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
nsresult DisplayBackgroundUnconditional(nsDisplayListBuilder* aBuilder,
|
||||||
const nsDisplayListSet& aLists,
|
const nsDisplayListSet& aLists,
|
||||||
|
@ -487,7 +487,11 @@ struct nsStyleBackground {
|
|||||||
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
|
const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
|
||||||
|
|
||||||
#define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
|
#define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT(var_, stylebg_) \
|
||||||
for (uint32_t var_ = (stylebg_)->mImageCount; var_-- != 0; )
|
for (uint32_t var_ = (stylebg_) ? (stylebg_)->mImageCount : 1; var_-- != 0; )
|
||||||
|
#define NS_FOR_VISIBLE_BACKGROUND_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, stylebg_, start_, count_) \
|
||||||
|
NS_ASSERTION((start_) >= 0 && (uint32_t)(start_) < ((stylebg_) ? (stylebg_)->mImageCount : 1), "Invalid layer start!"); \
|
||||||
|
NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, "Invalid layer range!"); \
|
||||||
|
for (uint32_t var_ = (start_) + 1; var_-- != (uint32_t)((start_) + 1 - (count_)); )
|
||||||
|
|
||||||
nscolor mBackgroundColor; // [reset]
|
nscolor mBackgroundColor; // [reset]
|
||||||
|
|
||||||
|
@ -1164,8 +1164,8 @@ nsTableFrame::DisplayGenericTablePart(nsDisplayListBuilder* aBuilder,
|
|||||||
// handling events.
|
// handling events.
|
||||||
// XXX how to handle collapsed borders?
|
// XXX how to handle collapsed borders?
|
||||||
if (aBuilder->IsForEventDelivery()) {
|
if (aBuilder->IsForEventDelivery()) {
|
||||||
nsresult rv = lists->BorderBackground()->AppendNewToTop(
|
nsresult rv = nsDisplayBackground::AppendBackgroundItemsToTop(aBuilder, aFrame,
|
||||||
new (aBuilder) nsDisplayBackground(aBuilder, aFrame));
|
lists->BorderBackground());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user