| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #include <time.h> | 7 #include <time.h> |
| 8 | 8 |
| 9 #include "base/ref_counted.h" | 9 #include "base/ref_counted.h" |
| 10 #include "skia/ext/skia_utils_mac.h" | 10 #include "skia/ext/skia_utils_mac.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 } | 39 } |
| 40 } else { | 40 } else { |
| 41 // Fill up available size. | 41 // Fill up available size. |
| 42 *size = available_size - *position; | 42 *size = available_size - *position; |
| 43 } | 43 } |
| 44 return true; | 44 return true; |
| 45 } | 45 } |
| 46 | 46 |
| 47 } // namespace | 47 } // namespace |
| 48 | 48 |
| 49 class BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData : public SkRefCnt { | 49 class BitmapPlatformDevice::BitmapPlatformDeviceData : public SkRefCnt { |
| 50 public: | 50 public: |
| 51 explicit BitmapPlatformDeviceMacData(CGContextRef bitmap); | 51 explicit BitmapPlatformDeviceData(CGContextRef bitmap); |
| 52 | 52 |
| 53 // Create/destroy CoreGraphics context for our bitmap data. | 53 // Create/destroy CoreGraphics context for our bitmap data. |
| 54 CGContextRef GetBitmapContext() { | 54 CGContextRef GetBitmapContext() { |
| 55 LoadConfig(); | 55 LoadConfig(); |
| 56 return bitmap_context_; | 56 return bitmap_context_; |
| 57 } | 57 } |
| 58 | 58 |
| 59 void ReleaseBitmapContext() { | 59 void ReleaseBitmapContext() { |
| 60 SkASSERT(bitmap_context_); | 60 SkASSERT(bitmap_context_); |
| 61 CGContextRelease(bitmap_context_); | 61 CGContextRelease(bitmap_context_); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 81 bool config_dirty_; | 81 bool config_dirty_; |
| 82 | 82 |
| 83 // Translation assigned to the CGContext: we need to keep track of this | 83 // Translation assigned to the CGContext: we need to keep track of this |
| 84 // separately so it can be updated even if the CGContext isn't created yet. | 84 // separately so it can be updated even if the CGContext isn't created yet. |
| 85 SkMatrix transform_; | 85 SkMatrix transform_; |
| 86 | 86 |
| 87 // The current clipping | 87 // The current clipping |
| 88 SkRegion clip_region_; | 88 SkRegion clip_region_; |
| 89 | 89 |
| 90 private: | 90 private: |
| 91 friend class base::RefCounted<BitmapPlatformDeviceMacData>; | 91 friend class base::RefCounted<BitmapPlatformDeviceData>; |
| 92 ~BitmapPlatformDeviceMacData() { | 92 ~BitmapPlatformDeviceData() { |
| 93 if (bitmap_context_) | 93 if (bitmap_context_) |
| 94 CGContextRelease(bitmap_context_); | 94 CGContextRelease(bitmap_context_); |
| 95 } | 95 } |
| 96 | 96 |
| 97 // Disallow copy & assign. | 97 // Disallow copy & assign. |
| 98 BitmapPlatformDeviceMacData(const BitmapPlatformDeviceMacData&); | 98 BitmapPlatformDeviceData(const BitmapPlatformDeviceData&); |
| 99 BitmapPlatformDeviceMacData& operator=(const BitmapPlatformDeviceMacData&); | 99 BitmapPlatformDeviceData& operator=(const BitmapPlatformDeviceData&); |
| 100 }; | 100 }; |
| 101 | 101 |
| 102 BitmapPlatformDeviceMac::\ | 102 BitmapPlatformDevice::BitmapPlatformDeviceData::BitmapPlatformDeviceData( |
| 103 BitmapPlatformDeviceMacData::BitmapPlatformDeviceMacData( | |
| 104 CGContextRef bitmap) | 103 CGContextRef bitmap) |
| 105 : bitmap_context_(bitmap), | 104 : bitmap_context_(bitmap), |
| 106 config_dirty_(true) { // Want to load the config next time. | 105 config_dirty_(true) { // Want to load the config next time. |
| 107 SkASSERT(bitmap_context_); | 106 SkASSERT(bitmap_context_); |
| 108 // Initialize the clip region to the entire bitmap. | 107 // Initialize the clip region to the entire bitmap. |
| 109 | 108 |
| 110 SkIRect rect; | 109 SkIRect rect; |
| 111 rect.set(0, 0, | 110 rect.set(0, 0, |
| 112 CGBitmapContextGetWidth(bitmap_context_), | 111 CGBitmapContextGetWidth(bitmap_context_), |
| 113 CGBitmapContextGetHeight(bitmap_context_)); | 112 CGBitmapContextGetHeight(bitmap_context_)); |
| 114 clip_region_ = SkRegion(rect); | 113 clip_region_ = SkRegion(rect); |
| 115 transform_.reset(); | 114 transform_.reset(); |
| 116 CGContextRetain(bitmap_context_); | 115 CGContextRetain(bitmap_context_); |
| 117 // We must save the state once so that we can use the restore/save trick | 116 // We must save the state once so that we can use the restore/save trick |
| 118 // in LoadConfig(). | 117 // in LoadConfig(). |
| 119 CGContextSaveGState(bitmap_context_); | 118 CGContextSaveGState(bitmap_context_); |
| 120 } | 119 } |
| 121 | 120 |
| 122 void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::SetMatrixClip( | 121 void BitmapPlatformDevice::BitmapPlatformDeviceData::SetMatrixClip( |
| 123 const SkMatrix& transform, | 122 const SkMatrix& transform, |
| 124 const SkRegion& region) { | 123 const SkRegion& region) { |
| 125 transform_ = transform; | 124 transform_ = transform; |
| 126 clip_region_ = region; | 125 clip_region_ = region; |
| 127 config_dirty_ = true; | 126 config_dirty_ = true; |
| 128 } | 127 } |
| 129 | 128 |
| 130 void BitmapPlatformDeviceMac::BitmapPlatformDeviceMacData::LoadConfig() { | 129 void BitmapPlatformDevice::BitmapPlatformDeviceData::LoadConfig() { |
| 131 if (!config_dirty_ || !bitmap_context_) | 130 if (!config_dirty_ || !bitmap_context_) |
| 132 return; // Nothing to do. | 131 return; // Nothing to do. |
| 133 config_dirty_ = false; | 132 config_dirty_ = false; |
| 134 | 133 |
| 135 // Transform. | 134 // Transform. |
| 136 SkMatrix t(transform_); | 135 SkMatrix t(transform_); |
| 137 | 136 |
| 138 // We must restore and then save the state of the graphics context since the | 137 // We must restore and then save the state of the graphics context since the |
| 139 // calls to Load the clipping region to the context are strictly cummulative, | 138 // calls to Load the clipping region to the context are strictly cummulative, |
| 140 // i.e., you can't replace a clip rect, other than with a save/restore. | 139 // i.e., you can't replace a clip rect, other than with a save/restore. |
| 141 // But this implies that no other changes to the state are done elsewhere. | 140 // But this implies that no other changes to the state are done elsewhere. |
| 142 // If we ever get to need to change this, then we must replace the clip rect | 141 // If we ever get to need to change this, then we must replace the clip rect |
| 143 // calls in LoadClippingRegionToCGContext() with an image mask instead. | 142 // calls in LoadClippingRegionToCGContext() with an image mask instead. |
| 144 CGContextRestoreGState(bitmap_context_); | 143 CGContextRestoreGState(bitmap_context_); |
| 145 CGContextSaveGState(bitmap_context_); | 144 CGContextSaveGState(bitmap_context_); |
| 146 LoadTransformToCGContext(bitmap_context_, t); | 145 LoadTransformToCGContext(bitmap_context_, t); |
| 147 t.setTranslateX(-t.getTranslateX()); | 146 t.setTranslateX(-t.getTranslateX()); |
| 148 t.setTranslateY(-t.getTranslateY()); | 147 t.setTranslateY(-t.getTranslateY()); |
| 149 LoadClippingRegionToCGContext(bitmap_context_, clip_region_, t); | 148 LoadClippingRegionToCGContext(bitmap_context_, clip_region_, t); |
| 150 } | 149 } |
| 151 | 150 |
| 152 | 151 |
| 153 // We use this static factory function instead of the regular constructor so | 152 // We use this static factory function instead of the regular constructor so |
| 154 // that we can create the pixel data before calling the constructor. This is | 153 // that we can create the pixel data before calling the constructor. This is |
| 155 // required so that we can call the base class' constructor with the pixel | 154 // required so that we can call the base class' constructor with the pixel |
| 156 // data. | 155 // data. |
| 157 BitmapPlatformDeviceMac* BitmapPlatformDeviceMac::Create(CGContextRef context, | 156 BitmapPlatformDevice* BitmapPlatformDevice::Create(CGContextRef context, |
| 158 int width, | 157 int width, |
| 159 int height, | 158 int height, |
| 160 bool is_opaque) { | 159 bool is_opaque) { |
| 161 SkBitmap bitmap; | 160 SkBitmap bitmap; |
| 162 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); | 161 bitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height); |
| 163 if (bitmap.allocPixels() != true) | 162 if (bitmap.allocPixels() != true) |
| 164 return NULL; | 163 return NULL; |
| 165 void* data = bitmap.getPixels(); | 164 void* data = bitmap.getPixels(); |
| 166 | 165 |
| 167 // Note: The Windows implementation clears the Bitmap later on. | 166 // Note: The Windows implementation clears the Bitmap later on. |
| 168 // This bears mentioning since removal of this line makes the | 167 // This bears mentioning since removal of this line makes the |
| 169 // unit tests only fail periodically (or when MallocPreScribble is set). | 168 // unit tests only fail periodically (or when MallocPreScribble is set). |
| 170 bitmap.eraseARGB(0, 0, 0, 0); | 169 bitmap.eraseARGB(0, 0, 0, 0); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 190 kCGImageAlphaPremultipliedFirst | | 189 kCGImageAlphaPremultipliedFirst | |
| 191 kCGBitmapByteOrder32Host); | 190 kCGBitmapByteOrder32Host); |
| 192 | 191 |
| 193 // Change the coordinate system to match WebCore's | 192 // Change the coordinate system to match WebCore's |
| 194 CGContextTranslateCTM(context, 0, height); | 193 CGContextTranslateCTM(context, 0, height); |
| 195 CGContextScaleCTM(context, 1.0, -1.0); | 194 CGContextScaleCTM(context, 1.0, -1.0); |
| 196 CGColorSpaceRelease(color_space); | 195 CGColorSpaceRelease(color_space); |
| 197 } | 196 } |
| 198 | 197 |
| 199 // The device object will take ownership of the graphics context. | 198 // The device object will take ownership of the graphics context. |
| 200 return new BitmapPlatformDeviceMac( | 199 return new BitmapPlatformDevice( |
| 201 new BitmapPlatformDeviceMacData(context), bitmap); | 200 new BitmapPlatformDeviceData(context), bitmap); |
| 202 } | 201 } |
| 203 | 202 |
| 204 // The device will own the bitmap, which corresponds to also owning the pixel | 203 // The device will own the bitmap, which corresponds to also owning the pixel |
| 205 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. | 204 // data. Therefore, we do not transfer ownership to the SkDevice's bitmap. |
| 206 BitmapPlatformDeviceMac::BitmapPlatformDeviceMac( | 205 BitmapPlatformDevice::BitmapPlatformDevice( |
| 207 BitmapPlatformDeviceMacData* data, const SkBitmap& bitmap) | 206 BitmapPlatformDeviceData* data, const SkBitmap& bitmap) |
| 208 : PlatformDeviceMac(bitmap), | 207 : PlatformDevice(bitmap), |
| 209 data_(data) { | 208 data_(data) { |
| 210 } | 209 } |
| 211 | 210 |
| 212 // The copy constructor just adds another reference to the underlying data. | 211 // The copy constructor just adds another reference to the underlying data. |
| 213 // We use a const cast since the default Skia definitions don't define the | 212 // We use a const cast since the default Skia definitions don't define the |
| 214 // proper constedness that we expect (accessBitmap should really be const). | 213 // proper constedness that we expect (accessBitmap should really be const). |
| 215 BitmapPlatformDeviceMac::BitmapPlatformDeviceMac( | 214 BitmapPlatformDevice::BitmapPlatformDevice( |
| 216 const BitmapPlatformDeviceMac& other) | 215 const BitmapPlatformDevice& other) |
| 217 : PlatformDeviceMac( | 216 : PlatformDevice( |
| 218 const_cast<BitmapPlatformDeviceMac&>(other).accessBitmap(true)), | 217 const_cast<BitmapPlatformDevice&>(other).accessBitmap(true)), |
| 219 data_(other.data_) { | 218 data_(other.data_) { |
| 220 data_->ref(); | 219 data_->ref(); |
| 221 } | 220 } |
| 222 | 221 |
| 223 BitmapPlatformDeviceMac::~BitmapPlatformDeviceMac() { | 222 BitmapPlatformDevice::~BitmapPlatformDevice() { |
| 224 data_->unref(); | 223 data_->unref(); |
| 225 } | 224 } |
| 226 | 225 |
| 227 BitmapPlatformDeviceMac& BitmapPlatformDeviceMac::operator=( | 226 BitmapPlatformDevice& BitmapPlatformDevice::operator=( |
| 228 const BitmapPlatformDeviceMac& other) { | 227 const BitmapPlatformDevice& other) { |
| 229 data_ = other.data_; | 228 data_ = other.data_; |
| 230 data_->ref(); | 229 data_->ref(); |
| 231 return *this; | 230 return *this; |
| 232 } | 231 } |
| 233 | 232 |
| 234 CGContextRef BitmapPlatformDeviceMac::GetBitmapContext() { | 233 CGContextRef BitmapPlatformDevice::GetBitmapContext() { |
| 235 return data_->GetBitmapContext(); | 234 return data_->GetBitmapContext(); |
| 236 } | 235 } |
| 237 | 236 |
| 238 void BitmapPlatformDeviceMac::setMatrixClip(const SkMatrix& transform, | 237 void BitmapPlatformDevice::setMatrixClip(const SkMatrix& transform, |
| 239 const SkRegion& region) { | 238 const SkRegion& region) { |
| 240 data_->SetMatrixClip(transform, region); | 239 data_->SetMatrixClip(transform, region); |
| 241 } | 240 } |
| 242 | 241 |
| 243 void BitmapPlatformDeviceMac::DrawToContext(CGContextRef context, int x, int y, | 242 void BitmapPlatformDevice::DrawToContext(CGContextRef context, int x, int y, |
| 244 const CGRect* src_rect) { | 243 const CGRect* src_rect) { |
| 245 bool created_dc = false; | 244 bool created_dc = false; |
| 246 if (!data_->bitmap_context_) { | 245 if (!data_->bitmap_context_) { |
| 247 created_dc = true; | 246 created_dc = true; |
| 248 GetBitmapContext(); | 247 GetBitmapContext(); |
| 249 } | 248 } |
| 250 | 249 |
| 251 // this should not make a copy of the bits, since we're not doing | 250 // this should not make a copy of the bits, since we're not doing |
| 252 // anything to trigger copy on write | 251 // anything to trigger copy on write |
| 253 CGImageRef image = CGBitmapContextCreateImage(data_->bitmap_context_); | 252 CGImageRef image = CGBitmapContextCreateImage(data_->bitmap_context_); |
| 254 CGRect bounds; | 253 CGRect bounds; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 266 bounds.size.height = height(); | 265 bounds.size.height = height(); |
| 267 CGContextDrawImage(context, bounds, image); | 266 CGContextDrawImage(context, bounds, image); |
| 268 } | 267 } |
| 269 CGImageRelease(image); | 268 CGImageRelease(image); |
| 270 | 269 |
| 271 if (created_dc) | 270 if (created_dc) |
| 272 data_->ReleaseBitmapContext(); | 271 data_->ReleaseBitmapContext(); |
| 273 } | 272 } |
| 274 | 273 |
| 275 // Returns the color value at the specified location. | 274 // Returns the color value at the specified location. |
| 276 SkColor BitmapPlatformDeviceMac::getColorAt(int x, int y) { | 275 SkColor BitmapPlatformDevice::getColorAt(int x, int y) { |
| 277 const SkBitmap& bitmap = accessBitmap(true); | 276 const SkBitmap& bitmap = accessBitmap(true); |
| 278 SkAutoLockPixels lock(bitmap); | 277 SkAutoLockPixels lock(bitmap); |
| 279 uint32_t* data = bitmap.getAddr32(0, 0); | 278 uint32_t* data = bitmap.getAddr32(0, 0); |
| 280 return static_cast<SkColor>(data[x + y * width()]); | 279 return static_cast<SkColor>(data[x + y * width()]); |
| 281 } | 280 } |
| 282 | 281 |
| 283 void BitmapPlatformDeviceMac::onAccessBitmap(SkBitmap*) { | 282 void BitmapPlatformDevice::onAccessBitmap(SkBitmap*) { |
| 284 // Not needed in CoreGraphics | 283 // Not needed in CoreGraphics |
| 285 } | 284 } |
| 286 | 285 |
| 287 void BitmapPlatformDeviceMac::processPixels(int x, int y, | 286 void BitmapPlatformDevice::processPixels(int x, int y, |
| 288 int width, int height, | 287 int width, int height, |
| 289 adjustAlpha adjustor) { | 288 adjustAlpha adjustor) { |
| 290 const SkBitmap& bitmap = accessBitmap(true); | 289 const SkBitmap& bitmap = accessBitmap(true); |
| 291 SkMatrix& matrix = data_->transform_; | 290 SkMatrix& matrix = data_->transform_; |
| 292 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; | 291 int bitmap_start_x = SkScalarRound(matrix.getTranslateX()) + x; |
| 293 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; | 292 int bitmap_start_y = SkScalarRound(matrix.getTranslateY()) + y; |
| 294 | 293 |
| 295 SkAutoLockPixels lock(bitmap); | 294 SkAutoLockPixels lock(bitmap); |
| 296 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && | 295 if (Constrain(bitmap.width(), &bitmap_start_x, &width) && |
| 297 Constrain(bitmap.height(), &bitmap_start_y, &height)) { | 296 Constrain(bitmap.height(), &bitmap_start_y, &height)) { |
| 298 uint32_t* data = bitmap.getAddr32(0, 0); | 297 uint32_t* data = bitmap.getAddr32(0, 0); |
| 299 size_t row_words = bitmap.rowBytes() / 4; | 298 size_t row_words = bitmap.rowBytes() / 4; |
| 300 for (int i = 0; i < height; i++) { | 299 for (int i = 0; i < height; i++) { |
| 301 size_t offset = (i + bitmap_start_y) * row_words + bitmap_start_x; | 300 size_t offset = (i + bitmap_start_y) * row_words + bitmap_start_x; |
| 302 for (int j = 0; j < width; j++) { | 301 for (int j = 0; j < width; j++) { |
| 303 adjustor(data + offset + j); | 302 adjustor(data + offset + j); |
| 304 } | 303 } |
| 305 } | 304 } |
| 306 } | 305 } |
| 307 } | 306 } |
| 308 | 307 |
| 309 } // namespace skia | 308 } // namespace skia |
| OLD | NEW |