1 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "gfxQuartzSurface.h"
7 #include "gfxContext.h"
8 #include "gfxImageSurface.h"
9 #include "mozilla/gfx/2D.h"
10 #include "mozilla/gfx/HelpersCairo.h"
12 #include "cairo-quartz.h"
14 void gfxQuartzSurface::MakeInvalid() { mSize
= mozilla::gfx::IntSize(-1, -1); }
16 gfxQuartzSurface::gfxQuartzSurface(const mozilla::gfx::IntSize
& desiredSize
,
17 gfxImageFormat format
)
18 : mCGContext(nullptr), mSize(desiredSize
) {
19 if (!mozilla::gfx::Factory::CheckSurfaceSize(desiredSize
)) MakeInvalid();
21 unsigned int width
= static_cast<unsigned int>(mSize
.width
);
22 unsigned int height
= static_cast<unsigned int>(mSize
.height
);
24 cairo_format_t cformat
= GfxFormatToCairoFormat(format
);
25 cairo_surface_t
* surf
= cairo_quartz_surface_create(cformat
, width
, height
);
27 mCGContext
= cairo_quartz_surface_get_cg_context(surf
);
29 CGContextRetain(mCGContext
);
33 RecordMemoryUsed(mSize
.height
* 4 + sizeof(gfxQuartzSurface
));
37 gfxQuartzSurface::gfxQuartzSurface(CGContextRef context
,
38 const mozilla::gfx::IntSize
& size
)
39 : mCGContext(context
), mSize(size
) {
40 if (!mozilla::gfx::Factory::CheckSurfaceSize(size
)) MakeInvalid();
42 unsigned int width
= static_cast<unsigned int>(mSize
.width
);
43 unsigned int height
= static_cast<unsigned int>(mSize
.height
);
45 cairo_surface_t
* surf
=
46 cairo_quartz_surface_create_for_cg_context(context
, width
, height
);
48 CGContextRetain(mCGContext
);
52 RecordMemoryUsed(mSize
.height
* 4 + sizeof(gfxQuartzSurface
));
56 gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t
* csurf
,
57 const mozilla::gfx::IntSize
& aSize
)
59 mCGContext
= cairo_quartz_surface_get_cg_context(csurf
);
60 CGContextRetain(mCGContext
);
65 already_AddRefed
<gfxImageSurface
> gfxQuartzSurface::GetAsImageSurface() {
66 cairo_surface_t
* surface
= cairo_quartz_surface_get_image(mSurface
);
67 if (!surface
|| cairo_surface_status(surface
)) return nullptr;
69 RefPtr
<gfxASurface
> img
= Wrap(surface
);
71 // cairo_quartz_surface_get_image returns a referenced image, and thebes
72 // shares the refcounts of Cairo surfaces. However, Wrap also adds a
73 // reference to the image. We need to remove one of these references
74 // explicitly so we don't leak.
77 img
->SetOpaqueRect(GetOpaqueRect());
79 return img
.forget().downcast
<gfxImageSurface
>();
82 gfxQuartzSurface::~gfxQuartzSurface() { CGContextRelease(mCGContext
); }