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 ///////////////////////////////////////////////////////////////////////////////
SkBaseDevice()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
SkBaseDevice(const SkDeviceProperties & deviceProperties)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
~SkBaseDevice()41 SkBaseDevice::~SkBaseDevice() {
42 delete fMetaData;
43 }
44
createCompatibleDevice(SkBitmap::Config config,int width,int height,bool isOpaque)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
createCompatibleDeviceForSaveLayer(SkBitmap::Config config,int width,int height,bool isOpaque)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
getMetaData()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
accessBitmap(bool changePixels)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
readPixels(SkBitmap * bitmap,int x,int y,SkCanvas::Config8888 config8888)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