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