1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SourceSurfaceCairo.h"
8 #include "DrawTargetCairo.h"
9 #include "HelpersCairo.h"
10 #include "DataSourceSurfaceWrapper.h"
17 static SurfaceFormat
CairoFormatToSurfaceFormat(cairo_format_t format
) {
19 case CAIRO_FORMAT_ARGB32
:
20 return SurfaceFormat::B8G8R8A8
;
21 case CAIRO_FORMAT_RGB24
:
22 return SurfaceFormat::B8G8R8X8
;
23 case CAIRO_FORMAT_RGB16_565
:
24 return SurfaceFormat::R5G6B5_UINT16
;
26 return SurfaceFormat::A8
;
28 return SurfaceFormat::B8G8R8A8
;
32 SourceSurfaceCairo::SourceSurfaceCairo(
33 cairo_surface_t
* aSurface
, const IntSize
& aSize
,
34 const SurfaceFormat
& aFormat
, DrawTargetCairo
* aDrawTarget
/* = nullptr */)
38 mDrawTarget(aDrawTarget
) {
39 cairo_surface_reference(mSurface
);
42 SourceSurfaceCairo::~SourceSurfaceCairo() { cairo_surface_destroy(mSurface
); }
44 IntSize
SourceSurfaceCairo::GetSize() const { return mSize
; }
46 SurfaceFormat
SourceSurfaceCairo::GetFormat() const { return mFormat
; }
48 already_AddRefed
<DataSourceSurface
> SourceSurfaceCairo::GetDataSurface() {
49 RefPtr
<DataSourceSurface
> dataSurf
;
51 if (cairo_surface_get_type(mSurface
) == CAIRO_SURFACE_TYPE_IMAGE
) {
52 dataSurf
= new DataSourceSurfaceCairo(mSurface
);
54 cairo_surface_t
* imageSurf
= cairo_image_surface_create(
55 GfxFormatToCairoFormat(mFormat
), mSize
.width
, mSize
.height
);
57 // Fill the new image surface with the contents of our surface.
58 cairo_t
* ctx
= cairo_create(imageSurf
);
59 cairo_set_source_surface(ctx
, mSurface
, 0, 0);
63 dataSurf
= new DataSourceSurfaceCairo(imageSurf
);
64 cairo_surface_destroy(imageSurf
);
67 // We also need to make sure that the returned surface has
68 // surface->GetType() == SurfaceType::DATA.
69 return MakeAndAddRef
<DataSourceSurfaceWrapper
>(dataSurf
);
72 cairo_surface_t
* SourceSurfaceCairo::GetSurface() const { return mSurface
; }
74 void SourceSurfaceCairo::DrawTargetWillChange() {
76 mDrawTarget
= nullptr;
78 // We're about to lose our version of the surface, so make a copy of it.
79 cairo_surface_t
* surface
= cairo_surface_create_similar(
80 mSurface
, GfxFormatToCairoContent(mFormat
), mSize
.width
, mSize
.height
);
81 cairo_t
* ctx
= cairo_create(surface
);
82 cairo_pattern_t
* pat
= cairo_pattern_create_for_surface(mSurface
);
83 cairo_set_source(ctx
, pat
);
86 cairo_pattern_destroy(pat
);
88 // Swap in this new surface.
89 cairo_surface_destroy(mSurface
);
94 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t
* imageSurf
)
95 : mImageSurface(imageSurf
) {
96 cairo_surface_reference(mImageSurface
);
99 DataSourceSurfaceCairo::~DataSourceSurfaceCairo() {
100 cairo_surface_destroy(mImageSurface
);
103 unsigned char* DataSourceSurfaceCairo::GetData() {
104 return cairo_image_surface_get_data(mImageSurface
);
107 int32_t DataSourceSurfaceCairo::Stride() {
108 return cairo_image_surface_get_stride(mImageSurface
);
111 IntSize
DataSourceSurfaceCairo::GetSize() const {
113 size
.width
= cairo_image_surface_get_width(mImageSurface
);
114 size
.height
= cairo_image_surface_get_height(mImageSurface
);
119 SurfaceFormat
DataSourceSurfaceCairo::GetFormat() const {
120 return CairoFormatToSurfaceFormat(
121 cairo_image_surface_get_format(mImageSurface
));
124 cairo_surface_t
* DataSourceSurfaceCairo::GetSurface() const {
125 return mImageSurface
;
129 } // namespace mozilla