SourceSurfaceCairo.cpp (3990B)
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 CairoFormatToSurfaceFormat(cairo_format_t format) { 18 switch (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; 25 case CAIRO_FORMAT_A8: 26 return SurfaceFormat::A8; 27 default: 28 return SurfaceFormat::B8G8R8A8; 29 } 30 } 31 32 SourceSurfaceCairo::SourceSurfaceCairo( 33 cairo_surface_t* aSurface, const IntSize& aSize, 34 const SurfaceFormat& aFormat, DrawTargetCairo* aDrawTarget /* = nullptr */) 35 : mSize(aSize), 36 mFormat(aFormat), 37 mSurface(aSurface), 38 mDrawTarget(aDrawTarget) { 39 cairo_surface_reference(mSurface); 40 } 41 42 SourceSurfaceCairo::~SourceSurfaceCairo() { cairo_surface_destroy(mSurface); } 43 44 IntSize SourceSurfaceCairo::GetSize() const { return mSize; } 45 46 SurfaceFormat SourceSurfaceCairo::GetFormat() const { return mFormat; } 47 48 already_AddRefed<DataSourceSurface> SourceSurfaceCairo::GetDataSurface() { 49 RefPtr<DataSourceSurface> dataSurf; 50 51 if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) { 52 dataSurf = new DataSourceSurfaceCairo(mSurface); 53 } else { 54 cairo_surface_t* imageSurf = cairo_image_surface_create( 55 GfxFormatToCairoFormat(mFormat), mSize.width, mSize.height); 56 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); 60 cairo_paint(ctx); 61 cairo_destroy(ctx); 62 63 dataSurf = new DataSourceSurfaceCairo(imageSurf); 64 cairo_surface_destroy(imageSurf); 65 } 66 67 // We also need to make sure that the returned surface has 68 // surface->GetType() == SurfaceType::DATA. 69 return MakeAndAddRef<DataSourceSurfaceWrapper>(dataSurf); 70 } 71 72 cairo_surface_t* SourceSurfaceCairo::GetSurface() const { return mSurface; } 73 74 void SourceSurfaceCairo::DrawTargetWillChange() { 75 if (mDrawTarget) { 76 mDrawTarget = nullptr; 77 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); 84 cairo_paint(ctx); 85 cairo_destroy(ctx); 86 cairo_pattern_destroy(pat); 87 88 // Swap in this new surface. 89 cairo_surface_destroy(mSurface); 90 mSurface = surface; 91 } 92 } 93 94 DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf) 95 : mImageSurface(imageSurf) { 96 cairo_surface_reference(mImageSurface); 97 } 98 99 DataSourceSurfaceCairo::~DataSourceSurfaceCairo() { 100 cairo_surface_destroy(mImageSurface); 101 } 102 103 unsigned char* DataSourceSurfaceCairo::GetData() { 104 return cairo_image_surface_get_data(mImageSurface); 105 } 106 107 int32_t DataSourceSurfaceCairo::Stride() { 108 return cairo_image_surface_get_stride(mImageSurface); 109 } 110 111 IntSize DataSourceSurfaceCairo::GetSize() const { 112 IntSize size; 113 size.width = cairo_image_surface_get_width(mImageSurface); 114 size.height = cairo_image_surface_get_height(mImageSurface); 115 116 return size; 117 } 118 119 SurfaceFormat DataSourceSurfaceCairo::GetFormat() const { 120 return CairoFormatToSurfaceFormat( 121 cairo_image_surface_get_format(mImageSurface)); 122 } 123 124 cairo_surface_t* DataSourceSurfaceCairo::GetSurface() const { 125 return mImageSurface; 126 } 127 128 } // namespace gfx 129 } // namespace mozilla