1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/2d/SourceSurfaceCairo.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,164 @@ 1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "SourceSurfaceCairo.h" 1.10 +#include "DrawTargetCairo.h" 1.11 +#include "HelpersCairo.h" 1.12 +#include "DataSourceSurfaceWrapper.h" 1.13 + 1.14 +#include "cairo.h" 1.15 + 1.16 +namespace mozilla { 1.17 +namespace gfx { 1.18 + 1.19 +static SurfaceFormat 1.20 +CairoFormatToSurfaceFormat(cairo_format_t format) 1.21 +{ 1.22 + switch (format) 1.23 + { 1.24 + case CAIRO_FORMAT_ARGB32: 1.25 + return SurfaceFormat::B8G8R8A8; 1.26 + case CAIRO_FORMAT_RGB24: 1.27 + return SurfaceFormat::B8G8R8X8; 1.28 + case CAIRO_FORMAT_A8: 1.29 + return SurfaceFormat::A8; 1.30 + default: 1.31 + return SurfaceFormat::B8G8R8A8; 1.32 + } 1.33 +} 1.34 + 1.35 +SourceSurfaceCairo::SourceSurfaceCairo(cairo_surface_t* aSurface, 1.36 + const IntSize& aSize, 1.37 + const SurfaceFormat& aFormat, 1.38 + DrawTargetCairo* aDrawTarget /* = nullptr */) 1.39 + : mSize(aSize) 1.40 + , mFormat(aFormat) 1.41 + , mSurface(aSurface) 1.42 + , mDrawTarget(aDrawTarget) 1.43 +{ 1.44 + cairo_surface_reference(mSurface); 1.45 +} 1.46 + 1.47 +SourceSurfaceCairo::~SourceSurfaceCairo() 1.48 +{ 1.49 + cairo_surface_destroy(mSurface); 1.50 +} 1.51 + 1.52 +IntSize 1.53 +SourceSurfaceCairo::GetSize() const 1.54 +{ 1.55 + return mSize; 1.56 +} 1.57 + 1.58 +SurfaceFormat 1.59 +SourceSurfaceCairo::GetFormat() const 1.60 +{ 1.61 + return mFormat; 1.62 +} 1.63 + 1.64 +TemporaryRef<DataSourceSurface> 1.65 +SourceSurfaceCairo::GetDataSurface() 1.66 +{ 1.67 + RefPtr<DataSourceSurface> dataSurf; 1.68 + 1.69 + if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) { 1.70 + dataSurf = new DataSourceSurfaceCairo(mSurface); 1.71 + } else { 1.72 + cairo_surface_t* imageSurf = cairo_image_surface_create(GfxFormatToCairoFormat(mFormat), 1.73 + mSize.width, mSize.height); 1.74 + 1.75 + // Fill the new image surface with the contents of our surface. 1.76 + cairo_t* ctx = cairo_create(imageSurf); 1.77 + cairo_set_source_surface(ctx, mSurface, 0, 0); 1.78 + cairo_paint(ctx); 1.79 + cairo_destroy(ctx); 1.80 + 1.81 + dataSurf = new DataSourceSurfaceCairo(imageSurf); 1.82 + cairo_surface_destroy(imageSurf); 1.83 + } 1.84 + 1.85 + // We also need to make sure that the returned surface has 1.86 + // surface->GetType() == SurfaceType::DATA. 1.87 + dataSurf = new DataSourceSurfaceWrapper(dataSurf); 1.88 + 1.89 + return dataSurf; 1.90 +} 1.91 + 1.92 +cairo_surface_t* 1.93 +SourceSurfaceCairo::GetSurface() const 1.94 +{ 1.95 + return mSurface; 1.96 +} 1.97 + 1.98 +void 1.99 +SourceSurfaceCairo::DrawTargetWillChange() 1.100 +{ 1.101 + if (mDrawTarget) { 1.102 + mDrawTarget = nullptr; 1.103 + 1.104 + // We're about to lose our version of the surface, so make a copy of it. 1.105 + cairo_surface_t* surface = cairo_surface_create_similar(mSurface, 1.106 + GfxFormatToCairoContent(mFormat), 1.107 + mSize.width, mSize.height); 1.108 + cairo_t* ctx = cairo_create(surface); 1.109 + cairo_pattern_t* pat = cairo_pattern_create_for_surface(mSurface); 1.110 + cairo_set_source(ctx, pat); 1.111 + cairo_paint(ctx); 1.112 + cairo_destroy(ctx); 1.113 + cairo_pattern_destroy(pat); 1.114 + 1.115 + // Swap in this new surface. 1.116 + cairo_surface_destroy(mSurface); 1.117 + mSurface = surface; 1.118 + } 1.119 +} 1.120 + 1.121 +DataSourceSurfaceCairo::DataSourceSurfaceCairo(cairo_surface_t* imageSurf) 1.122 + : mImageSurface(imageSurf) 1.123 +{ 1.124 + cairo_surface_reference(mImageSurface); 1.125 +} 1.126 + 1.127 +DataSourceSurfaceCairo::~DataSourceSurfaceCairo() 1.128 +{ 1.129 + cairo_surface_destroy(mImageSurface); 1.130 +} 1.131 + 1.132 +unsigned char * 1.133 +DataSourceSurfaceCairo::GetData() 1.134 +{ 1.135 + return cairo_image_surface_get_data(mImageSurface); 1.136 +} 1.137 + 1.138 +int32_t 1.139 +DataSourceSurfaceCairo::Stride() 1.140 +{ 1.141 + return cairo_image_surface_get_stride(mImageSurface); 1.142 +} 1.143 + 1.144 +IntSize 1.145 +DataSourceSurfaceCairo::GetSize() const 1.146 +{ 1.147 + IntSize size; 1.148 + size.width = cairo_image_surface_get_width(mImageSurface); 1.149 + size.height = cairo_image_surface_get_height(mImageSurface); 1.150 + 1.151 + return size; 1.152 +} 1.153 + 1.154 +SurfaceFormat 1.155 +DataSourceSurfaceCairo::GetFormat() const 1.156 +{ 1.157 + return CairoFormatToSurfaceFormat(cairo_image_surface_get_format(mImageSurface)); 1.158 +} 1.159 + 1.160 +cairo_surface_t* 1.161 +DataSourceSurfaceCairo::GetSurface() const 1.162 +{ 1.163 + return mImageSurface; 1.164 +} 1.165 + 1.166 +} 1.167 +}