blob: 0c9e9d66b6bd5b62eb1db811206ddb83de4497fa [file] [log] [blame]
/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkDevice.h"
#include "SkMetaData.h"
#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888;
#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888;
#else
const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1;
#endif
///////////////////////////////////////////////////////////////////////////////
SkBaseDevice::SkBaseDevice()
: fLeakyProperties(SkDeviceProperties::MakeDefault())
#ifdef SK_DEBUG
, fAttachedToCanvas(false)
#endif
{
fOrigin.setZero();
fMetaData = NULL;
}
SkBaseDevice::SkBaseDevice(const SkDeviceProperties& deviceProperties)
: fLeakyProperties(deviceProperties)
#ifdef SK_DEBUG
, fAttachedToCanvas(false)
#endif
{
fOrigin.setZero();
fMetaData = NULL;
}
SkBaseDevice::~SkBaseDevice() {
delete fMetaData;
}
SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config,
int width, int height,
bool isOpaque) {
return this->onCreateCompatibleDevice(config, width, height,
isOpaque, kGeneral_Usage);
}
SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config,
int width, int height,
bool isOpaque) {
return this->onCreateCompatibleDevice(config, width, height,
isOpaque, kSaveLayer_Usage);
}
SkMetaData& SkBaseDevice::getMetaData() {
// metadata users are rare, so we lazily allocate it. If that changes we
// can decide to just make it a field in the device (rather than a ptr)
if (NULL == fMetaData) {
fMetaData = new SkMetaData;
}
return *fMetaData;
}
const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) {
const SkBitmap& bitmap = this->onAccessBitmap();
if (changePixels) {
bitmap.notifyPixelsChanged();
}
return bitmap;
}
bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y,
SkCanvas::Config8888 config8888) {
if (SkBitmap::kARGB_8888_Config != bitmap->config() ||
NULL != bitmap->getTexture()) {
return false;
}
const SkBitmap& src = this->accessBitmap(false);
SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap->width(),
bitmap->height());
SkIRect devbounds = SkIRect::MakeWH(src.width(), src.height());
if (!srcRect.intersect(devbounds)) {
return false;
}
SkBitmap tmp;
SkBitmap* bmp;
if (bitmap->isNull()) {
tmp.setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(),
bitmap->height());
if (!tmp.allocPixels()) {
return false;
}
bmp = &tmp;
} else {
bmp = bitmap;
}
SkIRect subrect = srcRect;
subrect.offset(-x, -y);
SkBitmap bmpSubset;
bmp->extractSubset(&bmpSubset, subrect);
bool result = this->onReadPixels(bmpSubset,
srcRect.fLeft,
srcRect.fTop,
config8888);
if (result && bmp == &tmp) {
tmp.swap(*bitmap);
}
return result;
}