tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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