gfx/thebes/gfxQuartzSurface.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/thebes/gfxQuartzSurface.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,207 @@
     1.4 +/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     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 "gfxQuartzSurface.h"
    1.10 +#include "gfxContext.h"
    1.11 +#include "gfxImageSurface.h"
    1.12 +
    1.13 +#include "cairo-quartz.h"
    1.14 +
    1.15 +void
    1.16 +gfxQuartzSurface::MakeInvalid()
    1.17 +{
    1.18 +    mSize = gfxIntSize(-1, -1);    
    1.19 +}
    1.20 +
    1.21 +gfxQuartzSurface::gfxQuartzSurface(const gfxSize& desiredSize, gfxImageFormat format,
    1.22 +                                   bool aForPrinting)
    1.23 +    : mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting)
    1.24 +{
    1.25 +    gfxIntSize size((unsigned int) floor(desiredSize.width),
    1.26 +                    (unsigned int) floor(desiredSize.height));
    1.27 +    if (!CheckSurfaceSize(size))
    1.28 +        MakeInvalid();
    1.29 +
    1.30 +    unsigned int width = static_cast<unsigned int>(mSize.width);
    1.31 +    unsigned int height = static_cast<unsigned int>(mSize.height);
    1.32 +
    1.33 +    cairo_surface_t *surf = cairo_quartz_surface_create
    1.34 +        ((cairo_format_t) format, width, height);
    1.35 +
    1.36 +    mCGContext = cairo_quartz_surface_get_cg_context (surf);
    1.37 +
    1.38 +    CGContextRetain(mCGContext);
    1.39 +
    1.40 +    Init(surf);
    1.41 +    if (mSurfaceValid) {
    1.42 +      RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
    1.43 +    }
    1.44 +}
    1.45 +
    1.46 +gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
    1.47 +                                   const gfxSize& desiredSize,
    1.48 +                                   bool aForPrinting)
    1.49 +    : mCGContext(context), mSize(desiredSize), mForPrinting(aForPrinting)
    1.50 +{
    1.51 +    gfxIntSize size((unsigned int) floor(desiredSize.width),
    1.52 +                    (unsigned int) floor(desiredSize.height));
    1.53 +    if (!CheckSurfaceSize(size))
    1.54 +        MakeInvalid();
    1.55 +
    1.56 +    unsigned int width = static_cast<unsigned int>(mSize.width);
    1.57 +    unsigned int height = static_cast<unsigned int>(mSize.height);
    1.58 +
    1.59 +    cairo_surface_t *surf =
    1.60 +        cairo_quartz_surface_create_for_cg_context(context,
    1.61 +                                                   width, height);
    1.62 +
    1.63 +    CGContextRetain(mCGContext);
    1.64 +
    1.65 +    Init(surf);
    1.66 +    if (mSurfaceValid) {
    1.67 +      RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
    1.68 +    }
    1.69 +}
    1.70 +
    1.71 +gfxQuartzSurface::gfxQuartzSurface(CGContextRef context,
    1.72 +                                   const gfxIntSize& size,
    1.73 +                                   bool aForPrinting)
    1.74 +    : mCGContext(context), mSize(size), mForPrinting(aForPrinting)
    1.75 +{
    1.76 +    if (!CheckSurfaceSize(size))
    1.77 +        MakeInvalid();
    1.78 +
    1.79 +    unsigned int width = static_cast<unsigned int>(mSize.width);
    1.80 +    unsigned int height = static_cast<unsigned int>(mSize.height);
    1.81 +
    1.82 +    cairo_surface_t *surf = 
    1.83 +        cairo_quartz_surface_create_for_cg_context(context,
    1.84 +                                                   width, height);
    1.85 +
    1.86 +    CGContextRetain(mCGContext);
    1.87 +
    1.88 +    Init(surf);
    1.89 +    if (mSurfaceValid) {
    1.90 +      RecordMemoryUsed(mSize.height * 4 + sizeof(gfxQuartzSurface));
    1.91 +    }
    1.92 +}
    1.93 +
    1.94 +gfxQuartzSurface::gfxQuartzSurface(cairo_surface_t *csurf,
    1.95 +                                   const gfxIntSize& aSize,
    1.96 +                                   bool aForPrinting) :
    1.97 +    mSize(aSize), mForPrinting(aForPrinting)
    1.98 +{
    1.99 +    mCGContext = cairo_quartz_surface_get_cg_context (csurf);
   1.100 +    CGContextRetain (mCGContext);
   1.101 +
   1.102 +    Init(csurf, true);
   1.103 +}
   1.104 +
   1.105 +gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
   1.106 +                                   const gfxSize& desiredSize,
   1.107 +                                   long stride,
   1.108 +                                   gfxImageFormat format,
   1.109 +                                   bool aForPrinting)
   1.110 +    : mCGContext(nullptr), mSize(desiredSize), mForPrinting(aForPrinting)
   1.111 +{
   1.112 +    gfxIntSize size((unsigned int) floor(desiredSize.width),
   1.113 +                    (unsigned int) floor(desiredSize.height));
   1.114 +    if (!CheckSurfaceSize(size))
   1.115 +        MakeInvalid();
   1.116 +
   1.117 +    unsigned int width = static_cast<unsigned int>(mSize.width);
   1.118 +    unsigned int height = static_cast<unsigned int>(mSize.height);
   1.119 +
   1.120 +    cairo_surface_t *surf = cairo_quartz_surface_create_for_data
   1.121 +        (data, (cairo_format_t) format, width, height, stride);
   1.122 +
   1.123 +    mCGContext = cairo_quartz_surface_get_cg_context (surf);
   1.124 +
   1.125 +    CGContextRetain(mCGContext);
   1.126 +
   1.127 +    Init(surf);
   1.128 +    if (mSurfaceValid) {
   1.129 +      RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
   1.130 +    }
   1.131 +}
   1.132 +
   1.133 +gfxQuartzSurface::gfxQuartzSurface(unsigned char *data,
   1.134 +                                   const gfxIntSize& aSize,
   1.135 +                                   long stride,
   1.136 +                                   gfxImageFormat format,
   1.137 +                                   bool aForPrinting)
   1.138 +    : mCGContext(nullptr), mSize(aSize.width, aSize.height), mForPrinting(aForPrinting)
   1.139 +{
   1.140 +    if (!CheckSurfaceSize(aSize))
   1.141 +        MakeInvalid();
   1.142 +
   1.143 +    cairo_surface_t *surf = cairo_quartz_surface_create_for_data
   1.144 +        (data, (cairo_format_t) format, aSize.width, aSize.height, stride);
   1.145 +
   1.146 +    mCGContext = cairo_quartz_surface_get_cg_context (surf);
   1.147 +
   1.148 +    CGContextRetain(mCGContext);
   1.149 +
   1.150 +    Init(surf);
   1.151 +    if (mSurfaceValid) {
   1.152 +      RecordMemoryUsed(mSize.height * stride + sizeof(gfxQuartzSurface));
   1.153 +    }
   1.154 +}
   1.155 +
   1.156 +already_AddRefed<gfxASurface>
   1.157 +gfxQuartzSurface::CreateSimilarSurface(gfxContentType aType,
   1.158 +                                       const gfxIntSize& aSize)
   1.159 +{
   1.160 +    cairo_surface_t *surface =
   1.161 +        cairo_quartz_surface_create_cg_layer(mSurface, (cairo_content_t)aType,
   1.162 +                                             aSize.width, aSize.height);
   1.163 +    if (cairo_surface_status(surface)) {
   1.164 +        cairo_surface_destroy(surface);
   1.165 +        return nullptr;
   1.166 +    }
   1.167 +
   1.168 +    nsRefPtr<gfxASurface> result = Wrap(surface, aSize);
   1.169 +    cairo_surface_destroy(surface);
   1.170 +    return result.forget();
   1.171 +}
   1.172 +
   1.173 +CGContextRef
   1.174 +gfxQuartzSurface::GetCGContextWithClip(gfxContext *ctx)
   1.175 +{
   1.176 +	return cairo_quartz_get_cg_context_with_clip(ctx->GetCairo());
   1.177 +}
   1.178 +
   1.179 +int32_t gfxQuartzSurface::GetDefaultContextFlags() const
   1.180 +{
   1.181 +    if (mForPrinting)
   1.182 +        return gfxContext::FLAG_DISABLE_SNAPPING |
   1.183 +               gfxContext::FLAG_DISABLE_COPY_BACKGROUND;
   1.184 +
   1.185 +    return 0;
   1.186 +}
   1.187 +
   1.188 +already_AddRefed<gfxImageSurface> gfxQuartzSurface::GetAsImageSurface()
   1.189 +{
   1.190 +    cairo_surface_t *surface = cairo_quartz_surface_get_image(mSurface);
   1.191 +    if (!surface || cairo_surface_status(surface))
   1.192 +        return nullptr;
   1.193 +
   1.194 +    nsRefPtr<gfxASurface> img = Wrap(surface);
   1.195 +
   1.196 +    // cairo_quartz_surface_get_image returns a referenced image, and thebes
   1.197 +    // shares the refcounts of Cairo surfaces. However, Wrap also adds a
   1.198 +    // reference to the image. We need to remove one of these references
   1.199 +    // explicitly so we don't leak.
   1.200 +    img->Release();
   1.201 +
   1.202 +    img->SetOpaqueRect(GetOpaqueRect());
   1.203 +
   1.204 +    return img.forget().downcast<gfxImageSurface>();
   1.205 +}
   1.206 +
   1.207 +gfxQuartzSurface::~gfxQuartzSurface()
   1.208 +{
   1.209 +    CGContextRelease(mCGContext);
   1.210 +}

mercurial