Index: trunk/src/skia/ext/skia_utils_mac.mm |
=================================================================== |
--- trunk/src/skia/ext/skia_utils_mac.mm (revision 269961) |
+++ trunk/src/skia/ext/skia_utils_mac.mm (working copy) |
@@ -284,8 +284,11 @@ |
void SkiaBitLocker::releaseIfNeeded() { |
if (!cgContext_) |
return; |
- if (useBitmap_) { |
+ if (useDeviceBits_) { |
+ bitmap_.unlockPixels(); |
+ } else { |
// Find the bits that were drawn to. |
+ SkAutoLockPixels lockedPixels(bitmap_); |
const uint32_t* pixelBase |
= reinterpret_cast<uint32_t*>(bitmap_.getPixels()); |
int rowPixels = bitmap_.rowBytesAsPixels(); |
@@ -367,54 +370,56 @@ |
} |
CGContextRef SkiaBitLocker::cgContext() { |
+ SkBaseDevice* device = canvas_->getTopDevice(); |
+ DCHECK(device); |
+ if (!device) |
+ return 0; |
releaseIfNeeded(); // This flushes any prior bitmap use |
- |
- SkIRect clip_bounds; |
- const bool clip_is_empty = !canvas_->getClipDeviceBounds(&clip_bounds); |
- |
- SkImageInfo info; |
- size_t row_bytes; |
- SkIPoint origin; |
- void* top_pixels = canvas_->accessTopLayerPixels(&info, &row_bytes, &origin); |
- if (top_pixels && (clip_is_empty || canvas_->isClipRect())) { |
- useBitmap_ = false; |
+ const SkBitmap& deviceBits = device->accessBitmap(true); |
+ useDeviceBits_ = deviceBits.getPixels(); |
+ if (useDeviceBits_) { |
+ bitmap_ = deviceBits; |
+ bitmap_.lockPixels(); |
} else { |
- useBitmap_ = true; |
- info = SkImageInfo::MakeN32Premul(clip_bounds.width(), clip_bounds.height()); |
- origin.set(clip_bounds.x(), clip_bounds.y()); |
- CHECK(bitmap_.allocPixels(info)); |
+ bitmap_.setConfig( |
+ SkBitmap::kARGB_8888_Config, deviceBits.width(), deviceBits.height()); |
+ bitmap_.allocPixels(); |
bitmap_.eraseColor(0); |
- top_pixels = bitmap_.getPixels(); |
} |
- |
base::ScopedCFTypeRef<CGColorSpaceRef> colorSpace( |
CGColorSpaceCreateDeviceRGB()); |
- cgContext_ = CGBitmapContextCreate(top_pixels, info.width(), |
- info.height(), 8, row_bytes, colorSpace, |
- kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); |
+ cgContext_ = CGBitmapContextCreate(bitmap_.getPixels(), bitmap_.width(), |
+ bitmap_.height(), 8, bitmap_.rowBytes(), colorSpace, |
+ kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); |
// Apply device matrix. |
CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1); |
contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, |
- -info.height()); |
+ -device->height()); |
CGContextConcatCTM(cgContext_, contentsTransform); |
+ const SkIPoint& pt = device->getOrigin(); |
// Skip applying the clip when not writing directly to device. |
// They're applied in the offscreen case when the bitmap is drawn. |
- if (!useBitmap_) { |
+ if (useDeviceBits_) { |
// Apply clip in device coordinates. |
CGMutablePathRef clipPath = CGPathCreateMutable(); |
- if (clip_is_empty) { |
+ const SkRegion& clipRgn = canvas_->getTotalClip(); |
+ if (clipRgn.isEmpty()) { |
// CoreGraphics does not consider a newly created path to be empty. |
// Explicitly set it to empty so the subsequent drawing is clipped out. |
// It would be better to make the CGContext hidden if there was a CG |
// call that does that. |
CGPathAddRect(clipPath, 0, CGRectMake(0, 0, 0, 0)); |
- } else { |
- SkIRect r = clip_bounds; |
- r.offset(-origin); |
- CGPathAddRect(clipPath, 0, SkIRectToCGRect(r)); |
} |
+ SkRegion::Iterator iter(clipRgn); |
+ const SkIPoint& pt = device->getOrigin(); |
+ for (; !iter.done(); iter.next()) { |
+ SkIRect skRect = iter.rect(); |
+ skRect.offset(-pt); |
+ CGRect cgRect = SkIRectToCGRect(skRect); |
+ CGPathAddRect(clipPath, 0, cgRect); |
+ } |
CGContextAddPath(cgContext_, clipPath); |
CGContextClip(cgContext_); |
CGPathRelease(clipPath); |
@@ -422,7 +427,7 @@ |
// Apply content matrix. |
SkMatrix skMatrix = canvas_->getTotalMatrix(); |
- skMatrix.postTranslate(-SkIntToScalar(origin.fX), -SkIntToScalar(origin.fY)); |
+ skMatrix.postTranslate(-SkIntToScalar(pt.fX), -SkIntToScalar(pt.fY)); |
CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix); |
CGContextConcatCTM(cgContext_, affine); |