mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-19 09:30:44 +00:00
Bug 820246 - Split nsDisplayCanvasBackground into separate color and image items. r=roc
This commit is contained in:
parent
b604f8c8d2
commit
012ebe70a2
@ -9,7 +9,8 @@ DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BORDER_BACKGROUND)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BUTTON_BOX_SHADOW_OUTER)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(BUTTON_FOREGROUND)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CANVAS)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_COLOR)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CANVAS_BACKGROUND_IMAGE)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CANVAS_FOCUS)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CARET)
|
||||
DECLARE_DISPLAY_ITEM_TYPE(CHECKED_CHECKBOX)
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsIViewManager.h"
|
||||
#include "ImageLayers.h"
|
||||
#include "ImageContainer.h"
|
||||
#include "nsCanvasFrame.h"
|
||||
|
||||
#include "mozilla/StandardInteger.h"
|
||||
|
||||
@ -2083,14 +2084,22 @@ static void CheckForBorderItem(nsDisplayItem *aItem, uint32_t& aFlags)
|
||||
void
|
||||
nsDisplayBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx) {
|
||||
PaintInternal(aBuilder, aCtx, mVisibleRect, nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayBackgroundImage::PaintInternal(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx, const nsRect& aBounds,
|
||||
nsRect* aClipRect) {
|
||||
nsPoint offset = ToReferenceFrame();
|
||||
uint32_t flags = aBuilder->GetBackgroundPaintFlags();
|
||||
CheckForBorderItem(this, flags);
|
||||
|
||||
nsCSSRendering::PaintBackground(mFrame->PresContext(), *aCtx, mFrame,
|
||||
mVisibleRect,
|
||||
aBounds,
|
||||
nsRect(offset, mFrame->GetSize()),
|
||||
flags, nullptr, mLayer);
|
||||
flags, aClipRect, mLayer);
|
||||
|
||||
}
|
||||
|
||||
void nsDisplayBackgroundImage::ComputeInvalidationRegion(nsDisplayListBuilder* aBuilder,
|
||||
@ -2149,6 +2158,10 @@ nsDisplayBackgroundImage::GetBoundsInternal() {
|
||||
}
|
||||
|
||||
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
|
||||
if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
|
||||
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
||||
borderBox = frame->CanvasArea() + ToReferenceFrame();
|
||||
}
|
||||
const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
|
||||
return nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
|
||||
borderBox, *mBackgroundStyle, layer);
|
||||
|
@ -1913,6 +1913,9 @@ protected:
|
||||
gfxRect* aDestRect);
|
||||
nsRect GetBoundsInternal();
|
||||
|
||||
void PaintInternal(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx,
|
||||
const nsRect& aBounds, nsRect* aClipRect);
|
||||
|
||||
// Cache the result of nsCSSRendering::FindBackground. Always null if
|
||||
// mIsThemed is true or if FindBackground returned false.
|
||||
const nsStyleBackground* mBackgroundStyle;
|
||||
|
@ -4831,8 +4831,8 @@ AddCanvasBackgroundColor(const nsDisplayList& aList, nsIFrame* aCanvasFrame,
|
||||
{
|
||||
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
||||
if (i->GetUnderlyingFrame() == aCanvasFrame &&
|
||||
i->GetType() == nsDisplayItem::TYPE_CANVAS_BACKGROUND) {
|
||||
nsDisplayCanvasBackground* bg = static_cast<nsDisplayCanvasBackground*>(i);
|
||||
i->GetType() == nsDisplayItem::TYPE_CANVAS_BACKGROUND_COLOR) {
|
||||
nsDisplayCanvasBackgroundColor* bg = static_cast<nsDisplayCanvasBackgroundColor*>(i);
|
||||
bg->SetExtraBackgroundColor(aColor);
|
||||
return true;
|
||||
}
|
||||
|
@ -178,6 +178,19 @@ nsRect nsCanvasFrame::CanvasArea() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
||||
nsPoint offset = ToReferenceFrame();
|
||||
nsRect bgClipRect = frame->CanvasArea() + offset;
|
||||
if (NS_GET_A(mColor) > 0) {
|
||||
aCtx->SetColor(mColor);
|
||||
aCtx->FillRect(bgClipRect);
|
||||
}
|
||||
}
|
||||
|
||||
static void BlitSurface(gfxContext* aDest, const gfxRect& aRect, gfxASurface* aSource)
|
||||
{
|
||||
aDest->Translate(gfxPoint(aRect.x, aRect.y));
|
||||
@ -189,19 +202,13 @@ static void BlitSurface(gfxContext* aDest, const gfxRect& aRect, gfxASurface* aS
|
||||
}
|
||||
|
||||
void
|
||||
nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx)
|
||||
{
|
||||
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
|
||||
nsPoint offset = ToReferenceFrame();
|
||||
nsRect bgClipRect = frame->CanvasArea() + offset;
|
||||
if (mIsBottommostLayer && NS_GET_A(mExtraBackgroundColor) > 0) {
|
||||
aCtx->SetColor(mExtraBackgroundColor);
|
||||
aCtx->FillRect(bgClipRect);
|
||||
}
|
||||
|
||||
bool snap;
|
||||
nsRect bounds = GetBounds(aBuilder, &snap);
|
||||
nsRenderingContext context;
|
||||
nsRefPtr<gfxContext> dest = aCtx->ThebesContext();
|
||||
nsRefPtr<gfxASurface> surf;
|
||||
@ -230,15 +237,14 @@ nsDisplayCanvasBackground::Paint(nsDisplayListBuilder* aBuilder,
|
||||
}
|
||||
#endif
|
||||
|
||||
nsCSSRendering::PaintBackground(mFrame->PresContext(), surf ? context : *aCtx, mFrame,
|
||||
surf ? bounds : mVisibleRect,
|
||||
nsRect(offset, mFrame->GetSize()),
|
||||
aBuilder->GetBackgroundPaintFlags(),
|
||||
&bgClipRect, mLayer);
|
||||
PaintInternal(aBuilder,
|
||||
surf ? &context : aCtx,
|
||||
surf ? bgClipRect: mVisibleRect,
|
||||
&bgClipRect);
|
||||
|
||||
if (surf) {
|
||||
BlitSurface(dest, destRect, surf);
|
||||
|
||||
GetUnderlyingFrame()->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get());
|
||||
frame->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -302,11 +308,14 @@ nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
nsCSSRendering::FindBackground(PresContext(), this, &bgSC)) {
|
||||
bg = bgSC->GetStyleBackground();
|
||||
}
|
||||
aLists.BorderBackground()->AppendNewToTop(
|
||||
new (aBuilder) nsDisplayCanvasBackgroundColor(aBuilder, this));
|
||||
|
||||
// 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,
|
||||
isThemed, bg));
|
||||
new (aBuilder) nsDisplayCanvasBackgroundImage(aBuilder, this, i,
|
||||
isThemed, bg));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
@ -122,13 +122,11 @@ protected:
|
||||
* We can also paint an "extra background color" behind the normal
|
||||
* background.
|
||||
*/
|
||||
class nsDisplayCanvasBackground : public nsDisplayBackgroundImage {
|
||||
class nsDisplayCanvasBackgroundColor : public nsDisplayItem {
|
||||
public:
|
||||
nsDisplayCanvasBackground(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame,
|
||||
uint32_t aLayer, bool aIsThemed,
|
||||
const nsStyleBackground* aBackgroundStyle)
|
||||
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aIsThemed, aBackgroundStyle),
|
||||
mExtraBackgroundColor(NS_RGBA(0,0,0,0))
|
||||
nsDisplayCanvasBackgroundColor(nsDisplayListBuilder* aBuilder, nsIFrame *aFrame)
|
||||
: nsDisplayItem(aBuilder, aFrame)
|
||||
, mColor(NS_RGBA(0,0,0,0))
|
||||
{
|
||||
}
|
||||
|
||||
@ -136,27 +134,19 @@ public:
|
||||
nsRegion* aVisibleRegion,
|
||||
const nsRect& aAllowVisibleRegionExpansion) MOZ_OVERRIDE
|
||||
{
|
||||
return NS_GET_A(mExtraBackgroundColor) > 0 ||
|
||||
nsDisplayBackgroundImage::ComputeVisibility(aBuilder, aVisibleRegion,
|
||||
aAllowVisibleRegionExpansion);
|
||||
return NS_GET_A(mColor) > 0;
|
||||
}
|
||||
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
|
||||
bool* aSnap) MOZ_OVERRIDE
|
||||
{
|
||||
if (NS_GET_A(mExtraBackgroundColor) == 255) {
|
||||
if (NS_GET_A(mColor) == 255) {
|
||||
return nsRegion(GetBounds(aBuilder, aSnap));
|
||||
}
|
||||
return nsDisplayBackgroundImage::GetOpaqueRegion(aBuilder, aSnap);
|
||||
return nsRegion();
|
||||
}
|
||||
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor) MOZ_OVERRIDE
|
||||
{
|
||||
nscolor background;
|
||||
if (!nsDisplayBackgroundImage::IsUniform(aBuilder, &background))
|
||||
return false;
|
||||
NS_ASSERTION(background == NS_RGBA(0,0,0,0),
|
||||
"The nsDisplayBackground for a canvas frame doesn't paint "
|
||||
"its background color normally");
|
||||
*aColor = mExtraBackgroundColor;
|
||||
*aColor = mColor;
|
||||
return true;
|
||||
}
|
||||
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) MOZ_OVERRIDE
|
||||
@ -171,16 +161,6 @@ public:
|
||||
// We need to override so we don't consider border-radius.
|
||||
aOutFrames->AppendElement(mFrame);
|
||||
}
|
||||
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
|
||||
{
|
||||
// Put background-attachment:fixed canvas background images in their own
|
||||
// compositing layer. Since we know their background painting area can't
|
||||
// change (unless the viewport size itself changes), async scrolling
|
||||
// will work well.
|
||||
return mBackgroundStyle &&
|
||||
mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
||||
!mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
|
||||
}
|
||||
virtual void NotifyRenderingChanged() MOZ_OVERRIDE
|
||||
{
|
||||
mFrame->Properties().Delete(nsIFrame::CachedBackgroundImage());
|
||||
@ -188,20 +168,43 @@ public:
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder,
|
||||
nsRenderingContext* aCtx) MOZ_OVERRIDE;
|
||||
|
||||
// We still need to paint a background color as well as an image for this item,
|
||||
// so we can't support this yet.
|
||||
virtual bool SupportsOptimizingToImage() { return false; }
|
||||
|
||||
void SetExtraBackgroundColor(nscolor aColor)
|
||||
{
|
||||
mExtraBackgroundColor = aColor;
|
||||
mColor = aColor;
|
||||
}
|
||||
|
||||
NS_DISPLAY_DECL_NAME("CanvasBackground", TYPE_CANVAS_BACKGROUND)
|
||||
NS_DISPLAY_DECL_NAME("CanvasBackgroundColor", TYPE_CANVAS_BACKGROUND_COLOR)
|
||||
|
||||
private:
|
||||
nscolor mExtraBackgroundColor;
|
||||
nscolor mColor;
|
||||
};
|
||||
|
||||
class nsDisplayCanvasBackgroundImage : public nsDisplayBackgroundImage {
|
||||
public:
|
||||
nsDisplayCanvasBackgroundImage(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
|
||||
uint32_t aLayer, bool aIsThemed, const nsStyleBackground* aBg)
|
||||
: nsDisplayBackgroundImage(aBuilder, aFrame, aLayer, aIsThemed, aBg)
|
||||
{}
|
||||
|
||||
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) MOZ_OVERRIDE;
|
||||
|
||||
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) MOZ_OVERRIDE
|
||||
{
|
||||
// Put background-attachment:fixed canvas background images in their own
|
||||
// compositing layer. Since we know their background painting area can't
|
||||
// change (unless the viewport size itself changes), async scrolling
|
||||
// will work well.
|
||||
return mBackgroundStyle->mLayers[mLayer].mAttachment == NS_STYLE_BG_ATTACHMENT_FIXED &&
|
||||
!mBackgroundStyle->mLayers[mLayer].mImage.IsEmpty();
|
||||
}
|
||||
|
||||
// We still need to paint a background color as well as an image for this item,
|
||||
// so we can't support this yet.
|
||||
virtual bool SupportsOptimizingToImage() MOZ_OVERRIDE { return false; }
|
||||
|
||||
|
||||
NS_DISPLAY_DECL_NAME("CanvasBackgroundImage", TYPE_CANVAS_BACKGROUND_IMAGE)
|
||||
};
|
||||
|
||||
#endif /* nsCanvasFrame_h___ */
|
||||
|
@ -1,4 +1,4 @@
|
||||
random-if(bug685516) == background-image-zoom-1.html background-image-zoom-1-ref.html
|
||||
random-if(bug685516) fuzzy-if(Android,4,15) == background-image-zoom-1.html background-image-zoom-1-ref.html
|
||||
== background-image-zoom-2.html about:blank
|
||||
== image-zoom-1.html image-zoom-1-ref.html
|
||||
== image-zoom-2.html image-zoom-1-ref.html
|
||||
|
Loading…
x
Reference in New Issue
Block a user