already_AddRefed<gfxASurface> gfxASurface::CreateSimilarSurface(gfxContentType aContent, const gfxIntSize& aSize) { if (!mSurface || !mSurfaceValid) { return nsnull; } cairo_surface_t *surface = cairo_surface_create_similar(mSurface, cairo_content_t(aContent), aSize.width, aSize.height); if (cairo_surface_status(surface)) { cairo_surface_destroy(surface); return nsnull; } nsRefPtr<gfxASurface> result = Wrap(surface); cairo_surface_destroy(surface); return result.forget(); }
already_AddRefed<gfxASurface> gfxWindowsSurface::CreateSimilarSurface(gfxContentType aContent, const gfxIntSize& aSize) { if (!mSurface || !mSurfaceValid) { return nsnull; } cairo_surface_t *surface; if (GetContentType() == CONTENT_COLOR_ALPHA) { // When creating a similar surface to a transparent surface, ensure // the new surface uses a DIB. cairo_surface_create_similar won't // use a DIB for a CONTENT_COLOR surface if this surface doesn't // have a DIB (e.g. if we're a transparent window surface). But // we need a DIB to perform well if the new surface is composited into // a surface that's the result of create_similar(CONTENT_COLOR_ALPHA) // (e.g. a backbuffer for the window) --- that new surface *would* // have a DIB. surface = cairo_win32_surface_create_with_dib(cairo_format_t(gfxASurface::FormatFromContent(aContent)), aSize.width, aSize.height); } else { surface = cairo_surface_create_similar(mSurface, cairo_content_t(aContent), aSize.width, aSize.height); } if (cairo_surface_status(surface)) { cairo_surface_destroy(surface); return nsnull; } nsRefPtr<gfxASurface> result = Wrap(surface); cairo_surface_destroy(surface); return result.forget(); }