Chromium Code Reviews| Index: skia/ext/skia_utils_mac.mm |
| =================================================================== |
| --- skia/ext/skia_utils_mac.mm (revision 85477) |
| +++ skia/ext/skia_utils_mac.mm (working copy) |
| @@ -7,10 +7,12 @@ |
| #import <AppKit/AppKit.h> |
| #include "base/logging.h" |
| +#include "base/mac/mac_util.h" |
| #include "base/mac/scoped_cftyperef.h" |
| #include "base/memory/scoped_nsobject.h" |
| #include "base/memory/scoped_ptr.h" |
| #include "skia/ext/bitmap_platform_device_mac.h" |
| +#include "third_party/skia/include/core/SkRegion.h" |
| #include "third_party/skia/include/utils/mac/SkCGUtils.h" |
| #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| @@ -284,4 +286,61 @@ |
| return NSImageToSkBitmap(image, NSMakeSize(size, size), /* is_opaque=*/true); |
| } |
| + |
| +SkiaBitLocker::SkiaBitLocker(SkCanvas* canvas) |
| + : m_canvas(canvas) |
| + , m_cgContext(0) { |
|
Nico
2011/05/16 15:13:00
, goes on previous line
_cary
2011/05/16 15:58:02
Done.
|
| +} |
| + |
| +SkiaBitLocker::~SkiaBitLocker() { |
| + releaseIfNeeded(); |
| +} |
| + |
| +void SkiaBitLocker::releaseIfNeeded() { |
| + if (!m_cgContext) |
| + return; |
| + m_canvas->getDevice()->accessBitmap(true).unlockPixels(); |
| + CGContextRelease(m_cgContext); |
| + m_cgContext = 0; |
| +} |
| + |
| +CGContextRef SkiaBitLocker::cgContext() { |
| + SkDevice* device = m_canvas->getDevice(); |
| + DCHECK(device); |
| + if (!device) |
| + return 0; |
| + releaseIfNeeded(); |
| + const SkBitmap& bitmap = device->accessBitmap(true); |
| + bitmap.lockPixels(); |
| + void* pixels = bitmap.getPixels(); |
| + m_cgContext = CGBitmapContextCreate(pixels, device->width(), |
| + device->height(), 8, bitmap.rowBytes(), CGColorSpaceCreateDeviceRGB(), |
| + kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst); |
| + |
| + // Apply device matrix. |
| + CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1); |
| + contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, |
| + -device->height()); |
| + CGContextConcatCTM(m_cgContext, contentsTransform); |
| + |
| + // Apply clip in device coordinates. |
| + CGMutablePathRef clipPath = CGPathCreateMutable(); |
| + SkRegion::Iterator iter(m_canvas->getTotalClip()); |
| + for (; !iter.done(); iter.next()) { |
| + const SkIRect& skRect = iter.rect(); |
| + CGRect cgRect = SkIRectToCGRect(skRect); |
| + CGPathAddRect(clipPath, 0, cgRect); |
| + } |
| + CGContextAddPath(m_cgContext, clipPath); |
| + CGContextClip(m_cgContext); |
| + CGPathRelease(clipPath); |
| + |
| + // Apply content matrix. |
| + const SkMatrix& skMatrix = m_canvas->getTotalMatrix(); |
| + CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix); |
| + CGContextConcatCTM(m_cgContext, affine); |
| + |
| + return m_cgContext; |
| +} |
| + |
| } // namespace gfx |