1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include "SkDevice.h" 10 #include "SkMetaData.h" 11 12 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 13 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kBGRA_Premul_Config8888; 14 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 15 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = SkCanvas::kRGBA_Premul_Config8888; 16 #else 17 const SkCanvas::Config8888 SkBaseDevice::kPMColorAlias = (SkCanvas::Config8888) -1; 18 #endif 19 20 /////////////////////////////////////////////////////////////////////////////// 21 SkBaseDevice::SkBaseDevice() 22 : fLeakyProperties(SkDeviceProperties::MakeDefault()) 23 #ifdef SK_DEBUG 24 , fAttachedToCanvas(false) 25 #endif 26 { 27 fOrigin.setZero(); 28 fMetaData = NULL; 29 } 30 31 SkBaseDevice::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 41 SkBaseDevice::~SkBaseDevice() { 42 delete fMetaData; 43 } 44 45 SkBaseDevice* SkBaseDevice::createCompatibleDevice(SkBitmap::Config config, 46 int width, int height, 47 bool isOpaque) { 48 return this->onCreateCompatibleDevice(config, width, height, 49 isOpaque, kGeneral_Usage); 50 } 51 52 SkBaseDevice* SkBaseDevice::createCompatibleDeviceForSaveLayer(SkBitmap::Config config, 53 int width, int height, 54 bool isOpaque) { 55 return this->onCreateCompatibleDevice(config, width, height, 56 isOpaque, kSaveLayer_Usage); 57 } 58 59 SkMetaData& SkBaseDevice::getMetaData() { 60 // metadata users are rare, so we lazily allocate it. If that changes we 61 // can decide to just make it a field in the device (rather than a ptr) 62 if (NULL == fMetaData) { 63 fMetaData = new SkMetaData; 64 } 65 return *fMetaData; 66 } 67 68 const SkBitmap& SkBaseDevice::accessBitmap(bool changePixels) { 69 const SkBitmap& bitmap = this->onAccessBitmap(); 70 if (changePixels) { 71 bitmap.notifyPixelsChanged(); 72 } 73 return bitmap; 74 } 75 76 bool SkBaseDevice::readPixels(SkBitmap* bitmap, int x, int y, 77 SkCanvas::Config8888 config8888) { 78 if (SkBitmap::kARGB_8888_Config != bitmap->config() || 79 NULL != bitmap->getTexture()) { 80 return false; 81 } 82 83 const SkBitmap& src = this->accessBitmap(false); 84 85 SkIRect srcRect = SkIRect::MakeXYWH(x, y, bitmap->width(), 86 bitmap->height()); 87 SkIRect devbounds = SkIRect::MakeWH(src.width(), src.height()); 88 if (!srcRect.intersect(devbounds)) { 89 return false; 90 } 91 92 SkBitmap tmp; 93 SkBitmap* bmp; 94 if (bitmap->isNull()) { 95 tmp.setConfig(SkBitmap::kARGB_8888_Config, bitmap->width(), 96 bitmap->height()); 97 if (!tmp.allocPixels()) { 98 return false; 99 } 100 bmp = &tmp; 101 } else { 102 bmp = bitmap; 103 } 104 105 SkIRect subrect = srcRect; 106 subrect.offset(-x, -y); 107 SkBitmap bmpSubset; 108 bmp->extractSubset(&bmpSubset, subrect); 109 110 bool result = this->onReadPixels(bmpSubset, 111 srcRect.fLeft, 112 srcRect.fTop, 113 config8888); 114 if (result && bmp == &tmp) { 115 tmp.swap(*bitmap); 116 } 117 return result; 118 } 119