bitmap_platform_device_cairo.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "skia/ext/bitmap_platform_device_cairo.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/platform_canvas.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_OPENBSD)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cairo.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cairo/cairo.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace skia {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void CairoSurfaceReleaseProc(void*, void* context) {
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkASSERT(context);
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  cairo_surface_destroy(static_cast<cairo_surface_t*>(context));
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Back the destination bitmap by a Cairo surface.  The bitmap's
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// pixelRef takes ownership of the passed-in surface and will call
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// cairo_surface_destroy() upon destruction.
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)//
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Note: it may immediately destroy the surface, if it fails to create a bitmap
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// with pixels, thus the caller must either ref() the surface before hand, or
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// it must not refer to the surface after this call.
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool InstallCairoSurfacePixels(SkBitmap* dst,
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               cairo_surface_t* surface,
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               bool is_opaque) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkASSERT(dst);
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!surface) {
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return false;
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SkImageInfo info
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      = SkImageInfo::MakeN32Premul(cairo_image_surface_get_width(surface),
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                   cairo_image_surface_get_height(surface));
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return dst->installPixels(info,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            cairo_image_surface_get_data(surface),
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            cairo_image_surface_get_stride(surface),
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            &CairoSurfaceReleaseProc,
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                            static_cast<void*>(surface));
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_matrix_t cairo_matrix;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_matrix_init(&cairo_matrix,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getScaleX()),
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getSkewY()),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getSkewX()),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getScaleY()),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getTranslateX()),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    SkScalarToFloat(matrix.getTranslateY()));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_set_matrix(context, &cairo_matrix);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadClipToContext(cairo_t* context, const SkRegion& clip) {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_reset_clip(context);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(brettw) support non-rect clips.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkIRect bounding = clip.getBounds();
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_rectangle(context, bounding.fLeft, bounding.fTop,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bounding.fRight - bounding.fLeft,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  bounding.fBottom - bounding.fTop);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_clip(context);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void BitmapPlatformDevice::SetMatrixClip(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkMatrix& transform,
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkRegion& region) {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transform_ = transform;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  clip_region_ = region;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_dirty_ = true;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void BitmapPlatformDevice::LoadConfig() {
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!config_dirty_ || !cairo_)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;  // Nothing to do.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_dirty_ = false;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Load the identity matrix since this is what our clip is relative to.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_matrix_t cairo_matrix;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_matrix_init_identity(&cairo_matrix);
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cairo_set_matrix(cairo_, &cairo_matrix);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LoadClipToContext(cairo_, clip_region_);
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LoadMatrixToContext(cairo_, transform_);
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use this static factory function instead of the regular constructor so
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we can create the pixel data before calling the constructor. This is
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// required so that we can call the base class' constructor with the pixel
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   bool is_opaque,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   cairo_surface_t* surface) {
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cairo_surface_destroy(surface);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // must call this before trying to install the surface, since that may result
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // in the surface being destroyed.
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  cairo_t* cairo = cairo_create(surface);
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap bitmap;
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) {
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    cairo_destroy(cairo);
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return NULL;
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The device object will take ownership of the graphics context.
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return new BitmapPlatformDevice(bitmap, cairo);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   bool is_opaque) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This initializes the bitmap to all zeros.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        width, height);
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BitmapPlatformDevice* device = Create(width, height, is_opaque, surface);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (device && is_opaque)  // Fill with bright bluish green
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    device->eraseColor(SkColorSetARGB(255, 0, 255, 128));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return device;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           int height,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                           bool is_opaque) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Linux port always constructs initialized bitmaps, so there is no extra
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // work to perform here.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Create(width, height, is_opaque);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height,
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   bool is_opaque,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                   uint8_t* data) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_surface_t* surface = cairo_image_surface_create_for_data(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      data, CAIRO_FORMAT_ARGB32, width, height,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Create(width, height, is_opaque, surface);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Ownership of the cairo object is transferred.
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice::BitmapPlatformDevice(
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const SkBitmap& bitmap,
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    cairo_t* cairo)
158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    : SkBitmapDevice(bitmap),
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      cairo_(cairo),
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      config_dirty_(true),
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      transform_(SkMatrix::I()) {  // Want to load the config next time.
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetPlatformDevice(this, this);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice::~BitmapPlatformDevice() {
166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cairo_destroy(cairo_);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const SkImageInfo& info,
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                                   Usage /*usage*/) {
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SkASSERT(info.colorType() == kPMColor_SkColorType);
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return BitmapPlatformDevice::Create(info.width(), info.height(),
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      info.isOpaque());
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cairo_t* BitmapPlatformDevice::BeginPlatformPaint() {
177a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  LoadConfig();
178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cairo_surface_t* surface = cairo_get_target(cairo_);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell cairo to flush anything it has pending.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_surface_flush(surface);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tell Cairo that we (probably) modified (actually, will modify) its pixel
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffer directly.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_surface_mark_dirty(surface);
184a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return cairo_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BitmapPlatformDevice::DrawToNativeContext(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Should never be called on Linux.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkASSERT(false);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const SkRegion& region,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         const SkClipStack&) {
196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  SetMatrixClip(transform, region);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// PlatformCanvas impl
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               uint8_t* data, OnFailureType failureType) {
203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef(
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      BitmapPlatformDevice::Create(width, height, is_opaque, data));
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return CreateCanvas(dev, failureType);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Port of PlatformBitmap to linux
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformBitmap::~PlatformBitmap() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cairo_destroy(surface_);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The SkBitmap allocates and owns the bitmap memory; PlatformBitmap owns the
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // cairo drawing context tied to the bitmap. The SkBitmap's pixelRef can
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // outlive the PlatformBitmap if additional copies are made.
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  cairo_surface_t* surf = cairo_image_surface_create(
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CAIRO_FORMAT_ARGB32,
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      width,
222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      height);
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cairo_surface_destroy(surf);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return InstallCairoSurfacePixels(&bitmap_, surf, is_opaque);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace skia
231