Home | History | Annotate | Download | only in core
      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