SkDevice.cpp revision 900ecf2f1579d42c9d2959831787af0346320f86
1/* 2 * Copyright 2011 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8#include "SkDevice.h" 9#include "SkMetaData.h" 10 11#if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 12 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888; 13#elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 14 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888; 15#else 16 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1; 17#endif 18 19/////////////////////////////////////////////////////////////////////////////// 20 21SkBaseDevice::SkBaseDevice() 22 : fLeakyProperties(SkDeviceProperties::MakeDefault()) 23#ifdef SK_DEBUG 24 , fAttachedToCanvas(false) 25#endif 26{ 27 fOrigin.setZero(); 28 fMetaData = NULL; 29} 30 31SkBaseDevice::SkBaseDevice(const SkDeviceProperties& deviceProperties) 32 : fLeakyProperties(deviceProperties) 33#ifdef SK_DEBUG 34 , fAttachedToCanvas(false) 35#endif 36{ 37 fOrigin.setZero(); 38 fMetaData = NULL; 39} 40 41SkBaseDevice::~SkBaseDevice() { 42 delete fMetaData; 43} 44 45SkBaseDevice* SkBaseDevice::createCompatibleDevice(const SkImageInfo& info) { 46#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 47 // We call the old method to support older subclasses. 48 // If they have, we return their device, else we use the new impl. 49 SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); 50 SkBaseDevice* dev = this->onCreateCompatibleDevice(config, 51 info.width(), 52 info.height(), 53 info.isOpaque(), 54 kGeneral_Usage); 55 if (dev) { 56 return dev; 57 } 58 // fall through to new impl 59#endif 60 return this->onCreateDevice(info, kGeneral_Usage); 61} 62 63SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(const SkImageInfo& info) { 64#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 65 // We call the old method to support older subclasses. 66 // If they have, we return their device, else we use the new impl. 67 SkBitmap::Config config = SkColorTypeToBitmapConfig(info.colorType()); 68 SkBaseDevice* dev = this->onCreateCompatibleDevice(config, 69 info.width(), 70 info.height(), 71 info.isOpaque(), 72 kSaveLayer_Usage); 73 if (dev) { 74 return dev; 75 } 76 // fall through to new impl 77#endif 78 return this->onCreateDevice(info, kSaveLayer_Usage); 79} 80 81#ifdef SK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG 82SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config, 83 int width, int height, 84 bool isOpaque) { 85 SkImageInfo info = SkImageInfo::Make(width, height, 86 SkBitmapConfigToColorType(config), 87 isOpaque ? kOpaque_SkAlphaType 88 : kPremul_SkAlphaType); 89 return this->createCompatibleDevice(info); 90} 91#endif 92 93SkMetaData& SkBaseDevice::getMetaData() { 94 // metadata users are rare, so we lazily allocate it. If that changes we 95 // can decide to just make it a field in the device (rather than a ptr) 96 if (NULL == fMetaData) { 97 fMetaData = new SkMetaData; 98 } 99 return *fMetaData; 100} 101 102// TODO: should make this guy pure-virtual. 103SkImageInfo SkBaseDevice::imageInfo() const { 104 return SkImageInfo::MakeUnknown(this->width(), this->height()); 105} 106 107const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) { 108 const SkBitmap& bitmap = this->onAccessBitmap(); 109 if (changePixels) { 110 bitmap.notifyPixelsChanged(); 111 } 112 return bitmap; 113} 114 115bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y, 116 SkCanvas::Config8888 config8888) { 117 if (SkBitmap::kARGB_8888_Config != bitmap->config() || 118 NULL != bitmap->getTexture()) { 119 return false; 120 } 121 122 const SkBitmap& src = this->accessBitmap(false); 123 124 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap->width(), 125 bitmap->height()); 126 SkIRect devbounds = SkIRect::MakeWH(src.width(), src.height()); 127 if (!srcRect.intersect(devbounds)) { 128 return false; 129 } 130 131 SkBitmap tmp; 132 SkBitmap* bmp; 133 if (bitmap->isNull()) { 134 if (!tmp.allocPixels(SkImageInfo::MakeN32Premul(bitmap->width(), 135 bitmap->height()))) { 136 return false; 137 } 138 bmp = &tmp; 139 } else { 140 bmp = bitmap; 141 } 142 143 SkIRect subrect = srcRect; 144 subrect.offset(-x, -y); 145 SkBitmap bmpSubset; 146 bmp->extractSubset(&bmpSubset, subrect); 147 148 bool result = this->onReadPixels(bmpSubset, 149 srcRect.fLeft, 150 srcRect.fTop, 151 config8888); 152 if (result && bmp == &tmp) { 153 tmp.swap(*bitmap); 154 } 155 return result; 156} 157 158SkSurface* SkBaseDevice::newSurface(const SkImageInfo&) { return NULL; } 159 160const void* SkBaseDevice::peekPixels(SkImageInfo*, size_t*) { return NULL; } 161