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), 4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) NULL, 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CairoSurfaceReleaseProc, 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<void*>(surface)); 46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadMatrixToContext(cairo_t* context, const SkMatrix& matrix) { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_matrix_t cairo_matrix; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_matrix_init(&cairo_matrix, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getScaleX()), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getSkewY()), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getSkewX()), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getScaleY()), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getTranslateX()), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkScalarToFloat(matrix.getTranslateY())); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_set_matrix(context, &cairo_matrix); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void LoadClipToContext(cairo_t* context, const SkRegion& clip) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_reset_clip(context); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(brettw) support non-rect clips. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkIRect bounding = clip.getBounds(); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_rectangle(context, bounding.fLeft, bounding.fTop, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounding.fRight - bounding.fLeft, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounding.fBottom - bounding.fTop); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_clip(context); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void BitmapPlatformDevice::SetMatrixClip( 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkMatrix& transform, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkRegion& region) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transform_ = transform; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) clip_region_ = region; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_dirty_ = true; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void BitmapPlatformDevice::LoadConfig() { 82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!config_dirty_ || !cairo_) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Nothing to do. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config_dirty_ = false; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load the identity matrix since this is what our clip is relative to. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_matrix_t cairo_matrix; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_matrix_init_identity(&cairo_matrix); 89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cairo_set_matrix(cairo_, &cairo_matrix); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LoadClipToContext(cairo_, clip_region_); 92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LoadMatrixToContext(cairo_, transform_); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use this static factory function instead of the regular constructor so 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that we can create the pixel data before calling the constructor. This is 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// required so that we can call the base class' constructor with the pixel 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque, 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_t* surface) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_destroy(surface); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // must call this before trying to install the surface, since that may result 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // in the surface being destroyed. 109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cairo_t* cairo = cairo_create(surface); 110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkBitmap bitmap; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) { 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cairo_destroy(cairo); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return NULL; 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The device object will take ownership of the graphics context. 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new BitmapPlatformDevice(bitmap, cairo); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This initializes the bitmap to all zeros. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) width, height); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BitmapPlatformDevice* device = Create(width, height, is_opaque, surface); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (device && is_opaque) // Fill with bright bluish green 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) device->eraseColor(SkColorSetARGB(255, 0, 255, 128)); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return device; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The Linux port always constructs initialized bitmaps, so there is no extra 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // work to perform here. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Create(width, height, is_opaque); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_opaque, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8_t* data) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_t* surface = cairo_image_surface_create_for_data( 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data, CAIRO_FORMAT_ARGB32, width, height, 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width)); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Create(width, height, is_opaque, surface); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Ownership of the cairo object is transferred. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice::BitmapPlatformDevice( 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkBitmap& bitmap, 158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cairo_t* cairo) 159424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : SkBitmapDevice(bitmap), 160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) cairo_(cairo), 161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) config_dirty_(true), 162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) transform_(SkMatrix::I()) { // Want to load the config next time. 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetPlatformDevice(this, this); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BitmapPlatformDevice::~BitmapPlatformDevice() { 167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cairo_destroy(cairo_); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)SkBaseDevice* BitmapPlatformDevice::onCreateDevice(const SkImageInfo& info, 171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Usage /*usage*/) { 172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SkASSERT(info.colorType() == kN32_SkColorType); 173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return BitmapPlatformDevice::Create(info.width(), info.height(), 174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) info.isOpaque()); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)cairo_t* BitmapPlatformDevice::BeginPlatformPaint() { 178a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) LoadConfig(); 179a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cairo_surface_t* surface = cairo_get_target(cairo_); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell cairo to flush anything it has pending. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_flush(surface); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell Cairo that we (probably) modified (actually, will modify) its pixel 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffer directly. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_mark_dirty(surface); 185a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return cairo_; 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BitmapPlatformDevice::DrawToNativeContext( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformSurface surface, int x, int y, const PlatformRect* src_rect) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Should never be called on Linux. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SkASSERT(false); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkRegion& region, 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const SkClipStack&) { 197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) SetMatrixClip(transform, region); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// PlatformCanvas impl 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8_t* data, OnFailureType failureType) { 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef( 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BitmapPlatformDevice::Create(width, height, is_opaque, data)); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return CreateCanvas(dev, failureType); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Port of PlatformBitmap to linux 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformBitmap::~PlatformBitmap() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_destroy(surface_); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformBitmap::Allocate(int width, int height, bool is_opaque) { 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The SkBitmap allocates and owns the bitmap memory; PlatformBitmap owns the 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // cairo drawing context tied to the bitmap. The SkBitmap's pixelRef can 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // outlive the PlatformBitmap if additional copies are made. 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) cairo_surface_t* surf = cairo_image_surface_create( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CAIRO_FORMAT_ARGB32, 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) width, 223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) height); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cairo_surface_destroy(surf); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return InstallCairoSurfacePixels(&bitmap_, surf, is_opaque); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace skia 232