void nsDisplayCanvasBackground::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; nsRefPtr<gfxContext> ctx; #ifndef MOZ_GFX_OPTIMIZE_MOBILE if (IsSingleFixedPositionImage(aBuilder, bgClipRect) && aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap()) { surf = static_cast<gfxASurface*>(GetUnderlyingFrame()->Properties().Get(nsIFrame::CachedBackgroundImage())); nsRefPtr<gfxASurface> destSurf = dest->CurrentSurface(); if (surf && surf->GetType() == destSurf->GetType()) { BlitSurface(dest, mDestRect, surf); return; } surf = destSurf->CreateSimilarSurface(gfxASurface::CONTENT_COLOR_ALPHA, gfxIntSize(ceil(mDestRect.width), ceil(mDestRect.height))); if (surf) { ctx = new gfxContext(surf); ctx->Translate(-gfxPoint(mDestRect.x, mDestRect.y)); context.Init(aCtx->DeviceContext(), ctx); } } #endif nsCSSRendering::PaintBackground(mFrame->PresContext(), surf ? context : *aCtx, mFrame, surf ? bounds : mVisibleRect, nsRect(offset, mFrame->GetSize()), aBuilder->GetBackgroundPaintFlags(), &bgClipRect, mLayer); if (surf) { BlitSurface(dest, mDestRect, surf); GetUnderlyingFrame()->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get()); GetUnderlyingFrame()->AddStateBits(NS_FRAME_HAS_CACHED_BACKGROUND); } }
void nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame); nsPoint offset = ToReferenceFrame(); nsRect bgClipRect = frame->CanvasArea() + offset; nsRenderingContext context; nsRefPtr<gfxContext> dest = aCtx->ThebesContext(); nsRefPtr<gfxASurface> surf; nsRefPtr<gfxContext> ctx; gfxRect destRect; #ifndef MOZ_GFX_OPTIMIZE_MOBILE if (IsSingleFixedPositionImage(aBuilder, bgClipRect, &destRect) && aBuilder->IsPaintingToWindow() && !aBuilder->IsCompositingCheap() && !dest->CurrentMatrix().HasNonIntegerTranslation()) { // Snap image rectangle to nearest pixel boundaries. This is the right way // to snap for this context, because we checked HasNonIntegerTranslation above. destRect.Round(); surf = static_cast<gfxASurface*>(GetUnderlyingFrame()->Properties().Get(nsIFrame::CachedBackgroundImage())); nsRefPtr<gfxASurface> destSurf = dest->CurrentSurface(); if (surf && surf->GetType() == destSurf->GetType()) { BlitSurface(dest, destRect, surf); return; } surf = destSurf->CreateSimilarSurface(gfxASurface::CONTENT_COLOR_ALPHA, gfxIntSize(destRect.width, destRect.height)); if (surf) { ctx = new gfxContext(surf); ctx->Translate(-gfxPoint(destRect.x, destRect.y)); context.Init(aCtx->DeviceContext(), ctx); } } #endif PaintInternal(aBuilder, surf ? &context : aCtx, surf ? bgClipRect: mVisibleRect, &bgClipRect); if (surf) { BlitSurface(dest, destRect, surf); frame->Properties().Set(nsIFrame::CachedBackgroundImage(), surf.forget().get()); } }