| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "skia/ext/bitmap_platform_device_cairo.h" | 5 #include "skia/ext/bitmap_platform_device_cairo.h" |
| 6 #include "skia/ext/platform_canvas.h" | 6 #include "skia/ext/platform_canvas.h" |
| 7 | 7 |
| 8 #if defined(OS_OPENBSD) | 8 #if defined(OS_OPENBSD) |
| 9 #include <cairo.h> | 9 #include <cairo.h> |
| 10 #else | 10 #else |
| 11 #include <cairo/cairo.h> | 11 #include <cairo/cairo.h> |
| 12 #endif | 12 #endif |
| 13 | 13 |
| 14 namespace skia { | 14 namespace skia { |
| 15 | 15 |
| 16 namespace { | 16 namespace { |
| 17 | 17 |
| 18 void CairoSurfaceReleaseProc(void*, void* context) { | 18 void CairoSurfaceReleaseProc(void*, void* context) { |
| 19 SkASSERT(context); | 19 SkASSERT(context); |
| 20 cairo_surface_destroy(static_cast<cairo_surface_t*>(context)); | 20 cairo_surface_destroy(static_cast<cairo_surface_t*>(context)); |
| 21 } | 21 } |
| 22 | 22 |
| 23 // Back the destination bitmap by a Cairo surface. The bitmap's | 23 // Back the destination bitmap by a Cairo surface. The bitmap's |
| 24 // pixelRef takes ownership of the passed-in surface and will call | 24 // pixelRef takes ownership of the passed-in surface and will call |
| 25 // cairo_surface_destroy() upon destruction. | 25 // cairo_surface_destroy() upon destruction. |
| 26 // |
| 27 // Note: it may immediately destroy the surface, if it fails to create a bitmap |
| 28 // with pixels, thus the caller must either ref() the surface before hand, or |
| 29 // it must not refer to the surface after this call. |
| 26 bool InstallCairoSurfacePixels(SkBitmap* dst, | 30 bool InstallCairoSurfacePixels(SkBitmap* dst, |
| 27 cairo_surface_t* surface, | 31 cairo_surface_t* surface, |
| 28 bool is_opaque) { | 32 bool is_opaque) { |
| 29 SkASSERT(dst); | 33 SkASSERT(dst); |
| 30 if (!surface) { | 34 if (!surface) { |
| 31 return false; | 35 return false; |
| 32 } | 36 } |
| 33 SkImageInfo info | 37 SkImageInfo info |
| 34 = SkImageInfo::MakeN32Premul(cairo_image_surface_get_width(surface), | 38 = SkImageInfo::MakeN32Premul(cairo_image_surface_get_width(surface), |
| 35 cairo_image_surface_get_height(surface)); | 39 cairo_image_surface_get_height(surface)); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 // required so that we can call the base class' constructor with the pixel | 96 // required so that we can call the base class' constructor with the pixel |
| 93 // data. | 97 // data. |
| 94 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, | 98 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, |
| 95 bool is_opaque, | 99 bool is_opaque, |
| 96 cairo_surface_t* surface) { | 100 cairo_surface_t* surface) { |
| 97 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { | 101 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS) { |
| 98 cairo_surface_destroy(surface); | 102 cairo_surface_destroy(surface); |
| 99 return NULL; | 103 return NULL; |
| 100 } | 104 } |
| 101 | 105 |
| 106 // must call this before trying to install the surface, since that may result |
| 107 // in the surface being destroyed. |
| 108 cairo_t* cairo = cairo_create(surface); |
| 109 |
| 102 SkBitmap bitmap; | 110 SkBitmap bitmap; |
| 103 if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) { | 111 if (!InstallCairoSurfacePixels(&bitmap, surface, is_opaque)) { |
| 112 cairo_destroy(cairo); |
| 104 return NULL; | 113 return NULL; |
| 105 } | 114 } |
| 106 | 115 |
| 107 // The device object will take ownership of the graphics context. | 116 // The device object will take ownership of the graphics context. |
| 108 return new BitmapPlatformDevice(bitmap, surface); | 117 return new BitmapPlatformDevice(bitmap, cairo); |
| 109 } | 118 } |
| 110 | 119 |
| 111 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, | 120 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, |
| 112 bool is_opaque) { | 121 bool is_opaque) { |
| 113 // This initializes the bitmap to all zeros. | 122 // This initializes the bitmap to all zeros. |
| 114 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, | 123 cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, |
| 115 width, height); | 124 width, height); |
| 116 | 125 |
| 117 BitmapPlatformDevice* device = Create(width, height, is_opaque, surface); | 126 BitmapPlatformDevice* device = Create(width, height, is_opaque, surface); |
| 118 | 127 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 135 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, | 144 BitmapPlatformDevice* BitmapPlatformDevice::Create(int width, int height, |
| 136 bool is_opaque, | 145 bool is_opaque, |
| 137 uint8_t* data) { | 146 uint8_t* data) { |
| 138 cairo_surface_t* surface = cairo_image_surface_create_for_data( | 147 cairo_surface_t* surface = cairo_image_surface_create_for_data( |
| 139 data, CAIRO_FORMAT_ARGB32, width, height, | 148 data, CAIRO_FORMAT_ARGB32, width, height, |
| 140 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width)); | 149 cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width)); |
| 141 | 150 |
| 142 return Create(width, height, is_opaque, surface); | 151 return Create(width, height, is_opaque, surface); |
| 143 } | 152 } |
| 144 | 153 |
| 145 // The device will own the bitmap, which corresponds to also owning the pixel | 154 // Ownership of the cairo object is transferred. |
| 146 // data. Therefore, we do not transfer ownership to the SkBitmapDevice's bitmap. | |
| 147 BitmapPlatformDevice::BitmapPlatformDevice( | 155 BitmapPlatformDevice::BitmapPlatformDevice( |
| 148 const SkBitmap& bitmap, | 156 const SkBitmap& bitmap, |
| 149 cairo_surface_t* surface) | 157 cairo_t* cairo) |
| 150 : SkBitmapDevice(bitmap), | 158 : SkBitmapDevice(bitmap), |
| 151 cairo_(cairo_create(surface)), | 159 cairo_(cairo), |
| 152 config_dirty_(true), | 160 config_dirty_(true), |
| 153 transform_(SkMatrix::I()) { // Want to load the config next time. | 161 transform_(SkMatrix::I()) { // Want to load the config next time. |
| 154 SetPlatformDevice(this, this); | 162 SetPlatformDevice(this, this); |
| 155 } | 163 } |
| 156 | 164 |
| 157 BitmapPlatformDevice::~BitmapPlatformDevice() { | 165 BitmapPlatformDevice::~BitmapPlatformDevice() { |
| 158 cairo_destroy(cairo_); | 166 cairo_destroy(cairo_); |
| 159 } | 167 } |
| 160 | 168 |
| 161 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice( | 169 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice( |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 width, | 221 width, |
| 214 height); | 222 height); |
| 215 if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) { | 223 if (cairo_surface_status(surf) != CAIRO_STATUS_SUCCESS) { |
| 216 cairo_surface_destroy(surf); | 224 cairo_surface_destroy(surf); |
| 217 return false; | 225 return false; |
| 218 } | 226 } |
| 219 return InstallCairoSurfacePixels(&bitmap_, surf, is_opaque); | 227 return InstallCairoSurfacePixels(&bitmap_, surf, is_opaque); |
| 220 } | 228 } |
| 221 | 229 |
| 222 } // namespace skia | 230 } // namespace skia |
| OLD | NEW |