Coverage Report

Created: 2018-09-25 14:53

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