1/* 2 * Copyright 2016 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#ifndef SkBitmapKey_DEFINED 8#define SkBitmapKey_DEFINED 9 10#include "SkBitmap.h" 11#include "SkImage.h" 12#include "SkCanvas.h" 13 14struct SkBitmapKey { 15 SkIRect fSubset; 16 uint32_t fID; 17 bool operator==(const SkBitmapKey& rhs) const { 18 return fID == rhs.fID && fSubset == rhs.fSubset; 19 } 20 bool operator!=(const SkBitmapKey& rhs) const { return !(*this == rhs); } 21}; 22 23/** 24 This class has all the advantages of SkBitmaps and SkImages. 25 */ 26class SkImageSubset { 27public: 28 SkImageSubset(sk_sp<SkImage> i, SkIRect subset = {0, 0, 0, 0}) 29 : fImage(std::move(i)) { 30 if (!fImage) { 31 fSubset = {0, 0, 0, 0}; 32 fID = 0; 33 return; 34 } 35 fID = fImage->uniqueID(); 36 if (subset.isEmpty()) { 37 fSubset = fImage->bounds(); 38 // SkImage always has a non-zero dimensions. 39 SkASSERT(!fSubset.isEmpty()); 40 } else { 41 fSubset = subset; 42 if (!fSubset.intersect(fImage->bounds())) { 43 fImage = nullptr; 44 fSubset = {0, 0, 0, 0}; 45 fID = 0; 46 } 47 } 48 } 49 50 void setID(uint32_t id) { fID = id; } 51 52 bool isValid() const { return fImage != nullptr; } 53 54 SkIRect bounds() const { return SkIRect::MakeSize(this->dimensions()); } 55 56 SkISize dimensions() const { return fSubset.size(); } 57 58 sk_sp<SkImage> makeImage() const { 59 return fSubset == fImage->bounds() ? fImage : fImage->makeSubset(fSubset); 60 } 61 62 SkBitmapKey getKey() const { return SkBitmapKey{fSubset, fID}; } 63 64 void draw(SkCanvas* canvas, SkPaint* paint) const { 65 SkASSERT(this->isValid()); 66 SkRect src = SkRect::Make(fSubset), 67 dst = SkRect::Make(this->bounds()); 68 canvas->drawImageRect(fImage.get(), src, dst, paint); 69 } 70 71private: 72 SkIRect fSubset; 73 sk_sp<SkImage> fImage; 74 uint32_t fID; 75}; 76 77#endif // SkBitmapKey_DEFINED 78