• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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