OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_mac.h" | 5 #include "skia/ext/bitmap_platform_device_mac.h" |
6 | 6 |
7 #import <ApplicationServices/ApplicationServices.h> | 7 #import <ApplicationServices/ApplicationServices.h> |
8 #include <time.h> | 8 #include <time.h> |
9 | 9 |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 } | 89 } |
90 | 90 |
91 | 91 |
92 // We use this static factory function instead of the regular constructor so | 92 // We use this static factory function instead of the regular constructor so |
93 // that we can create the pixel data before calling the constructor. This is | 93 // that we can create the pixel data before calling the constructor. This is |
94 // required so that we can call the base class' constructor with the pixel | 94 // required so that we can call the base class' constructor with the pixel |
95 // data. | 95 // data. |
96 BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context, | 96 BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context, |
97 int width, | 97 int width, |
98 int height, | 98 int height, |
99 bool is_opaque) { | 99 bool is_opaque, |
| 100 bool do_clear) { |
100 if (RasterDeviceTooBigToAllocate(width, height)) | 101 if (RasterDeviceTooBigToAllocate(width, height)) |
101 return NULL; | 102 return NULL; |
102 | 103 |
103 SkBitmap bitmap; | 104 SkBitmap bitmap; |
104 // TODO: verify that the CG Context's pixels will have tight rowbytes or pass
in the correct | 105 // TODO: verify that the CG Context's pixels will have tight rowbytes or pass
in the correct |
105 // rowbytes for the case when context != NULL. | 106 // rowbytes for the case when context != NULL. |
106 bitmap.setInfo(SkImageInfo::MakeN32(width, height, is_opaque ? kOpaque_SkAlpha
Type : kPremul_SkAlphaType)); | 107 bitmap.setInfo(SkImageInfo::MakeN32(width, height, is_opaque ? kOpaque_SkAlpha
Type : kPremul_SkAlphaType)); |
107 | 108 |
108 void* data; | 109 void* data; |
109 if (context) { | 110 if (context) { |
110 data = CGBitmapContextGetData(context); | 111 data = CGBitmapContextGetData(context); |
111 bitmap.setPixels(data); | 112 bitmap.setPixels(data); |
112 } else { | 113 } else { |
113 if (!bitmap.tryAllocPixels()) | 114 if (!bitmap.tryAllocPixels()) |
114 return NULL; | 115 return NULL; |
115 data = bitmap.getPixels(); | 116 data = bitmap.getPixels(); |
116 } | 117 } |
| 118 if (do_clear) |
| 119 memset(data, 0, bitmap.getSafeSize()); |
117 | 120 |
118 // If we were given data, then don't clobber it! | 121 // If we were given data, then don't clobber it! |
119 #ifndef NDEBUG | 122 #ifndef NDEBUG |
120 if (!context && is_opaque) { | 123 if (!context && is_opaque) { |
121 // To aid in finding bugs, we set the background color to something | 124 // To aid in finding bugs, we set the background color to something |
122 // obviously wrong so it will be noticable when it is not cleared | 125 // obviously wrong so it will be noticable when it is not cleared |
123 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green | 126 bitmap.eraseARGB(255, 0, 255, 128); // bright bluish green |
124 } | 127 } |
125 #endif | 128 #endif |
126 | 129 |
127 if (!context) { | 130 if (!context) { |
128 context = CGContextForData(data, width, height); | 131 context = CGContextForData(data, width, height); |
129 if (!context) | 132 if (!context) |
130 return NULL; | 133 return NULL; |
131 } else | 134 } else |
132 CGContextRetain(context); | 135 CGContextRetain(context); |
133 | 136 |
134 BitmapPlatformDevice* rv = new BitmapPlatformDevice(context, bitmap); | 137 BitmapPlatformDevice* rv = new BitmapPlatformDevice(context, bitmap); |
135 | 138 |
136 // The device object took ownership of the graphics context with its own | 139 // The device object took ownership of the graphics context with its own |
137 // CGContextRetain call. | 140 // CGContextRetain call. |
138 CGContextRelease(context); | 141 CGContextRelease(context); |
139 | 142 |
140 return rv; | 143 return rv; |
141 } | 144 } |
142 | 145 |
143 BitmapPlatformDevice* BitmapPlatformDevice::CreateAndClear(int width, | |
144 int height, | |
145 bool is_opaque) { | |
146 BitmapPlatformDevice* device = Create(NULL, width, height, is_opaque); | |
147 if (!is_opaque) | |
148 device->clear(0); | |
149 return device; | |
150 } | |
151 | |
152 BitmapPlatformDevice* BitmapPlatformDevice::CreateWithData(uint8_t* data, | 146 BitmapPlatformDevice* BitmapPlatformDevice::CreateWithData(uint8_t* data, |
153 int width, | 147 int width, |
154 int height, | 148 int height, |
155 bool is_opaque) { | 149 bool is_opaque) { |
156 CGContextRef context = NULL; | 150 CGContextRef context = NULL; |
157 if (data) | 151 if (data) |
158 context = CGContextForData(data, width, height); | 152 context = CGContextForData(data, width, height); |
159 | 153 |
160 BitmapPlatformDevice* rv = Create(context, width, height, is_opaque); | 154 BitmapPlatformDevice* rv = Create(context, width, height, is_opaque, false); |
161 | 155 |
162 // The device object took ownership of the graphics context with its own | 156 // The device object took ownership of the graphics context with its own |
163 // CGContextRetain call. | 157 // CGContextRetain call. |
164 if (context) | 158 if (context) |
165 CGContextRelease(context); | 159 CGContextRelease(context); |
166 | 160 |
167 return rv; | 161 return rv; |
168 } | 162 } |
169 | 163 |
170 // The device will own the bitmap, which corresponds to also owning the pixel | 164 // The device will own the bitmap, which corresponds to also owning the pixel |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 bounds.size.height = height(); | 225 bounds.size.height = height(); |
232 CGContextDrawImage(context, bounds, image); | 226 CGContextDrawImage(context, bounds, image); |
233 } | 227 } |
234 CGImageRelease(image); | 228 CGImageRelease(image); |
235 | 229 |
236 if (created_dc) | 230 if (created_dc) |
237 ReleaseBitmapContext(); | 231 ReleaseBitmapContext(); |
238 } | 232 } |
239 | 233 |
240 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice( | 234 SkBaseDevice* BitmapPlatformDevice::onCreateCompatibleDevice( |
241 const CreateInfo& info) { | 235 const CreateInfo& cinfo) { |
242 SkASSERT(info.fInfo.colorType() == kN32_SkColorType); | 236 const SkImageInfo& info = cinfo.fInfo; |
243 return BitmapPlatformDevice::CreateAndClear(info.fInfo.width(), | 237 const bool do_clear = !info.isOpaque(); |
244 info.fInfo.height(), | 238 SkASSERT(info.colorType() == kN32_SkColorType); |
245 info.fInfo.isOpaque()); | 239 return Create(NULL, info.width(), info.height(), info.isOpaque(), do_clear); |
246 } | 240 } |
247 | 241 |
248 // PlatformCanvas impl | 242 // PlatformCanvas impl |
249 | 243 |
250 SkCanvas* CreatePlatformCanvas(CGContextRef ctx, int width, int height, | 244 SkCanvas* CreatePlatformCanvas(CGContextRef ctx, int width, int height, |
251 bool is_opaque, OnFailureType failureType) { | 245 bool is_opaque, OnFailureType failureType) { |
| 246 const bool do_clear = false; |
252 skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef( | 247 skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef( |
253 BitmapPlatformDevice::Create(ctx, width, height, is_opaque)); | 248 BitmapPlatformDevice::Create(ctx, width, height, is_opaque, do_clear)); |
254 return CreateCanvas(dev, failureType); | 249 return CreateCanvas(dev, failureType); |
255 } | 250 } |
256 | 251 |
257 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, | 252 SkCanvas* CreatePlatformCanvas(int width, int height, bool is_opaque, |
258 uint8_t* data, OnFailureType failureType) { | 253 uint8_t* data, OnFailureType failureType) { |
259 skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef( | 254 skia::RefPtr<SkBaseDevice> dev = skia::AdoptRef( |
260 BitmapPlatformDevice::CreateWithData(data, width, height, is_opaque)); | 255 BitmapPlatformDevice::CreateWithData(data, width, height, is_opaque)); |
261 return CreateCanvas(dev, failureType); | 256 return CreateCanvas(dev, failureType); |
262 } | 257 } |
263 | 258 |
(...skipping 13 matching lines...) Expand all Loading... |
277 | 272 |
278 if (!is_opaque) | 273 if (!is_opaque) |
279 bitmap_.eraseColor(0); | 274 bitmap_.eraseColor(0); |
280 | 275 |
281 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), | 276 surface_ = CGContextForData(bitmap_.getPixels(), bitmap_.width(), |
282 bitmap_.height()); | 277 bitmap_.height()); |
283 return true; | 278 return true; |
284 } | 279 } |
285 | 280 |
286 } // namespace skia | 281 } // namespace skia |
OLD | NEW |