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