/* * Copyright 2016 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef SkBitmapKey_DEFINED #define SkBitmapKey_DEFINED #include "SkBitmap.h" #include "SkImage.h" #include "SkCanvas.h" struct SkBitmapKey { SkIRect fSubset; uint32_t fID; bool operator==(const SkBitmapKey& rhs) const { return fID == rhs.fID && fSubset == rhs.fSubset; } bool operator!=(const SkBitmapKey& rhs) const { return !(*this == rhs); } }; /** This class has all the advantages of SkBitmaps and SkImages. */ class SkImageSubset { public: SkImageSubset(sk_sp i, SkIRect subset = {0, 0, 0, 0}) : fImage(std::move(i)) { if (!fImage) { fSubset = {0, 0, 0, 0}; fID = 0; return; } fID = fImage->uniqueID(); if (subset.isEmpty()) { fSubset = fImage->bounds(); // SkImage always has a non-zero dimensions. SkASSERT(!fSubset.isEmpty()); } else { fSubset = subset; if (!fSubset.intersect(fImage->bounds())) { fImage = nullptr; fSubset = {0, 0, 0, 0}; fID = 0; } } } void setID(uint32_t id) { fID = id; } bool isValid() const { return fImage != nullptr; } SkIRect bounds() const { return SkIRect::MakeSize(this->dimensions()); } SkISize dimensions() const { return fSubset.size(); } sk_sp makeImage() const { return fSubset == fImage->bounds() ? fImage : fImage->makeSubset(fSubset); } SkBitmapKey getKey() const { return SkBitmapKey{fSubset, fID}; } void draw(SkCanvas* canvas, SkPaint* paint) const { SkASSERT(this->isValid()); SkRect src = SkRect::Make(fSubset), dst = SkRect::Make(this->bounds()); canvas->drawImageRect(fImage.get(), src, dst, paint); } private: SkIRect fSubset; sk_sp fImage; uint32_t fID; }; #endif // SkBitmapKey_DEFINED