#include "config.h"
#include "BitLockerSkia.h"
#include "IntRect.h"
#include "SkCanvas.h"
#include "SkDevice.h"
#include "SkRegion.h"
#include <CoreGraphics/CoreGraphics.h>
namespace WebCore {
static CGAffineTransform SkMatrixToCGAffineTransform(const SkMatrix& matrix)
{
ASSERT(!matrix[SkMatrix::kMPersp0]);
ASSERT(!matrix[SkMatrix::kMPersp1]);
ASSERT(matrix[SkMatrix::kMPersp2] == 1.0f);
return CGAffineTransformMake(
matrix[SkMatrix::kMScaleX],
matrix[SkMatrix::kMSkewY],
matrix[SkMatrix::kMSkewX],
matrix[SkMatrix::kMScaleY],
matrix[SkMatrix::kMTransX],
matrix[SkMatrix::kMTransY]);
}
BitLockerSkia::BitLockerSkia(SkCanvas* canvas)
: m_canvas(canvas)
, m_cgContext(0)
{
}
BitLockerSkia::~BitLockerSkia()
{
releaseIfNeeded();
}
void BitLockerSkia::releaseIfNeeded()
{
if (!m_cgContext)
return;
m_canvas->getDevice()->accessBitmap(true).unlockPixels();
CGContextRelease(m_cgContext);
m_cgContext = 0;
}
CGContextRef BitLockerSkia::cgContext()
{
SkDevice* device = m_canvas->getDevice();
ASSERT(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);
CGAffineTransform contentsTransform = CGAffineTransformMakeScale(1, -1);
contentsTransform = CGAffineTransformTranslate(contentsTransform, 0, -device->height());
CGContextConcatCTM(m_cgContext, contentsTransform);
CGMutablePathRef clipPath = CGPathCreateMutable();
SkRegion::Iterator iter(m_canvas->getTotalClip());
for (; !iter.done(); iter.next()) {
IntRect rect = iter.rect();
CGPathAddRect(clipPath, 0, rect);
}
CGContextAddPath(m_cgContext, clipPath);
CGContextClip(m_cgContext);
CGPathRelease(clipPath);
const SkMatrix& skMatrix = m_canvas->getTotalMatrix();
CGAffineTransform affine = SkMatrixToCGAffineTransform(skMatrix);
CGContextConcatCTM(m_cgContext, affine);
return m_cgContext;
}
}