gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
                                   const gfxSize& desiredSize,
                                   long stride,
                                   gfxImageFormat format)
    : mCGContext(nullptr), mSize(desiredSize)
{
    mozilla::gfx::IntSize size((unsigned int) floor(desiredSize.width),
                    (unsigned int) floor(desiredSize.height));
    if (!CheckSurfaceSize(size))
        MakeInvalid();

    unsigned int width = static_cast<unsigned int>(mSize.width);
    unsigned int height = static_cast<unsigned int>(mSize.height);

    cairo_format_t cformat = GfxFormatToCairoFormat(format);
    cairo_surface_t *surf = cairo_quartz_surface_create_for_data
        (data, cformat, width, height, stride);

    mCGContext = cairo_quartz_surface_get_cg_context (surf);

    CGContextRetain(mCGContext);

    Init(surf);
    if (mSurfaceValid) {
      RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
    }
}
already_AddRefed<DataSourceSurface>
SourceSurfaceCairo::GetDataSurface()
{
  RefPtr<DataSourceSurface> dataSurf;

  if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
    dataSurf = new DataSourceSurfaceCairo(mSurface);
  } else {
    cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat),
                                                            mSize.width, mSize.height);

    // Fill the new image surface with the contents of our surface.
    cairo_t* ctx = cairo_create(imageSurf);
    cairo_set_source_surface(ctx, mSurface, 0, 0);
    cairo_paint(ctx);
    cairo_destroy(ctx);

    dataSurf = new DataSourceSurfaceCairo(imageSurf);
    cairo_surface_destroy(imageSurf);
  }

  // We also need to make sure that the returned surface has
  // surface->GetType() == SurfaceType::DATA.
  return MakeAndAddRef<DataSourceSurfaceWrapper>(dataSurf);
}
gfxQPainterSurface::gfxQPainterSurface(const mozilla::gfx::IntSize& size, gfxImageFormat format)
{
    cairo_format_t cformat = GfxFormatToCairoFormat(format);
    cairo_surface_t *csurf =
        cairo_qt_surface_create_with_qimage(cformat, size.width, size.height);
    mPainter = cairo_qt_surface_get_qpainter (csurf);

    Init (csurf);
}
gfxWindowsSurface::gfxWindowsSurface(const mozilla::gfx::IntSize& realSize, gfxImageFormat imageFormat) :
    mOwnsDC(false), mWnd(nullptr)
{
    mozilla::gfx::IntSize size(realSize);
    if (!mozilla::gfx::Factory::CheckSurfaceSize(size))
        MakeInvalid(size);

    cairo_format_t cformat = GfxFormatToCairoFormat(imageFormat);
    cairo_surface_t *surf =
        cairo_win32_surface_create_with_dib(cformat, size.width, size.height);

    Init(surf);

    if (CairoStatus() == CAIRO_STATUS_SUCCESS) {
        mDC = cairo_win32_surface_get_dc(CairoSurface());
        RecordMemoryUsed(size.width * size.height * 4 + sizeof(gfxWindowsSurface));
    } else {
        mDC = nullptr;
    }
}
gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
                                   const mozilla::gfx::IntSize& aSize,
                                   long stride,
                                   gfxImageFormat format)
    : mCGContext(nullptr), mSize(aSize.width, aSize.height)
{
    if (!CheckSurfaceSize(aSize))
        MakeInvalid();

    cairo_format_t cformat = GfxFormatToCairoFormat(format);
    cairo_surface_t *surf = cairo_quartz_surface_create_for_data
        (data, cformat, aSize.width, aSize.height, stride);

    mCGContext = cairo_quartz_surface_get_cg_context (surf);

    CGContextRetain(mCGContext);

    Init(surf);
    if (mSurfaceValid) {
      RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
    }
}
already_AddRefed<gfxASurface>
gfxWindowsSurface::CreateSimilarSurface(gfxContentType aContent,
                                        const mozilla::gfx::IntSize& aSize)
{
    if (!mSurface || !mSurfaceValid) {
        return nullptr;
    }

    cairo_surface_t *surface;
    if (GetContentType() == gfxContentType::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 gfxContentType::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(gfxContentType::COLOR_ALPHA)
        // (e.g. a backbuffer for the window) --- that new surface *would*
        // have a DIB.
        gfxImageFormat gformat =
            gfxPlatform::GetPlatform()->OptimalFormatForContent(aContent);
        cairo_format_t cformat = GfxFormatToCairoFormat(gformat);
        surface = cairo_win32_surface_create_with_dib(cformat, aSize.width,
                                                      aSize.height);
    } else {
        surface =
          cairo_surface_create_similar(mSurface, (cairo_content_t)(int)aContent,
                                       aSize.width, aSize.height);
    }

    if (cairo_surface_status(surface)) {
        cairo_surface_destroy(surface);
        return nullptr;
    }

    RefPtr<gfxASurface> result = Wrap(surface, aSize);
    cairo_surface_destroy(surface);
    return result.forget();
}
TemporaryRef<DataSourceSurface>
SourceSurfaceCairo::GetDataSurface()
{
  RefPtr<DataSourceSurfaceCairo> dataSurf;

  if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
    dataSurf = new DataSourceSurfaceCairo(mSurface);
  } else {
    cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat),
                                                            mSize.width, mSize.height);

    // Fill the new image surface with the contents of our surface.
    cairo_t* ctx = cairo_create(imageSurf);
    cairo_set_source_surface(ctx, mSurface, 0, 0);
    cairo_paint(ctx);
    cairo_destroy(ctx);

    dataSurf = new DataSourceSurfaceCairo(imageSurf);
    cairo_surface_destroy(imageSurf);
  }

  return dataSurf;
}