gfx/2d/SourceSurfaceCairo.cpp

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:5f38284af089
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/. */
5
6 #include "SourceSurfaceCairo.h"
7 #include "DrawTargetCairo.h"
8 #include "HelpersCairo.h"
9 #include "DataSourceSurfaceWrapper.h"
10
11 #include "cairo.h"
12
13 namespace mozilla {
14 namespace gfx {
15
16 static SurfaceFormat
17 CairoFormatToSurfaceFormat(cairo_format_t format)
18 {
19 switch (format)
20 {
21 case CAIRO_FORMAT_ARGB32:
22 return SurfaceFormat::B8G8R8A8;
23 case CAIRO_FORMAT_RGB24:
24 return SurfaceFormat::B8G8R8X8;
25 case CAIRO_FORMAT_A8:
26 return SurfaceFormat::A8;
27 default:
28 return SurfaceFormat::B8G8R8A8;
29 }
30 }
31
32 SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface,
33 const IntSize& aSize,
34 const SurfaceFormat& aFormat,
35 DrawTargetCairo* aDrawTarget /* = nullptr */)
36 : mSize(aSize)
37 , mFormat(aFormat)
38 , mSurface(aSurface)
39 , mDrawTarget(aDrawTarget)
40 {
41 cairo_surface_reference(mSurface);
42 }
43
44 SourceSurfaceCairo::~SourceSurfaceCairo()
45 {
46 cairo_surface_destroy(mSurface);
47 }
48
49 IntSize
50 SourceSurfaceCairo::GetSize() const
51 {
52 return mSize;
53 }
54
55 SurfaceFormat
56 SourceSurfaceCairo::GetFormat() const
57 {
58 return mFormat;
59 }
60
61 TemporaryRef<DataSourceSurface>
62 SourceSurfaceCairo::GetDataSurface()
63 {
64 RefPtr<DataSourceSurface> dataSurf;
65
66 if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
67 dataSurf = new DataSourceSurfaceCairo(mSurface);
68 } else {
69 cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat),
70 mSize.width, mSize.height);
71
72 // Fill the new image surface with the contents of our surface.
73 cairo_t* ctx = cairo_create(imageSurf);
74 cairo_set_source_surface(ctx, mSurface, 0, 0);
75 cairo_paint(ctx);
76 cairo_destroy(ctx);
77
78 dataSurf = new DataSourceSurfaceCairo(imageSurf);
79 cairo_surface_destroy(imageSurf);
80 }
81
82 // We also need to make sure that the returned surface has
83 // surface->GetType() == SurfaceType::DATA.
84 dataSurf = new DataSourceSurfaceWrapper(dataSurf);
85
86 return dataSurf;
87 }
88
89 cairo_surface_t*
90 SourceSurfaceCairo::GetSurface() const
91 {
92 return mSurface;
93 }
94
95 void
96 SourceSurfaceCairo::DrawTargetWillChange()
97 {
98 if (mDrawTarget) {
99 mDrawTarget = nullptr;
100
101 // We're about to lose our version of the surface, so make a copy of it.
102 cairo_surface_t* surface = cairo_surface_create_similar(mSurface,
103 GfxFormatToCairoContent(mFormat),
104 mSize.width, mSize.height);
105 cairo_t* ctx = cairo_create(surface);
106 cairo_pattern_t* pat = cairo_pattern_create_for_surface(mSurface);
107 cairo_set_source(ctx, pat);
108 cairo_paint(ctx);
109 cairo_destroy(ctx);
110 cairo_pattern_destroy(pat);
111
112 // Swap in this new surface.
113 cairo_surface_destroy(mSurface);
114 mSurface = surface;
115 }
116 }
117
118 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf)
119 : mImageSurface(imageSurf)
120 {
121 cairo_surface_reference(mImageSurface);
122 }
123
124 DataSourceSurfaceCairo::~DataSourceSurfaceCairo()
125 {
126 cairo_surface_destroy(mImageSurface);
127 }
128
129 unsigned char *
130 DataSourceSurfaceCairo::GetData()
131 {
132 return cairo_image_surface_get_data(mImageSurface);
133 }
134
135 int32_t
136 DataSourceSurfaceCairo::Stride()
137 {
138 return cairo_image_surface_get_stride(mImageSurface);
139 }
140
141 IntSize
142 DataSourceSurfaceCairo::GetSize() const
143 {
144 IntSize size;
145 size.width = cairo_image_surface_get_width(mImageSurface);
146 size.height = cairo_image_surface_get_height(mImageSurface);
147
148 return size;
149 }
150
151 SurfaceFormat
152 DataSourceSurfaceCairo::GetFormat() const
153 {
154 return CairoFormatToSurfaceFormat(cairo_image_surface_get_format(mImageSurface));
155 }
156
157 cairo_surface_t*
158 DataSourceSurfaceCairo::GetSurface() const
159 {
160 return mImageSurface;
161 }
162
163 }
164 }

mercurial