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 |