Esempio n. 1
0
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);
  }
}
Esempio n. 2
0
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());
  }
}